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

wz3gfoph  于 2023-04-04  发布在  Java
关注(0)|答案(5)|浏览(151)

我有一个简单的设置来记录消息: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控制台上的红色字体:

我知道我可以通过编写一个自定义的Handler来改变这种行为,但是我想知道为什么默认输出出现在stderr而不是stdout上?
日志记录器应该对fine + info使用stdout,对severe级别使用stderr。

fd3cxomn

fd3cxomn1#

java.util.logging API是在JSR 47: Logging API Specification下开发的。根据“建议的最终草案”中的更改日志,ConsoleHandler始终使用System.err. JCP页面还列出了API的原始作者,我认为只有这些名字才真正知道你问题的答案。
也就是说,我认为起源来自API文档。
通常,此流对应于显示输出或由主机环境或用户指定的另一个输出目标。按照惯例,此输出流用于显示错误消息或其他信息,即使主要输出流(变量out的值)已重定向到通常不被持续监视的文件或其他目标,这些信息也应立即引起用户的注意。
反对System.out:
“标准”输出流。此流已打开并准备好接受输出数据。通常此流对应于显示输出或主机环境或用户指定的另一个输出目标。
日志记录Map到诊断而不是原始数据。将数据与诊断错误信息分开是很重要的,特别是当下游使用者只准备接受数据信息而不是错误消息时,将数据与诊断错误信息一起传输时。有关详细信息,请参阅混淆stdin、stdout和stderr?。

8i9zcol2

8i9zcol22#

这是有据可查的。默认情况下,日志记录器发布到其父级的处理程序,递归到树,直到指定了另一个处理程序。您可以循环父级的处理程序,并查看父级日志记录器的默认处理程序是ConsoleHandler,它使用System.err发布日志记录。

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());
        }
    }
}
kiayqfof

kiayqfof3#

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

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

现在,此记录器上的所有消息都将显示在System.out控制台中。

9cbw7uwe

9cbw7uwe4#

默认情况下,记录器将INFO及以上级别(即INFO、WARNING和SEVERE)的日志记录输出到标准错误流(System.err)。
来源:www3.ntu.edu.sg/home/ehchua/programming/java/JavaLogging.html

yyhrrdl8

yyhrrdl85#

他们使用stderr的原因是因为这个流“用于程序发出的错误消息和诊断”(来源:https://www.gnu.org/software/libc/manual/html_node/Standard-Streams.html)。

相关问题