为某些记录器设置loglevel,但不设置其他记录器

时间:2009-05-13 12:16:20

标签: java logging

我正在开发一个使用java.util.logging来满足其日志记录需求的Java应用程序。该应用程序使用大量外部库(JDBC,JMS客户端,JSR-160实现等),其中一些还使用java.util.logging。

当我在命令行上指定一个标志时,我想将 my Loggers的日志级别设置为ALL,但到目前为止,我只找到了为所有记录器设置级别的方法,而不仅仅是矿。

我的记录器全部称为“com.mycompany.myapp.SomeClass”,当我将“com.mycompany.myapp”的级别设置为ALL时,不记录任何额外信息。当我将根记录器的级别设置为ALL时,所有记录器的所有信息都会记录到控制台,这是太多的信息!

如何在不让所有其他记录器充斥我的日志文件的情况下将自己的记录器设置为ALL?

4 个答案:

答案 0 :(得分:4)

实际上,我不确定你为什么会遇到你所描述的问题。我已经创建了一个简单的JUnit测试(如下所示),并且设置日志级别的工作方式完全符合我的预期(这似乎与您期望它们的工作方式一致)。

您是否尝试在自定义记录器中记录级别设置为INFO以下的消息?从我包含的测试中可以看出,默认情况下,默认日志记录处理程序设置为INFO。您需要更改该处理程序的级别以查看精细消息(也显示)。

import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.junit.Test;

public class SimpleLoggerTest {

    private void logMessages(Logger logger) {
        logger.warning(getLoggerName(logger) + ": warning message");
        logger.info(getLoggerName(logger) + ": info message");
        logger.fine(getLoggerName(logger) + ": fine message");
    }


    private String getLoggerName(Logger logger) {
        String loggerName = logger.getName();
        if (loggerName.isEmpty()) {
            return "[root logger]";
        }
        return loggerName;
    }

    private void listHandlerLevels(Logger logger) {
        for (Handler handler : logger.getHandlers()) {
            logger.info(getLoggerName(logger) + ": handler level = " + handler.getLevel());
        }
        Logger parentLogger = logger.getParent();
        if (null != parentLogger) {
            for (Handler handler : parentLogger.getHandlers()) {
                logger.info("parent logger handler (" + getLoggerName(parentLogger) + "): handler level = " + handler.getLevel());
            }
        }
    }

    private void setHandlerLevels(Logger logger, Level level) {
        for (Handler handler : logger.getHandlers()) {
            handler.setLevel(level);
        }
        Logger parentLogger = logger.getParent();
        if (null != parentLogger) {
            for (Handler handler : parentLogger.getHandlers()) {
                handler.setLevel(level);
            }
        }
    }
    @Test
    public void testLoggingLevel() {
        Logger myLogger = Logger.getLogger(SimpleLoggerTest.class.getName());
        Logger rootLogger = myLogger.getParent();

        // list the default handler levels
        listHandlerLevels(myLogger);
        listHandlerLevels(rootLogger);

        // log some messages
        logMessages(myLogger);
        logMessages(rootLogger);

        // change the logger levels
        myLogger.setLevel(Level.ALL);
        rootLogger.setLevel(Level.WARNING);

        // list the handler levels again
        listHandlerLevels(myLogger);
        listHandlerLevels(rootLogger);

        // log some messages (again)
        logMessages(myLogger);
        logMessages(rootLogger);

        // change Handler levels to FINE
        setHandlerLevels(myLogger, Level.FINE);

        // list the handler levels (last time)
        listHandlerLevels(myLogger);
        listHandlerLevels(rootLogger);

        // log some messages (last time)
        logMessages(myLogger);
        logMessages(rootLogger);
    }
}

生成此输出...

May 13, 2009 10:46:53 AM SimpleLoggerTest listHandlerLevels
INFO: parent logger handler ([root logger]): handler level = INFO
May 13, 2009 10:46:53 AM java.util.logging.LogManager$RootLogger log
INFO: [root logger]: handler level = INFO
May 13, 2009 10:46:53 AM SimpleLoggerTest logMessages
WARNING: SimpleLoggerTest: warning message
May 13, 2009 10:46:53 AM SimpleLoggerTest logMessages
INFO: SimpleLoggerTest: info message
May 13, 2009 10:46:53 AM java.util.logging.LogManager$RootLogger log
WARNING: [root logger]: warning message
May 13, 2009 10:46:53 AM java.util.logging.LogManager$RootLogger log
INFO: [root logger]: info message
May 13, 2009 10:46:53 AM SimpleLoggerTest listHandlerLevels
INFO: parent logger handler ([root logger]): handler level = INFO
May 13, 2009 10:46:53 AM SimpleLoggerTest logMessages
WARNING: SimpleLoggerTest: warning message
May 13, 2009 10:46:53 AM SimpleLoggerTest logMessages
INFO: SimpleLoggerTest: info message
May 13, 2009 10:46:53 AM java.util.logging.LogManager$RootLogger log
WARNING: [root logger]: warning message
May 13, 2009 10:46:53 AM SimpleLoggerTest listHandlerLevels
INFO: parent logger handler ([root logger]): handler level = FINE
May 13, 2009 10:46:53 AM SimpleLoggerTest logMessages
WARNING: SimpleLoggerTest: warning message
May 13, 2009 10:46:53 AM SimpleLoggerTest logMessages
INFO: SimpleLoggerTest: info message
May 13, 2009 10:46:53 AM SimpleLoggerTest logMessages
FINE: SimpleLoggerTest: fine message
May 13, 2009 10:46:53 AM java.util.logging.LogManager$RootLogger log
WARNING: [root logger]: warning message

这是我试图在my other response中传达的内容。

答案 1 :(得分:2)

每个Logger都有一个Handler,其中包含自己的日志Level

您的记录器的处理程序是否也可能未设置为ALL并忽略消息? (这很麻烦,我知道)。

这是来自O'Reilly的a 2002 article on Java logging

答案 2 :(得分:2)

是的,JDK自己的日志记录框架有时可能是一个真正的婊子。正确地注意到根记录器处理程序的日志级别是问题所在。你在问题中提出的解决方案几乎是一个很好的解决方案:

Logger logger = Logger.getLogger("com.mycompany.myapp");
Handler handler = new ConsoleHandler(); /* or whatever you like. */
handler.setLevel(Level.ALL);
logger.addHandler(handler);
logger.setLevel(Level.ALL);
logger.setUseParentHandlers(false); /* <- important. */

当您在该记录器“下方”创建记录器时,即名称为“com.mycompany.myapp.foo.Foo”时,它们将仅记录您创建的记录器。该记录器的父记录器(根记录器)不会从您的应用程序获取任何日志消息,但会从JDK的其他部分接收消息,如Swing或AWT。

答案 3 :(得分:0)

设置属性

com.mycompany.myapp.level = ALL

应该做你想做的事。

但是所有的记录器都需要与相关的类名相对应地命名! E.g。

package com.mycompany.myapp;

public class MyClass{
    private static Logger theLogger =
         Logger.getLogger(MyClass.class.getName());
    ...
}

另一种可能的解释是您的配置未正确传递到日志记录框架。尝试喂食

LogManager.getLogManager().readConfiguration(InputStream);

启动时的日志配置。这就是我的工作,这对我有用。