如何使用 Serilog outputTemplate(固定宽度和截断 SourceContext)获得格式良好的文件日志
How to get nicely formatted file logs with Serilog outputTemplate (fixed width and truncation of SourceContext)
我正在从 log4net 切换到 Serilog,但错过了我在 log4net 中的一些格式化可能性。我没有找到关于我可以在 outputTemplate 中使用哪些格式化程序的任何文档。有什么方法可以完成我在下面描述的内容吗?
使用输出模板
"outputTemplate": "[{Timestamp:yyyy-MM-dd HH:mm:ss.fff} {Level:u3}] ({SourceContext}) {Message:lj}{NewLine}{Exception}"
看起来像这样
[2020-03-30 11:31:06.464 DBG] (DomainLogic.TCMessageHandler) >>>Poll
[2020-03-30 11:31:06.481 DBG] (AmqpReader.Reader) >>>Read
[2020-03-30 11:31:06.485 INF] (AmqpReader.Reader) Fetched a message from the queue.
[2020-03-30 11:31:06.487 DBG] (AmqpReader.Reader) <<<Read - 00:00:00.0066941
[2020-03-30 11:31:06.504 DBG] (DomainLogic.TCMessageHandler) <<<Poll - 00:00:00.0399191
这就是我想要的
[2020-03-30 11:31:06.464 DBG] (DomainLogic.TCMessageHandler) >>>Poll
[2020-03-30 11:31:06.481 DBG] (AmqpReader.Reader ) >>>Read
[2020-03-30 11:31:06.485 INF] (AmqpReader.Reader ) Fetched a message from the queue.
[2020-03-30 11:31:06.487 DBG] (AmqpReader.Reader ) <<<Read - 00:00:00.0066941
[2020-03-30 11:31:06.504 DBG] (DomainLogic.TCMessageHandler) <<<Poll - 00:00:00.0399191
如果我设置了一个固定的宽度并且 SourceContext 比那个长,我希望它从左边截断。像这样
[2020-03-30 11:31:06.464 DBG] (ogic.TCMessageHandler) >>>Poll
[2020-03-30 11:31:06.481 DBG] (AmqpReader.Reader ) >>>Read
[2020-03-30 11:31:06.485 INF] (AmqpReader.Reader ) Fetched a message from the queue.
[2020-03-30 11:31:06.487 DBG] (AmqpReader.Reader ) <<<Read - 00:00:00.0066941
[2020-03-30 11:31:06.504 DBG] (ogic.TCMessageHandler) <<<Poll - 00:00:00.0399191
Serilog 输出模板(和消息模板)基于 .NET 格式字符串,不支持截断替换值。没有办法直接在输出模板中执行此操作,尽管您可以编写一个 ILogEventEnricher
来替换 属性 的截断版本,具体取决于您打算如何使用事件。
这是一个完全符合我要求的浓缩器。
public class StaticWidthSourceContextEnricher : ILogEventEnricher
{
private readonly int _width;
public StaticWidthSourceContextEnricher(int width)
{
_width = width;
}
public void Enrich(LogEvent logEvent, ILogEventPropertyFactory propertyFactory)
{
var typeName = logEvent.Properties.GetValueOrDefault("SourceContext").ToString();
if (typeName.Length > _width)
{
typeName = typeName.Substring(typeName.Length - _width);
}
else if (typeName.Length < _width)
{
typeName = typeName + new string(' ', _width - typeName.Length);
}
logEvent.AddOrUpdateProperty(propertyFactory.CreateProperty("SourceContext", typeName));
}
}
我正在从 log4net 切换到 Serilog,但错过了我在 log4net 中的一些格式化可能性。我没有找到关于我可以在 outputTemplate 中使用哪些格式化程序的任何文档。有什么方法可以完成我在下面描述的内容吗?
使用输出模板
"outputTemplate": "[{Timestamp:yyyy-MM-dd HH:mm:ss.fff} {Level:u3}] ({SourceContext}) {Message:lj}{NewLine}{Exception}"
看起来像这样
[2020-03-30 11:31:06.464 DBG] (DomainLogic.TCMessageHandler) >>>Poll
[2020-03-30 11:31:06.481 DBG] (AmqpReader.Reader) >>>Read
[2020-03-30 11:31:06.485 INF] (AmqpReader.Reader) Fetched a message from the queue.
[2020-03-30 11:31:06.487 DBG] (AmqpReader.Reader) <<<Read - 00:00:00.0066941
[2020-03-30 11:31:06.504 DBG] (DomainLogic.TCMessageHandler) <<<Poll - 00:00:00.0399191
这就是我想要的
[2020-03-30 11:31:06.464 DBG] (DomainLogic.TCMessageHandler) >>>Poll
[2020-03-30 11:31:06.481 DBG] (AmqpReader.Reader ) >>>Read
[2020-03-30 11:31:06.485 INF] (AmqpReader.Reader ) Fetched a message from the queue.
[2020-03-30 11:31:06.487 DBG] (AmqpReader.Reader ) <<<Read - 00:00:00.0066941
[2020-03-30 11:31:06.504 DBG] (DomainLogic.TCMessageHandler) <<<Poll - 00:00:00.0399191
如果我设置了一个固定的宽度并且 SourceContext 比那个长,我希望它从左边截断。像这样
[2020-03-30 11:31:06.464 DBG] (ogic.TCMessageHandler) >>>Poll
[2020-03-30 11:31:06.481 DBG] (AmqpReader.Reader ) >>>Read
[2020-03-30 11:31:06.485 INF] (AmqpReader.Reader ) Fetched a message from the queue.
[2020-03-30 11:31:06.487 DBG] (AmqpReader.Reader ) <<<Read - 00:00:00.0066941
[2020-03-30 11:31:06.504 DBG] (ogic.TCMessageHandler) <<<Poll - 00:00:00.0399191
Serilog 输出模板(和消息模板)基于 .NET 格式字符串,不支持截断替换值。没有办法直接在输出模板中执行此操作,尽管您可以编写一个 ILogEventEnricher
来替换 属性 的截断版本,具体取决于您打算如何使用事件。
这是一个完全符合我要求的浓缩器。
public class StaticWidthSourceContextEnricher : ILogEventEnricher
{
private readonly int _width;
public StaticWidthSourceContextEnricher(int width)
{
_width = width;
}
public void Enrich(LogEvent logEvent, ILogEventPropertyFactory propertyFactory)
{
var typeName = logEvent.Properties.GetValueOrDefault("SourceContext").ToString();
if (typeName.Length > _width)
{
typeName = typeName.Substring(typeName.Length - _width);
}
else if (typeName.Length < _width)
{
typeName = typeName + new string(' ', _width - typeName.Length);
}
logEvent.AddOrUpdateProperty(propertyFactory.CreateProperty("SourceContext", typeName));
}
}