The source code of the GetEventLogEntryType 方法表明 Trace 和 Debug 被有意映射到 Information:
private static EventLogEntryType GetEventLogEntryType(LogLevel level)
{
switch (level)
{
case LogLevel.Information:
case LogLevel.Debug:
case LogLevel.Trace:
return EventLogEntryType.Information;
case LogLevel.Warning:
return EventLogEntryType.Warning;
case LogLevel.Critical:
case LogLevel.Error:
return EventLogEntryType.Error;
default:
return EventLogEntryType.Information;
}
}
为什么
这是有道理的,因为 Windows 事件日志旨在成为
- 近实时
- 始终在线
- 高频
- 旨在供计算机上的所有驱动程序和服务使用,而不仅仅是应用程序。
在这方面它类似于 Kafka,而不是 Elastic。在现代监控术语中,Windows 事件日志更接近 OpenTelemetry 的跟踪而不是日志记录。
强调写作速度,影响最小。事件日志是一种操作系统资源,滥用它会影响它的所有用户——从驱动程序级别向上的一切。一个事件条目应该包含只要事件 ID 和一些参数,因此它占用尽可能少的空间。确实不是长文本描述。发出调试事件意味着发出更细粒度的事件,而不是更大的事件。
期望为服务启用调试日志记录不会影响系统的其余部分。一个服务可以发出 20 个 32 字节的事件,而不是每秒发出 1 个 24 字节的事件。
消息本身由事件查看器等工具使用事件库中作为资源提供的模板呈现。甚至可以拥有多语言模板。
这类似于语义日志记录,其中只有事件 ID 和参数实际上是日志消息的一部分。根据需要使用消息模板显示事件本身。
另一方面,.NET Trace 和 Debug 级别用于发出大量非常详细的信息文本信息。将此类信息写入操作系统的事件日志
这是传统的
至于为什么添加了该映射,这可能是为了与当时的其他日志库保持一致。源代码在 Github 上,View Blame 帮助跟踪跨版本和 repos 的代码。
该映射早在 2015 年就已存在于 the first commit of EventLogLogger 中:
private EventLogEntryType GetEventLogEntryType(LogLevel level)
{
switch (level)
{
case LogLevel.Information:
case LogLevel.Debug:
case LogLevel.Verbose:
return EventLogEntryType.Information;
case LogLevel.Warning:
return EventLogEntryType.Warning;
case LogLevel.Critical:
case LogLevel.Error:
return EventLogEntryType.Error;
default:
return EventLogEntryType.Information;
}
}
当时其他日志框架也做了同样的事情,例如 Serilog 的 EventLogSink :
switch (logEvent.Level)
{
case LogEventLevel.Debug:
case LogEventLevel.Information:
case LogEventLevel.Verbose:
type = EventLogEntryType.Information;
break;
case LogEventLevel.Error:
case LogEventLevel.Fatal:
type = EventLogEntryType.Error;
break;
case LogEventLevel.Warning:
type = EventLogEntryType.Warning;
break;
default:
SelfLog.WriteLine("Unexpected logging level, writing to EventLog as Information");
type = EventLogEntryType.Information;
break;
}