一、认识slf4j
1.1、slf4j概述
用户手册:http://www.slf4j.org/manual.html
slf4j(Simple Logging Facade For Java):为所有的日志框架提供了一套标准、规范的API框架,主要是提供了接口,具体的实现交由对应的日志框架,例如Log4j、Logback、Log4j2等。其自己本身也提供了简单的日志实现(slf4j-simple)。
现如今对于一般的Java项目而言,日志框架会选择slf4j-api作为门面,配置上具体的实现框架,中间使用桥接器来完成桥接。
介绍其中两个类:日志实例Logger以及LogFactory.getLogger()(工厂)获取日志实例。
1.2、第三方jar包、
想要使用slf4j日志门面,需要使用第三方jar包,下面为pom.xml的对应坐标:
<dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.7.30</version> </dependency>
若是想要之后切换日志框架,最好先引入指定版本的slf4j-api(尽管之后引入的对应的slf4j日志实现框架中有对应api依赖),来进行统一的API管理。
1.3、切换日志框架详略图
我们去到slf4j官网的用户手册网页即可查看到下图:
application下面的SLF4J API表示slf4j的日志门面,包含三种情况:
①若是只导入slf4j日志门面没有导入对应的日志实现框架,那么日志功能将会是默认关闭的,不会进行日志输出的。
②蓝色图里Logback、slf4j-simple、slf4j-nop出来的比较晚就遵循了slf4j的API规范,也就是说只要导入对应的实现就默认实现了对应的接口,来实现开发。
③对于中间两个日志实现框架log4j(slf4j-log4j12)、JUL(slf4j-jdk14)由于出现的比slf4j早,所以就没有遵循slf4j的接口规范,所以无法进行直接绑定,中间需要加一个适配层(Adaptation layer),通过对应的适配器来适配具体的日志实现框架,其对应的适配器其实就间接的实现了slf4j-api的接口规范。
注意:在图中对于logback需要引入两个jar包,不过在maven中有一个传递的思想,当配置logback-classic时就会默认传递core信息,所以我们只需要引入logback-classic的jar包即可。
1.4、相关注意点
在使用slf4j日志门面的过程中,若是引入了两个日志实现框架会报以下错误,并会默认实现第一个引入的日志实现:
这里是同时配置simple以及logback情况
注意:以pom.xml中配置顺序有关!!!
二、实际应用
2.1、配合自身简单日志实现(slf4j-simple)
若想使用自身的日志实现框架,需要引入第三方jar包slf4j-simple(slf4j自带实现类):
<dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-simple</artifactId> <version>1.7.5</version> </dependency>
其中该坐标包含了对应的slf4j-api的依赖,可以不用手动导入slf4j-api。
测试程序:
import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class LogTest { //获取Logger实例 public static final Logger LOGGER = LoggerFactory.getLogger(LogTest.class); public static void main(String[] args) { System.out.println(LOGGER.getName());//xyz.changlu.LogTest //1、打印日志记录 LOGGER.error("error"); LOGGER.warn("warn"); LOGGER.info("info"); LOGGER.debug("debug"); LOGGER.trace("trace"); //2、占位符输出 String name = "changlu"; int age = 20; LOGGER.info("报错,name:{},age:{}",name,age); //3、打印堆栈信息 try { int i = 5/0; }catch (Exception e){ LOGGER.error("报错",e); } } }
默认日志等级为INFO,能够实现占位符输出,并且可以在日志等级方法中传入异常实例,来打印对应的日志信息。
注意点:若是我们只使用日志门面而没有导入指定的日志实现框架,调用Logger实例并调用日志方法会出现以下错误:
2.2、配置logback日志实现
引入logback-classic的jar包,其中包含有slf4j-api以及logback-core的依赖,所以只需要引入该依赖即可:
<dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>1.2.3</version> </dependency>
测试程序:
import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class LogTest { //获取Logger实例 public static final Logger LOGGER = LoggerFactory.getLogger(LogTest.class); public static void main(String[] args) { System.out.println(LOGGER.getName());//xyz.changlu.LogTest //1、打印日志记录 LOGGER.error("error"); LOGGER.warn("warn"); LOGGER.info("info"); LOGGER.debug("debug"); LOGGER.trace("trace"); //2、占位符输出 String name = "changlu"; int age = 20; LOGGER.info("报错,name:{},age:{}",name,age); //3、打印堆栈信息 try { int i = 5/0; }catch (Exception e){ LOGGER.error("报错",e); } } }
2.3、配置Log4j日志实现(需适配器)
①首先添加日志框架实现依赖
之前在1.3中介绍,对于Log4j、JUL这些比较早出现的日志实现框架需要有对应的适配层,在这里我们引入对应的适配器slf4j-log412的依赖坐标:
<dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>1.7.25</version> </dependency>
slf4j-log4j12坐标中实际就包含了Log4j以及slf4j-api依赖,所以我们添加该坐标即可。
②添加log4j.properties配置文件
# rootLogger日志等级为trace,输出到屏幕上 log4j.rootLogger = trace,console # console log4j.appender.console = org.apache.log4j.ConsoleAppender log4j.appender.console.layout = org.apache.log4j.PatternLayout log4j.appender.console.layout.ConversionPattern= [%-5p]%r %l %d{yyyy-MM-dd HH:mm:ss:SSS} %m%n
测试程序:
import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class LogTest { //获取Logger实例 public static final Logger LOGGER = LoggerFactory.getLogger(LogTest.class); public static void main(String[] args) { System.out.println(LOGGER.getName());//xyz.changlu.LogTest //1、打印日志记录 LOGGER.error("error"); LOGGER.warn("warn"); LOGGER.info("info"); LOGGER.debug("debug"); LOGGER.trace("trace"); //2、占位符输出 String name = "changlu"; int age = 20; LOGGER.info("报错,name:{},age:{}",name,age); //3、打印堆栈信息 try { int i = 5/0; }catch (Exception e){ LOGGER.error("报错",e); } } }
2.4、配置JUL日志实现(需适配器)
对于slf4j日志门面实现JUL日志框架需要使用是适配器来实现slf4j的日志接口,我们直接添加对应适配器依赖如下:
<dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-jdk14</artifactId> <version>1.5.6</version> </dependency>
JUL是我们jdk自带的日志框架,所以不需要额外引入jar包,引入slf4j-jdk14坐标,其中就包含了slf4j-api的依赖,所以我们只需要引入一个坐标即可。
测试程序:
import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class LogTest { //获取Logger实例 public static final Logger LOGGER = LoggerFactory.getLogger(LogTest.class); public static void main(String[] args) { System.out.println(LOGGER.getName());//xyz.changlu.LogTest //1、打印日志记录 LOGGER.error("error"); LOGGER.warn("warn"); LOGGER.info("info"); LOGGER.debug("debug"); LOGGER.trace("trace"); //2、占位符输出 String name = "changlu"; int age = 20; LOGGER.info("报错,name:{},age:{}",name,age); //3、打印堆栈信息 try { int i = 5/0; }catch (Exception e){ LOGGER.error("报错",e); } } }
2.4、添加slf4j-nop依赖(日志开关)
当添加了slf4j-nop坐标后,其相当于一个日志开关,导入实现以后就不会使用任何实现框架:
<dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-nop</artifactId> <version>1.7.27</version> </dependency>
测试程序:
public class LogTest { //获取Logger实例 public static final Logger LOGGER = LoggerFactory.getLogger(LogTest.class); public static void main(String[] args) { LOGGER.error("error"); LOGGER.warn("warn"); LOGGER.info("info"); LOGGER.debug("debug"); LOGGER.trace("trace"); } }
默认就关闭了slf4j的日志框架使用。