java - 这个日志语句有什么问题?

标签 java logging slf4j

我最近在现有应用程序中偶然发现了以下几行日志记录代码。这段代码在很多方面对我来说都是完全错误的

Method method = ...;// passed in as parameter
//...
String className = method.getDeclaringClass().getName();
String methodName = method.getName();
long id = Thread.currentThread().getId();
String name = Thread.currentThread().getName();
String msg = String.format("some text, for: %s %s in thread %d %s", className, methodName, id, name);
LOGGER.debug("xxxxxxxx {}", msg);

我想知道

  • 这段代码有什么问题?
  • 什么对性能影响最大?
  • 编写这样的日志记录语句的最佳方式是什么?

(注意:如 {} 所示,它是一个 SLF4J 记录器,xxxxxxxx 是一个唯一的字符串,用于在代码库中标识此特定的日志记录语句)

最佳答案

日志记录是应用程序中的交叉关注点。
所以对于一般情况,我使用拦截器/方面模式来做到这一点。

String className = method.getDeclaringClass().getName();
String methodName = method.getName();
long id = Thread.currentThread().getId();
String name = Thread.currentThread().getName();
String msg = String.format("some text, for: %s %s in thread %d %s",
              className, methodName, id, name);

在当前记录器的有效级别之前不检查就进行所有这些计算是没有意义的,因为即使未写入日志也会应用它。
此外,如果需要并在附加程序的模式中指定,所有这些信息都可以由 API 记录器检索。

此外这也没有效果:

String msg = String.format("some text, for: %s %s in thread %d %s", className, methodName, id, name);
LOGGER.debug("xxxxxxxx {}", msg);

它还在检查级别之前格式化字符串。

使用实际代码,这样更好:

if (LOGGER.isDebugEnabled()){
   String className = method.getDeclaringClass().getName();
   String methodName = method.getName();
   long id = Thread.currentThread().getId();
   String name = Thread.currentThread().getName();
   String msg = String.format("some text, for: %s %s in thread %d %s", className, methodName, id, name);
   LOGGER.debug("xxxxxxxx {}", msg);
 }

但是一个更健壮的解决方案是使用 appender 模式来用线程 id、方法等装饰日志信息......


最后,如果当前级别的检查(此处:if (LOGGER.isDebugEnabled()){)不包含日志记录处理,作为一般方法,例如:

String msg = String.format("some text, for: %s %s in thread %d %s", className, methodName, id, name);
LOGGER.debug("xxxxxxxx {}", msg);

使用 log 方法更有效,因为它是为设计而设计的,而不是在你的示例中使用的,因为它会破坏它的目的。

通过这种方式,如果有效记录器级别不匹配,它可以节省计算:

LOGGER.debug("some text, for: {} {} in thread {} {}", className, methodName, id, name);

关于java - 这个日志语句有什么问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43626491/

相关文章:

java - Java 中是否可以有无限数量的类型参数?

java - 如何在日志文件中仅获取特定级别的消息?

java - 使用 slf4j 禁用特定日志输出

java - log4j:WARN 找不到记录器的附加程序。 Log4j 1.2.17 jar

java - slf4j 配置记录单个文件

java - java.util.Date 语言环境中的 toString() 方法是否独立?

java - 添加不带 .jar 文件的 Apache xml-rpc 库

java - 工具提示文本根据鼠标悬停在文本框中的单词而变化?

java - 基于String创建的slf4j和log4j的区别

java - 为什么我在不使用它时会收到 SLF4J 错误?