zoukankan      html  css  js  c++  java
  • SpringBoot整合log4j2

    1.去除默认的依赖并导入log4j2、lombok依赖

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
        <exclusions>
            <!-- 引入log4j日志时需去掉默认的logback -->
            <exclusion>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-logging</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    
    <!-- 日志管理log4j2 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-log4j2</artifactId>
        <version>2.1.0.RELEASE</version>
    </dependency>
    
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>

    上面log4j2是直接导入了SpringBoot对应的版本,也可以导入spring的版本,两种二选一:

    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-api</artifactId>
        <version>2.11.2</version>
    </dependency>
    
    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-core</artifactId>
        <version>2.11.2</version>
    </dependency>
    
    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-slf4j-impl</artifactId>
        <version>2.11.2</version>
    </dependency>
    
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>1.7.30</version>
    </dependency>

    2.在资源目录下新建log4j2.xml文件

    1)通用日志记录:所有等级的日志都记录在同一个文件中

    <?xml version="1.0" encoding="UTF-8"?>
    
    <configuration status="info">
        <Properties>
            <!-- 声明日志文件存储的目录 -->
            <Property name="LOG_HOME">E:/logs/app/</Property>
            <Property name="APP_NAME">log</Property>
            <Property name="LOG_PATTERN"
                      value="%date{yyyy-MM-dd HH:mm:ss.SSS} %-5level [%thread][%class{36}:%line] - %msg%n"></Property>
        </Properties>
        <Appenders>
            <!--输出控制台的配置-->
            <Console name="Console" target="SYSTEM_OUT">
                <!--控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch)-->
                <ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/>
                <!-- 输出日志的格式-->
                <PatternLayout pattern="${LOG_PATTERN}"/>
            </Console>
    
            <!--输出日志到文件的配置,每次大小超过size,则这size大小的日志会自动存入按年份-月份建立的文件夹下面-->
            <RollingFile name="RollingFile" fileName="${LOG_HOME}/${APP_NAME}.log"
                         filePattern="${LOG_HOME}/%d{yyyy-MM}/%d{yyyy-MM-dd}_%i.log">
                <ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/>
                <!-- 输出日志的格式-->
                <PatternLayout pattern="${LOG_PATTERN}"/>
                <Policies>
                    <TimeBasedTriggeringPolicy/>
                    <SizeBasedTriggeringPolicy size="100MB"/>
                </Policies>
                <!-- 最多保留文件数 -->
                <DefaultRolloverStrategy max="365"/>
            </RollingFile>
        </Appenders>
        <!--然后定义Logger,只有定义了Logger并引入的Appender,Appender才会生效。Root中level配置了日志级别,可配置其他级别-->
        <Loggers>
            <Root level="info">
                <AppenderRef ref="Console"/>
                <AppenderRef ref="RollingFile"/>
            </Root>
        </Loggers>
    
    </configuration>

    在配置中指定了日志存储的目录是E:logsapp,日志文件使用日期作为重要区分的条件。

    2)分级日志记录:不同等级的日志记录到对应的文件中

    <?xml version="1.0" encoding="UTF-8"?>
    
    <configuration status="info">
        <Properties>
            <!-- 声明日志文件存储的目录 -->
            <Property name="LOG_HOME">E:/logs/app/</Property>
            <Property name="LOG_PATTERN"
                      value="%date{yyyy-MM-dd HH:mm:ss.SSS} %-5level [%thread][%class{36}:%line] - %msg%n"></Property>
        </Properties>
        <Appenders>
            <!--输出控制台的配置-->
            <Console name="Console" target="SYSTEM_OUT">
                <!--控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch)-->
                <ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/>
                <!-- 输出日志的格式-->
                <PatternLayout pattern="${LOG_PATTERN}"/>
            </Console>
            <!-- ERROR级别日志 -->
            <RollingFile name="infoAppender" fileName="${LOG_HOME}/info.log"
                         filePattern="${LOG_HOME}/%d{yyyy-MM}/%d{yyyy-MM-dd}_info.log">
                <ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/>
                <PatternLayout pattern="${LOG_PATTERN}"/>
                <Policies>
                    <TimeBasedTriggeringPolicy/>
                    <SizeBasedTriggeringPolicy size="100MB"/>
                </Policies>
            </RollingFile>
            <!-- ERROR级别日志 -->
            <RollingFile name="errorAppender" fileName="${LOG_HOME}/error.log"
                         filePattern="${LOG_HOME}/%d{yyyy-MM}/%d{yyyy-MM-dd}_error.log">
                <ThresholdFilter level="error" onMatch="ACCEPT" onMismatch="DENY"/>
                <PatternLayout pattern="${LOG_PATTERN}"/>
                <Policies>
                    <TimeBasedTriggeringPolicy/>
                    <SizeBasedTriggeringPolicy size="100MB" />
                </Policies>
            </RollingFile>
        </Appenders>
        <Loggers>
            <Root level="info">
                <AppenderRef ref="Console"/>
                <AppenderRef ref="infoAppender"/>
                <AppenderRef ref="errorAppender"/>
            </Root>
        </Loggers>
    
    </configuration>

    对于是否分级记录,根据需求决定。两者选一即可。

    3.在配置文件配置log4j2文件的位置

    logging.config = classpath:log4j2.xml

    4.添加测试方法进行测试

    package com.zys.springboottestexample;
    
    import org.apache.logging.log4j.LogManager;
    import org.apache.logging.log4j.Logger;
    import org.junit.jupiter.api.Test;
    import org.springframework.boot.test.context.SpringBootTest;
    
    @SpringBootTest
    public class SpringbootTestExampleApplicationTests {
    
        //创建日志对象
        Logger logger = LogManager.getLogger(this.getClass());
    
        @Test
        void test() {
            logger.info("我是info日志");
            logger.warn("我是warn日志");
            logger.error("我是error日志");
        }
    
    }

    执行测试方法后,在控制台打印了日志,同时在对应的目录生成了日志文件,其内容和控制台是一致的。

    5.在测试类上使用@Sl4j注解输出日志

    import lombok.extern.slf4j.Slf4j;
    
    ...
    @Slf4j
    public class SpringbootTestExampleApplicationTests {
        
       ...
    
       @Test
        public void test2() {
            log.info("天气真热啊");
            log.error("天气真热啊");
        }
    
    }

    只写了关键的代码。使用sl4j时,直接使用log对象即可进行日志的输出。这里分别演示了使用log4j2和sl4j进行日志的输出和存储到日志,可根据习惯选择使用哪一种方式。使用sl4j输出时实际上会转成log4j2日志进行输出。

    6.日志占位符

    当需要动态的输出日志及参数时,可以使用占位符 "{}"进行占位。可以写多个占位符,它会根据后面的参数进行位置匹配填充。log4j2和sl4j用法一样,参考如下:

    logger.info("你的姓名是:{},年龄是:{}", "张三", 20);
    log.info("你的姓名是:{},年龄是:{}", "张三", 20);

    控制台打印的日志如下图:

    上述的实例中,有两个大括号,第一个大括号匹配后面的第一个参数“张三”,第二个大括号匹配第二个参数20。依次类推。这样可以减少字符串的拼接。

    7.使用原生的logback

    相比于log4j2,logback是有其自己的优势的,其中有一点是它对sql日志的打印配置非常简单,而log4j2配置会繁杂一些。下面看logback.xml配置

    <?xml version="1.0" encoding="UTF-8"?>
    <configuration scan="false" scanPeriod="60 seconds" debug="false">
        <!-- 定义日志的根目录 -->
        <property name="LOG_HOME" value="E:/logs/app" />
        <!-- 定义日志文件名称 -->
        <property name="appName" value="log"></property>
        <!-- 定义生成的文件夹 -->
        <timestamp key="package" datePattern="yyyy-MM"/>
        <!-- ch.qos.logback.core.ConsoleAppender 表示控制台输出 -->
        <appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
            <!--
            日志输出格式:
                %d表示日期时间,
                %thread表示线程名,
                %-5level:级别从左显示5个字符宽度
                %logger{50} 表示logger名字最长50个字符,否则按照句点分割。
                %msg:日志消息,
                %n是换行符
            -->
            <layout class="ch.qos.logback.classic.PatternLayout">
                <pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{50} - %msg%n</pattern>
            </layout>
        </appender>
    
        <!-- 滚动记录文件,先将日志记录到指定文件,当符合某个条件时,将日志记录到其他文件 -->
        <appender name="appLogAppender" class="ch.qos.logback.core.rolling.RollingFileAppender">
            <!-- 指定日志文件的名称 -->
            <file>${LOG_HOME}/${appName}.log</file>
            <!--
            当发生滚动时,决定 RollingFileAppender 的行为,涉及文件移动和重命名
            TimeBasedRollingPolicy: 最常用的滚动策略,它根据时间来制定滚动策略,既负责滚动也负责出发滚动。
            -->
            <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
                <!--
                滚动时产生的文件的存放位置及文件名称 %d{yyyy-MM-dd}:按天进行日志滚动
                %i:当文件大小超过maxFileSize时,按照i进行文件滚动
                -->
                <fileNamePattern>${LOG_HOME}/${package}/%d{yyyy-MM-dd}_%i.log</fileNamePattern>
                <!--
                可选节点,控制保留的归档文件的最大数量,超出数量就删除旧文件。假设设置每天滚动,
                且maxHistory是365,则只保存最近365天的文件,删除之前的旧文件。注意,删除旧文件是,
                那些为了归档而创建的目录也会被删除。
                -->
                <MaxHistory>365</MaxHistory>
                <!--
                当日志文件超过maxFileSize指定的大小是,根据上面提到的%i进行日志文件滚动 注意此处配置SizeBasedTriggeringPolicy是无法实现按文件大小进行滚动的,
           必须配置timeBasedFileNamingAndTriggeringPolicy
    --> <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"> <maxFileSize>100MB</maxFileSize> </timeBasedFileNamingAndTriggeringPolicy> </rollingPolicy> <!-- 日志输出格式: --> <layout class="ch.qos.logback.classic.PatternLayout"> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [ %thread ] - [ %-5level ] [ %logger{50} : %line ] - %msg%n</pattern> </layout> </appender> <!-- logger主要用于存放日志对象,也可以定义日志类型、级别 name:表示匹配的logger类型前缀,也就是包的前半部分 level:要记录的日志级别,包括 TRACE < DEBUG < INFO < WARN < ERROR additivity:作用在于children-logger是否使用 rootLogger配置的appender进行输出, false:表示只用当前logger的appender-reftrue: 表示当前logger的appender-ref和rootLogger的appender-ref都有效 --> <!-- Spring framework logger --> <logger name="org.springframework" level="debug" additivity="false"></logger> <!-- root与logger是父子关系,没有特别定义则默认为root,任何一个类只会和一个logger对应, 要么是定义的logger,要么是root,判断的关键在于找到这个logger,然后判断这个logger的appender和level。 --> <root level="info"> <appender-ref ref="stdout" /> <appender-ref ref="appLogAppender" /> </root> </configuration>

    配置后,只需要在配置文件配置日志的级别即可:

    #配置打印日志
    logging:
      level:
        com.zys.demo: debug

    配置不同的日志级别,就打印不同级别的日志。

    就是这么简单,你学废了吗?感觉有用的话,给笔者点个赞吧 !
  • 相关阅读:
    python全栈开发,Day43(引子,协程介绍,Greenlet模块,Gevent模块,Gevent之同步与异步)
    python全栈开发,Day42(Thread类的其他方法,同步锁,死锁与递归锁,信号量,事件,条件,定时器,队列,Python标准模块--concurrent.futures)
    python全栈开发,Day41(线程概念,线程的特点,进程和线程的关系,线程和python理论知识,线程的创建)
    处理大并发之五 使用libevent利器bufferevent
    [转]./configure,make,make install的作用
    [转]Centos安装zeromq和jzmq
    [zhuan] linux 下 wxWidgets 安装,编译
    [转]面向过程的分析(POA),和面向对象的分析(OOA)
    【转】libevent和基于libevent的网络编程
    [转] Linux下 config/configure/Configure、make 、make test/make check、sudo make install 的作用
  • 原文地址:https://www.cnblogs.com/zys2019/p/14798374.html
Copyright © 2011-2022 走看看