当我们打开或关闭某些日志位置时,log4j实际上在做什么? [英] what's log4j actually doing when we turn on or off some log places?

查看:79
本文介绍了当我们打开或关闭某些日志位置时,log4j实际上在做什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们知道我们可以通过其属性/配置文件来配置log4j以关闭特定位置(Java中的类或包)的日志。我的问题是:


  1. log4j实际上为这些标志做了什么?

  2. 是log4j中仍然调用的日志语句,但由于该标志而没有写入文件或控制台?那么仍然会对性能产生影响吗?

  3. 就像C ++中的#ifdef在编译时生效然后会限制性能影响吗?

谢谢,

解决方案

是的,日志语句仍将被执行。这就是为什么首先检查日志级别的好方法:类似

  if(log.isInfoEnabled()){
log.info(我的大长信息字符串:+ someMessage);
}

这是为了避免重新分配信息的空间字符串当日志级别不支持 INFO 语句时。



这不是什么 #ifdef - #ifdef 是编译器指令,而Log4J配置是在运行时处理的。



编辑:我讨厌由于无知而降级,所以这里有一篇文章支持我的答案。



来自 http://surguy.net/articles/removing-log-messages.xml


在Log4J中,如果你在
DEBUG级别记录一条消息,那么当前的Appender
是设置为仅记录INFO
级别及以上的消息,然后消息将不显示
。调用log方法
本身的性能
惩罚是最小的 - 几纳秒。
但是,可能需要更长的时间来
来评估log
方法的参数。例如:



logger.debug(大对象是
+ largeObject.toString());



评估largeObject.toString()可能
很慢,并且在
之前评估对记录器的调用,因此记录器
不能阻止它被评估,
即使它不会被使用。


编辑2 :来自log4j手册本身( http://logging.apache.org/log4j/1.2/manual.html ):



用户应该了解以下性能问题。


  1. 关闭日志记录时的记录性能。
    当完全关闭日志记录或仅针对一组级别关闭日志记录时,日志请求的开销包括方法调用和整数比较。在233 MHz Pentium II机器上,此成本通常在5到50纳秒范围内。



    但是,方法调用涉及参数构造的隐藏成本。 / p>

    例如,对于某些记录器猫,写作,

      logger。 debug(条目号:+ i +是+ String.valueOf(entry [i])); 

    会产生构造消息参数的成本,即将整数i和entry [i]转换为a字符串和连接中间字符串,无论是否记录消息。参数构造的成本可能非常高,这取决于所涉及参数的大小。



    为避免参数构造成本写入:

      if(logger.isDebugEnabled(){
    logger.debug(条目号:+ i +是+ String.valueOf(条目) [i]));
    }

    这不会产生参数构建的成本,如果调试被禁用。另一方面,如果记录器启用了调试,则会产生两倍于评估记录器是否启用的成本:一次在debugEnabled中,一次在调试中。这是一个微不足道的开销,因为评估一个记录器需要大约1%的时间来实际记录。



We know we can config log4j to turn off log on specific places (class or package in Java) via its properties/configuration file. My questions are followed:

  1. what's log4j actually doing for those flags?
  2. is the log statement in log4j still called but just not being written to file or console because of that flag? so still have performance impact?
  3. is it like #ifdef in C++ which take effect at compile time then can limit the performance impact?

thanks,

解决方案

Yes, the log statements will still be executed. This is why it's a good pattern to check the log level first: something like

if (log.isInfoEnabled()) {
    log.info("My big long info string: " + someMessage);
}

This is to keep from reallocating space for the info String when the log level does not support INFO statements.

It's not anything like #ifdef - #ifdef is a compiler directive, whereas Log4J configurations are processed at runtime.

Edit: I hate getting downmodded due to ignorance, so here is one article backing up my answer.

From http://surguy.net/articles/removing-log-messages.xml:

In Log4J, if you log a message at DEBUG level, and the current Appender is set to only log messages of INFO level and above, then the message will not be displayed. The performance penalty for calling the log method itself is minimal - a few nanoseconds. However, it may take longer to evaluate the arguments to the log method. For example:

logger.debug("The large object is "+largeObject.toString());

Evaluating largeObject.toString() may be slow, and it is evaluated before the call to the logger, so the logger cannot prevent it being evaluated, even though it will not be used.

Edit 2: from the log4j manual itself (http://logging.apache.org/log4j/1.2/manual.html):

The user should be aware of the following performance issues.

  1. Logging performance when logging is turned off. When logging is turned off entirely or just for a set of levels, the cost of a log request consists of a method invocation plus an integer comparison. On a 233 MHz Pentium II machine this cost is typically in the 5 to 50 nanosecond range.

    However, The method invocation involves the "hidden" cost of parameter construction.

    For example, for some logger cat, writing,

     logger.debug("Entry number: " + i + " is " + String.valueOf(entry[i]));
    

    incurs the cost of constructing the message parameter, i.e. converting both integer i and entry[i] to a String, and concatenating intermediate strings, regardless of whether the message will be logged or not. This cost of parameter construction can be quite high and it depends on the size of the parameters involved.

    To avoid the parameter construction cost write:

    if(logger.isDebugEnabled() {
      logger.debug("Entry number: " + i + " is " + String.valueOf(entry[i]));
    }
    

    This will not incur the cost of parameter construction if debugging is disabled. On the other hand, if the logger is debug-enabled, it will incur twice the cost of evaluating whether the logger is enabled or not: once in debugEnabled and once in debug. This is an insignificant overhead because evaluating a logger takes about 1% of the time it takes to actually log.

这篇关于当我们打开或关闭某些日志位置时,log4j实际上在做什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆