slf4j——A better choice
SLF4J来源于log4j项目,英文全称是 Simple Logging Facade for Java ,官方对这个项目的功能描述如下
The Simple Logging Facade for Java or (SLF4J) serves as a simple facade or abstraction for various logging frameworks, e.g. java.util.logging, log4j and logback, allowing the end-user to plug in the desired logging framework at deployment time.
可见SLF4J是比log4j更抽象的一个框架,可以使用底层log4j的实现来在程序里面写日志,为什么会引入这个更高级的API呢,主要基于如下理由
SLF4J supports an advanced feature called parameterized logging which can significantly boost logging performance for disabled logging statement.
For some Logger logger, writing,
logger.debug("Entry number: " + i + " is " + String.valueOf(entry[i])); |
incurs the cost of constructing the message parameter, that is converting both integer i and entry[i] to a String, and concatenating intermediate strings. This, regardless of whether the message will be logged or not.
One possible way to avoid the cost of parameter construction is by surrounding the log statement with a test. Here is an example.
if(logger.isDebugEnabled()) { logger.debug("Entry number: " + i + " is " + String.valueOf(entry[i]));} |
This way you will not incur the cost of parameter construction if debugging is disabled for logger. On the other hand, if the logger is enabled for the DEBUG level, you will incur the cost of evaluating whether the logger is enabled or not, twice: once in debugEnabled and once in debug. This is an insignificant overhead because evaluating a logger takes less than 1% of the time it takes to actually log a statement.
Better yet, use parameterized messages
There exists a very convenient alternative based on message formats. Assuming entry is an object, you can write:
Object entry = new SomeObject(); logger.debug("The entry is {}.", entry); |
After evaluating whether to log or not, and only if the decision is affirmative, will the logger implementation format the message and replace the ‘{}’ pair with the string value of entry. In other words, this form does not incur the cost of parameter construction in case the log statement is disabled.
The following two lines will yield the exact same output. However, the second form will outperform the first form by a factor of at least 30, in case of a disabled logging statement.
logger.debug("The new entry is "+entry+"."); logger.debug("The new entry is {}.", entry); |
A two argument variant is also available. For example, you can write:
logger.debug("The new entry is {}. It replaces {}.", entry, oldEntry); |
If three or more arguments need to be passed, you can make use of the Object[] variant. For example, you can write:
logger.debug("Value {} was inserted between {} and {}.", new Object[] {newVal, below, above}); |
Array type arguments, including multi-dimensional arrays, are also supported.
SLF4J uses its own message formatting implementation which differs from that of the Java platform. This is justified by the fact that SLF4J’s implementation performs about 10 times faster but at the cost of being non-standard and less flexible.
以上是官方文档解说,英文好的同学可以仔细阅读,我觉得大体的意思比log4和其他的logging系统,一个是有更好的性能,一个是编程更有效率还有使用起来更有弹性,毕竟是一个facade,可以方便在各个logging系统里面切换。当然还有更多的细节部分的优越性。
实际上可以把slf4j看做一个facade,如下图: