Serilog 属性 丰富但仍然需要调用实际写入调用?
Serilog property enrichment but still required in call to actual write call?
我正在将 Serilog 添加到我们的日志记录基础设施中,但对以下内容感到困惑:
public class OzCpWriteEntryExInput : OzCpAppServiceInputBase
{
private readonly ILogger _Logger;
/// <summary>
/// Class constructor
/// </summary>
public OzCpWriteEntryExInput(ILogger aLogger)
{
//Save params supplied
_Logger = aLogger;
//Create resources required
Entry = new OzCpLogEntryContextInput();
}
public OzCpLogEntryContextInput Entry { get; set; }
public ILogger Logger => _Logger;
}
public class OzCpLoggingService : OzCruisingPlatformAppServiceBase, IOzCpLoggingService
{
private const string MESSAGE_TEMPLATE =
"{LogVersion} {DateTimeUtc:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level}] [{LevelRange}] [{ApplicationHostName}] [{ApplicationName}] [{ApplicationVersion}] [{Location}] {Message}{NewLine}{Exception}{NewLine}{StackTrace}{NewLine}{UserDataKind}{@UserData}";
public OzCpBuildLoggerOutput BuildLogger(OzCpBuildLoggerInput aParams)
{
OzCpBuildLoggerOutput result = new OzCpBuildLoggerOutput();
//#TODO (DE) Convert logger hard coded values into settings
bool logToUdp = true;
//By default logging will include all events
LoggerConfiguration loggerConfiguration = new LoggerConfiguration()
.Enrich.WithProperty("LogVersion", "01.00")
.MinimumLevel.Verbose();
if (logToUdp)
{
loggerConfiguration.WriteTo.Udp(IPAddress.Loopback, 11000, 0, LogEventLevel.Verbose, MESSAGE_TEMPLATE);
}
//Finally we can build the logger
result.Logger = loggerConfiguration.CreateLogger();
return result;
}
/// <summary>
/// Writes an entry to the supplied logger and associated log sinks.
/// </summary>
/// <param name="aParams">Parameters defining the entry to be written.</param>
/// <returns>Returns whether the entry was written to the logger.</returns>
public OzCpWriteEntryExOutput WriteEntryEx(OzCpWriteEntryExInput aParams)
{
OzCpWriteEntryExOutput result = new OzCpWriteEntryExOutput();
//These variable values are only the ones out of the entry as the logger "enriches" the other values based on
//what has been passed in when it was configured
object[] messageTemplateVariableValues =
{
"***", //Log Version is actually an enriched property!!!!
aParams.Entry.DateTimeUtc,
aParams.Entry.LevelRange,
aParams.Entry.Location,
aParams.Entry.StackTrace,
aParams.Entry.UserDataKind,
aParams.Entry.UserData
};
switch (aParams.Entry.EntryKind)
{
case OzCpLoggingEntryKindEnum.Verbose:
aParams.Logger.Verbose(aParams.Entry.Exception, MESSAGE_TEMPLATE, messageTemplateVariableValues);
break;
}
return result;
}
}
WriteLogEx() 的调用者最终可以提供他们自己的 Serilog.ILogger。我不会深入探讨为什么会出现这种情况,只是假设这是一项要求。
作为示例,我包含了 BuildLogger(),它设置一个 ILogger 以使用自定义消息模板和一些 其他属性通过丰富配置构建器写入 UDP。
一切都很简单。但是,现在当我使用 ILogger.Verbose() 写入 ILogger 时,我需要为消息模板中的标记传递参数。
然而这似乎是基于 序数 所以第一个进入 {LogVersion} 应该通过先前为记录器设置的丰富配置来完成。
如果我不使用 LogVersion,格式化的消息模板将被关闭一个,如果我包含它,那么我自然会得到:
*** 2016-04-14 14:53:57.677 +10:00 [Information]...
而不是我想要的是:
01.00 2016-04-14 14:53:57.677 +10:00 [Information]...
那么如何调用 ILogger 的日志记录方法并按名称而不是位置传递标记值?
不是在 .Verbose()
语句中传递这些,而是在那里传递特定于事件的数据。可以通过上下文化记录器来添加其他输出模板属性:
var ctx = logger.ForContext("DateTimeUtc", aParams.Entry.DateTimeUtc)
.ForContext("LevelRange", aParams.Entry.LevelRange)
// and so-on.
ctx.Verbose("Message here...");
有一个 ForContext()
重载接受一个 PropertyEnricher
数组,我相信你可以用它来整理东西。
我正在将 Serilog 添加到我们的日志记录基础设施中,但对以下内容感到困惑:
public class OzCpWriteEntryExInput : OzCpAppServiceInputBase
{
private readonly ILogger _Logger;
/// <summary>
/// Class constructor
/// </summary>
public OzCpWriteEntryExInput(ILogger aLogger)
{
//Save params supplied
_Logger = aLogger;
//Create resources required
Entry = new OzCpLogEntryContextInput();
}
public OzCpLogEntryContextInput Entry { get; set; }
public ILogger Logger => _Logger;
}
public class OzCpLoggingService : OzCruisingPlatformAppServiceBase, IOzCpLoggingService
{
private const string MESSAGE_TEMPLATE =
"{LogVersion} {DateTimeUtc:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level}] [{LevelRange}] [{ApplicationHostName}] [{ApplicationName}] [{ApplicationVersion}] [{Location}] {Message}{NewLine}{Exception}{NewLine}{StackTrace}{NewLine}{UserDataKind}{@UserData}";
public OzCpBuildLoggerOutput BuildLogger(OzCpBuildLoggerInput aParams)
{
OzCpBuildLoggerOutput result = new OzCpBuildLoggerOutput();
//#TODO (DE) Convert logger hard coded values into settings
bool logToUdp = true;
//By default logging will include all events
LoggerConfiguration loggerConfiguration = new LoggerConfiguration()
.Enrich.WithProperty("LogVersion", "01.00")
.MinimumLevel.Verbose();
if (logToUdp)
{
loggerConfiguration.WriteTo.Udp(IPAddress.Loopback, 11000, 0, LogEventLevel.Verbose, MESSAGE_TEMPLATE);
}
//Finally we can build the logger
result.Logger = loggerConfiguration.CreateLogger();
return result;
}
/// <summary>
/// Writes an entry to the supplied logger and associated log sinks.
/// </summary>
/// <param name="aParams">Parameters defining the entry to be written.</param>
/// <returns>Returns whether the entry was written to the logger.</returns>
public OzCpWriteEntryExOutput WriteEntryEx(OzCpWriteEntryExInput aParams)
{
OzCpWriteEntryExOutput result = new OzCpWriteEntryExOutput();
//These variable values are only the ones out of the entry as the logger "enriches" the other values based on
//what has been passed in when it was configured
object[] messageTemplateVariableValues =
{
"***", //Log Version is actually an enriched property!!!!
aParams.Entry.DateTimeUtc,
aParams.Entry.LevelRange,
aParams.Entry.Location,
aParams.Entry.StackTrace,
aParams.Entry.UserDataKind,
aParams.Entry.UserData
};
switch (aParams.Entry.EntryKind)
{
case OzCpLoggingEntryKindEnum.Verbose:
aParams.Logger.Verbose(aParams.Entry.Exception, MESSAGE_TEMPLATE, messageTemplateVariableValues);
break;
}
return result;
}
}
WriteLogEx() 的调用者最终可以提供他们自己的 Serilog.ILogger。我不会深入探讨为什么会出现这种情况,只是假设这是一项要求。
作为示例,我包含了 BuildLogger(),它设置一个 ILogger 以使用自定义消息模板和一些 其他属性通过丰富配置构建器写入 UDP。
一切都很简单。但是,现在当我使用 ILogger.Verbose() 写入 ILogger 时,我需要为消息模板中的标记传递参数。
然而这似乎是基于 序数 所以第一个进入 {LogVersion} 应该通过先前为记录器设置的丰富配置来完成。
如果我不使用 LogVersion,格式化的消息模板将被关闭一个,如果我包含它,那么我自然会得到:
*** 2016-04-14 14:53:57.677 +10:00 [Information]...
而不是我想要的是:
01.00 2016-04-14 14:53:57.677 +10:00 [Information]...
那么如何调用 ILogger 的日志记录方法并按名称而不是位置传递标记值?
不是在 .Verbose()
语句中传递这些,而是在那里传递特定于事件的数据。可以通过上下文化记录器来添加其他输出模板属性:
var ctx = logger.ForContext("DateTimeUtc", aParams.Entry.DateTimeUtc)
.ForContext("LevelRange", aParams.Entry.LevelRange)
// and so-on.
ctx.Verbose("Message here...");
有一个 ForContext()
重载接受一个 PropertyEnricher
数组,我相信你可以用它来整理东西。