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

使用Serilog.Sinks.GoogleCloudLogging如何将SqlException日志级别提升为Fatal?

问题:将SqlException日志统一提升为Fatal级别(Serilog + GoogleCloudLogging)

我在.NET应用中使用Serilog搭配Serilog.Sinks.GoogleCloudLogging将日志发送至Datadog,希望自动将所有SqlException日志提升为Fatal(或Critical)级别,无论其初始日志级别为Error或Warning。

我尝试过三种方式但均未成功,Datadog中仍显示原始日志级别:

  • 自定义增强器:创建增强器检测并修改SqlException日志事件,但Google Cloud Logging中的日志级别未改变,代码如下:
public void Enrich(LogEvent logEvent, ILogEventPropertyFactory propertyFactory)
{
  if (logEvent.Exception is SqlException)
  {
    logEvent = new LogEvent(logEvent.Timestamp, LogEventLevel.Fatal, logEvent.Exception, logEvent.MessageTemplate,
      logEvent.Properties.Select(p => new LogEventProperty(p.Key, p.Value))
    );
  }
}
  • 过滤器:应用过滤器尝试提升级别,但接收器中无效果
  • ExceptionHandlingMiddleware:通过全局中间件捕获异常修改级别,Google Cloud仍显示Error级别

请问使用Serilog.Sinks.GoogleCloudLogging时,是否有办法将所有SqlException日志条目修改为Fatal级别?


解决方案

核心原因:之前的方法为什么无效?

  • 自定义增强器:Serilog的Enrich仅用于添加日志属性,无法修改日志事件本身的级别。你在增强器中重新赋值logEvent只是修改了局部变量,原日志事件并未被改变。
  • 普通过滤器:仅用于决定是否记录日志,不具备修改级别能力。
  • ExceptionHandlingMiddleware:如果中间件中用_logger.LogError(ex, ...)记录日志,级别已被固定为Error,后续Serilog无法修改已生成的LogEvent级别。

方法1:自定义包装Sink(最直接)

创建一个Sink包装类,拦截所有日志事件,判断是否包含SqlException,修改级别后再传递给GoogleCloudLoggingSink:

public class RewriteLevelSink : ILogEventSink
{
    private readonly ILogEventSink _innerSink;

    public RewriteLevelSink(ILogEventSink innerSink)
    {
        _innerSink = innerSink;
    }

    public void Emit(LogEvent logEvent)
    {
        if (logEvent.Exception is SqlException)
        {
            // 创建新的LogEvent,替换级别为Fatal
            var rewrittenEvent = new LogEvent(
                logEvent.Timestamp,
                LogEventLevel.Fatal,
                logEvent.Exception,
                logEvent.MessageTemplate,
                logEvent.Properties.Select(p => new LogEventProperty(p.Key, p.Value))
            );
            _innerSink.Emit(rewrittenEvent);
        }
        else
        {
            _innerSink.Emit(logEvent);
        }
    }
}

Serilog配置时使用这个包装Sink:

Log.Logger = new LoggerConfiguration()
    .WriteTo.Sink(new RewriteLevelSink(
        new GoogleCloudLoggingSink(new GoogleCloudLoggingSinkOptions
        {
            // 填写你的Google Cloud Logging配置
            ProjectId = "your-project-id",
            LogId = "your-log-id"
        })
    ))
    .CreateLogger();

方法2:使用Serilog.Expressions(更灵活)

先安装Serilog.Expressions包,然后通过transform参数直接修改日志级别:

Log.Logger = new LoggerConfiguration()
    .WriteTo.GoogleCloudLogging(
        options => 
        {
            // 填写你的Google Cloud Logging配置
            options.ProjectId = "your-project-id";
            options.LogId = "your-log-id";
        },
        transform: logEvent => 
            logEvent.Exception is SqlException 
                ? new LogEvent(
                    logEvent.Timestamp,
                    LogEventLevel.Fatal,
                    logEvent.Exception,
                    logEvent.MessageTemplate,
                    logEvent.Properties.Select(p => new LogEventProperty(p.Key, p.Value))
                  )
                : logEvent
    )
    .CreateLogger();

方法3:使用WriteTo.Map分支处理

通过Map操作按是否为SqlException分支处理日志,重写级别后再转发到接收器:

Log.Logger = new LoggerConfiguration()
    .WriteTo.Map(
        logEvent => logEvent.Exception is SqlException,
        (isSqlException, writeTo) =>
        {
            var sinkOptions = new GoogleCloudLoggingSinkOptions
            {
                ProjectId = "your-project-id",
                LogId = "your-log-id"
            };

            if (isSqlException)
            {
                // 重写级别为Fatal后发送
                writeTo.Sink(new RewriteLevelSink(new GoogleCloudLoggingSink(sinkOptions)));
            }
            else
            {
                // 正常发送原级别日志
                writeTo.Sink(new GoogleCloudLoggingSink(sinkOptions));
            }
        })
    .CreateLogger();

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 05:43:10