springboot3默认日志

1,814 阅读2分钟

日志处理

日志框架 logback+slf4j

logback:

  1. 官网:logback.qos.ch/documentati…

  2. logback分为三个模块:logback-core,logback-classic和logback-access

  3. logback-core:为其他两个模块奠定基础

  4. logback-classic:它是log4j的一个改良版本,同时它完整实现了slf4j API。这里面包含了core模块。

  5. logback-access:访问模块与Servlet容器集成提供通过Http来访问日志的功能。

  6. 相关组件

    在logback中包含三个组件Logger、Appender以及Layout:

    • Logger:日志记录器,把它关联到应用的对应的context上后,主要用于存放日志对象,也可以定义日志类型、级别。
    • Appender:用于指定日志输出的目的地,目的地可以是控制台、文件、数据库等等。
    • Layout:负责把事件转换成字符串,格式化的日志信息的输出,在Logback中Layout对象被封装在encoder中。
  7. 使用logback.xml文件进行自定义配置,日志框架会默认读取以下类型的配置文件:

    1. logback.groovy
    2. logback-test.xml
    3. logback.xml

配置文件详细信息:

  1. 结构

    <?xml version="1.0" encoding="UTF-8" ?>
    <configuration>
        <property name="键" value="值"/>
        <appender name="输出地方" class="输出实体类">
            <target>控制输出流对象,默认System.out</target>
            <encoder>
                <pattern>格式化</pattern>
                <charset>日志字符编码 </charset>
            </encoder>
    
            <file>文件路径</file>
    
            <filter class="过滤实体类">
                <level>过滤的级别</level>
                <onMatch>匹配时的操作</onMatch>
                <onMismatch>不匹配时的操作</onMismatch>
            </filter>
            
            <rollingPolicy class="日志滚动方式实体类">
                <fileNamePattern>文件名称格式</fileNamePattern>
                <maxHistory>日志文件保留的个数</maxHistory>
                <maxFileSize>单个日志的最大大小</maxFileSize>
                <totalSizeCap>全部日志的总大小</totalSizeCap>
            </rollingPolicy>
        </appender>
        
        <logger name="目标包路径" level="日志输出水平,优先级高于root">
            <appender-ref ref="引用appender,通过name属性"/>
        </logger>
    
        <root level="根日志输出水平">
            <appender-ref ref="引用appender,通过name属性"/>
        </root>
    </configuration>
    
    • 日志输出格式

      %level:日志等级

      %d{yyyy-MM-dd HH:mm:ss.SSS}:日期

      %c:类的完整名称

      %M:method

      %L:行号

      %thread:线程名称

      %m或者%msg:信息

      %n:换行

      • property用于设置可以复用的变量,引用方式:${键}

      • Appender

        • ConsoleAppender:输出到屏幕。
        • FileAppender:输出到指定文件。
          1. RollingFileAppender:可定时创建文件以及按文件大小进行切割。
        • 自定义appender附加器

          1. 继承UnsynchronizedAppenderBase类,重写abstract protected void append(E eventObject)方法,这个类没有线程同步
          2. 继承AppenderBase<E>类,也是重写append方法。这个类有线程同步
      • Filter用来进行过滤指定日志等级的日志记录。可设置在任意的appender

        • EvaluatorFilter:临界过滤器,滤掉低于指定临界值的日志。
        • LevelFilter:级别过滤器,对特定某个级别的日志进行过滤。
        • 还有其他的
        • 自定义Filter

          继承Filter<E>类,重写public abstract FilterReply decide(E event)方法, 方法解释:如果决策为 FilterReply.DENY,则事件将被丢弃。如果决策为 FilterReply.NEUTRAL,则将调用下一个过滤器(如果有)。如果决定是, FilterReply.ACCEPT 则将记录事件,而无需咨询链中的其他过滤器。 形参: event – 要决定的事件。

      • 在日志管理框架中,"滚动"(Rolling)是指按照某种策略自动地将当前的日志文件关闭,并创建一个新的日志文件继续记录日志的过程。这样做可以防止单个日志文件无限制地增长,便于管理和维护。以下是两种常见的滚动策略:

        1. TimeBasedRollingPolicy:这种策略是基于时间来触发的。你可以设定一个时间单位(比如每天、每小时或每分钟),当达到这个时间点时,日志文件就会滚动。例如,如果设置为每天滚动,那么每天结束时,当前的日志文件就会被关闭,并且一个新的日志文件会在第二天开始时创建。这种策略通常用于长期存储日志,使得日志文件可以按照日期进行归档。
          • fileNamePattern中不能使用**%i**
          • maxHistory表示保留日志文件个数【x个月,x个分钟,x个秒】,与fileNamePattern的日期格式有关,最后一个格式符号和个数对应,即:【mm=>x个月,MM=>x个分钟,ss=>x个秒】
        2. SizeBasedTriggeringPolicy:这种策略是基于日志文件的大小来触发的。你可以设定一个文件大小阈值(比如 10MB 或 100MB),当日志文件达到这个大小时,就会触发滚动。当日志文件达到指定的大小时,当前的日志文件会被关闭,并创建一个新的日志文件继续记录。这种策略适用于限制日志文件大小的场景,防止日志文件占用过多磁盘空间。
          • maxFileSize大小文件限制
  2. 异步日志,Logback中,可以使用异步日志来提高日志的性能和吞吐量。异步日志将日志的写入操作放在一个独立的线程中进行,不会阻塞主线程的执行。

    <appender name="附加器名称" class="ch.qos.logback.classic.AsyncAppender">
        <!-- 使用 AsyncAppender 包装了这个xxxAppender,将其转换为异步的 -->
        <appender-ref ref="其他附加器引用名称" />
        <!-- 指定了异步队列的大小 -->
        <queueSize>512</queueSize>
        <!-- 指定了当队列满时是否丢弃日志 
           0,表示不丢弃任何日志事件。新的日志事件将被阻塞,直到队列中有空闲位置
           大于0,表示当队列已满时,丢弃最早的<discardingThreshold>个日志事件,然后将新的日志事件添加到队列中 
           如果对日志的实时性要求较高,可以将 <discardingThreshold> 的值设置为一个较小的数值,以避免队列过大导致的性能问题-->
        <discardingThreshold>0</discardingThreshold>
    </appender>
    

slf4j:即简单日志门面(Simple Logging Facade for Java),不是具体的日志解决方案,它只服务于各种各样的日志系统。允许最终用户在部署其应用时使用其所希望的日志系统。就是适配器模式里的适配器。

日志级别排序为:TRACE< DEBUG<INFO< WARN< ERROR。默认日志等级为Debug,其中OFFALL作为日志开关。

简单的演示

  1. 依赖pom.xml

    <dependency>
        <groupId>ch.qos.logback</groupId>
        <artifactId>logback-core</artifactId>
        <version>1.5.11</version>
    </dependency>
    <!--       logback-classic包含了logback-core,logback-core可以不用引入,但是不建议 -->
    <dependency>
        <groupId>ch.qos.logback</groupId>
        <artifactId>logback-classic</artifactId>
        <version>1.5.11</version>
    </dependency>
    <!--日志门面-->
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>2.1.0-alpha1</version>
    </dependency>
    
  2. logback.xml配置

    <?xml version="1.0" encoding="UTF-8" ?>
    <configuration>
        <appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
            <encoder>
                <!--    格式化日志        -->
                <pattern>%d{yyyy-MM-dd HH:mm:ss} %thread %level %logger %msg \n</pattern>
                <!--    日志字符编码        -->
                <charset>UTF-8</charset>
            </encoder>
        </appender>
        <root level="INFO">
            <appender-ref ref="stdout"/>
        </root>
    </configuration>
    
  3. 代码

    package log;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    public class WaterLog {
        Logger logger = LoggerFactory.getLogger(WaterLog.class);
    
        public void discovery1(){
            logger.debug("debug");
            logger.info("info");
            logger.error("error");
        }
    }
    
    
    @Test
    void discoveryTest(){
        WaterLog waterLog = new WaterLog();
        waterLog.discovery1();
    }
    

    运行结果 image.png

    运行截图里少了一个输出,1处的debug,因为2设置了INfO,debug<info,所以不输出。

springboot3 默认日志框架

springboot采用logback+slf4j日志框架

  1. pom.xml依赖

    <!-- 这个里有日志框架 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    
  2. application.yaml配置

    logging:
      # 设置配置文件的位置路径
      config: classpath:logconfig/logback.xml
    
  3. logback.xml配置

    <?xml version="1.0" encoding="UTF-8" ?>
    <configuration>
        <!--用于设置可复用的变量-->
        <property name="file.path" value="D:\\biancheng\\JAVA_IDEA\\springboot-explore\\src\\main\\resources"/>
    </configuration>
    
  4. 代码

    package wnan.explore.log;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.stereotype.Component;
    @Component
    public class DemoLog {
       public void fun1() {
            Logger log = LoggerFactory.getLogger(DemoLog.class);
            log.debug("这是一个 DemoLog debug日志");
            log.info("这是一个 DemoLog info日志");
            log.warn("这是一个 DemoLog warning日志");
            log.error("这是一个 DemoLog error日志");
        }
    }
    
    @Autowired
    DemoLog log1;
    @Test
    void t2(){
        log1.fun1();
    }
    
    @Test
    void t3(){
        while(true){
            log1.fun1();
        }
    }
    
    • 控制台输出
    <!-- 设置日志输出位置 -->
    <!--    输出到控制台-->
    <appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
        <!--        输出对象-->
        <!--        <target>System.err</target>-->
        <!--   日志信息格式     -->
        <encoder>
            <!--    格式化日志        -->
            <pattern>%d{yyyy-MM-dd HH:mm:ss} %thread %level %logger %msg \n</pattern>
            <!--    日志字符编码        -->
            <charset>UTF-8</charset>
        </encoder>
    </appender>
    <!--    用于指定包下,日志的输出等级-->
    <logger name="wnan.explore.log" level="info">
        <appender-ref ref="stdout"/>      
    </logger>
    <!--日志输出等级-->
    <root level="debug">
        <!--   日志具体附加器    -->
        <appender-ref ref="stdout"/>
    </root>
    

    运行结果:

    重复输出了,因为logger和root都引用了stdout

    image.png 删除掉root里的appender的引用,还可以在logger里设置additivity="false",这样日志就不会传播给父logger。

    image.png

    • 输出到文件
    <!--    输出到文件-->
    <appender name="file" class="ch.qos.logback.core.FileAppender">
        <file>${file.path}/log_info/demo.log</file>
        <encoder>
            <!--    格式化日志        -->
            <pattern>%d{yyyy-MM-dd HH:mm:ss} %thread %level %logger %msg \n</pattern>
            <!--    日志字符编码        -->
            <charset>UTF-8</charset>
        </encoder>
    </appender>
    <logger name="wnan.explore.log" level="info">
        <appender-ref ref="file"/>
    </logger>
    

    image.png

    • 输出到文件,高级设置日期和文件大小滚动
    <!--    文件大小和时间滚动-->
    <appender name="roll_size_time" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${file.path}/log_info/log_tys.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <fileNamePattern>${file.path}/log_info/log_%d{yyyy-MM-dd-HH-mm-ss}_%i.log</fileNamePattern>
            <maxFileSize>10MB</maxFileSize>
            <maxHistory>3</maxHistory>
            <totalSizeCap>20GB</totalSizeCap>
        </rollingPolicy>
        <encoder>
            <!--    格式化日志        -->
            <pattern>%d{yyyy-MM-dd HH:mm:ss} %thread %level %logger %msg \n</pattern>
            <!--    日志字符编码        -->
            <charset>UTF-8</charset>
        </encoder>
        <!--  配置日志等级过滤器:LevelFilter  -->
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <!--  指定日志等级  -->
            <level>INFO</level>
            <!--  若是>=info(匹配)直接通过不过滤 -->
            <onMatch>ACCEPT</onMatch>
            <!--  若是<info(不匹配)过滤掉 -->
            <onMismatch>DENY</onMismatch>
        </filter>
    </appender>
    <logger name="wnan.explore.log" level="debug">
        <appender-ref ref="roll_size_time"/>
    </logger>
    

    运行结果: image.png

    日志文件的数量会保持三个。单个文件10MB

    • 文件输出到html
    <appender name="file_html" class="ch.qos.logback.core.FileAppender">
        <file>${file.path}/log_info/demo.html</file>
        <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
            <layout class="ch.qos.logback.classic.html.HTMLLayout">
                <!--    格式化日志        -->
                <pattern>%d{yyyy-MM-dd HH:mm:ss} %thread %level %logger %msg \n</pattern>
                <!--    日志字符编码        -->
                <charset>UTF-8</charset>
            </layout>
        </encoder>
    </appender>
    <!--    用于指定包下,日志的输出等级-->
    <logger name="wnan.explore.log" level="info">
        <appender-ref ref="file_html"/>      
    </logger>
    <!--日志输出等级-->
    <root level="debug">
    </root>
    

    输出 image.png

源码--->>>springboot-explore