【问题标题】:.NET logging level not mapping to event viewer event level.NET 日志记录级别未映射到事件查看器事件级别
【发布时间】:2022-11-10 22:15:36
【问题描述】:

当使用Microsoft.Extensions.Logging.EventLog 包进行日志记录时,the level 不会将TraceDebug 转移到事件查看器;他们以Information 的身份过来。

是我还是这就是包装的工作方式?我认为他们会将DebugTrace 级别事件映射到Verbose,但情况似乎并非如此。

logger.LogTrace("trace");
logger.LogDebug("debug");
logger.LogInformation("info");

事件查看器中的日志级别:

【问题讨论】:

    标签: .net .net-core logging event-viewer


    【解决方案1】:

    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;
    }
    

    【讨论】:

    • 仍然不明白为什么他们不会在事件查看器发言中将Debug 和/或Trace 映射到Verbose。对此有什么想法吗? ?
    • @spottedmahn Git Blame 显示映射为 all the way back to 2015。我怀疑这是为了与其他日志库保持一致。 Serilog did the same at the time
    • 至于其他库为什么这样做,确实有道理。增加服务、驱动程序或应用程序中的事件日志级别意味着在不影响其他进程的情况下发出更多消息。事件日志比文件日志更接近 Kafka 队列。当您提高日志记录级别时,大多数日志记录框架会发出更大的消息,其中大部分包含非数据文本。这与事件日志的预期相反
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-09-22
    • 2011-05-06
    • 1970-01-01
    • 1970-01-01
    • 2020-04-27
    • 1970-01-01
    • 2010-12-17
    相关资源
    最近更新 更多