Java log4j 与 System.out.println - 记录器的优势?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2727500/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 12:10:46  来源:igfitidea点击:

log4j vs. System.out.println - logger advantages?

javaloggingjunittimestamplogfiles

提问by wishi

I'm using log4j for the first time in a project. A fellow programmer told me that using System.out.printlnis considered a bad style and that log4j is something like standard for logging matters nowadays.

我第一次在项目中使用 log4j。一位程序员同事告诉我,使用System.out.println被认为是一种糟糕的风格,而且 log4j 是当今记录问题的标准。

We do lots of JUnit testing - System.outstuff turns out to be harder to test.

我们进行了大量的 JUnit 测试——System.out结果证明这些东西更难测试。

Therefore I began utilizing log4j for a Console controller class, that's just handling command-line parameters.

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

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

Seems to work:

似乎工作:

logger.debug("String");

Produces:

产生:

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

I got twoquestions regarding this:

关于这个我有两个问题:

  1. From my basic understanding using this logger should provide me comfortable options to write a logfile with timestamps - instead of spamming the console - if debug mode is enabled at the logger?
  2. Why is System.out.println harder to test? I searched stackoverflow and found a testing recipe. So I wonder what kind of advantage I really get by using log4j.
  1. 根据我的基本理解,使用这个记录器应该为我提供舒适的选项来编写带有时间戳的日志文件 - 而不是向控制台发送垃圾邮件 - 如果在记录器上启用了调试模式?
  2. 为什么 System.out.println 更难测试?我搜索了 stackoverflow 并找到了一个测试配方。所以我想知道我使用 log4j 真正获得了什么样的优势。

采纳答案by Bozhidar Batsov

The logger gives to ability to define different levels of importance of the logged messages and the ability to use different sink for the output - the console, a file, etc.

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

Also it's easy to enable or disable only some type of message when using a logger - for example you don't want to see every debug message in production.

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

I don't think that using loggers offers any significant advantages in unit tests, but I'd prefer it even there anyways. In unit tests asserts are usually my primary concern.

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

Btw you should really consider using something like Commons Loggingor SLF4Jas a log framework facade - it's bad style to tie your code to a specific logging framework. Common Logging and SLF4J make it easy to switch logging frameworks if you choose to.

顺便说一句,您真的应该考虑使用诸如Commons LoggingSLF4J 之类的东西作为日志框架外观 - 将您的代码绑定到特定的日志框架是一种糟糕的风格。如果您愿意,Common Logging 和 SLF4J 可以轻松切换日志框架。

回答by Tobias Kienzler

  1. Use e.g.

    org.apache.log4j.BasicConfigurator.configure(new FileAppender(  
        new PatternLayout("%d{ISO8601} %-5p %t: %m%n"),  // see e.g. http://en.wikipedia.org/wiki/Log4j#TTCC  
        "log/mainWhatever.log"));
    
  2. Using logger.setLevel(...)you can easily choose whether to display logger.debug(..)messages, e.g. set it to level warn and any trace, debug and info statements will not be printed. This saves you the time of having to comment out only occasionally needed debug statements.

  1. 使用例如

    org.apache.log4j.BasicConfigurator.configure(new FileAppender(  
        new PatternLayout("%d{ISO8601} %-5p %t: %m%n"),  // see e.g. http://en.wikipedia.org/wiki/Log4j#TTCC  
        "log/mainWhatever.log"));
    
  2. 使用logger.setLevel(...)您可以轻松选择是否显示logger.debug(..)消息,例如将其设置为级别警告,并且不会打印任何跟踪、调试和信息语句。这可以节省您只需要注释掉偶尔需要的调试语句的时间。

Also have a look at Wikipedia.

也看看维基百科

回答by Michael Aaron Safyan

Anything that you print to System.out will go to "standard out", and while you can redirect standard out to a file and compare it, what have you, that is very inflexible. Additionally, you cannot filter what goes to standard out if you use System.out... everything will be printed. With log4j, you can set different logging levels, so that logging messages that are below a certain severity/importance threshold are not printed (e.g. if you change the logging level to WARN, then DEBUG and INFO messages will not be displayed anymore).

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

Additionally, log4j allows logging to be controlled on a class-by-class basis, whereas System.out can only be controlled at the granularity of the entire application (if you redirect System.out, you redirect it for the entire program). By contrast, each logger in log4j can be given a different appender. In addition, you can give a log4j logger multiple appenders (so that it goes the system logger, and over the network, for example). You can even have a log4j logger append to a StringBuilder, so that you can easily read what was written. And while System.out can be redirected, this redirection tends to be fairly limited; System.out can be redirected to a file or to a pipe (to another program), but you wouldn't be able to redirect it to a URL, for example; by contrast, it would be very easy to create an appender that transmits logging messages using HTTP POST.

此外,log4j 允许在逐个类的基础上控制日志记录,而 System.out 只能在整个应用程序的粒度上进行控制(如果重定向 System.out,则是针对整个程序重定向它)。相比之下,log4j 中的每个记录器都可以被赋予不同的 appender。此外,您可以为 log4j 记录器提供多个附加程序(例如,以便它进入系统记录器并通过网络)。您甚至可以将 log4j 记录器附加到 StringBuilder,以便您可以轻松阅读所写的内容。虽然 System.out 可以重定向,但这种重定向往往相当有限;System.out 可以被重定向到一个文件或一个管道(到另一个程序),但是你不能将它重定向到一个 URL,例如;相比之下,

回答by Prashanth

Using logger.setLevel(...) you can easily choose whether to display logger.debug(..) messages, e.g. set it to level warn and any trace, debug and info statements will not be printed. This saves you the time of having to comment out only occasionally needed debug statements

使用 logger.setLevel(...) 您可以轻松选择是否显示 logger.debug(..) 消息,例如将其设置为级别警告,并且不会打印任何跟踪、调试和信息语句。这可以节省您只需要注释掉偶尔需要的调试语句的时间

回答by Rahul Srivastava

In the case of log4j,It provide a middle ware service where you can manage logging levels like DEBUG,INFO,ERROR etc. And you can enable and disable logging.But in the case of System.out.println() you have to manage every thing.

在 log4j 的情况下,它提供了一个中间件服务,您可以在其中管理日志级别,如 DEBUG、INFO、ERROR 等。您可以启用和禁用日志记录。但在 System.out.println() 的情况下,您必须管理一切。