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

Serilog多Sink日志分类配置异常问题求助

问题分析

你的Serilog配置逻辑错误,因为Serilog的过滤器是全局链式叠加的,不是针对单个输出目标(sink)独立生效的。原代码的执行逻辑是:

  1. 所有日志先写入SQLite(此时无过滤器)
  2. 之后只保留Serilog.AspNetCore.RequestLoggingMiddleware来源的日志,后续的File和Seq都只会处理这类日志
  3. 再叠加“仅包含异常的日志”过滤器,最终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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 04:40:02