使用 Serilog 的 MVC 日志记录不序列化对象
MVC logging with Serilog not serializing objects
MVC 核心 Web 服务项目,使用 AspNetCore 2.0.0 和 Serilogger 2.0.2。
在我们的一个控制器中,我正在尝试使用 Serilog 将请求数据记录到 Application Insights。
在我们的Startup:Configure方法中...
Serilog.ILogger serilogLogger = new LoggerConfiguration()
.MinimumLevel.Debug()
.Enrich.FromLogContext()
.WriteTo.ApplicationInsightsEvents( Configuration.GetValue<string>( "ApplicationInsights:InstrumentationKey" ) )
.CreateLogger();
loggerFactory.AddSerilog( serilogLogger );
没什么特别的。在我们的控制器中,我们有以下内容
public async Task<IActionResult> Create( [FromBody] List<Event> value )
{
foreach( Event e in value )
{
_logger.LogWarning( "***** Event Create {@event}", e );
}
}
我们在 App Insights 中看到的内容如下:
{"AspNetCoreEnvironment":"Development","{OriginalFormat}":"***** Event Create {@event}","DeveloperMode":"true","CategoryName":"Demo.Controllers.EventController","@event":"Demo.Models.Event"}
为什么它只给我类型,并将其序列化为 Json?
我已经尝试在 Event class 上重载 ToString 方法并从 LogWarning() 中删除 @,我们继续在日志中打印出类型。在本例中是 "string".
在这个页面的帮助下弄明白了:
https://github.com/serilog/serilog/wiki/Structured-Data
我们在设置中添加了一个 Destructure.With() 调用,并添加了一个 class 来处理我们数据的所有解构。
Serilog.ILogger logger = new LoggerConfiguration()
.ReadFrom.Configuration(Configuration)
.WriteTo.ApplicationInsightsEvents(Configuration.GetValue<string>("ApplicationInsights:InstrumentationKey"))
.Destructure.With<DestructureModels>()
.CreateLogger();
loggerFactory.AddSerilog(logger);
我们的解构 class 看起来像这样:
public class DestructureModels : IDestructuringPolicy
{
public bool TryDestructure( object value, ILogEventPropertyValueFactory propertyValueFactory, out LogEventPropertyValue result )
{
// to handle custom serialization of objects in the log messages
//
if( value.GetType().Namespace.Contains("MyProj.Models"))
{
result = new ScalarValue(JsonConvert.SerializeObject(value));
return true;
}
else
{
result = null;
return false;
}
}
}
不完美,因为它似乎只在设置为发送到 CustomEvents 时有效,它不适用于 AppInsights 中的 Traces。上面的解构 class 将被调用,但您不会在 AppInsights 中获取值。非常令人沮丧的是,缺少关于 how/why 这个东西有效的文档。此外,我们需要在我们的代码中显式记录,而不是能够利用 AppInsights 跟踪记录。
MVC 核心 Web 服务项目,使用 AspNetCore 2.0.0 和 Serilogger 2.0.2。
在我们的一个控制器中,我正在尝试使用 Serilog 将请求数据记录到 Application Insights。
在我们的Startup:Configure方法中...
Serilog.ILogger serilogLogger = new LoggerConfiguration()
.MinimumLevel.Debug()
.Enrich.FromLogContext()
.WriteTo.ApplicationInsightsEvents( Configuration.GetValue<string>( "ApplicationInsights:InstrumentationKey" ) )
.CreateLogger();
loggerFactory.AddSerilog( serilogLogger );
没什么特别的。在我们的控制器中,我们有以下内容
public async Task<IActionResult> Create( [FromBody] List<Event> value )
{
foreach( Event e in value )
{
_logger.LogWarning( "***** Event Create {@event}", e );
}
}
我们在 App Insights 中看到的内容如下:
{"AspNetCoreEnvironment":"Development","{OriginalFormat}":"***** Event Create {@event}","DeveloperMode":"true","CategoryName":"Demo.Controllers.EventController","@event":"Demo.Models.Event"}
为什么它只给我类型,并将其序列化为 Json? 我已经尝试在 Event class 上重载 ToString 方法并从 LogWarning() 中删除 @,我们继续在日志中打印出类型。在本例中是 "string".
在这个页面的帮助下弄明白了: https://github.com/serilog/serilog/wiki/Structured-Data
我们在设置中添加了一个 Destructure.With() 调用,并添加了一个 class 来处理我们数据的所有解构。
Serilog.ILogger logger = new LoggerConfiguration()
.ReadFrom.Configuration(Configuration)
.WriteTo.ApplicationInsightsEvents(Configuration.GetValue<string>("ApplicationInsights:InstrumentationKey"))
.Destructure.With<DestructureModels>()
.CreateLogger();
loggerFactory.AddSerilog(logger);
我们的解构 class 看起来像这样:
public class DestructureModels : IDestructuringPolicy
{
public bool TryDestructure( object value, ILogEventPropertyValueFactory propertyValueFactory, out LogEventPropertyValue result )
{
// to handle custom serialization of objects in the log messages
//
if( value.GetType().Namespace.Contains("MyProj.Models"))
{
result = new ScalarValue(JsonConvert.SerializeObject(value));
return true;
}
else
{
result = null;
return false;
}
}
}
不完美,因为它似乎只在设置为发送到 CustomEvents 时有效,它不适用于 AppInsights 中的 Traces。上面的解构 class 将被调用,但您不会在 AppInsights 中获取值。非常令人沮丧的是,缺少关于 how/why 这个东西有效的文档。此外,我们需要在我们的代码中显式记录,而不是能够利用 AppInsights 跟踪记录。