Log4j突然停止记录

我正在构建一个部署到在Linux上运行的WebSphere Portal Server的Portlet应用程序。 每个Portlet WAR使用Log4j进行日志记录,使用这样的配置,每个WAR都有两个日志文件:

log4j.logger.im.the.package=DEBUG, InfoAppender, DebugAppender log4j.appender.InfoAppender=org.apache.log4j.RollingFileAppender log4j.appender.InfoAppender.Threshold=INFO log4j.appender.InfoAppender.File=/tmp/infoWARName.log log4j.appender.InfoAppender.layout=org.apache.log4j.PatternLayout log4j.appender.InfoAppender.layout.ConversionPattern=%d %p [%c] - %m%n log4j.appender.DebugAppender=org.apache.log4j.RollingFileAppender log4j.appender.DebugAppender.Threshold=DEBUG log4j.appender.DebugAppender.File=/tmp/debugWARName.log log4j.appender.DebugAppender.layout=org.apache.log4j.PatternLayout log4j.appender.DebugAppender.layout.ConversionPattern=%d %p [%c] - %m%n 

部署之后,一切都像魅力和日志文件一样开始填充。 几个小时后,同时,Logging停止, info.logdebug.log根本没有更新。 我们需要在服务器中重新部署Portlet WAR以重新开始记录。

有任何想法吗?

更新:

我开始怀疑它与我的Logging JARS有关。 目前,这是我的WEB-INF/lib文件夹中的JAR:

 com.springsource.org.apache.commons.logging-1.1.1.jar com.springsource.org.apache.log4j-1.2.15.jar com.springsource.slf4j.api-1.5.6.jar slf4j-log4j12-1.5.6.jar 

第二次更新:

从赏金到结束的几个小时,这就是每个Portlet应用程序中Log4j的配置方式。 这是web.xml

  log4jConfigLocation classpath:miAppLog4j.properties   org.springframework.web.util.Log4jConfigListener  

miAppLog4j.properties文件位于WAR外部的文件夹和Portal中。 我们通过WebSphere Portal中的共享库在 Portlet Classpath中创建了它。

您已经提供了一些基本信息,因此我只能描绘一些候选原因和可能性:

1.文件锁/句柄/ IO流的问题

  • 通过日志滚动触发?

    在你的情况下是负面的。 对于任何给定的WAR,您的两个单独的日志文件(信息和调试)会同时停止。 每个文件都以默认的最大大小(10MB)滚动。 这两个日志不太可能同时滚动。 日志滚动不能触发错误。 通过配置log4j.appender.InfoAppender.MaxFileSize=200MB额外确认

  • 由操纵Linux文件的用户触发?

    在你的情况下是负面的。 user / sysadmin操作文件可能会创建锁或过时的文件句柄。 Linux应该永远不会遇到用户拖尾文件的问题(但是Windows会这样做)。 Linux可能会遇到用户压缩或编辑文件的问题。 但是你的问题似乎是非常可重复的,除非你有自动脚本来操作日志文件,否则这个问题很可能。

  • 由Websphere或Spring中的“竞争”配置设置触发,服务器/框架重复使用相同的日志文件?

    在您的情况下似乎不太可能。 似乎您还没有设置Websphere commons日志记录配置。 Commons日志记录自动包含在websphere服务器父类ClassLoader中,并且可以配置为通过配置“包装”到Log4J:

    文件commons-logging.properties

     # Set application classloader mode as PARENT_LAST when deploying in WAS as .ear priority=1 org.apache.commons.logging.LogFactory=org.apache.commons.logging.impl.LogFactoryImpl 
  • 由硬件问题/磁盘故障触发?

    ??? 似乎很奇怪,这样的问题会非常可重复。

2. java线程有问题吗?

  • 线程死亡或死锁
  • “其他”代码中的大量线程处理/争用,因此不运行带有日志记录的代码

    根据您的描述,我假设应用程序仍在运行并且具有正常的性能和function,但是不会写入日志。 你确定吗? 如果是这样,那么它不是webapp线程的线程问题。

    另外我可以确认它不是Log4J逻辑中的线程问题,因为它创建/使用自己的线程的唯一时间是使用AsynchAppender / ExternallyRolledFileAppender / SocketAppender / TelnetAppender之一时或者当PropertyConfigurator.configureAndWatch或DOMConfigurator.configureAndWatch时方法被调用。

    负面

3.使用不同的配置更改ClassLoader中的Log4J类?

  • Parent ClassLoader与Webapp ClassLoader发生冲突

    例如,您的webapps最初是从WEBINF目录中自己配置的类开始的,一切都很好,但是稍后一段时间后,一个不同的应用程序导致(或其中一个门户网站服务器管理工​​具)导致一个冲突类被加载到父ClassLoader和你的应用程序“拿起”这个新的非法版本的类并失败。

    很可能是一个问题 – 谷歌上的数千名用户都在努力使用Websphere类加载器。

建议采取的行动:

  • 确保所有Web应用程序都使用PARENT_LAST ClassLoading – 转到管理控制台并确保它们在所有WebApp配置中都设置了PARENT_LAST

  • 确保您收到写入控制台的Log4J内部错误消息例如,在应用程序运行时通过强制删除错误日志作为管理员进行故意测试,从而创建过时的句柄。 如果“Log4J:”错误消息未出现在控制台中,则这是一个严重的问题。
    下次出现问题时,请捕获任何此类控制台消息并报告它们。 此外,您可以在JVM / websphere启动时设置“-D log4j.debug”,以便准确地找出Log4J在问题出现之前/期间正在做什么 – 消息将转到控制台。

  • 你真的需要为所有的包和类设置日志级别为DEBUG吗? 最好设置为INFO或WARN,并且只在调试特定问题时有选择地设置?

那是很多文字………. B ^)

5年多来,Log4j几乎没有修复任何错误:它实际上是一个死机项目。 如果可以接受,请考虑将其替换为Logback ,后者直接实现SLF4j。

Logback和SLF4J是由编写Log4J(Ceki)的同一个人编写的,拥有更加自由的许可,并拥有一个良好的社区。 它是各种可能的Log4J 1的inheritance者(除了它的名字)。

我认为问题是你有多个WAR写入同一个日志文件。 根据我们的经验,log4j无法可靠地执行此操作,尤其是对于滚动的appender。 当一个人滚动它,其他人感到困惑,无法进一步记录。 或者继续登录旧文件。

我怀疑你必须将每个WAR日志都放到另一个文件中。

我尝试将日志文件位置移动到临时文件系统以外的某个位置。

我不确定为什么log4j会在你的应用程序中停止。 但你可以(应该)升级到log4j 2.0。 切换不应该太费力。 您需要将log4j.properties文件重写为XML文件,因为新版本不再支持属性文件。

在Java Magazin中,一篇文章指出log4j 2.0在multithreading环境中表现得更强大,因此它有可能解决您的问题。 如果没有,您仍然可以享受新版本的好处。

它带来了一些不错的function和增强function(从log4j站点复制):

API分离

Log4j的API与实现分开,使应用程序开发人员可以清楚地了解他们可以使用哪些类和方法,同时确保向前兼容性。 这使Log4j团队能够以兼容的方式安全地改进实施。

提高性能

Log4j 2在关键区域的执行速度比Log4j 1.x快,在大多数情况下类似于Logback。 有关更多信息,请参见性能 支持多个API虽然Log4j 2 API将提供最佳性能,但Log4j 2提供对SLF4J和Commons Logging API的支持。

自动重新加载配置

与Logback一样,Log4j 2可以在修改时自动重新加载其配置。 与Logback不同,它会在重新配置发生时不会丢失日志事件。

高级过滤

与Logback一样,Log4j 2支持基于Log事件中的上下文数据,标记,正则表达式和其他组件进行过滤。 可以指定过滤以在传递给Loggers之前或通过Appender时应用于所有事件。 此外,filter还可以与记录器关联。 与Logback不同,您可以在任何这些情况下使用通用的Filter类。

插件架构

Log4j使用插件模式配置组件。 因此,您无需编写代码来创建和配置Appender,Layout,Pattern Converter等。 Log4j自动识别插件并在配置引用它们时使用它们。

财产支持

您可以在配置中引用属性,Log4j将直接替换它们,或者Log4j将它们传递给将动态解析它们的底层组件。 属性来自配置文件,系统属性,环境变量,ThreadContext Map以及事件中存在的数据中定义的值。 用户可以通过添加自己的Lookup插件来进一步自定义属性提供程序。