new extensions
421f83bebda5293f0bb1abcb1ec697185a8ede18
4 files changed
src/VanDerHeijden.Logging.Web/README.mdsrc/VanDerHeijden.Logging.Web/VanDerHeijden.Logging.Web.csprojsrc/VanDerHeijden.Logging.Web/WebLoggingExtensions.cssrc/VanDerHeijden.Logging.Web/icon.png
diff --git a/src/VanDerHeijden.Logging.Web/README.md b/src/VanDerHeijden.Logging.Web/README.md
deleted file mode 100644
index d993e3f..0000000
--- a/src/VanDerHeijden.Logging.Web/README.md
+++ /dev/null
@@ -1,121 +0,0 @@
-# VanDerHeijden.Logging
-
-High-performance, low-allocation batched logging for .NET 10, built on Microsoft.Extensions.Logging.
-Log entries are enqueued to an in-memory Channel<T> and flushed asynchronously in configurable batches. No I/O occurs on the hot path (application code).
-
-Supports pluggable writers:
-- Daily rotating text files
-- MongoDB collections
-- SQL Server (SqlBulkCopy)
-- Redis lists (RPUSH)
-- Custom implementations
-
-**VanDerHeijden.Logging.Web** adds HTTP-context extensions for structured request logging.
-
-## Packages
-
-| Package | Description | NuGet Link |
-|----------------------------------|--------------------------------------------------|------------|
-| VanDerHeijden.Logging | Core abstractions & batched logger | [NuGet](https://www.nuget.org/packages/VanDerHeijden.Logging) |
-| VanDerHeijden.Logging.File | Daily rotating text file writer | (separate package) |
-| VanDerHeijden.Logging.Web | ILogger extensions with HttpContext scope | (separate package) |
-| VanDerHeijden.Logging.MongoDb | MongoDB collection writer | (separate) |
-| VanDerHeijden.Logging.Sql | SQL Server bulk insert writer | (separate) |
-| VanDerHeijden.Logging.Redis | Redis list writer | (separate) |
-
-## Installation
-
-```bash
-dotnet add package VanDerHeijden.Logging
-dotnet add package VanDerHeijden.Logging.File # recommended text file sink
-dotnet add package VanDerHeijden.Logging.Web # for web request context logging
-```
-
-## Core Setup (Program.cs)
-
-```csharp
-using VanDerHeijden.Logging.File;
-
-builder.Logging.AddBatchedFileLogger(options =>
-{
- options.LogDirectory = "Logs";
- options.BatchSize = 200;
- options.MaxIdleMilliseconds = 4000;
- options.FullMode = BatchFullMode.DropOldest; // or Wait
- // Optional: custom file naming, buffer size, etc.
-});
-```
-
-## Web Logging Extensions Usage
-
-In controllers, services, endpoints:
-
-```csharp
-using Microsoft.AspNetCore.Mvc;
-using VanDerHeijden.Logging.Web;
-
-[ApiController]
-[Route("api/orders")]
-public class OrdersController(ILogger<OrdersController> logger) : ControllerBase
-{
- [HttpPost]
- public IActionResult Create(OrderDto dto)
- {
- try
- {
- // business logic...
- logger.LogInformationWithContext(
- HttpContext,
- "Order created {OrderId} by {User}",
- 12345,
- dto.UserId);
-
- return Ok();
- }
- catch (Exception ex)
- {
- logger.LogErrorWithContext(
- HttpContext,
- "Failed to create order {OrderId}",
- dto.Id);
-
- return StatusCode(500);
- }
- }
-}
-```
-
-Available extensions (all add structured scope):
-
-- `LogInformationWithContext(HttpContext?, string, params object?[])`
-- `LogWarningWithContext`
-- `LogErrorWithContext`
-- `LogDebugWithContext`
-
-Scope properties added (if HttpContext provided):
-
-- TraceId
-- RequestMethod
-- RequestUrl (full scheme/host/path/query)
-- ClientIp (X-Forwarded-For aware)
-- Referer
-- UserAgent
-- User (from ClaimsPrincipal)
-- SessionId (if session enabled)
-
-Falls back to plain log if context is null.
-
-## Features
-
-- Zero I/O / low-allocation on Log() calls
-- Configurable batch size & idle timeout
-- Background flush consumer
-- Daily file rotation (no restart needed)
-- Thread-safe, proxy-friendly (X-Forwarded-For)
-- Structured properties for sinks like Seq, ELK, etc.
-
-## Repository
-
-https://github.com/alphons/VanDerHeijden.Logging
-
-MIT license. Issues / PRs welcome.
diff --git a/src/VanDerHeijden.Logging.Web/VanDerHeijden.Logging.Web.csproj b/src/VanDerHeijden.Logging.Web/VanDerHeijden.Logging.Web.csproj
deleted file mode 100644
index 57978ac..0000000
--- a/src/VanDerHeijden.Logging.Web/VanDerHeijden.Logging.Web.csproj
+++ /dev/null
@@ -1,29 +0,0 @@
-<Project Sdk="Microsoft.NET.Sdk">
-
- <PropertyGroup>
- <TargetFramework>net10.0</TargetFramework>
- <ImplicitUsings>enable</ImplicitUsings>
- <Nullable>enable</Nullable>
- <PackageId>VanDerHeijden.Logging.Web</PackageId>
- <Version>10.0.4</Version>
- <Authors>VanDerHeijden</Authors>
- <Description>Web log writer for VanDerHeijden.Logging: writes batched log entries to daily rotating text files.</Description>
- <PackageTags>logging;web;batched</PackageTags>
- <PackageReadmeFile>README.md</PackageReadmeFile>
- <GenerateDocumentationFile>true</GenerateDocumentationFile>
- <PackageProjectUrl>https://github.com/alphons/VanDerHeijden.Logging</PackageProjectUrl>
- <RepositoryUrl>https://github.com/alphons/VanDerHeijden.Logging.git</RepositoryUrl>
- <RepositoryType>git</RepositoryType>
- <PackageLicenseExpression>GPL-3.0-or-later</PackageLicenseExpression>
- <PackageIcon>icon.png</PackageIcon>
- </PropertyGroup>
-
-
-
- <ItemGroup>
- <PackageReference Include="Microsoft.AspNetCore.Http.Abstractions" Version="2.3.9" />
- <PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="10.0.3" />
- <PackageReference Include="Microsoft.Net.Http.Headers" Version="10.0.3" />
- </ItemGroup>
-
-</Project>
diff --git a/src/VanDerHeijden.Logging.Web/WebLoggingExtensions.cs b/src/VanDerHeijden.Logging.Web/WebLoggingExtensions.cs
deleted file mode 100644
index 3c55540..0000000
--- a/src/VanDerHeijden.Logging.Web/WebLoggingExtensions.cs
+++ /dev/null
@@ -1,126 +0,0 @@
-using Microsoft.AspNetCore.Http;
-using Microsoft.Extensions.Logging;
-using Microsoft.Net.Http.Headers;
-
-namespace VanDerHeijden.Logging.Web;
-
-/// <summary>
-/// Extension methods for ILogger<T> to log messages with HTTP context information as structured logging scope.
-/// </summary>
-public static class WebLoggingExtensions
-{
- /// <summary>
- /// Logs an information message with HTTP context properties added to the logging scope.
- /// </summary>
- /// <typeparam name="T">The type of the logging category.</typeparam>
- /// <param name="logger">The logger instance.</param>
- /// <param name="context">The current HTTP context. If null, logs without context scope.</param>
- /// <param name="message">The log message (may contain named format items).</param>
- /// <param name="args">Arguments for the message format.</param>
- public static void LogInformationWithContext<T>(
- this ILogger<T> logger,
- HttpContext? context,
- string message,
- params object?[] args)
- {
- LogWithContext(logger, context, LogLevel.Information, message, args);
- }
-
- /// <summary>
- /// Logs an error message with HTTP context properties added to the logging scope.
- /// </summary>
- /// <typeparam name="T">The type of the logging category.</typeparam>
- /// <param name="logger">The logger instance.</param>
- /// <param name="context">The current HTTP context. If null, logs without context scope.</param>
- /// <param name="message">The log message (may contain named format items).</param>
- /// <param name="args">Arguments for the message format.</param>
- public static void LogErrorWithContext<T>(
- this ILogger<T> logger,
- HttpContext? context,
- string message,
- params object?[] args)
- {
- LogWithContext(logger, context, LogLevel.Error, message, args);
- }
-
- /// <summary>
- /// Logs a warning message with HTTP context properties added to the logging scope.
- /// </summary>
- /// <typeparam name="T">The type of the logging category.</typeparam>
- /// <param name="logger">The logger instance.</param>
- /// <param name="context">The current HTTP context. If null, logs without context scope.</param>
- /// <param name="message">The log message (may contain named format items).</param>
- /// <param name="args">Arguments for the message format.</param>
- public static void LogWarningWithContext<T>(
- this ILogger<T> logger,
- HttpContext? context,
- string message,
- params object?[] args)
- {
- LogWithContext(logger, context, LogLevel.Warning, message, args);
- }
-
- /// <summary>
- /// Logs a debug message with HTTP context properties added to the logging scope.
- /// </summary>
- /// <typeparam name="T">The type of the logging category.</typeparam>
- /// <param name="logger">The logger instance.</param>
- /// <param name="context">The current HTTP context. If null, logs without context scope.</param>
- /// <param name="message">The log message (may contain named format items).</param>
- /// <param name="args">Arguments for the message format.</param>
- public static void LogDebugWithContext<T>(
- this ILogger<T> logger,
- HttpContext? context,
- string message,
- params object?[] args)
- {
- LogWithContext(logger, context, LogLevel.Debug, message, args);
- }
-
- /// <summary>
- /// Internal helper that applies HTTP context as logging scope and logs at the specified level.
- /// </summary>
- /// <typeparam name="T">The type of the logging category.</typeparam>
- /// <param name="logger">The logger instance.</param>
- /// <param name="context">The HTTP context to extract properties from. Can be null.</param>
- /// <param name="level">The log level to use.</param>
- /// <param name="message">The log message template.</param>
- /// <param name="args">Arguments for the message template.</param>
- private static void LogWithContext<T>(
- ILogger<T> logger,
- HttpContext? context,
- LogLevel level,
- string message,
- object?[] args)
- {
- if (context == null)
- {
- logger.Log(level, message, args);
- return;
- }
-
- string? ip = context.Connection.RemoteIpAddress?.ToString() ?? "unknown";
- string? forwarded = context.Request.Headers["X-Forwarded-For"].FirstOrDefault();
- if (!string.IsNullOrEmpty(forwarded))
- {
- ip = forwarded.Split(',').First().Trim();
- }
-
- Dictionary<string, object?> scopeProps = new()
- {
- ["RequestMethod"] = context.Request.Method,
- ["RequestUrl"] = $"{context.Request.Scheme}://{context.Request.Host}{context.Request.Path}{context.Request.QueryString}",
- ["ClientIp"] = ip,
- ["TraceId"] = context.TraceIdentifier,
- ["Referer"] = context.Request.Headers[HeaderNames.Referer].FirstOrDefault() ?? string.Empty,
- ["UserAgent"] = context.Request.Headers[HeaderNames.UserAgent].FirstOrDefault() ?? string.Empty,
- ["SessionId"] = context.Session?.Id ?? string.Empty,
- ["User"] = context.User?.Identity?.Name ?? "anonymous"
- };
-
- using (logger.BeginScope(scopeProps))
- {
- logger.Log(level, message, args);
- }
- }
-}
diff --git a/src/VanDerHeijden.Logging.Web/icon.png b/src/VanDerHeijden.Logging.Web/icon.png
deleted file mode 100644
index a0f1fdb..0000000
Binary files a/src/VanDerHeijden.Logging.Web/icon.png and /dev/null differ