介绍
Simple Logging Facade for Java(SLF4J)用作各种日志框架的简单外观或抽象,例如java.util.logging,logback和log4j。SLF4J允许最终用户在部署时插入所需的日志记录框架。请注意,启用SLF4J的库/应用程序意味着只添加一个强制依赖项,即 slf4j-api-1.8.0-beta2.jar。
新建demo
新建一个maven项目。
slf4j简单入门
添加依赖pom.xml
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.25</version>
</dependency>
coding
按照官方文档给的例子,写一个简单的程序
package com.dsdj.test;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class LogTest {
@Test
public void test1(){
Logger logger = LoggerFactory.getLogger(LogTest.class);
logger.info("hello word");
}
}
如果只添加了slf4j-api包,运行会出出现下面的错误
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
这是因为slf4j-api包 是日志的接口,不提供具体的实现。按照官方文档的说明
This warning is printed because no slf4j binding could be found on your class path.
The warning will disappear as soon as you add a binding to your class path. Assuming you add slf4j-simple-1.8.0-beta2.jar so that your class path contains:
添加 slf4j-simple包,这个包是slf4j提供的一个简单实现 。当我们调用接口时,接口的工厂会自动寻找恰当的实现,返回一个实现的实例给我提供服务
coding
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.25</version>
</dependency>
<!--https://mvnrepository.com/artifact/org.slf4j/slf4j-simple-->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.7.25</version>
</dependency>
再次编译输出下面内容
[main] INFO com.dsdj.test.LogTest - hello word
slf4j的常用模式
拷贝官方文档的代码
package com.dsdj.test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class LogTestMain {
public static final Logger logger = LoggerFactory.getLogger(LogTestMain.class);
Integer t;
Integer oldT;
public static void main(String[] args) {
}
public void setTemperature(Integer temperature) {
oldT = t;
t = temperature;
logger.debug("Temperature set to {}. Old temperature was {}.", t, oldT);
if (temperature.intValue() > 50) {
logger.info("Temperature has risen above 50 degrees.");
}
}
}
测试
@Test
public void test2(){
Wombat wombat = new Wombat();
wombat.setTemperature(58);
}
输出
[main] INFO com.dsdj.test.contant.Wombat - Temperature set to 58. Old temperature was null.
[main] INFO com.dsdj.test.contant.Wombat - Temperature has risen above 50 degrees.
总结:
- 官方推荐我们的打印日志的方式是使用占位符的形式
The sample code below illustrates the typical usage pattern for SLF4J. Note the use of {}-placeholders on line 15.
原因如下
// 传统的字符串产生方式,如果没有要记录Debug等级的信息,就会浪费时间在产生不必要的信息上
logger.info("Temperature set to "+t+" Old temperature was "+oldT+".");
// 为了避免上述问题,我们可以先检查是不是开启了Debug信息记录功能,只是程序的编码会比较复杂
if (logger.isDebugEnabled()) {
logger.info("Temperature set to "+t+" Old temperature was "+oldT+".");
}
// 如果Debug等级没有开启,则不会产生不必要的字符串,同时也能保持程序编码的简洁
logger.debug("Temperature set to {}. Old temperature was {}.", t, oldT);
- SLF4J 认为 ERROR 与 FATAL 并没有实质上的差别,所以拿掉了 FATAL 等级,只剩下TRACE, DEBUG, INFO, WARN, ERROR五种等级。
- 对于Java工程师来说,关于日志工具的使用,最佳实践就是在应用中使用如Log4j + SLF4J 这样的组合来进行日志输出。参考阿里巴巴的java规范手册
使用进阶
-
slf4j的使用原理是门面模式的使用。
-
slf4j与常用的日志框架可以完美结合,例如LogBack、Log4j、Log4j2。我们可以替换上文中使用的 slf4j-simple包。而我们的代码不需要改动,这就是slf4j的优势,解决了不同日志的解耦。这也是为什么阿里巴巴java操作规范中禁止直接调用日志框架的api。