一篇文章带你搞定 Java 日志框架 slf4j

Posted 南淮北安

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一篇文章带你搞定 Java 日志框架 slf4j相关的知识,希望对你有一定的参考价值。

一、门面模式

slf4j是门面模式的典型应用,因此在讲slf4j前,先简单学习下门面模式,

门面模式,其核心为外部与一个子系统的通信必须通过一个统一的外观对象进行,使得子系统更易于使用

用一张图来表示门面模式的结构为:

门面模式的核心为Facade即门面对象,门面对象核心为几个点:

  • 知道所有子角色的功能和责任
  • 将客户端发来的请求委派到子系统中,没有实际业务逻辑
  • 不参与子系统内业务逻辑的实现

二、为什么要使用 slf4j ?

我们自己的系统中使用了logback这个日志系统
我们的系统使用了 A.jar,A.jar 中使用的日志系统为 log4j
我们的系统又使用了 B.jar,B.jar 中使用的日志系统为 slf4j-simple

这样,我们的系统就不得不同时支持并维护 logback、log4j、slf4j-simple 三种日志框架,非常不便。

解决这个问题的方式就是引入一个适配层,由适配层决定使用哪一种日志系统,而调用端只需要做的事情就是打印日志而不需要关心如何打印日志,slf4j 或者 commons-logging 就是这种适配层,slf4j 是本文研究的对象

从上面的描述,我们必须清楚地知道一点:slf4j只是一个日志标准,并不是日志系统的具体实现

理解这句话非常重要,slf4j只做两件事情:

  • 提供日志接口
  • 提供获取具体日志对象的方法

slf4j-simplelogback都是 slf4j 的具体实现,log4j 并不直接实现 slf4j,但是有专门的一层桥接 slf4j-log4j12 来实现slf4j。

三、如何使用

slf4j 的直接/间接实现有 slf4j-simple、logback、slf4j-log4j12,我们先定义一个 pom.xml,引入相关jar包:

(1)slf4j-api.jar + slf4j-simple.jar
(2)slf4j-api.jar + slf4j-jdk.jar
(3)slf4j-api.jar + slf4j-log4j12.jar + log4j.jar
(4)slf4j-api.jar + logback

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>testSlf4j</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>14</maven.compiler.source>
        <maven.compiler.target>14</maven.compiler.target>
    </properties>

    <dependencies>
        <!--提供日志接口-->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.5.6</version>
        </dependency>
        <!-- 1>>>具体实现-->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-jdk14</artifactId>
            <version>1.5.6</version>
        </dependency>
        <!-- 2>>>具体实现-->
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.12</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.7.21</version>
        </dependency>
        <!-- 3>>>具体实现-->
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.2.3</version>
        </dependency>
        <!-- 4>>>具体实现-->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-simple</artifactId>
            <version>1.7.2</version>
        </dependency>
    </dependencies>
</project>

简单测试:

public class TestLogger {
    public static void main(String[] args) {
        Logger logger = LoggerFactory.getLogger(TestLogger.class);
        logger.error("123");
    }
}

接着我们首先把上面 pom.xml 的具体的四种实现注释掉,即不引入任何slf4j的实现类,运行TestLogger 方法,我们看一下控制台的输出为:


看到没有任何日志的输出,这验证了我们的观点:slf4j不提供日志的具体实现,只有slf4j是无法打印日志的

接着打开 slf4j-simple 的注释,运行 TestLogger 方法,我们看一下控制台的输出为:

看到我们只要引入了一个slf4j的具体实现类,即可使用该日志框架输出日志。

最后做一个测验,我们把所有日志打开,运行 TestLogger 方法,控制台输出为:

和上面的差别是,可以输出日志,但是会输出一些告警日志,提示我们同时引入了多个slf4j的实现,然后选择其中的一个作为我们使用的日志系统。

slf4j 的作用:只要所有代码都使用门面对象 slf4j,我们就不需要关心其具体实现,最终所有地方使用一种具体实现即可,更换、维护都非常方便

同时,SLF4J的日志接口传入的是一个带占位符的字符串,用后面的变量自动替换占位符

public class TestLogger {
    public static void main(String[] args) {
        Logger logger = LoggerFactory.getLogger(TestLogger.class);

        Person person = new Person();
        person.setName("test");
        person.setAge(18);

        logger.info("Set age {} for Person {} ok", person.getAge(), person.getName());
        logger.error("123");
    }
}

以上是关于一篇文章带你搞定 Java 日志框架 slf4j的主要内容,如果未能解决你的问题,请参考以下文章

Java日志框架 -- SLF4J日志门面(入门案例SLF4J优点SLF4J日志绑定SL4J桥接旧的日志框架)

Java日志框架 -- SLF4J日志门面(入门案例SLF4J优点SLF4J日志绑定SL4J桥接旧的日志框架)

Java日志框架 -- SLF4J日志门面(入门案例SLF4J优点SLF4J日志绑定SL4J桥接旧的日志框架)

Java Slf4j日志配置输出到文件中

日志门面框架Slf4j

SpringBoot整合Slf4j+logback日志框架