我正在将API从JUL(Java Util Logging)迁移到Log4j 2,因此我必须保持对暴露JUL级别的现有方法的兼容性。
例如:
log(java.util.logging.Level level, String message)
所以我决定使用Log4j JDK日志记录适配器来保持一切正常,但默认布局会打印出新的Log4j级别。
以下代码
Logger.getLogger("bla").severe("An issue occurred");
正在制作
ERROR: An issue occurred
我想在输出上保留旧的JUL级别,以便迁移对用户透明。 如何更改布局以保持打印旧的JUL级别?如下:
SEVERE: An issue occurred
答案 0 :(得分:2)
您可以执行以下操作:
创建一个RoutingAppender,通过打印JUL级别名称而不是log4j级别名称,将适当级别的消息定向到可以处理它们的appender。
使用以下方法测试的简单主类:
package main.java;
import java.util.logging.LogManager;
import java.util.logging.Logger;
public class Main {
public static void main(String[] args) {
Logger logger = LogManager.getLogManager().getLogger(Main.class.getName());
//Must set the level to FINEST in the code because the config file will not understand a custom level.
logger.setLevel(Level.FINEST);
logger.info("info lvl");
logger.finest("finest lvl");
logger.finer("finer lvl");
logger.fine("fine lvl");
logger.config("config lvl");
logger.warning("warning lvl");
logger.severe("severe lvl");
}
}
Log4j2.xml配置:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn">
<Appenders>
<Console name="consoleAppender" target="SYSTEM_OUT">
<PatternLayout pattern="%p{WARN=WARNING, DEBUG=FINE, ERROR=SEVERE, TRACE=FINER}: %m%n" />
</Console>
<Console name="customLevelAppender" target="SYSTEM_OUT">
<PatternLayout pattern="%p: %m%n"/>
</Console>
<Routing name="Routing">
<Routes>
<Script name="RoutingInit" language="JavaScript"><![CDATA[
logEvent.getLevel();]]>
</Script>
<Route ref="customLevelAppender" key="CONFIG" />
<Route ref="customLevelAppender" key="FINEST" />
<Route ref="consoleAppender" />
</Routes>
</Routing>
</Appenders>
<Loggers>
<Logger name="main.java" level="trace" additivity="false">
<AppenderRef ref="Routing" />
</Logger>
<Root level="info">
<AppenderRef ref="consoleAppender" />
</Root>
</Loggers>
</Configuration>
示例输出:
INFO: info lvl
FINEST: finest lvl
FINER: finer lvl
FINE: fine lvl
CONFIG: config lvl
WARNING: warning lvl
SEVERE: severe lvl
注意:似乎因为FINEST和CONFIG是自定义级别,因此无法以与其他级别相同的方式处理它们。这就是为什么需要名为&#34; customLevelAppender&#34;的第二个appender的原因。以及为什么该appender不需要任何特殊配置。