为什么 java.util.logging.Logger 打印到 stderr?
Why does java.util.logging.Logger print to stderr?
我有一个简单的设置来记录消息:JDK 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
级别。
默认情况下,记录器将INFO及以上级别(即INFO、WARNING和SEVERE)的日志记录输出到标准错误流(System.err)。
来源:www3.ntu.edu.sg/home/ehchua/programming/java/JavaLogging.html
有据可查。默认情况下,记录器发布到它们父级的处理程序,递归到树,直到指定另一个处理程序。您可以遍历父级的处理程序,并看到父级记录器的默认处理程序是 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());
}
}
}
java.util.logging API was developed under JSR 47: Logging API Specification。根据 "Proposed Final Draft" 中的更改日志,ConsoleHandler 始终使用 System.err。 JCP 页面还列出了 API 的原始作者,我认为只有那些名字才能真正知道您问题的答案。
也就是说,我认为来源来自 System.err API 文档。
Typically this stream corresponds to display output or another output destination specified by the host environment or user. By convention, this output stream is used to display error messages or other information that should come to the immediate attention of a user even if the principal output stream, the value of the variable out, has been redirected to a file or other destination that is typically not continuously monitored.
反对System.out:
The "standard" output stream. This stream is already open and ready to accept output data. Typically this stream corresponds to display output or another output destination specified by the host environment or user.
记录映射到诊断而不是原始数据。将数据与诊断错误信息分开很重要,尤其是当管道处理在一起时,因为下游消费者只准备好接受数据信息而不是错误消息。有关详细信息,请参阅 Confused about stdin, stdout and stderr?。
他们使用 stderr 的原因是因为这个流 "is used for error messages and diagnostics issued by the program"(来源:https://www.gnu.org/software/libc/manual/html_node/Standard-Streams.html)。
您可以创建和扩展 ConsoleHandler
以将输出设置为 System.out
而不是 System.err
Logger logger = Logger.getLoger("your_logger_name");
logger.setUseParentHandler(false);
logger.addHandler(new ConsoleHandler() {
{setOutputStream(System.out);}
});
现在,此记录器上的所有消息都将显示在 System.out
控制台中。
我有一个简单的设置来记录消息:JDK 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
级别。
默认情况下,记录器将INFO及以上级别(即INFO、WARNING和SEVERE)的日志记录输出到标准错误流(System.err)。
来源:www3.ntu.edu.sg/home/ehchua/programming/java/JavaLogging.html
有据可查。默认情况下,记录器发布到它们父级的处理程序,递归到树,直到指定另一个处理程序。您可以遍历父级的处理程序,并看到父级记录器的默认处理程序是 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());
}
}
}
java.util.logging API was developed under JSR 47: Logging API Specification。根据 "Proposed Final Draft" 中的更改日志,ConsoleHandler 始终使用 System.err。 JCP 页面还列出了 API 的原始作者,我认为只有那些名字才能真正知道您问题的答案。
也就是说,我认为来源来自 System.err API 文档。
Typically this stream corresponds to display output or another output destination specified by the host environment or user. By convention, this output stream is used to display error messages or other information that should come to the immediate attention of a user even if the principal output stream, the value of the variable out, has been redirected to a file or other destination that is typically not continuously monitored.
反对System.out:
The "standard" output stream. This stream is already open and ready to accept output data. Typically this stream corresponds to display output or another output destination specified by the host environment or user.
记录映射到诊断而不是原始数据。将数据与诊断错误信息分开很重要,尤其是当管道处理在一起时,因为下游消费者只准备好接受数据信息而不是错误消息。有关详细信息,请参阅 Confused about stdin, stdout and stderr?。
他们使用 stderr 的原因是因为这个流 "is used for error messages and diagnostics issued by the program"(来源:https://www.gnu.org/software/libc/manual/html_node/Standard-Streams.html)。
您可以创建和扩展 ConsoleHandler
以将输出设置为 System.out
而不是 System.err
Logger logger = Logger.getLoger("your_logger_name");
logger.setUseParentHandler(false);
logger.addHandler(new ConsoleHandler() {
{setOutputStream(System.out);}
});
现在,此记录器上的所有消息都将显示在 System.out
控制台中。