代码之家  ›  专栏  ›  技术社区  ›  casademora

log4net日志记录方法(调试、信息等)有多快?

  •  6
  • casademora  · 技术社区  · 16 年前

    我非常喜欢 log4net 但是最近,一些人(在我的部门)质疑它是否包含在我们的项目中,因为每个日志方法看起来都很繁重。我认为有比其他人更好的技术,但这是另一个问题。

    我很好奇,log4net debugformat类型调用对应用程序的典型影响是什么。我将遗漏变量,比如每行代码的日志语句数等,因为我只是在寻找您在现实世界中看到的任何东西。

    而且,我知道在长评估语句中添加一个保护子句的简单方法,例如:

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

    所以,我们暂时不考虑这个问题。

    4 回复  |  直到 9 年前
        1
  •  11
  •   Will Hartung    16 年前

    我不熟悉log4net或log.debugformat(…)。

    但是伐木的成本实际上有两个方面。

    第一个是日志调用,第二个是日志信息的实际持久化。

    当实际不需要日志记录时,这些保护将有助于将日志记录调用减少到最低限度。它往往非常快,因为它只不过是一个方法调用和两个标量的比较。

    但是,如果不使用保护,则成本很可能成为创建实际日志参数的代价。

    例如,在log4j中,这是一个常见的习惯用法:

    log.debug("Runtime error. Order #" + order.getOrderNo() + " is not posted.");
    

    这里,成本是生成消息的字符串表达式的实际计算结果。这是因为不管日志级别如何,都会创建该表达式和生成的字符串。想象一下,如果你有这样的东西:

    log.debug("Something wrong with this list: " + longListOfData);
    

    这可能会创建一个大而昂贵的字符串变量,如果日志级别没有设置为调试,那么它将被浪费掉。

    警卫:

    if (log.isDebug()) {
        log.debug(...);
    }
    

    消除这个问题,因为isdebug调用很便宜,特别是与实际创建的参数相比。

    在我的代码中,我已经为日志编写了一个包装器,我可以像这样创建日志:

    log.debug("Runtime error. Order # {0} is not posted.", order.getOrderNo());
    

    这是一个很好的妥协。这依赖于Java VARARGS,并且我的代码检查日志记录级别,然后适当地格式化消息。这几乎和警卫一样快,但写起来要干净得多。

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

    当然,最重要的是日志记录的实际成本(到屏幕、到文件、到套接字等)。但这只是你需要接受的代价。我的最佳实践是,在可行的情况下,将实际的日志消息路由到一个队列,然后使用单独的线程将该队列获取并输出到适当的通道。这至少有助于保持登录与主计算的不一致,但它有自己的开销和复杂性。

        2
  •  6
  •   Pablo Romeo    12 年前

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

    使用lambda表达式来构建消息,甚至可以避免对其进行完全的计算。

        3
  •  4
  •   Joseph Yaduvanshi    13 年前

    这个 log4net FAQ has an answer to this 尽管没有达到你想要的详细程度。

    总之:使用这些保护条款。

        4
  •  3
  •   keisar    13 年前

    只是给威尔·哈顿的答案一个.NET视角:)

    调试格式代码为:

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

    基本上是一样的,所以我相信当你使用debugformat时,你不需要使用guard子句(你可能还有一点开销,但我认为它很小,可以忽略不计)。

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