ILogger (ASP.NET Core) 日志被调用甚至 IsEnabled 返回 false

Mak*_*kla 5 asp.net-core

我试图了解ILogger 接口中IsEnabled方法的目的。我希望每次可以记录某些内容时都会自动调用该方法,但是无论返回 IsEnabled 什么,都会调用方法 Log。

我应该在 Log 方法中检查 IsEnabled 吗?

    public bool IsEnabled(LogLevel logLevel)
    {
        return logLevel >= this.level;
    }

    public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter)
    {
        if (this.IsEnabled(logLevel))   //it seams that this is required ????
        {
            string s = formatter(state, exception);
            string formatted = s.Replace("\r\n", "\r\n                          ");
            Console.WriteLine(string.Format("{0,-15} {1,-5} - {2}", logLevel, eventId, formatted));
        }
    }
Run Code Online (Sandbox Code Playgroud)

那么目的是什么以及谁(为什么)调用 IsEnabled。

Gra*_*ant 11

IsEnabled当您传递参数时尤其重要。

没有启用

logger.LogDebug("My debug message with {payload}", Serialize(myPayload));
Run Code Online (Sandbox Code Playgroud)

在这种情况下,myPayload 在每次调用时都会被序列化,LogDebug无论您的日志级别设置如何。这可能在生产环境中造成不必要的影响,并可能导致意外错误。如果 Serialize 方法由于意外数据而失败怎么办?

使用 IsEnabled

if (logger.IsEnabled(LogLevel.Debug))
{
    logger.LogDebug("My debug message with {payload}", Serialize(myPayload));
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,仅当LogDebug在您的设置中启用时, myPayload 才会被序列化。

平衡的方法

就我个人而言,我跳过IsEnabled对 Log() 方法(例如logger.LogDebug("constant string"))的“常量文本”调用的检查,并且仅IsEnabled在需要使用参数进行记录时进行测试。


Mic*_*haC 4

除非微软改变它,否则你应该给IsEnabled自己打电话。

原因是,如果 API 调用 IsEnabled,然后用户的代码调用 IsEnabled,则每个日志操作的调用量将增加一倍,并且对性能的影响将超过最终的帮助。

此外,在将某些内容写入日志接收器之前,日志记录框架始终会尊重过滤器和最小日志级别。这意味着,如果您总是调用LogDebug,并且Information是您配置的最低日志级别,则调试消息将不会出现在日志中。

但!LogDebug如果您不检查logger.IsEnabled(LogLevel.Debug)并仅在必要时运行代码,则会执行要调用和过滤的代码。

希望这是有道理的

  • 我知道这是一个旧答案,但我觉得有必要评论一下,让“ILogger”接口强制创建一个“IsEnabled”方法似乎很奇怪,而该方法不希望被调用(除了您自己的代码) , 如果你想)。为什么它是界面的一部分?如果我需要一个“IsEnabled”方法,即使它不是接口的一部分,我也可以创建一个。(似乎没有理由认为“IsEnabled”是“ILogger”接口的一部分。) (6认同)