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

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

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

最佳答案

你的问题:

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

根本原因分析:

它实际上是针对某些问题而发生的。

  • 如果您在以下位置未正确完成log4j的配置,log4j.properties文件。
  • 如果您的append属性未设为true。
  • 如果您使用像Log4JJUL这样的两个记录器,它们使用相同的记录器
    appneder(标准输出)。
  • 如果您的log4j jar文件未正确设置为您的类路径。


  • 解决方案:

    Ans-1:
    在类路径中,有一个库设置可拦截Log4J调用并将其转换为JUL调用。然后可能会导致此问题。因此,正确指定实际需要导入的内容。 java.util.logging.Loggerorg.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,以确保所有记录器都与之合作。

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

    Log4J实际做什么?

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

    资源链接:
  • Log4J creates log file but does not write to it
  • Issue with log4j log not writing to file




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

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

    触发restart时,DevTools将运行,然后清除所有已注册的关闭 Hook 。 Log4J2的DefaultShutdownCallbackRegistry是一个这样的钩子(Hook)。 Log4jContextFactory保留对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钩子(Hook)之前清除注册表中的回调会更好。这样可以防止发生异常,并且日志记录在重新启动后仍可以继续工作。
    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:



    要编写监听器,您可以按照以下教程进行操作
  • ServletContextListener Example
  • Writing a Listener Class
  • Servlet Listener Example – ServletContextListener,HttpSessionListener and ServletRequestListener
  • 10-07 19:07
    查看更多