简体   繁体   English

Log4j日志记录性能

[英]Log4j logging performance

Log4j pattern layout docs warns that generating caller class information is costly and should be used only when performance is not a concern. Log4j模式布局文档警告说,生成调用方类信息的成本很高,仅在不考虑性能时才应使用。 I want to have the class name in logs for easy analysis and also doesn't want to have an impact in performance. 我希望将类名记录在日志中以便于分析,也不想影响性能。 Having stated that I have two options, 说了我两个选择,

  1. Store class name using getClass().getName() in every class and use that string in logging String class = getClass().getName(); ... ... logger.debug(class + "log message"); 在每个类中使用getClass()。getName()存储类名称,并在记录日志时使用该字符串String class = getClass().getName(); ... ... logger.debug(class + "log message"); String class = getClass().getName(); ... ... logger.debug(class + "log message");

  2. Hardcode the class name and give it in log String class = "com.foo.myclass"; ... ... logger.debug(class + "log message"); 硬编码类名称,并在日志中提供它String class = "com.foo.myclass"; ... ... logger.debug(class + "log message"); String class = "com.foo.myclass"; ... ... logger.debug(class + "log message");

Which would give better performance or is there any other way to log fully qualified class name and method name without affecting performance. 这将提供更好的性能,或者还有其他方法可以记录完全限定的类名和方法名而不影响性能。 Thanks in Advance! 提前致谢!

Note: I am using log4j 1.2.16 注意:我正在使用log4j 1.2.16

Generating the caller class name is costly but if you're following the typical Log4J design pattern of one Logger per class with the Logger name being the same as the class name 生成调用方类名称的成本很高,但是如果遵循典型的Log4J设计模式,即每个类一个Logger ,且Logger名称与类名称相同

private static final Logger LOG = Logger.getLogger(ThisClassName.class);

then it may be sufficient to simply use %c instead of %C in your layout pattern. 那么在布局模式中仅使用%c代替%C可能就足够了。 This uses the logger name (which is a property of the logger itself) rather than inspecting the call stack, and does not involve the overhead incurred with patterns like %C or %L . 这使用记录器名称(这是记录器本身的属性),而不是检查调用堆栈,并且不涉及%C%L类的模式所引起的开销。

If you really do need the runtime class of the caller rather than the static name of the class that textually encloses a particular logging call, then you could use a per-instance logger rather than (or as well as) the per-class one 如果确实需要调用者的运行时类,而不是用文本形式包含特定日志记录调用的类的静态名称,则可以使用按实例记录器,而不是(或同时按)每个类

private final Logger instLog = Logger.getLogger(this.getClass());

and now the logger name will be the runtime type of this , ie if B extends A and we call a method on an instance of B then the logger name will be B, even for methods that are actually defined by the superclass A. 现在记录器名称将是this的运行时类型,即,如果B扩展了A并且我们在B的实例上调用方法,则记录器名称将为B,即使对于超类A实际定义的方法也是如此。

A usual pattern for loging with log4j is the following 以下是使用log4j进行记录的常用模式:

public class Foo {

    private static final Logger LOG = Logger.getLogger(Foo.class);

    someMethod(){
         ...
         if(LOG.isDebugEnabled()){
              LOG.debug("log message");
         }
    }
}

The classname is the logger name so it will (by default) appears in the log message. 类名是记录器名称,因此(默认情况下)它将显示在日志消息中。

Most importantly regarding performance: there is a guard preventing the overhead of the computation of the log message when the log level is not enabled. 关于性能,最重要的一点是:当未启用日志级别时,有一个防护措施可以防止计算日志消息的开销。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM