Serilog多Sink日志分类配置异常问题求助
问题分析
你的Serilog配置逻辑错误,因为Serilog的过滤器是全局链式叠加的,不是针对单个输出目标(sink)独立生效的。原代码的执行逻辑是:
- 所有日志先写入SQLite(此时无过滤器)
- 之后只保留
Serilog.AspNetCore.RequestLoggingMiddleware来源的日志,后续的File和Seq都只会处理这类日志 - 再叠加“仅包含异常的日志”过滤器,最终Seq只能接收既是HTTP请求日志又带异常的日志,完全不符合需求。
修正后的配置
要实现三个独立的日志分流逻辑,需要给每个sink单独配置过滤条件,使用WriteTo.Conditional来实现:
new LoggerConfiguration() .Enrich.WithExceptionDetails(new DestructuringOptionsBuilder() .WithDefaultDestructurers() .WithRootName("Message") .WithRootName("Exception")) .Enrich.WithProperty("App.Version", System.Reflection.Assembly.GetExecutingAssembly().GetName().Version?.ToString() ?? "0.0.0.0") .Enrich.WithMachineName() .Enrich.WithEnvironmentUserName() // 1. 除HTTP请求日志外,写入SQLite .WriteTo.Conditional( logEvent => !Matching.FromSource("Serilog.AspNetCore.RequestLoggingMiddleware")(logEvent), wt => wt.SQLite(GetFilePath("logs.db")) ) // 2. 仅HTTP请求日志,写入每日滚动文件 .WriteTo.Conditional( logEvent => Matching.FromSource("Serilog.AspNetCore.RequestLoggingMiddleware")(logEvent), wt => wt.File( GetFilePath("access.log"), rollingInterval: RollingInterval.Day, retainedFileCountLimit: 31 ) ) // 3. 仅包含异常的日志,写入Seq .WriteTo.Conditional( logEvent => logEvent.Exception != null, wt => wt.Seq("https://mylogger.appserver.com/") );
关键说明
- 每个
WriteTo.Conditional独立控制对应sink的日志过滤逻辑,互相不干扰 - SQLite的条件是排除HTTP请求日志来源,用
!取反 - File的条件是仅包含HTTP请求日志来源
- Seq的条件是仅包含带有异常的日志(无论来源是什么)
另外注意原代码里重复调用了三次.WithRootName("Exception"),这会覆盖之前的设置,只保留最后一次的"Exception",已修正为只保留必要的两次(Message和Exception)。
内容的提问来源于stack exchange,提问作者Kazem Ma
相关产品推荐
相关产品推荐

