log4j vs. System.out.println - logger 的优势?

2022-09-01 15:45:55

我第一次在项目中使用log4j。一位程序员告诉我,使用被认为是一种不好的风格,log4j是当今日志记录问题的标准。System.out.println

我们做了很多JUnit测试 - 事实证明,测试的东西更难。System.out

因此,我开始将log4j用于控制台控制器类,这只是处理命令行参数。

// log4j logger config 
org.apache.log4j.BasicConfigurator.configure();
Logger logger = LoggerFactory.getLogger(Console.class);
Category cat = Category.getRoot(); 

似乎有效:

logger.debug("String");

生产:

1 [main] DEBUG project.prototype.controller.Console  - String

关于这个问题,我有个问题:

  1. 根据我对使用此记录器的基本理解,如果在记录器上启用了调试模式,应该为我提供舒适的选择来编写带有时间戳的日志文件 - 而不是在控制台上发送垃圾邮件?
  2. 为什么System.out.println更难测试?我搜索了stackoverflow并找到了一个测试配方。所以我想知道使用log4j我真正获得了什么样的优势。

答案 1

记录器能够定义记录消息的不同重要性级别,并能够对输出使用不同的接收器 - 控制台,文件等。

此外,在使用记录器时,仅启用或禁用某些类型的消息也很容易 - 例如,您不希望在生产中看到每个调试消息。

我不认为使用记录器在单元测试中提供了任何显着的优势,但无论如何,我更喜欢它。在单元测试中,断言通常是我主要关注的问题。

顺便说一句,你真的应该考虑使用像Commons LoggingSLF4J这样的东西作为日志框架的外观 - 将你的代码绑定到特定的日志记录框架是不好的风格。通用日志记录和 SLF4J 可让您轻松切换日志记录框架(如果您愿意)。


答案 2

您打印到System.out的任何内容都将转到“标准输出”,虽然您可以将标准输出重定向到文件并进行比较,但您有什么,这是非常不灵活的。此外,如果您使用 System.out...,则无法筛选出标准内容。一切都将被打印出来。使用log4j,您可以设置不同的日志记录级别,以便不会打印低于特定严重性/重要性阈值的日志记录消息(例如,如果将日志记录级别更改为WARN,则调试和INFO消息将不再显示)。

此外,log4j允许逐个类地控制日志记录,而System.out只能在整个应用程序的粒度上进行控制(如果您重定向System.out,则可以将其重定向到整个程序)。相比之下,log4j中的每个记录器都可以被赋予不同的附加器。此外,您可以为log4j记录器提供多个附加器(例如,它可以通过系统记录器和网络进行)。您甚至可以将log4j记录器附加到StringBuilder,以便您可以轻松阅读所写的内容。虽然System.out可以重定向,但这种重定向往往相当有限;System.out可以重定向到文件或管道(到另一个程序),但您无法将其重定向到URL,例如;相比之下,创建一个使用HTTP POST传输日志记录消息的追加器将非常容易。