我有一个简单的设置来记录消息: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 上?
记录器应将 stdout 用于
fine
+info
并使用 stderr 用于 severe
级别。
java.util.logging API 是根据 JSR 47: Logging API Specification 开发的。根据“Proposed Final Draft”中的更改日志,ConsoleHandler 始终使用 System.err。 JCP 页面还列出了 API 的原始作者,我认为只有那些名字才能真正知道您问题的答案。
也就是说,我认为起源来自System.err API 文档。
通常此流对应于显示输出或主机环境或用户指定的另一个输出目标。按照惯例,此输出流用于显示错误消息或应立即引起用户注意的其他信息,即使主要输出流(变量 out 的值)已被重定向到文件或其他目的地通常不会持续监控。
反对System.out:
“标准”输出流。此流已打开并准备好接受输出数据。通常,此流对应于显示输出或主机环境或用户指定的另一个输出目标。
记录映射到诊断而不是原始数据。将数据与诊断错误信息分开很重要,尤其是当管道处理在一起时,因为下游消费者只准备好接受数据信息而不是错误消息。有关更多详细信息,请参阅对标准输入、标准输出和标准错误感到困惑?。
有据可查。默认情况下,记录器发布到它们父级的处理程序,递归到树,直到指定另一个处理程序。您可以遍历父级的处理程序,并看到父级记录器的默认处理程序是 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());
}
}
}
您可以创建和扩展
ConsoleHandler
以将输出设置为System.out
而不是System.err
Logger logger = Logger.getLoger("your_logger_name");
logger.setUseParentHandler(false);
logger.addHandler(new ConsoleHandler() {
{setOutputStream(System.out);}
});
现在,此记录器上的所有消息都将显示在
System.out
控制台中。
logger默认输出INFO及以上级别(即INFO、WARNING和SEVERE)的日志记录到标准错误流(System.err)。
资料来源:www3.ntu.edu.sg/home/ehchua/programming/java/JavaLogging.html
他们使用 stderr 的原因是因为这个流“用于程序发出的错误消息和诊断”(来源:https://www.gnu.org/software/libc/manual/html_node/Standard-Streams.html ).