Websphere和QOS logback:锁定日志文件以进行滚动

时间:2013-03-26 02:52:28

标签: java websphere logback

大家好日子。

我无法解决下一个问题:

我们正在为我们的应用程序使用WebSphere app服务器,以及用于管理日志文件的“logback”日志框架。

似乎everithing工作正常,但最近我们检测到文件滚动的不可接受的行为。 我们在WebSphere滚动日志文件上首次启动应用程序(按大小和天数)工作正常,但是当我们停止应用程序时 - 当前日志文件被java.exe(IBM WAS)进程锁定,当我们再次启动应用程序时 - 由于先前的锁定,滚动日志不起作用。当我通过Windows Unlocker查看文件时,我很惊讶 - 有2个进程锁定当前文件。如果我们停止app并再次启动它 - 将会有3个java.exe锁定当前日志文件,尽管在任务管理器中只运行一个进程。有时我会在这种“测试”期间发现OutOfMemory错误。

所以,我们最后有一个非常大的日志文件。 (20GB及以上)

我发现了一些类似的问题,但log4j正在滚动。并且没有任何解释为什么会这样 - 只有一个 - 像log4j不推荐用于websphere。

似乎问题根本不在“记录器”中。 那么,有没有人可以回答2个问题 -


  1. 当应用程序已经停止时,为什么WebSphere锁定文件而不释放它?

  2. 如果以正确的方式停止应用程序(不使用解锁器,任务管理器等作弊),如何释放(或者说不要锁定)日志文件的锁定?


  3. 感谢您的关注......任何帮助都将不胜感激。


    更新1:

    最近我尝试使用带有logback的小型网络应用程序 - 它运行良好 - 没有重复锁定。

    此外,当我们的大型应用程序停止时,我查看了日志,并找到了这个(停止应用程序时日志中唯一的一个字符串)

    27-03 05:59:39 [WebContainer : 7] INFO o.hibernate.impl.SessionFactoryImpl:close - closing

    关闭但未关闭?我希望我以正确的方式思考......

    ---- UPD 3

    嗯......我花了很多时间在websphere上部署自定义WAR,但我仍然无法找到有时WAS锁定日志文件的原因,有时候 - 不会。

    我无法相信,我很惊讶没有人遇到同样的麻烦

1 个答案:

答案 0 :(得分:1)

这篇文章确实帮助了我 - http://logback.qos.ch/manual/jmxConfig.html 虽然我们的应用程序中没有使用任何JMXConfigurator ......

所以我在web.xml中添加了

<listener>
    <listener-class>ru.fns.commonex.listener.CleanUpServletContextListener</listener-class>
</listener>

监听器有下一个代码:

@Override
public void contextDestroyed(ServletContextEvent sce) {
    log.debug("contextDestroyed({}) called.", sce);
    deRegisterLog();
}

/**
* Avoiding memory leaks
*
* If your application is deployed in a web-server or an application server,
* the registration of an JMXConfigurator instance creates a reference from the system class loader
* into your application which will prevent it from being garbage collected when it is stopped or re-deployed,
* resulting in a severe memory leak.
*
* Thus, unless your application is a standalone Java application,
* you MUST unregister the JMXConfigurator instance from the JVM's Mbeans server.
* Invoking the reset() method of the appropriate LoggerContext will automatically unregister any
* JMXConfigurator instance. A good place to reset the logger context is in the contextDestroyed()
* method of a javax.servlet.ServletContextListener.
*/
private void deRegisterLog() {
    LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
    log.info("Trying to stop logger factory {}", lc);
    if (lc != null) {
        lc.stop();
    }
}