为什么java.util.logging.Logger会打印到stderr?

20

我有一个简单的设置来记录消息:Java 8 Update 65和Eclipse Mars:

import java.util.logging.Logger;

public class Example {

    private final static Logger LOGGER = Logger.getLogger(Example.class.getName());

    public static void main(String[] args) {
        LOGGER.info("Test");
    }

}

我期望能够在标准输出(stdout)上获得输出,就像使用System.out.println();一样,但实际上它被打印在标准错误(stderr)上,这导致了Eclipse控制台上的红色字体:

enter image description here

我知道可以通过编写自定义的Handler来更改此行为,但我想知道为什么默认输出显示在stderr而不是stdout上?

记录器应该使用stdout来记录fine+info级别,并使用stderr来记录severe级别。

5个回答

10
java.util.logging API是在JSR 47: Logging API Specification下开发的。根据“Proposed Final Draft”中的更改日志,ConsoleHandler总是使用System.err。 JCP页面还列出了API的原始作者,我认为只有这些人才真正知道您问题的答案。
话虽如此,我认为源头来自System.err API文档。

通常,此流对应于由主机环境或用户指定的显示输出或另一个输出目的地。按照惯例,该输出流用于显示错误消息或其他信息,即使主要输出流(变量out的值)已重定向到通常不会持续监视的文件或其他目的地,也应立即引起用户的注意。

相对于System.out

“标准”输出流。该流已经打开并准备好接收输出数据。通常,此流对应于由主机环境或用户指定的显示输出或另一个输出目标。

日志映射到诊断,而不是原始数据。 将数据与诊断错误信息分开非常重要,特别是当将进程管道连接在一起时,因为下游使用者只准备接受数据信息而不是错误消息。 有关更详细的信息,请参见Confused about stdin, stdout and stderr?

3

这已经有详细的记录了。默认情况下,记录器会递归地向其父处理程序发布日志,直到指定其他处理程序为止。您可以遍历父处理程序,并查看父记录器的默认处理程序是使用System.err来发布日志记录的ConsoleHandler。

public class Main {
    public static void main(String[] args) {
        Handler[] handlers = Logger.getLogger(Main.class.getName()).getParent().getHandlers();
        for (Handler handler : handlers) {
            System.out.println(handler.getClass().getName());
        }
    }
}

3

您可以创建并扩展ConsoleHandler,将输出设置为System.out而不是System.err

Logger logger = Logger.getLoger("your_logger_name");
logger.setUseParentHandler(false);
logger.addHandler(new ConsoleHandler() {
    {setOutputStream(System.out);}
});

现在,所有这个记录器上的信息都将出现在 System.out 控制台中。

不要这样做,这会关闭 System.err。可以看一下 setOutPutStream。更好的方法是:final class MigrationsCliConsoleHandler extends StreamHandler { MigrationsCliConsoleHandler() { setOutputStream(System.out); } @Override public void close() { flush(); } } - Michael Simons
1
OP已经意识到这一点,并在原始问题中进行了说明。有一个完全不同的问题专门讨论您正在尝试回答的主题 - jmehrens

2

你有这个声明的来源或证明吗? - Dennis Kriechel
抱歉,我应该在评论中提供它 :) https://www3.ntu.edu.sg/home/ehchua/programming/java/JavaLogging.html - Jose A. Rodríguez Salor
4
OP已知记录员做了那件事情,问题是:“为什么”?请让我知道您需要翻译的其他内容。 - Tom
@Tom 是的,这是另一个问题,但至少我知道这是有意为之的。 - Dennis Kriechel
还发现了这个:ConsoleHandler:一个简单的处理程序,用于将格式化记录写入System.err。来源:https://docs.oracle.com/javase/7/docs/technotes/guides/logging/overview.html(第1.5章)。 - Dennis Kriechel

2

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接