我使用的是log4j2版本2.10.0
我已经实现了StringBuilderFormattable
接口来进行无gc日志记录。
示例实施:
public static class Formattable implements StringBuilderFormattable {
@Override
public void formatTo(StringBuilder buffer) {
buffer.append("FORMAT_TO_CALLED");
}
@Override
public String toString() {
return "TO_STRING_CALLED";
}
}
我打电话给LOGGER.info(new Formattable());
得到TO_STRING_CALLED
而不是预期FORMAT_TO_CALLED
。
我目前正在使用这些属性运行它:
-Dlog4j2.enable.threadlocals=true
-Dlog4j2.enable.direct.encoders=true
-Dlog4j2.asyncLoggerWaitStrategy=Yield
经过一番挖掘后,我发现log4j找到javax.servlet.Servlet
类,并将Constants.IS_WEB_APP
属性设置为true
,因此我的-Dlog4j2.enable.threadlocals=true
实际上设置为false,因此它使用ParameterizedMessageFactory
代替ReusableMessageFactory
导致调用toString
,我尝试在具有相同配置的简单项目中运行它,但没有javax.servlet.Servlet
它可以正常工作。
所以问题是为什么它有这样的行为,它会调用toString()
而不是formatTo()
?为什么它依赖于它是否是网络应用程序?我理解webapp threadlocals可能导致的问题,但我不明白为什么ParameterizedMessageFactory
也不会使用此formatTo
。此外,如果我仅使用此核心线程StringBuilderFormattable
进行日志记录,将log4j2.is.webapp
设置为false
是否安全?