.NET Core中Serilog数据库日志冗余问题求助(需保留请求响应体)
减少Serilog数据库日志行数(保留请求与响应体)
核心优化方向
在保留请求、响应体的前提下压缩日志行数,关键是避免重复日志条目、过滤框架冗余输出,同时将请求全生命周期的核心数据合并到单条日志中。
具体实现方案
1. 补全并调整Serilog配置
完善你的appsettings.json配置,过滤低级别框架日志,精简输出字段:
"Serilog": { "MinimumLevel": { "Default": "Information", "Override": { "Microsoft": "Warning", // 过滤微软类库的Info及以下冗余日志 "System": "Warning" } }, "WriteTo": [ { "Name": "MSSqlServer", // 按实际使用的数据库调整 "Args": { "connectionString": "你的数据库连接字符串", "tableName": "Logs", "autoCreateSqlTable": true, "columnOptionsSection": { "removeStandardColumns": ["MessageTemplate"], // 移除重复的模板列(非必需可删除) "customColumns": [ { "ColumnName": "RequestBody", "DataType": "nvarchar(max)" }, { "ColumnName": "ResponseBody", "DataType": "nvarchar(max)" } ] } } } ] }
2. 合并请求响应日志为单条
通过自定义中间件,在请求结束时一次性输出包含请求体、响应体的单条日志,避免请求开始/结束时分别打日志:
public class RequestResponseLoggingMiddleware { private readonly RequestDelegate _next; private readonly ILogger<RequestResponseLoggingMiddleware> _logger; public RequestResponseLoggingMiddleware(RequestDelegate next, ILogger<RequestResponseLoggingMiddleware> logger) { _next = next; _logger = logger; } public async Task InvokeAsync(HttpContext context) { // 读取请求体 context.Request.EnableBuffering(); var requestBody = await new StreamReader(context.Request.Body).ReadToEndAsync(); context.Request.Body.Position = 0; // 捕获响应体 var originalResponseBody = context.Response.Body; using var responseBodyStream = new MemoryStream(); context.Response.Body = responseBodyStream; await _next(context); responseBodyStream.Seek(0, SeekOrigin.Begin); var responseBody = await new StreamReader(responseBodyStream).ReadToEndAsync(); responseBodyStream.Seek(0, SeekOrigin.Begin); await responseBodyStream.CopyToAsync(originalResponseBody); context.Response.Body = originalResponseBody; // 输出单条合并日志 _logger.LogInformation( "请求路径: {Path}, 请求方法: {Method}, 请求体: {RequestBody}, 响应体: {ResponseBody}", context.Request.Path, context.Request.Method, requestBody, responseBody); } } // 在Program.cs注册中间件 app.UseMiddleware<RequestResponseLoggingMiddleware>();
3. 精简日志上下文 enrichment
如果日志中包含自动添加的非必需字段(如请求ID、会话ID等),可移除不必要的Enrich配置,只保留核心上下文信息:
Log.Logger = new LoggerConfiguration() .ReadFrom.Configuration(Configuration) // 只保留必需的enricher,比如下面示例只保留环境信息 .Enrich.WithEnvironmentName() .WriteTo.Console() .CreateLogger();
效果验证
调整后,每个请求仅生成一条包含请求体、响应体的日志,同时过滤掉框架自动生成的冗余日志,既能保留核心业务数据,又能大幅减少日志表的行数。
内容的提问来源于stack exchange,提问作者sosNiLa
相关产品推荐
相关产品推荐

