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

Appsettings.json中Serilog过滤规则不生效问题咨询

Serilog-Expressions 过滤健康检查日志的正确配置方案

一、核心排查:过滤规则的正确写法

过滤不生效大多是表达式错误或规则位置不对,先从最基础的配置入手:

1. 排除健康检查日志的两种常用方式

首先确保已安装Serilog.Expressions和Serilog.AspNetCore包,然后根据健康检查日志的特征配置过滤:

方式1:通过SourceContext排除

健康检查日志的SourceContext固定为Microsoft.AspNetCore.Diagnostics.HealthChecks,直接针对这个属性过滤最可靠:

"Serilog": {
  "Using": ["Serilog.Sinks.MSSqlServer", "Serilog.Expressions"],
  "MinimumLevel": "Information",
  "Filter": [
    {
      "Name": "ByExcluding",
      "Args": {
        "expression": "SourceContext = 'Microsoft.AspNetCore.Diagnostics.HealthChecks'"
      }
    }
  ],
  "WriteTo": [
    {
      "Name": "MSSqlServer",
      "Args": {
        "connectionString": "你的数据库连接字符串",
        "tableName": "Logs",
        "autoCreateSqlTable": true,
        "columnOptionsSection": {
          "addStandardColumns": ["RequestPath"]
        }
      }
    }
  ]
}

方式2:通过RequestPath排除

如果想用RequestPath过滤但没效果,先确认已启用请求日志属性收集:
在Program.cs中添加:

builder.Host.UseSerilog((ctx, lc) => lc
    .ReadFrom.Configuration(ctx.Configuration)
    .Enrich.FromLogContext());

// 必须放在UseRouting之后
app.UseSerilogRequestLogging();

然后配置文件的过滤表达式改为:

"Filter": [
  {
    "Name": "ByExcluding",
    "Args": {
      "expression": "RequestPath like '%health%'"
    }
  }
]

二、过滤规则的位置与优先级

  • 全局过滤:写在Serilog.Filter节点下,对所有Sink生效,这是最常用的方式。
  • Sink级过滤:如果只想让MSSqlServer排除健康日志,其他Sink正常输出,用Filtered包装Sink:
"WriteTo": [
  {
    "Name": "Filtered",
    "Args": {
      "expression": "not (RequestPath like '%health%' or SourceContext = 'Microsoft.AspNetCore.Diagnostics.HealthChecks')",
      "writeTo": [
        {
          "Name": "MSSqlServer",
          "Args": {
            // 你的SQL Sink配置
          }
        }
      ]
    }
  }
]

三、过滤可用属性的来源

过滤表达式用的是日志事件的属性,不是数据库表的列名,属性来源分三类:

  • 内置属性:Serilog自带的SourceContext、Timestamp、Level、MessageTemplate等,所有日志事件都包含。
  • 框架注入属性:ASP.NET Core提供的RequestPath、RequestMethod、StatusCode等,需要通过UseSerilogRequestLogging()或Enrich.FromLogContext()收集,仅请求相关日志有这些属性。
  • 自定义属性:自己通过LogContext.PushProperty("CustomProp", value)添加的属性,或者日志语句中的变量(比如Log.Information("用户{UserId}操作", userId)里的UserId),均可用于过滤。

四、自定义列过滤无效的排查要点

如果自定义列(比如RequestPath)过滤没效果,检查这几点:

  1. 确认属性已注入日志事件:先把日志输出到控制台,查看日志的Properties节点是否包含目标属性(比如RequestPath)。
  2. 属性名大小写严格匹配:日志事件中的属性名和过滤表达式里的要完全一致(比如requestPath和RequestPath是两个不同属性)。
  3. 列名≠属性名:过滤基于日志事件的属性,数据库列名只是属性的存储映射,不能用列名写过滤表达式。

五、验证过滤生效的小技巧

  • 先切换日志输出到控制台,看健康检查日志是否被过滤。如果控制台已过滤,说明是数据库Sink配置问题;如果控制台仍输出,是过滤表达式或属性收集的问题。
  • 开启Serilog调试日志排查错误:在Program.cs中添加:
Serilog.Debugging.SelfLog.Enable(msg => Console.WriteLine(msg));

查看是否有属性找不到或表达式解析错误的提示。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 13:53:25