如何在Tomcat 5.5中控制webapp中第三方组件的日志记录?

时间:2011-03-29 21:43:48

标签: java tomcat log4j tomcat5.5 oscache

我们在Linux上使用Tomcat 5.5。我们的webapp使用log4j进行日志记录(基于功能而不是很多记录器),并有意将记录器的可加性设置为false。我们的记录器记录到我们自己的日志文件。他们都没有登录到控制台。

我们遇到的一个问题是,当我们的记录器级别设置为DEBUG时,我们开始从第三方组件中获取catalina.out中的大量调试记录,特别是oscache。

在... / common / classes中有一个最小的log4j.properties文件:

log4j.rootLogger=INFO, A1
log4j.appender.A1=org.apache.log4j.ConsoleAppender
log4j.appender.A1.layout=org.apache.log4j.PatternLayout

# Print the date in ISO 8601 format
log4j.appender.A1.layout.ConversionPattern=%d [%t] %-5p %c - %m%n

在/ webapps / ourapp / WEB-INF / classes中没有log4g.properties文件。

我尝试的第一件事就是改为log4j.rootLogger=ERROR, A1,但没有任何区别。

接下来我尝试创建一个包含单行的... / webapps / ourapp / WEB-INF / classes / log4j.properties文件

log4j.logger.com.opensymphony.oscache=ERROR

看看是否会阻止oscache记录。它确实如此,但令人惊讶的是(对我而言)它停止了所有不需要的记录,而不仅仅是oscache记录。所以我评论了这条线并再次尝试。仍然没有任何不必要的记录。我将文件移到了一边,现在不需要的日志记录又回来了。我创建了一个零长度的log4j.properties并且所有不需要的日志记录再次消失(!)虽然这是我想要的短期内容,但它让我想知道其他日志记录被扔掉了(以及为什么!)。所以我只是依靠它而感到不舒服。

Tomcat 5.5文档中的“日志记录”章节仅表示您可以通过在WEB-INF / classes中放置属性文件来进行每个应用程序配置,但是(至少不是我能找到的)谈论如何与common / classes中指定的配置交互。

所以:

  • 第一方如何将第三方组件记录到catalina.out?我猜他们的日志记录可能会冒泡到根记录器,但是为什么即使根记录器级别调到ERROR,它们仍然会记录?
  • 为什么将记录器上的记录器级别设置为DEBUG会使此记录开始?我们的记录器有自己的名字,因此oscache和其他东西无法成为我们记录器的祖先。
  • 为什么即使是零长度的WEB-INF / classes / log4j.properties文件也会停止一大堆日志记录?
  • 我怎么能以“正确”的方式做到这一点,并以有意义的方式限制记录,而不是依靠一些奇怪的(对我来说)副作用来关闭它?


Curiouser和curiouser。我试过亚光的打开调试的建议。我还为webapp做了一个更广泛的log4j.properties文件:

log4j.rootLogger=INFO, SSOA1
log4j.appender.SSOA1=org.apache.log4j.ConsoleAppender
log4j.appender.SSOA1.layout=org.apache.log4j.PatternLayout

# Print the date in ISO 8601 format
log4j.appender.SSOA1.layout.ConversionPattern=%d [%t] %-5p %c - %m%n

log4j.logger.com.opensymphony.oscache=ERROR
#log4j.additivity.com.opensymphony.oscache=false

当tomcat启动时,我看到:

log4j: Using URL [file:/srv/www/tomcat5/base/webapps/myapp/WEB-INF/classes/log4j.properties] for automatic log4j configuration.
log4j: Reading configuration from URL file:/srv/www/tomcat5/base/webapps/myapp/WEB-INF/classes/log4j.properties
log4j: Parsing for [root] with value=[INFO, SSOA1].
log4j: Level token is [INFO].
log4j: Category root set to INFO
log4j: Parsing appender named "SSOA1".
log4j: Parsing layout options for "SSOA1".
log4j: Setting property [conversionPattern] to [%d [%t] %-5p %c - %m%n].
log4j: End of parsing for "SSOA1".
log4j: Parsed "SSOA1" options.
log4j: Parsing for [com.opensymphony.oscache] with value=[ERROR].
log4j: Level token is [ERROR].
log4j: Category com.opensymphony.oscache set to ERROR
log4j: Handling log4j.additivity.com.opensymphony.oscache=[null]
log4j: Finished configuring.

但是尽管oscache记录器的级别设置为错误,我仍然会在日志中看到这样的内容:

2011-03-30 14:53:22,076 [main] DEBUG com.opensymphony.oscache.base.algorithm.AbstractConcurrentReadCache - get called (key=AUDIT_KEY_OLDEST_TIMSTAMP)

如果我将oscache记录器级别强制为ERROR(log4j调试输出表示我是),那么为什么要发送这个DEBUG消息呢?子记录器覆盖代码中的级别?

我注意到的是,如果我在webapp的log4j.properties文件中取消注释oscache记录器的“可加性”行,那么记录确实会消失。因此,看起来oscache日志记录依赖于祖先appender而不是它自己的appender。但是,将oscache记录器级别设置为ERROR的所有怪异似乎并没有停止这些事情。

2 个答案:

答案 0 :(得分:2)

您可以配置log4j.properties以仅获取下面的代码日志,并将其放在与catalina.out不同的文件中。

handlers = org.apache.juli.FileHandler

org.apache.juli.FileHandler.level = ALL org.apache.juli.FileHandler.directory = $ {catalina.base} /日志 org.apache.juli.FileHandler.prefix = yourapp名。

com.yourproject.module.package.level = ALL

答案 1 :(得分:2)

我已经弄清楚到底发生了什么。问题是,在webapp的另一部分的内部埋没是下面的代码,当该组件进入调试模式时运行:

public static synchronized void setDebugOn(boolean debugOn) {
    if (isAllDebugOn() ^ debugOn) {
        setAllDebugOn(debugOn);
        Enumeration en = LogManager.getCurrentLoggers();
        while (en.hasMoreElements()) {
            setDebugOn((Logger) en.nextElement(), debugOn);
        }
        setDebugOn(LogManager.getRootLogger(), debugOn);
    }
}

public static void setDebugOn(String name, boolean debugOn) {
    setDebugOn(getLogger(name), debugOn);
}

private static void setDebugOn(Logger logger, boolean debugOn) {
    logger.setLevel(debugOn ? Level.DEBUG : Level.INFO);
}

换句话说,当这个组件进入调试模式时,它还会将 WEBLEP中的每个LOG4J LOGGER 放入调试模式(我已经通过更改代码来验证打印出来这三个中最后一个方法内的每个记录器的名称。所以blammo - 碰巧使用log4j的所有第三方东西开始记录它的调试输出,无论log4j.properties说什么。叹气。

当我使用该循环更改方法时,只会弄乱与该组件相关的特定记录器的级别,然后我的log4j.properties配置开始按预期工作。