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

罗兰

当我们停止在Weblogic 12c中的战争然后再次开始战争时,我表现出奇怪的行为。由于某些我无法理解的原因,Log4j2停止写入日志。它创建一个新的日志文件,但不写入任何条目。

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

那么,您是否对Weblogic 12c中Log4J2的安装和启动之间可能有什么区别以及可能在哪里查找错误有任何想法?

天空步行者

你的问题:

由于某些我无法理解的原因,Log4j2停止写入日志。它创建一个新的日志文件,但不写入任何条目。


根本原因分析:

实际上是某些问题发生的。

  1. 如果您的log4j配置未在log4j.properties文件中正确完成
  2. 如果您的append属性未设为true。
  3. 如果您使用Log4JJUL这样的两个记录器,则它们使用相同的appneder(Stdout)。
  4. 如果您的log4j jar文件未正确设置为您的类路径。

解:

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

Ans-2:属性为case sensitive所以你file name would be same with appender并且不要忘记使添加器为true。

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

Ans-3:特别是对于Hibernate,请包含slf4j,以确保所有记录器都与之合作。


回答4:有时tomcat会出现此问题。如果启用了tomcat安全性,并且策略文件中缺少几个权限,则会发生这种类型的问题。授予权限后,它将正常工作。


Log4J实际上做什么?

Log4J将仅打印包含信息及以上信息,并将其打印到控制台和文件中。您可以通过更改INFOALLin来更改此行为log4j.rootLogger如果这不起作用,请添加-Dlog4j.debug=true到JVM参数中-这将使Log4J发出有关其自身的调试消息(到System.out),以便您查看正在发生的情况。归功于@ Isaac

资源链接:

  1. Log4J创建日志文件,但不写入日志文件
  2. log4j日志未写入文件的问题

log4j2的更新:


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

wilkinsona POV的根本原因分析

restart被触发时,DevTools运行,然后将清除所有注册的关闭挂钩。Log4J2就是这样的钩子DefaultShutdownCallbackRegistryLog4jContextFactory维护对的引用,DefaultShutdownCallbackRegistry而LogManager保留对Log4jContextFactory的静态引用。Log4J2's classes are loaded by the app classloader which means that there's a single LogManager, Log4jContextFactory, and DefaultShutdownCallbackRegistry shared across restarts.

DefaultShutdownCallbackRegistry作为重新启动的一部分运行时,它将停止LoggerContext并将其自身的状态设置为STOPPED随着重新启动的进行,将LoggerContext创建一个新的新文件,并尝试在注册表中为其注册一个关闭回调。由于注册表的状态仍然为,因此失败STOPPED

解:

Wilkinsona提供了一种破解方法来解决此问题。如下。尝试解决它。

在Restarter运行JVM的shutdown钩子之前,最好清除注册表中的回调。这样可以防止发生异常,并且重新启动后日志记录仍可以继续工作。

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();
    }
}

资源链接:

  1. Log4j 2.4破坏了rc1 devtools
  2. 在DevTools重新启动中调用context.close()而不是shutdown挂钩

UPDATE2:

什么样的侦听器添加到我的JEE应用程序中,以获得预期的行为?

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

  1. ServletContextListener示例
  2. 编写一个侦听器类
  3. Servlet侦听器示例– ServletContextListener,HttpSessionListener和ServletRequestListener

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章