【问题标题】:how does logging filter work internally when it comes to performance considerations?考虑到性能时,日志过滤器在内部是如何工作的?
【发布时间】:2023-01-09 15:45:08
【问题描述】:

假设我们在 appsetting.json 中有一个带有 LogLevel 的类别名称为“调试”,下面是源代码行

_logger.LogDebug("SubjectId is {Id}", id);

假设应用程序处于生产状态,我们将日志记录级别改为“信息”而不是“调试”。

但是那段源代码仍然存在于源代码中,日志语句仍然会首先执行,然后以某种方式将日志记录过滤掉。这不是很低效吗,因为它仍然需要调用一个方法?我们可以根本不调用_logger.LogDebug("SubjectId is {Id}", id); 使用一些高级运行时技术让 CLR 运行时根本不调用此方法吗?

还是当前的日志记录设计已经使用了某种技术来实现我上面描述的?

【问题讨论】:

  • 如果没有运行时本身的支持,我无法想象这种技术可以在运行时执行此操作(而且我相信现在没有这样的支持)。然而,简单方法调用+比较可能产生任何显着效果的应用程序数量非常非常少。如果你有这样的超级性能关键应用程序——那么你不会调用Debug——你至少会首先检查是否启用了调试,然后才会调用Debug

标签: c# .net logging


【解决方案1】:

如评论中所述,需要这样做可能会对系统性能提出非常高的要求。有可能您有一些其他方法调用、与数据库的通信、对外部系统的调用等,这些将比简单的日志调用花费更长的时间。旨在首先优化那些。

您可以做的是检查是否启用了调试日志记录,然后仅在这种情况下调用 LogDebug 方法:

if (_logger.IsEnabled(LogLevel.Debug))
    _logger.LogDebug("SubjectId is {Id}", id);

这适用于一种或几种方法。但是,如果您需要在多个日志语句之前使用 if,那么编写起来很快就会变得乏味。

.NET 5 和更新版本支持源代码生成器,可用于为您生成日志记录代码(包括if)。这是我在这个主题上找到的最好的帖子:Improving logging performance with source generators

【讨论】:

    猜你喜欢
    • 2018-07-28
    • 2012-12-25
    • 1970-01-01
    • 1970-01-01
    • 2021-02-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-31
    相关资源
    最近更新 更多