使用Java日志记录API时如何禁用默认控制台处理程序?


92

嗨,我正在尝试在我的应用程序中实现Java日志记录。我想使用两个处理程序。文件处理程序和我自己的控制台处理程序。我的两个处理程序都工作正常。我的日志记录发送到文件和控制台。我的日志记录也发送到我不想要的默认控制台处理程序。如果运行我的代码,您会看到发送到控制台的另外两行。我不想使用默认的控制台处理程序。有谁知道如何禁用默认控制台处理程序。我只想使用我创建的两个处理程序。

Handler fh = new FileHandler("test.txt");
fh.setFormatter(formatter);
logger.addHandler(fh);

Handler ch = new ConsoleHandler();
ch.setFormatter(formatter);
logger.addHandler(ch);

import java.util.Date;
import java.util.logging.ConsoleHandler;
import java.util.logging.FileHandler;
import java.util.logging.Formatter;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.LogManager;
import java.util.logging.LogRecord;
import java.util.logging.Logger;

public class LoggingExample {
    private static Logger logger = Logger.getLogger("test");

    static {
        try {
            logger.setLevel(Level.INFO);

            Formatter formatter = new Formatter() {

                @Override
                public String format(LogRecord arg0) {
                    StringBuilder b = new StringBuilder();
                    b.append(new Date());
                    b.append(" ");
                    b.append(arg0.getSourceClassName());
                    b.append(" ");
                    b.append(arg0.getSourceMethodName());
                    b.append(" ");
                    b.append(arg0.getLevel());
                    b.append(" ");
                    b.append(arg0.getMessage());
                    b.append(System.getProperty("line.separator"));
                    return b.toString();
                }

            };

            Handler fh = new FileHandler("test.txt");
            fh.setFormatter(formatter);
            logger.addHandler(fh);

            Handler ch = new ConsoleHandler();
            ch.setFormatter(formatter);
            logger.addHandler(ch);

            LogManager lm = LogManager.getLogManager();
            lm.addLogger(logger);
        } catch (Throwable e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        logger.info("why does my test application use the standard console logger ?\n" + " I want only my console handler (Handler ch)\n " + "how can i turn the standard logger to the console off. ??");
    }
}

1
我可以轻轻地建议使用b.append(formatMessage(arg0))来代替b.append(arg0.getMessage())。使用该formatMessage方法,可以使格式化程序与use public void log(Level level, String msg, Object param1)和类似方法兼容。
维克多

Answers:


102

默认控制台处理程序附加到根记录器,该记录器是所有其他记录器(包括您的记录器)的父级。因此,我看到了两种解决您的问题的方法:

如果这仅影响您的特定类别,则最简单的解决方案是禁用将日志传递给父记录器:

logger.setUseParentHandlers(false);

如果要为整个应用程序更改此行为,则可以在添加自己的处理程序之前,从根记录器中完全删除默认控制台处理程序:

Logger globalLogger = Logger.getLogger("global");
Handler[] handlers = globalLogger.getHandlers();
for(Handler handler : handlers) {
    globalLogger.removeHandler(handler);
}

注意:如果您也想在其他类中使用相同的日志处理程序,则最好的方法是从长远来看将日志配置移到配置文件中。


2
setUseParentHandlers方法有效,谢谢。如何从根记录器中删除默认控制台处理程序?
Loudiyimo

10
您也可以使用Logger.getLogger(“”)-这对我有用,而“ global”不起作用(可能是SLF4J的结果吗?)
sehugg 2011年

2
如果您想要slf4j,我建议您使用 LogManager.getLogManager().reset(); SLF4JBridgeHandler.install();
Somatik 2011年

8
“”是根记录器的标识符。“全局”是命名记录器(root的子代),默认情况下会创建该记录器,并将其用于简单的日志记录方案中
Paolo Fulgoni 2014年

1
这个答案对我不起作用,但Dominique的答案确实有效
BullyWiiPlaza

108

做就是了

LogManager.getLogManager().reset();

1
谢谢,这是正确的答案。标记为正确的答案无效。
Andreas L.

1
这应该指出,这将影响每个命名的每个处理程序,Logger因此对于更复杂的Log系统可能是一个问题。在过程开始时应调用一次,以确保不会影响未来记录器。当然,需要控制台的人需要ConsoleHandler按预期收到一个to。
AxelH

20

这很奇怪,但 Logger.getLogger("global") 在我的设置(以及中Logger.getLogger(Logger.GLOBAL_LOGGER_NAME))中不起作用。

但是Logger.getLogger("")做得很好。

希望此信息也能对某人有所帮助...


3
有人可以告诉我们为什么getLogger(Logger.GLOBAL_LOGGER_NAME)不起作用,但是getLogger(“”)起作用吗?
deinocheirus

2
@deinocheirus看到我对这个答案的
Paolo Fulgoni

9

重置配置并将根级别设置为OFF

LogManager.getLogManager().reset();
Logger globalLogger = Logger.getLogger(java.util.logging.Logger.GLOBAL_LOGGER_NAME);
globalLogger.setLevel(java.util.logging.Level.OFF);

5

您必须指示记录器不要向其父记录器发送消息:

...
import java.util.logging.*;
...
Logger logger = Logger.getLogger(this.getClass().getName());
logger.setUseParentHandlers(false);
...

但是,应该在向记录器添加更多处理程序之前完成此操作。


就我而言,这是可行的,尽管我必须为此记录器手动添加处理程序。
Sachin Gorade
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.