You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C# Serilog使用子记录器与过滤器实现多文件输出的配置问题

C# Serilog 多格式日志分文件输出方案

需求背景

C#开发中使用Serilog组件时,需要实现两类日志分文件输出:

  • 调用WriteOperationalLog时输出常规格式日志
  • 调用WriteJsonLog时输出纯JSON格式日志

初始问题

最初尝试通过子记录器过滤JSON日志写入独立文件,但过滤器使用不当触发无限循环,初始配置代码如下:

Log.Logger = new LoggerConfiguration()
.MinimumLevel.Debug()
.WriteTo.File(filepath, rollingInterval: RollingInterval.Day) 
.WriteTo.Logger(lc => lc
    .Filter.ByIncludingOnly(WriteJsonLog)
    .WriteTo.File(new ExpressionTemplate("{ @m } \n"), filepathJson, rollingInterval: RollingInterval.Day))
.CreateLogger();

最终解决方案

步骤1:为JSON日志添加专属标记

在WriteJSONLog方法中通过Serilog.Context为JSON类日志添加专属属性标记,代码如下:

using(LogContext.PushProperty("JSON", true))
{
    Log.Information(json);
}

步骤2:调整日志配置实现分流过滤

借助Serilog.Filters包的属性匹配规则,分别对两类日志做过滤,写入对应文件,修正后的配置如下:

Log.Logger = new LoggerConfiguration()
.Enrich.FromLogContext() // 允许记录器读取日志上下文属性,此处用于识别JSON标识属性
.MinimumLevel.Debug()
.WriteTo.Logger(lc => lc
    .Filter.ByExcluding(Matching.WithProperty("JSON")) // 排除带JSON标记的日志,剩余写入常规日志文件
    .WriteTo.File(filepath, rollingInterval: RollingInterval.Day)) 
.WriteTo.Logger(lc => lc
    .Filter.ByIncludingOnly(Matching.WithProperty("JSON")) // 仅保留带JSON标记的日志,写入JSON专属文件
    .WriteTo.File(new ExpressionTemplate("{ @m } \n"), filepathJson, rollingInterval: RollingInterval.Day)) // 仅输出原始JSON内容,无多余格式前缀后缀
.CreateLogger();

核心注意点

  • Enrich.FromLogContext()是必填配置,否则日志上下文添加的JSON属性不会被记录器识别,过滤器无法生效
  • 两个子记录器分别做互斥过滤,避免同一日志同时写入两个文件,也避免了过滤逻辑循环触发的问题
  • 输出JSON文件时使用ExpressionTemplate("{ @m } \n"),可以直接输出原始JSON字符串,不会额外添加Serilog默认的时间、级别等前缀,符合纯JSON日志的需求

内容的提问来源于stack exchange,提问作者EvilBurp

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 12:24:03