日志记录器 vs. System.out.println

56

我正在使用Eclipse的PMD插件,当我使用System.out.println()时,它会给出以下错误提示:

System.(out|err).print已经使用,请考虑使用日志记录器。

我的问题是——什么是日志记录器?它如何用于打印到屏幕?为什么它更好?


1
还可以参考最近的这个问题:https://dev59.com/sHE85IYBdhLWcg3wgDpI - BalusC
6个回答

38

请查看log4j的简短介绍

问题出在使用System.out来打印调试或诊断信息。这是一种不好的做法,因为您无法轻松更改日志级别、关闭它、自定义它等。

但是,如果您有合理的理由使用System.out来向用户打印信息,则可以忽略此警告。


我会将答案扩展为“[...]将信息打印给用户或其他进程,那么您可以忽略此警告”。想想Unix进程将输出管道传递给另一个进程,正是System.out的概念赋予了它这种能力。 - lcfd

12
如果你在应用程序的main()方法中使用System.out|err.println(..)输出用户信息到控制台,那么你并没有做错什么。你可以通过插入注释“//NOPMD”来摆脱该消息。
System.out.println("Fair use of System.out.println(..).");// NOPMD

为此,PMD-Violations概述中有一个“标记为已审核”的选项。

当然,您可以通过以下代码片段欺骗PMD:

PrintStream out=System.out;
out.println("I am fooling PMD.");  

在main()方法之外,使用像Log4j这样的日志系统。

更新:

您也可以修改PMD规则“SystemPrintln”,以使用以下XPath:

//MethodDeclaration[@MethodName!="main"]//Name[
starts-with(@Image, 'System.out.print')
or
starts-with(@Image, 'System.err.print')
] | //Initializer//Name[
starts-with(@Image, 'System.out.print')
or
starts-with(@Image, 'System.err.print')
]

这将忽略你代码中任何名为'main'的方法中的 System.out.println 等内容,但会检查初始化代码中的 System.out.println。 我喜欢这个方法,因为在'main(String args[])'方法中,从我的角度来看,System.out.println是安全的。但需谨慎使用,我必须检查AST中System.out.println可能出现的位置,并调整XPath。


9

这个链接提供了更简洁的关于如何使用Log4j的信息:不要使用System.out.println! 但是它只有一个小缺点,你不应该将库放在/jre/lib/ext中,而是将其放在应用程序的运行时类路径中并随应用程序一起发布。

优点是你可以使用日志级别来指示信息的重要性,这样你就可以在外部配置哪些级别显示/隐藏输出(这样你就不会被毕竟无用的信息所困扰),输出应该是什么样子的(例如包括时间戳、线程ID、类名、方法名等),输出应该写入到哪里(例如控制台、文件、电子邮件等),以及在某些情况下,例如文件也应该如何创建(例如按年、月和/或日分组)。

有几个记录器实现,如Java SE的内置java.util.logging.Logger、方便的Apache Commons Logging、流行的Apache Log4j、它的后继者Logback等。你可以使用Slf4j作为额外的抽象层,在需要时在这些记录器之间切换。


8

日志记录器具有多个日志级别。

如果我们编写的是一个非常简短的程序,仅用于学习目的,那么使用System.out.println就可以了。但是,当我们正在开发高质量的软件项目时,应该使用专业的日志记录器,并避免使用SOPs。

专业的日志记录器提供不同的日志级别和灵活性。我们可以相应地获取日志消息。例如,X组消息只应在生产环境中打印,Y组消息应在错误情况下打印等。

System.out中,我们只有有限的选项来重定向消息,但是在日志记录器中,您可以使用附加器提供多种选项。我们甚至可以创建自定义输出选项并将其重定向到该选项。


4
看起来PMD假定你正在调用System.out.println()进行调试,类似于“我在你的方法中执行你的代码”。如果你这样做了,使用像Log4J这样的记录器会比仅输出到屏幕更好,因为它有多个流选项。但是,如果你正在编写控制台应用程序并且正在调用System.out作为其中的一部分,请忽略警告。

1

System.out.println 不好用,因为它无法配置。相反,Logger 可以被配置以记录各种级别的信息,而且还有很多其他功能。


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