Log4j突然停止记录

时间:2013-01-09 16:42:13

标签: java log4j websphere

我正在构建一个部署到在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

部署之后,一切都像魅力和日志文件一样开始填充。几个小时后,同时,记录停止,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

<context-param>
    <param-name>log4jConfigLocation</param-name>
    <param-value>classpath:miAppLog4j.properties</param-value>
</context-param>
<listener>
    <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
</listener>

miAppLog4j.properties文件位于WAR外部的文件夹和Portal中。我们通过Shared Library in WebSphere Portal在Portlet类路径中创建了它。

5 个答案:

答案 0 :(得分:22)

您提供了一些基本信息,因此我只能勾勒出一些候选原因和可能性:

<强> 1。文件锁定/句柄/ IO流问题

  • 通过日志滚动触发?

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

  • 进行额外确认
  • 操纵Linux文件的用户触发了什么?

    在你的情况下是否定的。 user / sysadmin操作文件可能会创建锁或过时的文件句柄。 Linux应该永远不会遇到用户 tail -ing文件的问题(但是windows确实如此)。 Linux可能会遇到用户压缩或编辑文件的问题。但是你的问题似乎是非常可重复的,除非你有自动脚本来操作日志文件,否则这个问题就不可能了。

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

    在您的情况下似乎不太可能。似乎您没有设置Websphere commons日志记录配置。 Commons logging自动包含在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线程有问题吗?

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

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

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

    即。的

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

  • Parent ClassLoader与Webapp ClassLoader冲突

    E.g。你的webapps最初是从他们自己配置的WEBINF目录类开始的,一切都很好,但是稍后一段时间不同的应用程序导致(或者一个门户服务器管理工​​具)导致一个碰撞类被加载到父ClassLoader和你的app “拿起”这个新的非法版本的课程并失败。

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

建议采取的行动:

  • 确保您的所有网络应用都使用PARENT_LAST ClassLoading - 转到管理控制台并确保他们在所有WebApp配置中设置了PARENT_LAST

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

  • 您是否真的需要为所有软件包设置日志级别为DEBUG&amp;班?最好设置为INFO或WARN,并且只在调试特定问题时有选择地启用它?

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

答案 1 :(得分:5)

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

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

答案 2 :(得分:3)

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

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

答案 3 :(得分:0)

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

答案 4 :(得分:-3)

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

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

它带来了一些不错的功能和增强功能(从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时应用于所有事件。此外,过滤器还可以与记录器关联。与Logback不同,您可以在任何这些情况下使用通用的Filter类。

插件架构

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

财产支持

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