结论
- 日志中间件 = 请求日志的切面(AOP)
- Serilog = 真正的日志框架(记录、文件、控制台、格式化)
- 最佳实践:两个必须配合使用!
一、它们到底是什么?
1. 写的 日志中间件 / 过滤器(中间件/过滤器 的对比选择)
作用:
- 拦截请求
- 输出 请求路径、方法、耗时、状态码
- 属于业务 / 请求层面的日志
它不负责:
- 日志写入文件
- 日志格式化
- 日志分级(Info/Warn/Error)
- 日志滚动、清理
它只是 **"日志的来源"**。
2. Serilog
作用:
- 真正的日志系统
- 把日志输出到:控制台、文件、ES、数据库等
- 支持结构化日志
- 自动切割文件、自动清理
- 企业级标配
它是 **"日志的输出工具"**。
二、正确关系
日志中间件(产生日志) → Serilog(输出日志)
就像:
- 过滤器 / 中间件 = 说话的人
- Serilog = 麦克风 + 音响 + 录音设备
三、企业标准用法(你必须这么写)
1. 用 Serilog 接管整个程序的日志(Program.cs)
2. 日志中间件 不直接用 Console.WriteLine
3. 日志中间件 调用 Serilog 记录请求日志
四、企业级最终代码(复制即用)
第一步:安装 Serilog 包(DDD四层架构安装结构)
cs
Serilog
Serilog.AspNetCore
Serilog.Sinks.Console
Serilog.Sinks.File
第二步:appsettings.json配置
cs
//添加 Serilog 配置
"Serilog": {
"MinimumLevel": {
"Default": "Debug",
"Override": {
"Microsoft": "Warning",
"System": "Warning"
}
},
"WriteTo": [
{ "Name": "Console" },
{
"Name": "File",
"Args": {
"path": "Logs/log-.txt",
"rollingInterval": "Day",
"outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] {Message:lj}{NewLine}{Exception}"
}
}
]
}
第三步:LogMiddleware.cs 日志中间件(使用 Serilog)
cs
public class LogMiddleware
{
private readonly RequestDelegate _next;
private readonly ILogger<LogMiddleware> _logger;
// 直接注入 Serilog 的 ILogger
public LogMiddleware(RequestDelegate next, ILogger<LogMiddleware> logger)
{
_next = next;
_logger = logger;
}
public async Task InvokeAsync(HttpContext context)
{
var path = context.Request.Path;
var method = context.Request.Method;
_logger.LogInformation($"【请求开始】{method} {path}");
var stopwatch = Stopwatch.StartNew();
await _next(context);
stopwatch.Stop();
_logger.LogInformation($"【请求结束】{method} {path} | 耗时:{stopwatch.ElapsedMilliseconds}ms");
}
}
第四步:Program.cs 注册使用 (将中间件封装成扩展方法)
cs
//Serilog 注册(用 Serilog 替换默认日志)
builder.Host.UseSerilog((ctx, cfg) =>
{
cfg.ReadFrom.Configuration(ctx.Configuration);// 从 appsettings.json 读取日志配置
});
//................
app.UseLogMiddleware();
五、最终效果
- 控制台漂亮输出日志
- 自动生成
Logs/log-20251225.txt日志文件 - 全局异常、请求、业务都统一用 Serilog 记录
- 日志格式统一、可收集、可排查