log4net日志记录方法(Debug,Info等)的速度有多快?

时间:2008-10-07 15:17:36

标签: performance logging log4net

我是log4net的忠实粉丝,但最近,有些人(在我的部门)质疑它是否包含在我们的项目中,因为每种日志记录方法看似沉重。我认为有比其他技术更好的技术,但这是另一个问题。

我很想知道,log4net DebugFormat类型调用对您的应用程序的典型影响是什么。我将在每行代码中省略诸如日志语句数等变量,因为我只是在寻找你在现实世界中看到的任何东西。

并且,我知道在长评估语句中添加保护子句的简单技术,例如:

if (log.IsDebug)
{
  log.DebugFormat(...);
}

所以,我们暂时不考虑这一点。

4 个答案:

答案 0 :(得分:11)

我不熟悉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,我的代码检查日志记录级别,然后适当地格式化消息。这几乎与守卫一样快,但写得更清晰。

现在,log.DebugFormat可能会做类似的事情,我不知道。

当然,最重要的是记录(到屏幕,文件,套接字等)的实际成本。但这只是你需要接受的成本。在实际操作中,我的最佳实践是将实际的日志消息路由到队列,然后使用单独的线程将其重新获取并输出到正确的通道。这至少有助于使日志记录与主计算不一致,但它有自己的费用和复杂性。

答案 1 :(得分:6)

我知道这是一个旧线程,但是如何使用一种方法来避免使用基于日志级别的if语句填充代码,例如: http://www.beefycode.com/post/Extension-Methods-for-Deferred-Message-Formatting-in-Log4Net.aspx

使用lambda表达式构建消息,您甚至可以避免完全评估它。

答案 2 :(得分:4)

log4net FAQ has an answer to this,但不是您要查找的详细程度。

总结:使用那些保护条款。

答案 3 :(得分:3)

Just Will Will Hartung的回答是.NET的观点:)

DebugFormat代码是:

if (IsDebugEnabled)
{
    Logger.Log(ThisDeclaringType, m_levelDebug, new SystemStringFormat(CultureInfo.InvariantCulture, format, args), null);
}

基本上它是一样的所以我相信当你使用DebugFormat时你不需要使用guard子句(你可能仍然有一个小的开销,但我认为它足够小,可以被忽略)

会留下评论,但我没有足够的声誉:/