Microsoft.Extensions.Logging.HttpLogging 1.0.6
Microsoft.Extensions.Logging.HttpLogging
将 .NET Web 应用的 HTTP 请求/响应日志异步采集并写入 SQL Server,支持中间件采集、后台通道缓冲、存储过程写入、查询与维护。适合本地与企业内部集中化日志场景。
核心特性
- HTTP 日志中间件:自动采集请求/响应的基础信息、头、客户端信息等。
- 异步缓冲:使用有界
Channel(容量 1000,满时丢弃最旧)降低主线程阻塞。 - 后台写入:托管服务批量消费消息并通过存储过程入库。
- 可插拔处理器:实现
IHttpLoggingMessageHandler自定义写入策略(默认 SQL Server 存储过程)。 - 客户端能力:
IHttpLoggingClient提供追加、查询、删除、清空等维护操作。 - 多实例隔离:通过
HttpLoggingOptions.Key支持多路并行(通道/处理器/客户端均按 Key 隔离)。 - 配置监控:
IOptionsMonitor<HttpLoggingOptions>支持运行期更新连接串等配置。
安装
dotnet add package Microsoft.Extensions.Logging.HttpLogging
快速开始
1) 注册日志与中间件(默认处理器)
using Microsoft.Extensions.Logging;
builder.Services.AddLogging(logging =>
{
logging.AddHttpLogging(options =>
{
options.ConnectionString = "Server=localhost;Database=LogsDb;Trusted_Connection=True;TrustServerCertificate=True;";
options.Application = "MyWebApp";
options.TableName = "[dbo].[_Log_Http]";
options.PorcName = "[dbo].[_Log_Http_Append]";
options.SearchPorcName = "[dbo].[_Log_Http_Search]";
options.Key = "Logging.Http"; // 多实例时确保唯一
options.EnableRequest = true;
options.EnableResponse = false;
options.EnableHeaders = true;
options.EnableAgent = true;
options.EnableRequestBody = false; // 默认禁用,避免性能问题
options.EnableResponseBody = false;
options.RequestBodyLogLimit = 1024 * 1024; // 1MB
options.ResponseBodyLogLimit = 1024 * 1024; // 1MB
});
});
// 启用 HTTP 日志中间件(需在路由前)
var app = builder.Build();
app.UseHttpAccessLogging(); // 必须在 app.UseRouting() 之前
app.UseRouting();
app.MapGet("/ping", () => "pong");
app.Run();
首次运行若数据库无表/过程,默认处理器不会自动建表;请按下文“表结构与存储过程”准备对象。
2) 使用自定义消息处理器
实现自定义处理器以替代默认 SQL 写入策略:
using Microsoft.Extensions.Logging;
public class MyHttpHandler : IHttpLoggingMessageHandler
{
private readonly ILogger<MyHttpHandler> _logger;
public MyHttpHandler(ILogger<MyHttpHandler> logger) => _logger = logger;
public Task HandleAsync(HttpLoggingMessage message, CancellationToken token = default)
{
// 写入自定义存储(如文件/ES/消息队列/第三方平台)
_logger.LogInformation("{Method} {Path} from {IP}", message.Method, message.Path, message.IPAddress);
return Task.CompletedTask;
}
public void Dispose() { /* 释放资源 */ }
}
// 注册自定义处理器
builder.Services.AddLogging(logging =>
{
logging.AddHttpLogging<MyHttpHandler>(options =>
{
options.Key = "Logging.Http.Custom";
// 若不使用 SQL,可忽略连接串/过程名等
});
});
多实例:不同业务线或环境可使用不同
Key分别配置与隔离。
从配置文件绑定
{
"Logging": {
"Http": {
"ConnectionString": "Server=localhost;Database=LogsDb;Trusted_Connection=True;TrustServerCertificate=True;",
"Application": "MyWebApp",
"TableName": "[dbo].[_Log_Http]",
"PorcName": "[dbo].[_Log_Http_Append]",
"SearchPorcName": "[dbo].[_Log_Http_Search]",
"Key": "Logging.Http",
"EnableRequest": true,
"EnableResponse": false,
"EnableHeaders": true,
"EnableAgent": true,
"EnableRequestBody": false,
"EnableResponseBody": false,
"RequestBodyLogLimit": 1048576,
"ResponseBodyLogLimit": 1048576
}
}
}
builder.Services.AddLogging(logging =>
{
logging.AddHttpLogging(o => builder.Configuration.GetSection("Logging:Http").Bind(o));
});
app.UseHttpLogging();
HTTP 日志消息结构
HttpLoggingMessage 字段:
- Application:应用名
- Machine:机器名
- SystemOs:操作系统信息
- Method:HTTP 方法
- Path:请求路径
- IPAddress:客户端 IP
- Agent:User-Agent
- Headers:请求/响应头(JSON)
- Direction:
Request或Response - Content:请求或响应主体(受
EnableRequestBody/EnableResponseBody与大小限制影响)
客户端维护能力(IHttpLoggingClient)
在控制器或后台任务中注入使用:
app.MapGet("/logs/search", async (HttpLoggingClientFactory factory, string? path) =>
{
var client = factory.CreateClient(); // 默认使用 Key=Logging.Http
var result = await client.SearchAsync(new HttpLoggingSearchOptions
{
Path = path,
PageIndex = 1,
PageSize = 50
});
return Results.Ok(result);
});
app.MapPost("/logs/add", async (HttpLoggingClientFactory factory) =>
{
var client = factory.CreateClient();
await client.AddAsync(new HttpLoggingMessage
{
Application = "MyWebApp",
Method = "POST",
Path = "/logs/add",
Direction = HttpDirection.Request,
Content = "manual"
});
return Results.Ok();
});
app.MapDelete("/logs/{id:long}", async (HttpLoggingClientFactory factory, long id) =>
{
var client = factory.CreateClient();
var affected = await client.DeleteAsync(id);
return Results.Ok(new { affected });
});
app.MapDelete("/logs", async (HttpLoggingClientFactory factory, DateTime? before) =>
{
var client = factory.CreateClient();
var affected = await client.DeleteAsync(new HttpLoggingSearchOptions { EndTime = before });
return Results.Ok(new { affected });
});
app.MapPost("/logs/clear", async (HttpLoggingClientFactory factory) =>
{
var client = factory.CreateClient();
await client.ClearAsyc();
return Results.Ok();
});
- 解析客户端:
var client = factory.CreateClient("Logging.Http");指定 Key 获取对应实例。 - 查询过程:依赖
SearchPorcName返回分页结果集。
参数配置详解(HttpLoggingOptions)
- Key:实例隔离键。默认
Logging.Http。 - ConnectionString:SQL Server 连接串。
- TableName:日志表名,默认
[dbo].[_Log_Http]。 - PorcName:写入存储过程名,默认
[dbo].[_Log_Http_Append]。 - SearchPorcName:查询存储过程名,默认
[dbo].[_Log_Http_Search]。 - Application:应用标识,默认
AppDomain.CurrentDomain.FriendlyName。 - EnableRequest:是否记录请求信息(默认 true)。
- EnableResponse:是否记录响应信息(默认 false)。
- EnableHeaders:是否记录头(默认 true)。
- EnableAgent:是否记录 User-Agent(默认 true)。
- EnableRequestBody:是否记录请求体(默认 false)。
- EnableResponseBody:是否记录响应体(默认 false)。
- RequestBodyLogLimit:请求体记录大小上限(默认 1MB)。
- ResponseBodyLogLimit:响应体记录大小上限(默认 1MB)。
表结构与存储过程约定
建议表结构(与默认处理器写入字段一致,含必要索引):
- ID bigint identity primary key
- Application nvarchar(128)
- Machine nvarchar(128)
- SystemOs nvarchar(256)
- Method nvarchar(16)
- Path nvarchar(1024)
- IPAddress nvarchar(64)
- Agent nvarchar(512) null
- Headers nvarchar(max) null
- Direction tinyint -- 0=Request,1=Response
- Content nvarchar(max) null
- Time datetime default(getdate())
写入过程 PorcName:入参与 HttpLoggingMessage 字段对应,插入一条记录。
查询过程 SearchPorcName:根据 HttpLoggingSearchOptions 支持模糊与时间范围,返回两个结果集(总数 + 当前页)。
注意:本库不强制自动建表/建过程,生产环境建议手工创建并做索引优化(Path/Time/Method/Application 等)。
进阶说明
- 多实例:不同
Key将创建独立Channel、处理器与客户端。 - 中间件顺序:务必在
UseRouting之前调用UseHttpLogging,以捕获完整请求。 - 连接重建:默认处理器在连接异常或连接串变化时自动重建
SqlConnection。 - 性能建议:
- 默认关闭消息体采集;在排障时短期打开并设置大小上限。
- 高并发场景队列满会丢弃最旧日志,需结合业务容忍度评估并可根据源码调整策略。
- 分库或分表可降低单表压力。
常见问题(FAQ)
- 中间件未生效?确保已调用
app.UseHttpLogging()且顺序在UseRouting()前。 - 无法写入 SQL?检查连接串、过程名、权限与过程参数是否一致。
- 如何按环境隔离?使用不同的
Key、不同的表/过程或数据库。 - 是否支持 .NET 8/10?项目目标为 .NET 8,可在更高版本运行。
许可证
版权所有 © netor.me 本项目遵循 MIT 协议。
联系方式
- 官网: http://netor.me
- 邮箱: support@netor.me
Showing the top 20 packages that depend on Microsoft.Extensions.Logging.HttpLogging.
| Packages | Downloads |
|---|---|
|
Microsoft.Extensions.Logging.Operates
将操作日志记录到数据库,支持高并发缓冲与后台批量入库。自动建表与存储过程,轻松实现集中日志持久化与查询分析。
|
3 |
2025年11月30日
- 新增agent搜索
2025年12月1日
- 新增自定义扩展
2025年12月1日
- 新增记录httpmethod的筛选配置
2025年12月3日
- 重构可以通过key 添加多个实力
- 可以单独使用 AddHttpLoggingClient 只集成客户端
.NET 8.0
- Dapper (>= 2.1.66)
- Microsoft.Data.SqlClient (>= 6.0.2)
- Netor.Extensions.StringExtensions (>= 6.1.1)