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

Serilog SQL Server Sink自定义Source列无法自动填充值导致插入失败

Serilog SQL Server Sink自定义Source列无法自动填充值导致插入失败

看起来你遇到的问题是自定义的Source列因为没法自动获取程序集名称,导致插入非空列时抛出NULL异常。我来帮你梳理下问题所在和解决办法:

问题根源分析

你的配置里同时用了additionalColumns和customColumns来定义Source列,这会造成映射冲突:

  • additionalColumns只是告诉Serilog要创建这个列,但不会把任何日志属性和它绑定;
  • customColumns是用来将日志中的属性映射到数据库列,但你得确保这个属性确实存在于日志事件里。

另外你尝试的几种Enrich方式没生效,要么是配置顺序不对,要么是缺少必要的NuGet包(比如用WithAssemblyName时)。

解决方案

1. 修正配置文件中的列映射

先修改appsettings.json里的Serilog配置,删掉重复的additionalColumns,只保留customColumns,同时确保列的非空设置正确:

"Serilog": {
  "Using": [
    "Serilog.Sinks.File",
    "Serilog.Sinks.MSSqlServer"
  ],
  "MinimumLevel": "Information",
  "WriteTo": [
    {
      "Name": "File",
      "Args": {
        "path": "Logs/log-.txt",
        "rollingInterval": "Day",
        "rollOnFileSizeLimit": true,
        "retainedFileCountLimit": 7,
        "fileSizeLimitBytes": 10000000,
        "flushToDiskInterval": "00:00:10"
      }
    },
    {
      "Name": "MSSqlServer",
      "Args": {
        "connectionString": "Server=xxxxxxxx",
        "tableName": "Error_Logs",
        "autoCreateSqlTable": true,
        "columnOptions": {
          "customColumns": [
            {
              "PropertyName": "Source",
              "ColumnName": "Source",
              "DataType": "nvarchar(128)",
              "AllowNull": false
            }
          ],
          "minimumLevel": "Error"
        }
      }
    }
  ]
}

2. 确保程序集名称被正确注入到日志属性

下面两种方式选一个就行:

方式一:代码中直接添加固定属性

在Program.cs里调整Logger配置顺序,确保Enrich.WithProperty在配置加载后执行(顺序其实不影响,但放后面逻辑更清晰):

using System.Reflection;
using Serilog;

// ...其他代码

Log.Logger = new LoggerConfiguration()
    .ReadFrom.Configuration(builder.Configuration, "AppSettings:Serilog")
    // 直接把当前程序集名称注入为Source属性
    .Enrich.WithProperty("Source", Assembly.GetExecutingAssembly().GetName().Name)
    .Enrich.FromLogContext()
    .CreateLogger();

方式二:使用Serilog的程序集名称Enricher

如果你想用配置文件里的Enrich节点,得先安装Serilog.Enrichers.Assembly这个NuGet包,然后修改配置:

"Serilog": {
  // ...其他配置
  "Enrich": ["WithAssemblyName"],
  "WriteTo": [
    // ...其他sink配置
    {
      "Name": "MSSqlServer",
      "Args": {
        // ...其他参数
        "columnOptions": {
          "customColumns": [
            {
              // 这里的PropertyName要和Enricher提供的属性名一致,默认是"AssemblyName"
              "PropertyName": "AssemblyName",
              "ColumnName": "Source",
              "DataType": "nvarchar(128)",
              "AllowNull": false
            }
          ]
        }
      }
    }
  ]
}

之后确保Program.cs里保留.Enrich.FromLogContext(),或者让ReadFrom.Configuration自动读取配置里的Enrich节点即可。

3. 测试验证

最后写一条Error级别的日志测试下:

Log.Error("Test error message");

去数据库的Error_Logs表里看看,Source列应该已经被正确填充为当前程序集的名称,不会再出现NULL插入错误了。

备注:内容来源于stack exchange,提问作者Skyhighjinks

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.23 11:29:06