将 Jersey JUL 日志记录重定向到 Log4j2

Redirect Jersey JUL logging to Log4j2

我需要将 Jersey request/response 日志重定向到我的 log4j2。

我在 ApplicationJAXRS extends Application:

上使用此代码启用了 Jersey 日志记录
@Override
public Set<Class<?>> getClasses() {
    return new HashSet<Class<?>>() {{
        add(LoggingFilter.class);
    }};
    }

Jersey 似乎在内部使用 JUL(Java 日志记录),默认输出是 STDOUT。此时我可以在 Eclipse 控制台上看到 STDOUT。

Log4j2 文档中有一节是关于 JDK Logging Adapter 的。 它说

To use the JDK Logging Adapter, you must set the system property java.util.logging.manager to org.apache.logging.log4j.jul.LogManager

This must be done either through the command line (i.e., using the -Djava.util.logging.manager=org.apache.logging.log4j.jul.LogManager argument) or by using System.setProperty() before any calls are made to LogManager or Logger.

为了在任何 Logger 调用之前调用 System.setProperty(*),我尝试将其放在 Aplication class.

中的 @PostConstruct
@PostConstruct
    public void init() {
        System.setProperty("java.util.logging.manager", "org.apache.logging.log4j.jul.LogManager");
    }

我可以用它来登录我的日志文件。

这是我的 log4j2.xml:

    <Appenders>
        <RollingFile name="RollingFile" fileName="${log-path}/${name}.log" 
            filePattern="${log-path}/${date:yyyy-MM}/${name}-%d{yyyy-MM-dd}-%i.log">
            <PatternLayout>
                <Pattern>%d{dd-MM-yy HH:mm:ss,SSS} %-5p [%t] (%F:%L) - %m%n</Pattern>
            </PatternLayout>
            <Policies>
                <TimeBasedTriggeringPolicy interval="1" modulate="true"/>
            </Policies>
            <DefaultRolloverStrategy max="10" />
        </RollingFile>
        <Console name="Console" target="SYSTEM_OUT">
            <PatternLayout pattern="%d %-5p [%t] %C{2} (%F:%L) - %m%n" />
        </Console>
    </Appenders>
    <Loggers>
        <Root level="debug">
            <AppenderRef ref="Console" level="debug"/>
            <AppenderRef ref="RollingFile" level="debug"/>
        </Root>
    </Loggers>
</Configuration>

我想您必须设置 。将代码添加到您的 init 方法以查看设置系统 属性 是否有效。

@PostConstruct
public void init() {
    String cn = "org.apache.logging.log4j.jul.LogManager";
    System.setProperty("java.util.logging.manager", cn);
    LogManager lm = LogManager.getLogManager();
    if (!cn.equals(lm.getClass().getName())) {
       try {
           ClassLoader.getSystemClassLoader().loadClass(cn);
       } catch (ClassNotFoundException cnfe) {
          throw new IllegalStateException("Jars not in system class path.", cnfe);
       }
       throw new IllegalStateException("Found " + lm.getClass().getName() + " set as launch param instead.");
    }
}

虽然您仍然需要设置系统 属性 java.util.logging.manager=org.apache.logging.log4j.jul.LogManager

,但这实际上适用于 Jersey 案例

将您的记录器实例化为 log4j2 的常规应用程序日志记录器。然后,使用 org.apache.logging.log4j.jul.LogManager 显式实例化一个 java.util.logging.Logger。然后使用第二个 Logger 实例注册一个新的 LoggingFilter ,如此处所示,在此示例中使用 Jersey 2 Client(为清楚起见,使用详细命名):

org.apache.logging.log4j.Logger logger = org.apache.logging.log4j.LogManager.getLogger(this.getClass().getName());

java.util.logging.Logger jerseyLogger = org.apache.logging.log4j.jul.LogManager.getLogManager().getLogger(this.getClass().getName());

jerseyLogger.setLevel(java.util.logging.Level.SEVERE); //OPTIONAL

Client client = ClientBuilder.newClient();
client.register(new LoggingFilter(jerseyLogger, false));

logger.info("App logging uses the normal logger");

现在,对记录器的调用按预期工作,所有 Jersey 的 jul 日志记录输出都按预期定向回 l​​og4j2 附加程序。