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

Rol*_*and 5 java log4j weblogic weblogic12c log4j2

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

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

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

Sky*_*ker 2

你的问题:

\n\n

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

\n\n
\n\n

根本原因分析:

\n\n

对于某些问题,确实会发生这种情况。

\n\n
    \n
  1. 如果您的 log4j 配置未在\nlog4j.properties文件中正确完成。
  2. \n
  3. 如果您的附加属性未设为 true。
  4. \n
  5. 如果您使用两个记录器,例如Log4J和JUL,它们使用相同的\nappneder(Stdout)。
  6. \n
  7. 如果您的 log4j jar 文件未正确设置为您的类路径。
  8. \n
\n\n
\n\n

解决方案:

\n\n

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

\n\n

Ans-2: \n属性是case sensitive. 所以你的file name would be same with appender. 并且不要忘记将appender设置为true。

\n\n
log4j.appender.mainAppender.File=yourLogFile.log\nlog4j.appender.mainAppender.Append=true\n
Run Code Online (Sandbox Code Playgroud)\n\n

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

\n\n
\n\n

Ans-4: \n有时 Tomcat 会出现此问题。如果启用了 tomcat 安全性,并且策略文件中缺少多个权限,则会出现此类问题。授予权限后,就可以正常工作了。

\n\n
\n\n

Log4J 实际上做了什么?

\n\n

Log4J 只会打印 info 及 up 消息,并且会将它们打印到控制台和文件。您可以通过更改INFO为ALLin来更改此行为log4j.rootLogger。如果这不起作用,请添加-Dlog4j.debug=true到您的 JVM 参数 - 这将使 Log4J 发出有关其自身的调试消息(到 System.out),这样您就可以看到发生了什么。\n感谢@Isaac

\n\n

资源链接:

\n\n
    \n
  1. Log4J 创建日志文件但不写入它
  2. \n
  3. log4j 日志未写入文件的问题
  4. \n
\n\n
\n\n
\n

log4j2 的更新:

\n
\n\n
\n\n

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

\n\n

威尔金索纳POV 根本原因分析

\n\n

当 arestart被触发时,DevTools 运行,然后清除所有已注册的关闭挂钩。Log4J2 就是这样的一个钩子DefaultShutdownCallbackRegistry。Log4jContextFactory 维护对 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.

\n\n

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

\n\n

解决方案:

\n\n

Wilkinsona 提供了一种破解方法来解决这个问题。这是下面给出的。尝试去应对它。

\n\n

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

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

资源链接:

\n\n
    \n
  1. Log4j 2.4 破坏了 rc1 devtools
  2. \n
  3. 在 DevTools 重启中调用 context.close() 而不是 shutdown hook
  4. \n
\n\n
\n\n

更新2:

\n\n
\n

要向我的 JEE 应用程序添加哪种类型的侦听器才能获得\n 预期的行为?

\n
\n\n

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

\n\n
    \n
  1. ServletContextListener 示例
  2. \n
  3. 编写监听器类
  4. \n
  5. Servlet 侦听器示例 \xe2\x80\x93 ServletContextListener、\nHttpSessionListener 和 ServletRequestListener
  6. \n
\n