我很想知道,在你的应用程序中,使用log4net DebugFormat类型调用的典型影响是什么。我将忽略诸如每行代码的日志语句数量等变量,因为我只是想了解你在现实世界中见过的任何情况。
此外,我也知道添加长评估语句的守卫子句的简单技巧,例如:
if (log.IsDebug)
{
log.DebugFormat(...);
}
所以,现在先排除这个考虑。
if (log.IsDebug)
{
log.DebugFormat(...);
}
我不熟悉log4net,或者log.DebugFormat(...)。
但是记录日志的成本主要在两个方面。
第一个是记录日志调用,第二个是实际保存日志信息。
当记录日志不是必需时,使用守卫可以将记录日志调用最小化。由于它只是一个方法调用和两个标量比较,因此通常非常快速。
然而,当您不使用守卫时,成本可能会变成创建实际记录日志参数的代价。
例如,在log4j中,这是一种常见的习惯用法:
log.debug("Runtime error. Order #" + order.getOrderNo() + " is not posted.");
在这里,“cost”指的是对字符串表达式进行实际评估并生成消息的成本。这是由于无论记录级别如何,都会创建该表达式和生成的字符串。想象一下,如果你有这样的东西:
log.debug("Something wrong with this list: " + longListOfData);
这可能会创建一个大而昂贵的字符串变量,如果日志级别未设置为DEBUG,则该变量将被浪费。
守卫:
if (log.isDebug()) {
log.debug(...);
}
由于isDebug调用相对于参数实际创建而言很廉价,因此消除了这个问题。
在我的代码中,我编写了一个记录器的封装,我可以像这样创建日志:
log.debug("Runtime error. Order # {0} is not posted.", order.getOrderNo());
这是一个不错的妥协方案。它依赖于Java varargs,并且我的代码检查日志级别,然后适当地格式化消息。这几乎和guards一样快,但更容易编写。
现在,log.DebugFormat可能会做类似的事情,但我不确定。
当然,在此基础上,实际的日志记录成本(输出到屏幕、文件、套接字等)也是需要接受的成本。我的最佳实践是,如果可行,将实际的日志消息路由到队列中,然后使用单独的线程将其收集并输出到正确的通道。这至少有助于将日志记录与主计算分开,但它也有自己的费用和复杂性。
我知道这是一个旧帖子,但是如何使用一种避免根据日志级别填充if语句的方法来解决问题呢?可以考虑使用lambda表达式来构建消息,甚至可以完全避免对其进行评估。这篇文章提供了一些关于延迟消息格式化在Log4Net中的扩展方法:http://www.beefycode.com/post/Extension-Methods-for-Deferred-Message-Formatting-in-Log4Net.aspx
我会给Will Hartung的回答加上.NET的视角 :)
DebugFormat代码如下:
if (IsDebugEnabled)
{
Logger.Log(ThisDeclaringType, m_levelDebug, new SystemStringFormat(CultureInfo.InvariantCulture, format, args), null);
}
基本上它是一样的,所以我相信当你使用DebugFormat时,你不需要使用守卫条款(你可能仍然有一些开销,但我认为这足够小,可以忽略)
本来想留下评论的,但我声望不够 :/