2013-01-09 137 views
14

我构建了一个部署到在Linux上运行的WebSphere Portal Server的Portlet应用程序。每个portlet WAR使用log4j对于这样的配置记录,让每WAR两个日志文件:Log4j突然停止登录

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以重新开始日志记录。

任何想法?

更新:

我开始怀疑它与我的日志罐子做的。目前,这是JAR的我WEB-INF/lib文件夹中:

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 

第二次更新:

在从赏金到几个小时,这是Log4j的是如何在每一个Portlet应用程序配置。下面是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文件所在文件夹外部的战争和门户。我们通过Shared Library in WebSphere Portal在Portlet Classpath中使其成为可用。

+2

你有没有检查'/ tmp'中是否有足够的空间存放日志? – tcb

+0

我检查过了,硬盘上有足够的空间:只有4%被使用 –

+0

你检查了SystemOut.log吗? – keuleJ

回答

0

我想尝试移动除临时文件系统以外的其他位置的日志文件位置。

+0

我会尝试。有什么理由要这样做?或者任何已知的问题? –

+2

我猜测操作系统可能试图删除该文件,因为该文件位于/ tmp中,所以应该可以自由执行。如果日志文件在几秒钟内变得不可写入,我已经看到Log4j完全停止写入 - 当它变为可写时,它不会再次开始写入。 – GreyBeardedGeek

+0

将日志文件移至/ home,问题仍然存在。尽管log4j config文件仍然位于/ tmp –

3

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

我怀疑你将不得不让每个WAR日志到不同的文件。

+1

每个WAR都有自己的Log4j配置及其专有的日志文件。我对原始问题做了一些编辑,使其更清楚。 –

22

你提供一些基本信息,所以我只能画出一些候选人的原因和可能性:

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

  • 通过日志Triggerred滚动?

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

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

    对您的情况有负面影响。用户/系统管理员操作文件可能会创建锁定或陈旧的文件句柄。 Linux应该永远不会对用户产生问题尾部 -ing一个文件(但窗口确实)。 Linux可能会在用户压缩或编辑文件时遇到问题。但是你的问题似乎是非常可重复的,除非你有自动化的脚本处理日志文件,否则这种情况不太可能发生。

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

    似乎不太可能在你的情况。似乎你还没有设置Websphere公共日志记录配置。通用日志被自动包括在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方法。

    Negative

3.更改类加载器中的类Log4J的,与使用不同的配置呢?

  • 父类加载器上有冲突的webapp的ClassLoader

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

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

建议操作:

  • 确保您所有的web应用程序使用PARENT_LAST类加载 -

  • 去管理控制台,并确保他们PARENT_LAST集中的所有Web应用程序的配置中确保您将Log4J内部错误消息写入控制台 例如通过在应用程序运行时强制删除错误日志作为管理员进行故意测试,创建一个陈旧的句柄。如果“Log4J:”错误消息没有出现在控制台中,那么这是一个严重的问题。
    下次发生问题时,请收集任何此类控制台消息并报告它们。另外,您可以在JVM/websphere启动时设置“-D log4j.debug”,以便精确地找出Log4J在问题出现之前/期间所做的事情 - 消息将发送到控制台。

  • 您是否确实需要将日志级别设置为DEBUG才能为您的所有软件包&类?最好设置为INFO或WARN,并且只有在调试特定问题时才有选择地设置。

这是很多文字..........乙^)

+0

我增加了一些额外的细节,也许他们可以提供帮助 –

5

在过去的5年中,Log4j的几乎没有固定的任何错误:它实际上是一个死的项目。 如果可以的话,考虑用Logback替换它,它直接实现SLF4j。

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

-3

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

在Java杂志中,一篇文章指出log4j 2.0在多线程环境中表现得更加健壮,因此它有可能解决您的问题。如果不是,你仍然有新版本的好处。

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

API分离

的Log4j提供的API是从实现分离并明确应用程序开发人员哪些类和方法他们可以使用,同时确保向前兼容这使得Log4j团队能够以兼容的方式安全地完成实施。

改进的性能比Log4j的1.x的速度在关键领域

的Log4j 2执行和同样在大多数情况下的logback。请参阅性能了解更多信息。 支持多种API 虽然Log4j 2 API将提供最佳性能,但Log4j 2提供对SLF4J和Commons Logging API的支持。配置的

自动重新加载

喜欢的logback,Log4j的2可自动修改后重新加载其配置。与Logback不同,它将这样做,而不会在重新配置发生时丢失日志事件。

高级滤波

喜欢的logback,Log4j的2个支持筛选基于上下文数据,标记,正则表达式,以及其他部件在日志事件。筛选可以指定为在传递给记录器或通过Appender时应用于所有事件。另外,过滤器也可以与记录器相关联。与Logback不同,您可以在任何这些情况下使用通用的Filter类。

插件架构

Log4j的用于配置部件插件图案。因此,您不需要编写代码来创建和配置Appender,布局,模式转换器等等。 Log4j会自动识别插件并在配置引用它们时使用它们。

属性支持

可以在配置引用属性是,log4j将直接替换它们,或将Log4j中它们传递到,将动态解决这些问题的基础组件。属性来自配置文件中定义的值,系统属性,环境变量,ThreadContext映射和事件中存在的数据。用户可以通过添加自己的Lookup Plugin来进一步定制属性提供程序。