【问题标题】:SLF4J getLogger performance impact using Log4j2SLF4J getLogger 使用 Log4j2 对性能的影响
【发布时间】:2015-04-27 17:59:43
【问题描述】:

如果我们在集中式日志记录类的日志记录语句中使用以下语句,会对性能产生什么影响。

class LogUtil {
    public static debug(String message) {
        LoggerFactory.getLogger(Thread.currentThread().getStackTrace()[2].getClassName  ()).debug(message);
    }
}

我正在使用 SLF4J 和 log4j2。

【问题讨论】:

    标签: slf4j log4j2


    【解决方案1】:

    我不知道您为什么不遵循 log4j 中提供的示例。如果您真的想要一种集中式的日志记录方式,那么您应该尝试像 aspect4j 这样的面向方面的编程。

    我可以在此处看到您会对性能产生影响的两个地方:

    1. 您正在获取当前线程的堆栈跟踪,与简单的 Class.getName() 相比,这可能会比较耗时
    2. 您正在从堆栈跟踪中获取一个元素,然后是它的类名

    【讨论】:

      【解决方案2】:

      Logger.debug(..) 相比,SLF4J LoggerFactory.getLogger(..) 的调用次数很少。方法 getLogger(..) 在返回 Logger 实例之前可以做很多记账,所以最好避免这种模式(或至少阅读 Java 源代码)。

      SLF4J 已经完成了您的“集中式日志记录”。但如果需要,您可以创建自己的外观,例如:

      public class MyLoggerFactory {
          public static MyLogger getLogger() {
              final Logger logger = LoggerFactory.getLogger(
                        Thread.currentThread()
                              .getStackTrace()[2]
                              .getClassName());
              return new MyLogger(logger);
          }
      }
      
      public class MyLogger {
          private final Logger logger;
      
          class MyLogger(Logger logger) { this.logger = logger; }
      
          public void debug(Object message) {
              logger.debug(message);
          }
      }
      
      class SomeClass {
          private static final MyLogger logger = MyLoggerFactory.getLogger();
      
          public void method() {
               logger.debug("Log something");
          }
      }
      

      【讨论】:

        【解决方案3】:

        此方法的另一个缺点是 Log4j 的位置信息将指向 LogUtil 类中的调试方法,这似乎是您正在复制的内容。 Log4j 获取位置信息的方法通常比这里要快得多。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-12-10
          • 2013-08-30
          • 2021-03-09
          • 2011-06-08
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多