在 Serilog MsSql 接收器中填充自定义列

Sun*_*ilA 5 c# serilog asp.net-core

我在我的 dotnet 核心应用程序中使用 Serilog。我已将自定义列添加到 Serilog 提供的默认列列表中。下面是我的“Serilog”配置在 appsettings.json 文件中的样子 -

"Serilog": {
"MinimumLevel": "Information",
"WriteTo": [
  {
    "Name": "MSSqlServer",
    "Args": {
      "connectionString": <connectionString>
      "tableName": "Log",
      "autoCreateSqlTable": true,
      "columnOptionsSection": {
        "removeStandardColumns": [ "MessageTemplate", "Properties"], //remove the Properties column in the standard ones
        "customColumns": [
          {
            "ColumnName": "ControllerName",
            "DataType": "varchar",
            "DataLength": 50
          }
        ]
      },
      "timeStamp": {
        "columnName": "Timestamp",
        "convertToUtc": true
      }
    }
    }
]
}
Run Code Online (Sandbox Code Playgroud)

因此,我从 Serilog 创建的默认列列表中删除了“MessageTemplate”和“Properties”,并将“ControllerName”作为新列添加到表Log中,Serilog 在其中记录其数据。我想要的是,当我记录信息时,我想为“ControllerName”列提供值。如何做呢?我找到了以下解决方案:

_logger.LogInformation("{ControllerName}{Message}", "TestController", "Starting up.."); 
Run Code Online (Sandbox Code Playgroud)

这行代码为 ControllerName 列提供值,但消息列获取的值如下

"TestController""Starting up.."
Run Code Online (Sandbox Code Playgroud)

我希望消息列的值如下

 Starting up..
Run Code Online (Sandbox Code Playgroud)

Cai*_*ete 7

看来您正在使用 Microsoft 的ILogger<T>而不是 Serilog 的ILogger,因此为了添加将包含在日志事件中而不是消息的一部分的上下文属性,您必须使用例如创建一个新的日志记录范围BeginScope

using (_logger.BeginScope("{ControllerName}", nameof(TestController)))
{
    _logger.LogInformation("{Message}", "Starting up..."); 
}
Run Code Online (Sandbox Code Playgroud)

另一种选择是向 Serilog 添加一个属性LogContext

using (LogContext.PushProperty("ControllerName", nameof(TestController))
{
    _logger.LogInformation("{Message}", "Starting up..."); 
}
Run Code Online (Sandbox Code Playgroud)

这将为您提供与上面相同的最终结果,但它是特定于 Serilog 的 API,并且有点违背了最初BeginScope使用的目的,因此除非您决定使用 Serilog,否则这是首选。ILogger<T>BeginScopeILogger

一项重要的观察是,为了使其LogContext正常工作,您需要在配置记录器时启用它。例如:

Log.Logger = new LoggerConfiguration()
    .Enrich.FromLogContext() // <<<<<<<<<<#############
    .WriteTo.Console()
    .CreateLogger();
Run Code Online (Sandbox Code Playgroud)

如果您要使用 Serilog ILogger,那么除了能够使用之外,LogContext您还可以使用以下命令创建新上下文Log.ForContext

var contextLogger = logger.ForContext("ControllerName", nameof(TestController));
contextLogger.Information("{Message}", "Starting up...");
Run Code Online (Sandbox Code Playgroud)

ps:如果你不确定是否应该使用微软的ILogger<T>还是Serilog的ILogger,我建议阅读这个答案:ASP.NET Core中的Serilog DI,要注入哪个ILogger接口?