Factory http context last

alphons <alphons@heijden.com> 9 Apr 2026, 11:11
eb60806baafd0aa29a6115d0eed156c45701460e
6 files changed
  • src/VanDerHeijden.Logging.File/FileLoggingBuilderExtensions.cs
  • src/VanDerHeijden.Logging.MongoDb/MongoDbLoggingBuilderExtensions.cs
  • src/VanDerHeijden.Logging.Redis/RedisLoggingBuilderExtensions.cs
  • src/VanDerHeijden.Logging.Sql/SqlLoggingBuilderExtensions.cs
  • src/VanDerHeijden.Logging/BatchedLogger.cs
  • tests/VanDerHeijden.Logging.Web/Controllers/HomeController.cs
diff --git a/src/VanDerHeijden.Logging.File/FileLoggingBuilderExtensions.cs b/src/VanDerHeijden.Logging.File/FileLoggingBuilderExtensions.cs
index 30b1437..b319100 100644
--- a/src/VanDerHeijden.Logging.File/FileLoggingBuilderExtensions.cs
+++ b/src/VanDerHeijden.Logging.File/FileLoggingBuilderExtensions.cs
@@ -30,11 +30,11 @@ public static class FileLoggingBuilderExtensions
var batchedLogger = new BatchedLogger<string>(logWriter, fullMode: BoundedChannelFullMode.Wait);
return new BatchedLoggerProvider<string>(
batchedLogger,
- entryFactory: (message, _, ctx, exception) =>
+ entryFactory: (category, message, _, exception, ctx) =>
{
var http = ctx is null ? "" : $" [{ctx.Method} {ctx.Path} {ctx.ClientIp}]";
var ex = exception is null ? "" : $"{Environment.NewLine}{exception}";
- return $"{DateTime.Now:yyyy-MM-dd HH:mm:ss.fff}{http} {message}{ex}{Environment.NewLine}";
+ return $"{DateTime.Now:yyyy-MM-dd HH:mm:ss.fff}{http} [{category}] {message}{ex}{Environment.NewLine}";
},
httpContextAccessor
);
diff --git a/src/VanDerHeijden.Logging.MongoDb/MongoDbLoggingBuilderExtensions.cs b/src/VanDerHeijden.Logging.MongoDb/MongoDbLoggingBuilderExtensions.cs
index 362b320..fe6421d 100644
--- a/src/VanDerHeijden.Logging.MongoDb/MongoDbLoggingBuilderExtensions.cs
+++ b/src/VanDerHeijden.Logging.MongoDb/MongoDbLoggingBuilderExtensions.cs
@@ -39,11 +39,11 @@ public static class MongoDbLoggingBuilderExtensions
var batchedLogger = new BatchedLogger<LogEntry>(logWriter, batchSize: 100, maxIdleMs: 3000, fullMode: BoundedChannelFullMode.DropOldest);
return new BatchedLoggerProvider<LogEntry>(
batchedLogger,
- entryFactory: (message, logLevel, ctx, exception) => new LogEntry
+ entryFactory: (category, message, logLevel, exception, ctx) => new LogEntry
{
Timestamp = DateTime.UtcNow,
Level = logLevel.ToString(),
- Category = message.Split(':')[0],
+ Category = category,
Message = message,
Exception = exception?.ToString(),
Path = ctx?.Path,
diff --git a/src/VanDerHeijden.Logging.Redis/RedisLoggingBuilderExtensions.cs b/src/VanDerHeijden.Logging.Redis/RedisLoggingBuilderExtensions.cs
index 4e23fba..33a3414 100644
--- a/src/VanDerHeijden.Logging.Redis/RedisLoggingBuilderExtensions.cs
+++ b/src/VanDerHeijden.Logging.Redis/RedisLoggingBuilderExtensions.cs
@@ -35,11 +35,11 @@ public static class RedisLoggingBuilderExtensions
var batchedLogger = new BatchedLogger<RedisLogEntry>(logWriter, batchSize: 200, maxIdleMs: 2000, fullMode: BoundedChannelFullMode.DropOldest);
return new BatchedLoggerProvider<RedisLogEntry>(
batchedLogger,
- entryFactory: (message, logLevel, ctx, exception) => new RedisLogEntry
+ entryFactory: (category, message, logLevel, exception, ctx) => new RedisLogEntry
{
Timestamp = DateTime.UtcNow,
Level = logLevel.ToString(),
- Category = message.Split(':')[0],
+ Category = category,
Message = message,
Exception = exception?.ToString(),
Path = ctx?.Path,
diff --git a/src/VanDerHeijden.Logging.Sql/SqlLoggingBuilderExtensions.cs b/src/VanDerHeijden.Logging.Sql/SqlLoggingBuilderExtensions.cs
index aaea802..01e54d5 100644
--- a/src/VanDerHeijden.Logging.Sql/SqlLoggingBuilderExtensions.cs
+++ b/src/VanDerHeijden.Logging.Sql/SqlLoggingBuilderExtensions.cs
@@ -32,11 +32,11 @@ public static class SqlLoggingBuilderExtensions
var batchedLogger = new BatchedLogger<SqlLogEntry>(logWriter, batchSize: 200, maxIdleMs: 4000, fullMode: BoundedChannelFullMode.Wait);
return new BatchedLoggerProvider<SqlLogEntry>(
batchedLogger,
- entryFactory: (message, logLevel, ctx, exception) => new SqlLogEntry
+ entryFactory: (category, message, logLevel, exception, ctx) => new SqlLogEntry
{
Timestamp = DateTime.UtcNow,
Level = logLevel.ToString(),
- Category = message.Split(':')[0],
+ Category = category,
Message = message,
Exception = exception?.ToString(),
Path = ctx?.Path,
diff --git a/src/VanDerHeijden.Logging/BatchedLogger.cs b/src/VanDerHeijden.Logging/BatchedLogger.cs
index f3309d1..50bef7d 100644
--- a/src/VanDerHeijden.Logging/BatchedLogger.cs
+++ b/src/VanDerHeijden.Logging/BatchedLogger.cs
@@ -161,8 +161,8 @@ public sealed class BatchedLogger<T> : IDisposable
/// <typeparam name="T">The type of log entry produced by <paramref name="entryFactory"/>.</typeparam>
/// <param name="batchedLogger">The shared batched logger used by all created loggers.</param>
/// <param name="entryFactory">
-/// A factory that converts a formatted message, <see cref="LogLevel"/>, an optional <see cref="HttpLogContext"/>,
-/// and an optional <see cref="Exception"/> into a <typeparamref name="T"/> entry.
+/// A factory that converts a category name, formatted message, <see cref="LogLevel"/>, an optional
+/// <see cref="HttpLogContext"/>, and an optional <see cref="Exception"/> into a <typeparamref name="T"/> entry.
/// </param>
/// <param name="httpContextAccessor">
/// Optional <see cref="IHttpContextAccessor"/> used to enrich log entries with request metadata.
@@ -170,7 +170,7 @@ public sealed class BatchedLogger<T> : IDisposable
/// </param>
public sealed class BatchedLoggerProvider<T>(
BatchedLogger<T> batchedLogger,
- Func<string, LogLevel, HttpLogContext?, Exception?, T> entryFactory,
+ Func<string, string, LogLevel, Exception?, HttpLogContext?, T> entryFactory,
IHttpContextAccessor? httpContextAccessor = null) : ILoggerProvider
{
/// <summary>
@@ -190,7 +190,7 @@ public sealed class BatchedLoggerProvider<T>(
internal sealed class BatchedCategoryLogger<T>(
BatchedLogger<T> batchedLogger,
string categoryName,
- Func<string, LogLevel, HttpLogContext?, Exception?, T> entryFactory,
+ Func<string, string, LogLevel, Exception?, HttpLogContext?, T> entryFactory,
IHttpContextAccessor? httpContextAccessor) : ILogger
{
public IDisposable? BeginScope<TState>(TState state) where TState : notnull => null;
@@ -199,8 +199,8 @@ internal sealed class BatchedCategoryLogger<T>(
public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception? exception, Func<TState, Exception?, string> formatter)
{
if (!IsEnabled(logLevel)) return;
- var message = $"{categoryName}: {formatter(state, exception)}";
- batchedLogger.Write(entryFactory(message, logLevel, BuildHttpContext(), exception));
+ var message = formatter(state, exception);
+ batchedLogger.Write(entryFactory(categoryName, message, logLevel, exception, BuildHttpContext()));
}
private HttpLogContext? BuildHttpContext()
diff --git a/tests/VanDerHeijden.Logging.Web/Controllers/HomeController.cs b/tests/VanDerHeijden.Logging.Web/Controllers/HomeController.cs
index a6c510e..3f9f2a6 100644
--- a/tests/VanDerHeijden.Logging.Web/Controllers/HomeController.cs
+++ b/tests/VanDerHeijden.Logging.Web/Controllers/HomeController.cs
@@ -2,10 +2,18 @@
namespace VanDerHeijden.Logging.Web.Controllers;
-public class HomeController : Controller
+public class HomeController(ILogger<HomeController> logger) : Controller
{
public IActionResult Index()
{
+ try
+ {
+ throw new Exception("Custom exception");
+ }
+ catch(Exception exception)
+ {
+ logger.LogError(exception, "Line1");
+ }
return View();
}
}