• Java日志 -slf4j、logback、log4j2、springboot中日志


    1、SLF4J的使用

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

    官方网站: https://www.slf4j.org/

    SLF4J是目前市面上最流行的日志门面。现在的项目中,基本上都是使用SLF4J作为我们的日志系统。
    SLF4J日志门面主要提供两大功能:

    1、日志框架的绑定
    2、日志框架的桥接
    
    • 1
    • 2

    1.1 slf4j入门

    1、添加依赖

    <!--slf4j core 使用slf4j必須添加-->
    <dependency>
    	<groupId>org.slf4j</groupId>
    	<artifactId>slf4j-api</artifactId>
    	<version>1.7.27</version>
    </dependency>
    
    <!--slf4j 自带的简单日志实现 -->
    <dependency>
    	<groupId>org.slf4j</groupId>
    	<artifactId>slf4j-simple</artifactId>
    	<version>1.7.27</version>
    </dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    2、编写代码

    package com.atguigu.redis_springboot.log.slf4j;
    import org.junit.Test;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    public class Slf4jDemo {
    
       public static final Logger LOGGER =  LoggerFactory.getLogger(Slf4jDemo.class);
    
        @Test
        public void test01(){
            //打印日志信息
            LOGGER.error("error");
            LOGGER.warn("warn");
            LOGGER.info("info");
            LOGGER.debug("debug");
            LOGGER.trace("trace");
    
            String name = "zhangsan";
            Integer age = 19;
    
            LOGGER.info("用户信息:{},{}",name,age);
    
            // 将系统异常信息写入日志
            try {
                int i = 1 / 0;
            } catch (Exception e) {
                // e.printStackTrace();
                LOGGER.info("出现异常:", e);
            }
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    3、测试结果
    在这里插入图片描述

    1.2 Slf4j如何绑定日志框架

    1.2.1 绑定logback日志框架

    1、导入依赖

    <!--slf4j core 使用slf4j必須添加-->
            <dependency>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-api</artifactId>
                <version>1.7.27</version>
            </dependency>
            <!--slf4j 自带的简单日志实现 -->
            <dependency>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-simple</artifactId>
                <version>1.7.27</version>
            </dependency>
    
            <!--logback日志实现框架-->
            <dependency>
                <groupId>ch.qos.logback</groupId>
                <artifactId>logback-classic</artifactId>
                <version>1.2.3</version>
            </dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    2、代码实现和上面一样
    3、测试
    在这里插入图片描述
    从结果上看,如果同时使用slf4jSimple和logback,那么slf4j底层会默认使用slf4jSimple简单日志框架。如果想要使用logback日志框架,则只需要将slf4j 自带的简单日志实现slf4j-simple依赖注释掉。

    1.2.2 绑定log4j日志实现

    <!--绑定log4j日志实现,需要导入适配器-->
            <dependency>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-log4j12</artifactId>
                <version>1.7.12</version>
            </dependency>
    
            <dependency>
                <groupId>log4j</groupId>
                <artifactId>log4j</artifactId>
                <version>1.2.17</version>
            </dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    1.2.3 绑定日志实现小结

    使用slf4j的日志绑定流程:

    1. 添加slf4j-api的依赖
    2. 使用slf4j的API在项目中进行统一的日志记录
    3. 绑定具体的日志实现框架
      1. 绑定已经实现了slf4j的日志框架,直接添加对应依赖
      2. 绑定没有实现slf4j的日志框架,先添加日志的适配器,再添加实现类的依赖
    4. slf4j有且仅有一个日志实现框架的绑定(如果出现多个默认使用第一个依赖日志实现)

    2、Logback的使用

    Logback主要分为三个模块:

    • logback-core:其它两个模块的基础模块
    • logback-classic:它是log4j的一个改良版本,同时它完整实现了slf4j API
    • logback-access:访问模块与Servlet容器集成提供通过Http来访问日志的功能

    2.1 logback入门

    1、添加依赖

    <dependency>
    	<groupId>org.slf4j</groupId>
    	<artifactId>slf4j-api</artifactId>
    	<version>1.7.25</version>
    </dependency>
    
    <dependency>
    	<groupId>ch.qos.logback</groupId>
    	<artifactId>logback-classic</artifactId>
    	<version>1.2.3</version>
    </dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    2、java代码

    //定义日志对象
    public final static Logger LOGGER = LoggerFactory.getLogger(LogBackTest.class);
    
    @Test
    public void testSlf4j(){
    	//打印日志信息
    	LOGGER.error("error");
    	LOGGER.warn("warn");
    	LOGGER.info("info");
    	LOGGER.debug("debug");
    	LOGGER.trace("trace");
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    2.2 logback配置

    logback会依次读取以下类型配置文件:

    • logback.groovy
    • logback-test.xml
    • logback.xml 如果均不存在会采用默认配置

    1、logback组件之间的关系

    1. Logger:日志的记录器,把它关联到应用的对应的context上后,主要用于存放日志对象,也
      可以定义日志类型、级别。
    2. Appender:用于指定日志输出的目的地,目的地可以是控制台、文件、数据库等等。
    3. Layout:负责把事件转换成字符串,格式化的日志信息的输出。在logback中Layout对象被封
      装在encoder中

    2、基本配置信息
    logback.xml配置文件

    <?xml version="1.0" encoding="UTF-8"?>
    <configuration>
        <!-- 配置集中管理属性 -->
        <property name="pattern" value="%d{yyyy-MM-dd HH:mm:ss.SSS} %c [%thread] %-5level %msg%n"/>
        <!--
            日志输出格式:
            %-5level
            %d{yyyy-MM-dd HH:mm:ss.SSS}日期
            %c类的完整名称
            %M为method
            %L为行号
            %thread线程名称
            %m或者%msg为信息
            %n换行
        -->
    
        <!-- 日志文件存放目录 -->
        <property name="log_dir" value="E:/log"></property>
    
        <!-- 控制台日志输出的appender -->
        <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
            <!--输出流对象 默认 System.out 改为 System.err-->
            <target>System.err</target>
            <!--日志格式配置-->
            <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
                <pattern>${pattern}</pattern>
            </encoder>
        </appender>
    
        <!-- 日志文件输出的appender -->
        <appender name="file" class="ch.qos.logback.core.FileAppender">
            <!--日志输出路径-->
            <file>${log_dir}/logback.log</file>
            <!--日志格式配置-->
            <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
                <pattern>${pattern}</pattern>
            </encoder>
        </appender>
    
        <!-- 生成html格式appender对象 -->
        <appender name="htmlFile" class="ch.qos.logback.core.FileAppender">
            <!--日志格式配置-->
            <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
                <layout class="ch.qos.logback.classic.html.HTMLLayout">
                    <pattern>%level%d{yyyy-MM-dd HH:mm:ss}%c%M%L%thread%m</pattern>
                </layout>
            </encoder>
            <!--日志输出路径-->
            <file>${log_dir}/logback.html</file>
        </appender>
    
        <!--
            用来设置某一个包或者具体的某一个类的日志打印级别、以及指定<appender>。
            <logger>仅有一个name属性,一个可选的level和一个可选的addtivity属性
            name: 用来指定受此logger约束的某一个包或者具体的某一个类。
            level: 用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF,如果未设置此属性,那么当前logger将会继承上级的级别。
            additivity:是否向上级logger传递打印信息。默认是true。
            <logger>可以包含零个或多个<appender-ref>元素,标识这个appender将会添加到这个logger
        -->
    
        <!--
            也是<logger>元素,但是它是根logger。默认debug
            level:用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF,
            <root>可以包含零个或多个<appender-ref>元素,标识这个appender将会添加到这个 logger。
        -->
        <root level="ALL">
            <appender-ref ref="console"/>
            <appender-ref ref="file"/>
            <appender-ref ref="htmlFile"/>
        </root>
    
    </configuration>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72

    以上配置使用了控制台输出、日志文件、html文件形式输出三种方式,下面看一下效果
    控制台效果:(因为是日志级别是ALL,所以日志都会打印)在这里插入图片描述
    日志文件:
    在这里插入图片描述
    html文件:
    在这里插入图片描述

    3、日志文件拆分和归档的appender对象,添加一下配置信息到logback.xml文件中

    (1)配置文件

    <!-- 日志文件拆分和归档的appender对象-->
        <appender name="rollFile" class="ch.qos.logback.core.rolling.RollingFileAppender">
            <!--日志格式配置-->
            <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
                <pattern>${pattern}</pattern>
            </encoder>
            <!--日志输出路径-->
            <file>${log_dir}/roll_logback.log</file>
            <!--指定日志文件拆分和压缩规则-->
            <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
                <!--通过指定压缩文件名称,来确定分割文件方式-->
                <fileNamePattern>${log_dir}/rolling.%d{yyyy-MM-dd}.log%i.gz</fileNamePattern>
                <!--文件拆分大小-->
                <maxFileSize>1MB</maxFileSize>
            </rollingPolicy>
        </appender>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    (2)java代码

    @Test
        public void test01(){
            for (int i = 0; i < 10000; i++) {
                //打印日志信息
                LOGGER.error("error");
                LOGGER.warn("warn");
                LOGGER.info("info");
                LOGGER.debug("debug");
                LOGGER.trace("trace");
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    测试
    在这里插入图片描述(3)如果想设置日志文件的日志级别,可以设置过滤器来实现,还可以自定义logger

    <!-- 日志文件拆分和归档的appender对象-->
        <appender name="rollFile" class="ch.qos.logback.core.rolling.RollingFileAppender">
            <!--日志格式配置-->
            <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
                <pattern>${pattern}</pattern>
            </encoder>
            <!--日志输出路径-->
            <file>${log_dir}/roll_logback.log</file>
            <!--指定日志文件拆分和压缩规则-->
            <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
                <!--通过指定压缩文件名称,来确定分割文件方式-->
                <fileNamePattern>${log_dir}/rolling.%d{yyyy-MM-dd}.log%i.gz</fileNamePattern>
                <!--文件拆分大小-->
                <maxFileSize>1MB</maxFileSize>
            </rollingPolicy>
    
            <!--filter配置-->
            <filter class="ch.qos.logback.classic.filter.LevelFilter">
                <!--设置拦截日志级别-->
                <level>error</level>
                <onMatch>ACCEPT</onMatch>
                <onMismatch>DENY</onMismatch>
            </filter>
        </appender>
        
    	<!--自定义logger additivity表示是否从 rootLogger继承配置-->
        <logger name="com.atguigu" level="debug" additivity="false">
            <appender-ref ref="console"/>
        </logger>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    3、log4j2的使用

    Apache Log4j 2是对Log4j的升级版,参考了logback的一些优秀的设计,并且修复了一些问题,因此带 来了一些重大的提升,主要有:

    • 异常处理,在logback中,Appender中的异常不会被应用感知到,但是在log4j2中,提供了一些异
      常处理机制。
    • 性能提升, log4j2相较于log4j 和logback都具有很明显的性能提升,后面会有官方测试的数据。
    • 自动重载配置,参考了logback的设计,当然会提供自动刷新参数配置,最实用的就是我们在生产
      上可以动态的修改日志的级别而不需要重启应用。
    • 无垃圾机制,log4j2在大部分情况下,都可以使用其设计的一套无垃圾机制,避免频繁的日志收集
      导致的jvm gc。

    官网: https://logging.apache.org/log4j/2.x/

    4、SpringBoot中的日志使用

    springboot框架在企业中的使用越来越普遍,springboot日志也是开发中常用的日志系统。springboot
    默认就是使用SLF4J作为日志门面,logback作为日志实现来记录日志

    3.1 SpringBoot中的日志设计

    springboot中的日志

    <dependency>
    	<artifactId>spring-boot-starter-logging</artifactId>
    	<groupId>org.springframework.boot</groupId>
    </dependency>
    
    • 1
    • 2
    • 3
    • 4

    依赖关系图
    在这里插入图片描述
    总结:

    1. springboot 底层默认使用logback作为日志实现。
    2. 使用了SLF4J作为日志门面
    3. 将JUL也转换成slf4j
    4. 也可以使用log4j2作为日志门面,但是最终也是通过slf4j调用logback

    3.2 SpringBoot日志使用

    1、 在springboot中测试打印日志

    @SpringBootTest
        class SpringbootLogApplicationTests {
            //记录器
            public static final Logger LOGGER =
                    LoggerFactory.getLogger(SpringbootLogApplicationTests.class);
    
            @Test
            public void contextLoads() {
                // 打印日志信息
                LOGGER.error("error");
                LOGGER.warn("warn");
                LOGGER.info("info"); // 默认日志级别
                LOGGER.debug("debug");
                LOGGER.trace("trace");
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    2、修改默认日志配置

    logging.level.com.itheima=trace
    # 在控制台输出的日志的格式 同logback
    logging.pattern.console=%d{yyyy-MM-dd} [%thread] [%-5level] %logger{50} -%msg%n
    # 指定文件中日志输出的格式
    logging.file=D:/logs/springboot.log
    logging.pattern.file=%d{yyyy-MM-dd} [%thread] %-5level %logger{50} - %msg%n
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    3、指定配置
    给类路径下放上每个日志框架自己的配置文件;SpringBoot就不使用默认配置的了
    在这里插入图片描述
    4、使用SpringBoot解析日志配置
    logback-spring.xml:由SpringBoot解析日志配置

    <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
    	<springProfile name="dev">
    		<pattern>${pattern}</pattern>
    	</springProfile>
    	
    	<springProfile name="pro">
    		<pattern>%d{yyyyMMdd:HH:mm:ss.SSS} [%thread] %-5level%msg%n</pattern>
    	</springProfile>
    </encoder>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    application.properties

    spring.profiles.active=dev
    
    • 1

    5、将日志切换为log4j2

    <dependency>
    	<groupId>org.springframework.boot</groupId>
    	<artifactId>spring-boot-starter-web</artifactId>
    	<exclusions>
    		<!--排除logback-->
    		<exclusion>
    			<artifactId>spring-boot-starter-logging</artifactId>
    			<groupId>org.springframework.boot</groupId>
    		</exclusion>
    	</exclusions>
    </dependency>
    
    <!-- 添加log4j2 -->
    <dependency>
    	<groupId>org.springframework.boot</groupId>
    	<artifactId>spring-boot-starter-log4j2</artifactId>
    </dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
  • 相关阅读:
    Azure DevOps (六) 通过FTP上传流水线制品到Linux服务器
    pta——递增的整数序列链表的插入,奇数值结点链表
    《2022爱分析·银行数字化厂商全景报告》发布,菊风连续入选「视频银行」优质代表厂商
    leetcode 132. 分割回文串 II
    C++项目实战——基于多设计模式下的同步&异步日志系统-⑩-异步缓冲区类与异步工作器类设计
    FastJson 漏洞复现
    压控振荡器的设计与分析
    Autosar模块介绍:AutosarOS(3)
    Python简单数据清洗
    vue优化之如何管理系统变量
  • 原文地址:https://blog.csdn.net/java123456111/article/details/125498380