我是第一次在项目中使用 log4j。一位程序员同事告诉我,使用 System.out.println 被认为是一种不好的风格,而 log4j 类似于当今日志记录问题的标准。
我们进行了大量的 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
我对此有两个问题:
- 根据我的基本理解,使用此记录器应该为我提供舒适的选项来编写带有时间戳的日志文件 - 而不是向控制台发送垃圾邮件 - 如果启用了调试模式在记录器处?
- 为什么 System.out.println 更难测试?我搜索了 stackoverflow 并找到了测试配方。所以我想知道使用 log4j 到底能带来什么样的优势。
I'm using log4j for the first time in a project. A fellow programmer told me that using System.out.println
is considered a bad style and that log4j is something like standard for logging matters nowadays.
We do lots of JUnit testing - System.out
stuff turns out to be harder to test.
Therefore I began utilizing log4j for a Console controller class, that's just handling command-line parameters.
// 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 two questions regarding this:
- 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?
- 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.
发布评论
评论(5)
记录器能够定义所记录消息的不同重要性级别,以及使用不同接收器进行输出的能力 - 控制台、文件等。
此外,在使用记录器时,可以轻松启用或禁用某些类型的消息- 例如,您不想看到生产中的每条调试消息。
我不认为使用记录器在单元测试中提供任何显着的优势,但无论如何我还是更喜欢它。在单元测试中,断言通常是我最关心的问题。
顺便说一句,您确实应该考虑使用 Commons Logging 或 SLF4J 作为日志框架外观 - 将代码绑定到特定日志框架是不好的风格。如果您愿意,通用日志记录和 SLF4J 可以让您轻松切换日志记录框架。
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 Logging or SLF4J as 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.
打印到 System.out 的任何内容都将转到“标准输出”,虽然您可以将标准输出重定向到文件并进行比较,但您有什么,这是非常不灵活的。此外,如果您使用 System.out,则无法过滤进入标准输出的内容...所有内容都将被打印。使用log4j,您可以设置不同的日志记录级别,以便不打印低于特定严重性/重要性阈值的日志消息(例如,如果将日志记录级别更改为WARN,则将不再显示DEBUG 和INFO 消息)。
此外,log4j 允许逐类控制日志记录,而 System.out 只能在整个应用程序的粒度上进行控制(如果重定向 System.out,则会针对整个程序重定向它)。相比之下,log4j 中的每个记录器都可以被赋予不同的附加程序。此外,您可以为 log4j 记录器提供多个附加程序(例如,它可以成为系统记录器,并通过网络)。您甚至可以将 log4j 记录器附加到 StringBuilder,以便您可以轻松读取写入的内容。虽然 System.out 可以重定向,但这种重定向往往相当有限; System.out 可以重定向到文件或管道(到另一个程序),但您无法将其重定向到 URL,例如;相比之下,创建一个使用 HTTP POST 传输日志消息的附加程序将非常容易。
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).
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.
使用例如
使用
logger.setLevel(...)
您可以轻松选择是否显示logger.debug(..)
消息,例如将其设置为警告级别,并且不会打印任何跟踪、调试和信息语句。这节省了您只需注释掉偶尔需要的调试语句的时间。另请参阅维基百科。
Use e.g.
Using
logger.setLevel(...)
you can easily choose whether to displaylogger.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.Also have a look at Wikipedia.
使用logger.setLevel(...),您可以轻松选择是否显示logger.debug(..)消息,例如将其设置为警告级别,并且不会打印任何跟踪、调试和信息语句。这节省了您只需注释掉偶尔需要的调试语句的时间
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
对于 log4j,它提供了一个中间件服务,您可以在其中管理日志记录级别,例如 DEBUG、INFO、ERROR 等。并且您可以启用和禁用日志记录。但是对于 System.out.println(),您必须管理一切。
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.