log4j Java参数化消息是否会干扰方法签名?

ggazkfy8  于 2022-11-06  发布在  Java
关注(0)|答案(2)|浏览(111)

我正在将Log4j从v1更新到v2。我正在更新的代码有许多Log4j Logger.debug(Object message, Throwable throwable)方法和签名的示例,其中message是通过字符串连接构造的。例如:

/* Log4j v1 */
import org.apache.log4j.Logger;
private static final Logger logger = Logger.getLogger();

String datafilter = "blah";
try {
    /* code */
}
catch (Exception e) {
    logger.debug("Compiler Exception for " + datafilter, e);
    System.exit(3);
}

当更新到Log4j v2时,Log4j migration guide声明应该使用参数化消息(如logger.info("hi {}", userName)),而不是字符串连接。

/* Log4j v2 */
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.LogManager;
private static final Logger logger = LogManager.getLogger();

String datafilter = "blah";
try {
    /* code */
}
catch (Exception e) {
    /* Is the following correct? */
    logger.debug("Compiler Exception for {}", datafilter, e);
    System.exit(3);
}

但是,logger.debug("Compiler Exception for {}", datafilter, e)的方法签名在我看来很奇怪,因为参数化消息的参数与Logger.debug()(或Logger.info()或其他参数)的其他参数混合在一起。
这是将参数化消息引入Log4j的正确方式吗?编译器会自动理解哪些参数用于替换,哪些是方法签名的预期部分吗?还是需要以某种方式描述参数化消息?

klr1opcd

klr1opcd1#

  • “编译器是否会自动了解哪些参数用于替换以及哪些是方法签名的预期部分”*

不,编译器不理解第二种情况下Throwable参数的特殊含义,但Log4j2理解:

  • 在第一种情况下,编译器选择debug(CharSequence, Throwable),并且Log4j2确信您希望将异常附加到消息中,
  • 在第二种情况下,编译器选择debug(String, Object, Object)方法,Log4j2计算字符串中{}占位符的数量(为1),如果第一个未使用的参数是Throwable,则将其用作附加到日志记录事件的异常。

请尝试:

logger.debug("Compiler Exception for {}", datafilter, e);
logger.debug("Compiler Exception for {}: {}", datafilter, e);

以更好地理解它们之间的区别。

fcg9iug3

fcg9iug32#

log4j2的文档中,没有方法签名允许您在格式化消息的同时传递rised异常。
您可以使用String.format() Java方法作为message参数,并使用以下signature

logger.debug(String.format("Compiler Exception for %s", datafilter), e);

相关问题