log4net日志记录方法(Debug、Info等)有多快?

6
我是log4net的忠实粉丝,但最近,由于每个日志方法看似过于繁重,我的一些同事开始质疑它在我们项目中的应用。我会辩称有更好的技术可供选择,但这是另一个问题。
我很想知道,在你的应用程序中,使用log4net DebugFormat类型调用的典型影响是什么。我将忽略诸如每行代码的日志语句数量等变量,因为我只是想了解你在现实世界中见过的任何情况。
此外,我也知道添加长评估语句的守卫子句的简单技巧,例如:
if (log.IsDebug)
{
  log.DebugFormat(...);
}

所以,现在先排除这个考虑。

你是将日志记录到控制台、文件还是数据库中?这在性能方面非常重要。 - Ben Hoffstein
4个回答

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,并且我的代码检查日志级别,然后适当地格式化消息。这几乎和guards一样快,但更容易编写。

现在,log.DebugFormat可能会做类似的事情,但我不确定。

当然,在此基础上,实际的日志记录成本(输出到屏幕、文件、套接字等)也是需要接受的成本。我的最佳实践是,如果可行,将实际的日志消息路由到队列中,然后使用单独的线程将其收集并输出到正确的通道。这至少有助于将日志记录与主计算分开,但它也有自己的费用和复杂性。


6

4

log4net FAQ中有答案,虽然不是你想要的详细程度。

总之:使用那些守卫条款。


3

我会给Will Hartung的回答加上.NET的视角 :)

DebugFormat代码如下:

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

基本上它是一样的,所以我相信当你使用DebugFormat时,你不需要使用守卫条款(你可能仍然有一些开销,但我认为这足够小,可以忽略)

本来想留下评论的,但我声望不够 :/


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接