我正在将Log4j从v1更新到v2。我正在更新的代码有许多Log4jLogger.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迁移指南指出,应该使用参数化消息(如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的正确方式吗?编译器会自动理解哪些参数是子教程的参数,哪些是方法签名的预期部分吗?还是我需要以某种方式描述参数化消息?
"编译器会自动理解哪些参数用于子教程,哪些是方法签名的预期部分吗
不,编译器不理解第二种情况下Throwable
参数的特殊含义,但Log4j2理解:
- 在第一种情况下,编译器选择
debug(CharSequence, Throwable)
,并且Log4j2确信您希望将异常附加到消息中 - 在第二种情况下,编译器选择
debug(String, Object, Object)
方法,Log4j2计算字符串中{}
占位符的数量(即一个(,如果第一个未使用的参数是Throwable
,则将其用作附加到日志事件的异常
尝试:
logger.debug("Compiler Exception for {}", datafilter, e);
logger.debug("Compiler Exception for {}: {}", datafilter, e);
以便更好地理解差异。
在log4j2的文档中,没有方法签名允许您在格式化消息时同时传递rised异常。
您可以对消息参数使用String.format()
Java方法,并使用以下签名:
logger.debug(String.format("Compiler Exception for %s", datafilter), e);