Java日志框架--Slf4j的使用

一、日志门面的意义

当我们的系统变的更加复杂的时候,我们的日志就容易发生混乱。随着系统开发的运行,可能会更新不同的日志框架,造成当前系统中存在不同的日志依赖,让我们难以统一的管理和控制,就算我们强制要求所有的模块使用相同的日志框架,系统中也难以避免使用其他类似spring,mybatis等其他的第三方框架,它们依赖于我们规定不同的日志框架,而且他们自身的日志系统就有着不一致性,依然会出来日志体系的混乱。。。

常见的日志门面:JCL、slf4j

常见的日志实现:JUL、log4j、logback、log4j2

二、Slf4j的使用(http://www.slf4j.org/

简单日志门面(Simple Logging Facade For Java):Slf4j主要是为了给Java日志访问提供一套标准,规范的API框架,其主要意义在于提供接口,具体的实现可以交由其他日志框架,例如log4j和logback等。当然slf4j自己也提供了功能较为简单的实现,但是一般很少用到。对于一般的java项目而言,日志框架会选择slf4j-api作为门面,配上具体的实现框架(log4j、logback等),中间使用桥接器完成桥接。

slf4j是目前世面上最流行的日志门面。现在的项目中,基本上都是使用slf4j作为我们的日志系统。

Slf4j日志门面主要提供两大功能:

     1.日志框架的绑定;

slf4j支持各种日志框架。slf4j发行版附带了几个称为“slf4j绑定”的jar文件,每个绑定对应一个受支持的框架。

使用slf4j的日志绑定流程:

(1)添加slf4j-api的依赖

(2)使用slf4j的API在项目中进行统一的日志记录

(3)绑定具体的日志实现框架

   绑定已经实现了slf4j的日志框架,直接添加对应依赖

   绑定没有实现slf4j的日志框架,先添加日志的适配器,在添加实现类的依赖

(4)  slf4j有且仅有一个日志实现框架的绑定(如果出现多个默认使用第一个依赖日志实现)

要切换日志记录框架,只需在类路径上替换slf4j绑定即可。例如,要从java.util.logging切换到log4j,只需将slf4j-jdk14-1.7.28.jar替换为slf4j-log4j12-1.7.28.jar。

SLF4J不依赖任何特殊类的装载机。实际上,每个SLF4J绑定在编译时都 进行了硬连线以使用一个且仅一个特定的日志记录框架。例如,slf4j-log4j12-1.7.28.jar绑定在编译时绑定为使用log4j。在代码中,除了slf4j-api-1.7.28.jar之外,您只需将选择的一个和仅一个绑定拖放 到适当的类路径位置即可。在类路径上不要放置多个绑定。这是一般想法的图形化说明。

2.日志框架的桥接;

通常,您依赖的某些组件依赖于slf4j以外的日志记录API。您也可以假设这些组件在不久的将来不会切换到slf4j。为了解决这种情况,slf4j附带了几个桥接模块,这些模块将对log4j,JCL和java.util.logging API的调用重定向,就好像它们是对slf4j API一样。

桥接解决的是项目中日志的遗留问题,当系统中存在之前的日志API,可以通过桥接转换到slf4j的实现

1.先去除之前老的日志框架的依赖

2.添加slf4j提供的桥接组件

3.为项目添加slf4j的具体实现 

注意问题:

1.jcl-over-slf4j.jarslf4j-jcl.jar不能同时部署。前一个jar文件将导致jcl将日志系统的选择委托给slf4j,后一个jar文件将导致slf4j将日志系统的选择委托给jcl,从而导致无限循环。

2.log4j-over-slf4j.jarslf4j-log4j12.jar不能同时出现

3.jul-to-slf4j.jarslf4j-jdk14.jar不能同时出现

4.所有的桥接都只对Logger日志记录器对象有效,如果程序中调用了内部的配置类或者是Appender,Filter等对象,将无法产生效果。

三、Slf4j入门

日志框架的绑定:

1.添加依赖:

slf4j绑定内置的日志实现框架

 <!--        slf4j日志门面-->
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>1.7.26</version>
    </dependency>
<!--        slf4j内置的简单实现-->
    <dependency>
         <groupId>org.slf4j</groupId>
         <artifactId>slf4j-simple</artifactId>
         <version>1.7.21</version>
    </dependency>

slf4j绑定logback日志实现框架

<!--        slf4j日志门面-->
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>1.7.26</version>
    </dependency>

<!--        logback日志实现-->
    <dependency>
          <groupId>ch.qos.logback</groupId>
          <artifactId>logback-classic</artifactId>
          <version>1.2.3</version>
    </dependency>

 nop日志开关:

<!--        slf4j日志门面-->
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>1.7.26</version>
    </dependency>

<!--        nop日志开关-->
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-nop</artifactId>
        <version>1.7.25</version>
    </dependency>

slf4j绑定log4j日志实现框架 


<!--        slf4j日志门面-->
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>1.7.26</version>
    </dependency>

<!--    绑定 log4j日志实现,需要导入适配器-->
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-log4j12</artifactId>
        <version>1.7.29</version>
    </dependency>

    <dependency>
        <groupId>log4j</groupId>
        <artifactId>log4j</artifactId>
        <version>1.2.17</version>
    </dependency>

绑定 log4j日志实现,不仅需要导入适配器,还需要导入配置文件log4j.properties:

#配置根  Loggers控制日志的输出级别与日志是否输出
log4j.rootLogger=trace,console

#自定义logger对象设置
log4j.logger.LoggerDemo = info,file

#配置输出到控制台  Appenders是指定日志的输出方式
log4j.appender.console=org.apache.log4j.ConsoleAppender
#指定输出控制台
log4j.appender.console.Target = System.out
#指定布局,输出日志的格式
log4j.appender.console.layout=org.apache.log4j.PatternLayout
#指定布局的参数
log4j.appender.console.layout.ConversionPattern=[%-10p] %r %l %d{yyyy-MM-dd HH:mm:ss.SSS} %m%n


#配置输出到控制台  Appenders是指定日志的输出方式
log4j.appender.file=org.apache.log4j.FileAppender
#指定布局,输出日志的格式
log4j.appender.file.layout=org.apache.log4j.PatternLayout
#指定布局的参数
log4j.appender.file.layout.ConversionPattern=[%-10p] %r %l %d{yyyy-MM-dd HH:mm:ss.SSS} %m%n
#指定日志文件保存路径
log4j.appender.file.file = /logs/log4j.log
#指定日志文件字符集
log4j.appender.file.encoding = UTF-8

#配置输出到控制台  Appenders是指定日志的输出方式
log4j.appender.rollingFile=org.apache.log4j.RollingFileAppender
#指定布局,输出日志的格式
log4j.appender.rollingFile.layout=org.apache.log4j.PatternLayout
#指定布局的参数
log4j.appender.rollingFile.layout.ConversionPattern=[%-10p] %r %l %d{yyyy-MM-dd HH:mm:ss.SSS} %m%n
#指定日志文件保存路径
log4j.appender.rollingFile.file = /logs/log4j.log
#指定日志文件字符集
log4j.appender.rollingFile.encoding = UTF-8
#指定日志文件内容的大小
log4j.appender.rollingFile.maxFileSize = 1MB
#指定日志文件的数量
log4j.appender.rollingFile.maxBackupIndex = 10

#配置输出到控制台  Appenders是指定日志的输出方式
log4j.appender.dailyRollingFile=org.apache.log4j.DailyRollingFileAppender
#指定布局,输出日志的格式
log4j.appender.dailyRollingFile.layout=org.apache.log4j.PatternLayout
#指定布局的参数
log4j.appender.dailyRollingFile.layout.ConversionPattern=[%-10p] %r %l %d{yyyy-MM-dd HH:mm:ss.SSS} %m%n
#指定日志文件保存路径
log4j.appender.dailyRollingFile.file = /logs/log4j.log
#指定日志文件字符集
log4j.appender.dailyRollingFile.encoding = UTF-8
#指定日志输出规则
log4j.appender.dailyRollingFile.datePattern = '.'yyyy-MM-dd-HH-mm-ss


#mysql
log4j.appender.logDB=org.apache.log4j.jdbc.JDBCAppender
#指定布局,输出日志的格式
log4j.appender.logDB.layout=org.apache.log4j.PatternLayout

log4j.appender.logDB.Driver = com.mysql.jdbc.Driver
log4j.appender.logDB.URL = jdbc:mysql://localhost:3306/logs
log4j.appender.logDB.User = root
log4j.appender.logDB.Password = root
log4j.appender.logDB.Sql = INSERT INTO log(project_name,create_date,level,category,file_name,thread_name,line,all_category,message) values('itcast','%d{yyyy-MM-dd HH:mm:ss}','%p','%c','%F','%t','%L','%l','%m')

slf4j绑定jul日志实现框架 


  <!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-api -->
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>1.5.6</version>
    </dependency>

<!--    绑定jul日志实现,需要导入适配器-->
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-jdk14</artifactId>
        <version>1.5.6</version>
    </dependency>

2.测试Demo

import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class SLF4j {

    public static final Logger LOGGER = LoggerFactory.getLogger(SLF4j.class);

//        快速入门
    @Test
    public void test01() throws Exception{
//        日志输出
        LOGGER.error("error");
        LOGGER.warn("waring");
        LOGGER.info("info");
        LOGGER.debug("debug");
        LOGGER.trace("trace");

//        使用占位符输出日志消息
        String name = "itheima";
        Integer age = 14;
        LOGGER.info("用户:{},{}",name,age);

//        异常日志输出
        try {
            int i = 1/0;
        } catch (Exception e) {
            LOGGER.error("出现异常:",e);
        }
    }
}

3.测试结果:

slf4j绑定内置的日志实现框架的测试结果:

[main] ERROR SLF4j - error
[main] WARN SLF4j - waring
[main] INFO SLF4j - info
[main] INFO SLF4j - 用户:itheima,14
[main] ERROR SLF4j - 出现异常:
java.lang.ArithmeticException: / by zero
	at SLF4j.test01(SLF4j.java:26)
...

slf4j绑定logback日志实现框架的测试结果:

20:25:21.724 [main] ERROR SLF4j - error
20:25:21.739 [main] WARN SLF4j - waring
20:25:21.739 [main] INFO SLF4j - info
20:25:21.739 [main] DEBUG SLF4j - debug
20:25:21.739 [main] INFO SLF4j - 用户:itheima,14
20:25:21.742 [main] ERROR SLF4j - 出现异常:
java.lang.ArithmeticException: / by zero
	

 nop日志开关,打开日志开关的测试结果:

 日志开关打开了,关闭了日志打印的功能

F:\DevelopmentTools\Java\jdk1.8.0_152\bin\java.exe -ea -...

Process finished with exit code 0

slf4j绑定log4j日志实现框架的测试结果:

[ERROR     ] 0 SLF4j.test01(SLF4j.java:14) 2020-02-20 00:10:50.942 error
[WARN      ] 3 SLF4j.test01(SLF4j.java:15) 2020-02-20 00:10:50.945 waring
[INFO      ] 3 SLF4j.test01(SLF4j.java:16) 2020-02-20 00:10:50.945 info
[DEBUG     ] 3 SLF4j.test01(SLF4j.java:17) 2020-02-20 00:10:50.945 debug
[TRACE     ] 4 SLF4j.test01(SLF4j.java:18) 2020-02-20 00:10:50.946 trace
[INFO      ] 5 SLF4j.test01(SLF4j.java:23) 2020-02-20 00:10:50.947 用户:itheima,14
[ERROR     ] 5 SLF4j.test01(SLF4j.java:28) 2020-02-20 00:10:50.947 出现异常:
java.lang.ArithmeticException: / by zero

slf4j绑定jul日志实现框架的测试结果:

二月 20, 2020 12:31:55 下午 SLF4j test01
严重: error
二月 20, 2020 12:31:55 下午 SLF4j test01
警告: waring
二月 20, 2020 12:31:55 下午 SLF4j test01
信息: info
二月 20, 2020 12:31:55 下午 SLF4j test01
信息: 用户:itheima,14
二月 20, 2020 12:31:55 下午 SLF4j test01
严重: 出现异常:
java.lang.ArithmeticException: / by zero

日志框架的桥接:

1.添加依赖:

log4j的桥接器,替代log4.jar包以及适配器,让logback日志实现log4j日志

<!--        slf4j日志门面-->
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>1.7.26</version>
    </dependency>
<!--        logback日志实现-->
    <dependency>
        <groupId>ch.qos.logback</groupId>
        <artifactId>logback-classic</artifactId>
        <version>1.2.3</version>
    </dependency>
<!--    配置log4j的桥接器-->
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>log4j-over-slf4j</artifactId>
        <version>1.7.26</version>
    </dependency>

2.测试demo 

import org.apache.log4j.Logger;
import org.junit.Test;

public class Log4jTest {
//    定义 log4j 日志记录器
    public static final Logger LOGGER = Logger.getLogger(Log4jTest.class);

//    测试桥接器
    @Test
    public void test01() throws Exception{
        LOGGER.info("hello log4j");
    }

}

3.测试结果:

13:20:55.469 [main] INFO Log4jTest - hello log4j
发布了17 篇原创文章 · 获赞 11 · 访问量 7998

猜你喜欢

转载自blog.csdn.net/LOVE_Me__/article/details/104395184