带有Log4j2的Weblogic 12c在停止/启动后停止记录

当我们在Weblogic 12c中停止战争然后再次启动时,我得到了一个pecurliar行为.由于某种原因,我不了解Log4j2停止写入日志.它会创建一个新的日志文件,但不会写入任何条目.

我已经调试并看到Log4jServletContainerInitializer和Log4jServletContextListener被调用就像他们在安装战争时一样.我没有注意到任何差异(不幸的是,这只是我的注意力范围的测试).

那么你是否知道在Weblogic 12c中的Log4J2安装和启动之间可能有什么不同,以及可能在哪里寻找错误?

最佳答案 你的问题:

由于某种原因,我不了解Log4j2停止写入日志.它会创建一个新的日志文件,但不会写入任何条目.

根本原因分析:

这实际上是在一些问题上发生的.

>如果未正确完成log4j的配置
log4j.properties文件.
>如果您的追加属性未成立.
>如果您使用两个记录器,如Log4J和JUL,它们使用相同的记录器
appneder(STDOUT).
>如果您的log4j jar文件未正确设置为类路径.

解:

ANS-1:
在类路径中,有一个库设置拦截Log4J调用并将它们转换为JUL调用.然后它可能会导致此问题.因此,请正确指定实际需要哪个导入. java.util.logging.Logger或org.apache.log4j.Logger

ANS-2:
属性区分大小写.所以你的文件名与appender相同.并且不要忘记使追随者变为真实.

log4j.appender.mainAppender.File=yourLogFile.log
log4j.appender.mainAppender.Append=true

ANS-3:
特别是对于Hibernate,包括slf4j以确保所有记录器与它协作.

ANS-4:
有时tomcat会出现此问题.如果启用了tomcat安全性,并且策略文件中缺少多个权限,则会出现此类问题.授予权限后,它将正常工作.

Log4J实际上做了什么?

Log4J只会打印info和up的消息,并将它们打印到控制台和文件中.您可以通过在log4j.rootLogger中将INFO更改为ALL来更改此行为.如果这不起作用,请将-Dlog4j.debug = true添加到您的JVM参数中 – 这将使Log4J发出关于它自身的调试消息(到System.out),这样您就可以看到正在发生的事情.
信用额度为@ Isaac

资源链接:

> Log4J creates log file but does not write to it
> Issue with log4j log not writing to file

UPDATE for log4j2:

非常感谢rgoers指出log4j2的问题.我正在更新.

根据wilkinsona P.O.V的根本原因分析

触发重启时,DevTools会运行,然后清除所有已注册的关闭挂钩.一个这样的钩子是Log4J2的DefaultShutdownCallbackRegistry. Log4jContextFactory维护对DefaultShutdownCallbackRegistry的引用,LogManager保存对Log4jContextFactory的静态引用. Log4J2的类由app类加载器加载,这意味着在重新启动时共享一个LogManager,Log4jContextFactory和DefaultShutdownCallbackRegistry.

当DefaultShutdownCallbackRegistry作为重启的一部分运行时,它会停止LoggerContext并将其自己的状态设置为STOPPED.随着重新启动的进行,将创建一个新的LoggerContext,并尝试使用注册表为其注册关闭回调.由于注册表的状态仍然是STOPPED,因此失败.

解:

Wilkinsona提供了一种解决问题的黑客方法.这在下面给出.尽量应对它.

在Restarter运行JVM的关闭挂钩之前清除注册表中的回调更好.它可以防止发生异常,并在重新启动后继续执行日志记录.

private void prepareLog4J2ForRestart() throws Exception {
    if (ClassUtils.isPresent("org.apache.logging.log4j.LogManager",
            getClass().getClassLoader())) {
        LoggerContextFactory factory = LogManager.getFactory();
        Field field = ReflectionUtils.findField(factory.getClass(),
                "shutdownCallbackRegistry");
        ReflectionUtils.makeAccessible(field);
        ShutdownCallbackRegistry shutdownCallbackRegistry = (ShutdownCallbackRegistry) ReflectionUtils
                .getField(field, factory);
        Field hooksField = ReflectionUtils
                .findField(shutdownCallbackRegistry.getClass(), "hooks");
        ReflectionUtils.makeAccessible(hooksField);
        @SuppressWarnings("unchecked")
        Collection<Cancellable> state = (Collection<Cancellable>) ReflectionUtils
                .getField(hooksField, shutdownCallbackRegistry);
        state.clear();
    }
}

资源链接:

> Log4j 2.4 breaks rc1 devtools
> Call context.close() rather than shutdown hook in DevTools restart

UPDATE2:

What kind of listener to add to my JEE application, to get the
expected behaviour?

要编写监听器,您可以按照教程进行操作

> ServletContextListener Example
> Writing a Listener Class
> Servlet Listener Example – ServletContextListener,
HttpSessionListener and ServletRequestListener

点赞