在 Serilog MsSql 接收器中填充自定义列
Populate custom columns in Serilog MsSql sink
我在我的 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
}
}
}
]
}
所以我从 Serilog 创建的默认列列表中删除了“MessageTemplate”和“Properties”,并将 “ControllerName” 作为新列添加到 table Log,Serilog 在其中记录其数据。我想要的是,当我记录信息时,我想为“ControllerName”列提供值。如何做呢?
我找到了以下解决方案:
_logger.LogInformation("{ControllerName}{Message}", "TestController", "Starting up..");
这行代码为 ControllerName 列提供了值,但是 message 列得到的值是
"TestController""Starting up.."
我希望消息列的值设为
Starting up..
看来您使用的是 Microsoft 的 ILogger<T>
而不是 Serilog 的 ILogger
因此为了添加上下文 属性 它将包含在您的日志事件中而不是消息的一部分,您必须使用 BeginScope
创建一个新的 logging scope 例如
using (_logger.BeginScope("{ControllerName}", nameof(TestController)))
{
_logger.LogInformation("{Message}", "Starting up...");
}
另一种方法是在 Serilog 的 LogContext
:
中添加一个 属性
using (LogContext.PushProperty("ControllerName", nameof(TestController))
{
_logger.LogInformation("{Message}", "Starting up...");
}
这将为您提供与上面 BeginScope
相同的最终结果,但它是 Serilog-specific API 并且有点违背了使用 ILogger<T>
的目的首先,所以 BeginScope
将是首选,除非你决定使用 Serilog 的 ILogger
代替。
一个重要的观察结果是,为了使 LogContext
正常工作,您需要在配置记录器时启用它。例如:
Log.Logger = new LoggerConfiguration()
.Enrich.FromLogContext() // <<<<<<<<<<#############
.WriteTo.Console()
.CreateLogger();
如果您要使用 Serilog 的 ILogger
,那么除了能够使用 LogContext
之外,您还可以使用 Log.ForContext
:
创建一个新的上下文
var contextLogger = logger.ForContext("ControllerName", nameof(TestController));
contextLogger.Information("{Message}", "Starting up...");
ps:如果您不确定是应该使用 Microsoft 的 ILogger<T>
还是 Serilog 的 ILogger
,我建议阅读此答案:
我在我的 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
}
}
}
]
}
所以我从 Serilog 创建的默认列列表中删除了“MessageTemplate”和“Properties”,并将 “ControllerName” 作为新列添加到 table Log,Serilog 在其中记录其数据。我想要的是,当我记录信息时,我想为“ControllerName”列提供值。如何做呢? 我找到了以下解决方案:
_logger.LogInformation("{ControllerName}{Message}", "TestController", "Starting up..");
这行代码为 ControllerName 列提供了值,但是 message 列得到的值是
"TestController""Starting up.."
我希望消息列的值设为
Starting up..
看来您使用的是 Microsoft 的 ILogger<T>
而不是 Serilog 的 ILogger
因此为了添加上下文 属性 它将包含在您的日志事件中而不是消息的一部分,您必须使用 BeginScope
创建一个新的 logging scope 例如
using (_logger.BeginScope("{ControllerName}", nameof(TestController)))
{
_logger.LogInformation("{Message}", "Starting up...");
}
另一种方法是在 Serilog 的 LogContext
:
using (LogContext.PushProperty("ControllerName", nameof(TestController))
{
_logger.LogInformation("{Message}", "Starting up...");
}
这将为您提供与上面 BeginScope
相同的最终结果,但它是 Serilog-specific API 并且有点违背了使用 ILogger<T>
的目的首先,所以 BeginScope
将是首选,除非你决定使用 Serilog 的 ILogger
代替。
一个重要的观察结果是,为了使 LogContext
正常工作,您需要在配置记录器时启用它。例如:
Log.Logger = new LoggerConfiguration()
.Enrich.FromLogContext() // <<<<<<<<<<#############
.WriteTo.Console()
.CreateLogger();
如果您要使用 Serilog 的 ILogger
,那么除了能够使用 LogContext
之外,您还可以使用 Log.ForContext
:
var contextLogger = logger.ForContext("ControllerName", nameof(TestController));
contextLogger.Information("{Message}", "Starting up...");
ps:如果您不确定是应该使用 Microsoft 的 ILogger<T>
还是 Serilog 的 ILogger
,我建议阅读此答案: