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

Serilog按EventType属性过滤日志:JSON转代码遇阻求助

根据EventType属性将Serilog日志输出到不同Sink的硬编码实现方案

需求背景

需要根据日志事件的EventType属性值,把日志分发到不同的输出Sink。已经通过JSON配置搞定了这个策略,但在C#硬编码时踩了坑,试了Serilog Expressions的语法后完全没日志输出。

原JSON配置片段

之前能用的JSON配置大概是这样:

{
  "Serilog": {
    "WriteTo": [
      {
        "Name": "Conditional",
        "Args": {
          "condition": "EventType = 'Error'",
          "sink": {
            "Name": "File",
            "Args": { "path": "./logs/errors.log" }
          }
        }
      },
      {
        "Name": "Conditional",
        "Args": {
          "condition": "EventType = 'Info'",
          "sink": {
            "Name": "File",
            "Args": { "path": "./logs/info.log" }
          }
        }
      }
    ]
  }
}

尝试失败的C#代码

我一开始试了两种写法都没输出:
第一种直接硬写属性判断:

Log.Logger = new LoggerConfiguration()
    .WriteTo.File("./logs/errors.log", restrictedToMinimumLevel: LogEventLevel.Error,
        filter: e => e.Properties["EventType"].ToString() == "'Error'")
    .WriteTo.File("./logs/info.log", restrictedToMinimumLevel: LogEventLevel.Information,
        filter: e => e.Properties["EventType"].ToString() == "'Info'")
    .CreateLogger();

第二种尝试用Serilog Expressions的语法,结果也不行:

Log.Logger = new LoggerConfiguration()
    .WriteTo.File("./logs/errors.log", 
        filter: "@EventType = 'Error'")
    .WriteTo.File("./logs/info.log", 
        filter: "@EventType = 'Info'")
    .CreateLogger();

可行方案:用WriteTo.Conditional实现

后来改用WriteTo.Conditional就成功了,正确的硬编码写法如下:

Log.Logger = new LoggerConfiguration()
    .WriteTo.Conditional(
        condition: e => e.Properties.TryGetValue("EventType", out var eventType) && 
                        eventType.ToString() == "'Error'",
        sink: wt => wt.File("./logs/errors.log"))
    .WriteTo.Conditional(
        condition: e => e.Properties.TryGetValue("EventType", out var eventType) && 
                        eventType.ToString() == "'Info'",
        sink: wt => wt.File("./logs/info.log"))
    .CreateLogger();

提示:如果不想处理ToString()带单引号的问题,可以用更精准的类型判断来获取属性值:

.WriteTo.Conditional(
    condition: e => e.Properties.TryGetValue("EventType", out var eventType) && 
                    eventType is ScalarValue scalar && 
                    scalar.Value.ToString() == "Error",
    sink: wt => wt.File("./logs/errors.log"))

更推荐的方案:WriteTo.Logger

如果你的日志规则更复杂(比如不同Sink要设置不同的日志级别、格式化器),WriteTo.Logger嵌套配置的方式更合适,优势很明显:

  • 每个子Logger可以独立配置完整的日志规则,包括级别过滤、格式化、输出Sink等
  • 结构更清晰,后续维护复杂的多Sink策略更方便
    示例代码:
Log.Logger = new LoggerConfiguration()
    .WriteTo.Logger(lc => lc
        .Filter.ByIncludingOnly(e => e.Properties.TryGetValue("EventType", out var et) && 
                                     et is ScalarValue s && s.Value.ToString() == "Error")
        .WriteTo.File("./logs/errors.log", restrictedToMinimumLevel: LogEventLevel.Error))
    .WriteTo.Logger(lc => lc
        .Filter.ByIncludingOnly(e => e.Properties.TryGetValue("EventType", out var et) && 
                                     et is ScalarValue s && s.Value.ToString() == "Info")
        .WriteTo.File("./logs/info.log", restrictedToMinimumLevel: LogEventLevel.Information))
    .CreateLogger();

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 14:25:25