写点什么

【Spring 专题】「开发指南」夯实实战基础功底之解读 logback-spring.xml 文件的详解实现

作者:洛神灬殇
  • 2022-12-21
    江苏
  • 本文字数:5537 字

    阅读完需:约 18 分钟

【Spring专题】「开发指南」夯实实战基础功底之解读logback-spring.xml文件的详解实现

logback 的 maven 配置

<dependency>    <groupId>org.slf4j</groupId>    <artifactId>slf4j-api</artifactId>    <version>2.0.3</version></dependency><dependency>    <groupId>ch.qos.logback</groupId>    <artifactId>logback-core</artifactId>    <version>1.4.4</version></dependency><dependency>    <groupId>ch.qos.logback</groupId>    <artifactId>logback-access</artifactId>    <version>1.4.4</version></dependency><dependency>    <groupId>ch.qos.logback</groupId>    <artifactId>logback-classic</artifactId>    <version>1.4.4</version></dependency>
复制代码

日志框架层级

根节点: configuration

<configuration scan="true" scanPeriod="60 seconds" debug="false">
复制代码


  • scan : 当此属性设置为 true 时,配置文件如果发生改变,将会被重新加载,默认值为 true

  • scanPeriod : 设置监测配置文件是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒。当 scan 为 true 时,此属性生效。默认的时间间隔为 1 分钟

  • debug : 当此属性设置为 true 时,将打印出 logback 内部日志信息,实时查看 logback 运行状态,默认值为 false。

日志输出组件

子节点:appender

appender 用来格式化日志输出节点,有两个属性 name class,class 用来指定哪种输出策略。

总体的层级结构

  • appender:定义 appender 填充器的名称和类定义

  • encoder:日志格式配置定义声明编码格式实现类

  • pattern:主要定义日志输出的字符串格式


常用就是控制台输出策略和文件输出策略,如下。

ConsoleAppender-控制台输出器

ConsoleAppender 主要的作用是将日志信息打印到控制台上,更加准确的说:使用 System.out 或者 System.err 方式输出,主要子标签有:encodertarget 这两个元素标签,具体案例样式如下所示。


<appender name="console" class="ch.qos.logback.core.ConsoleAppender">     <encoder>         <pattern>%date{"yyyy-MM-dd,HH:mm:ss,SSS"} [%X{TID}] [%thread] %-5level %logger{36} - %msg%n</pattern>         <charset>UTF-8</charset> <!-- 此处设置字符集 -->     </encoder></appender>
复制代码


最外面 xml 标签(append)里面定义了对应的 append 的名称 name,以及(class)对应的实际填充对象类,如下所示。


<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
复制代码

encoder 标签

  • <encoder>:主要用于定义对应的编码模式和编码格式组件的声明。

  • <pattern>:主要用于定义对应的该 encoder 下的编码模式字符串,例如:%date{"yyyy-MM-dd,HH:mm:ss,SSS"} [%X{TID}] [%thread] %-5level %logger{36} - %msg%n


内部的格式字符,例如:%date 等的相关的格式讲解后面的章节会统一详细的去进行介绍,大家可以根据后面的章节进行学习即可。

FileAppender-文件输出器

用于将日志信息输出到文件中,主要子标签有:appender,encoder,file,对应的层级关系为:


  • appender:日志文件输出 appender 对象

  • encoder:日志格式配置定义声明编码格式实现类

  • file:日志输出路径,代表着文件目录加文件名称

appender

同上,依然保持不变的配置模式


  <appender name="file" class="ch.qos.logback.core.FileAppender">      <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">           <pattern>${pattern}</pattern>     </encoder>      <file>${log_dir}/logback.log</file> </appender>
复制代码

encoder 标签

  • <encoder>:主要用于定义对应的编码模式和编码格式组件的声明。

  • <pattern>:主要用于定义对应的该 encoder 下的编码模式字符串,例如:%date{"yyyy-MM-dd,HH:mm:ss,SSS"} [%X{TID}] [%thread] %-5level %logger{36} - %msg%n

file 标签

  • <file>:日志输出路径,代表着文件目录加文件名称


<file>${log_dir}/logback.log</file>
复制代码

RollingFileAppender-滚动文件输出器

RollingFileAppender 是 FileAppender 的子类,继承关系。

扩展能力

如果满足一定的条件,能够动态的创建一个文件。然后将日志写入到新的文件中。

主要子标签

file(文件全路径),filter(过滤器),encoder(输出格式化),rollingPolicy(滚动策略),总体的相关案例如下所示。


<appender name="errorLogFile" class="ch.qos.logback.core.rolling.RollingFileAppender">        <file>${LOG_BASE_DIR}/log-error.log</file>        <filter class="ch.qos.logback.classic.filter.LevelFilter">            <level>Error</level>            <onMatch>ACCEPT</onMatch>            <onMismatch>DENY</onMismatch>        </filter>        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">            <fileNamePattern>${LOG_BASE_DIR}/log-error.%d{yyyy-MM-dd}.%i.log</fileNamePattern>            <maxFileSize>${LOG_FILE_MAX_SIZE}</maxFileSize>            <maxHistory>${LOG_FILE_MAX_HISTORY}</maxHistory>            <totalSizeCap>${LOG_FILE_TOTAL_SIZE_CAP}</totalSizeCap>        </rollingPolicy>        <encoder>            <pattern>%date{"HH:mm:ss,SSS"} [%X{TID}] [%thread] %-5level %logger{36} - %msg%n</pattern>            <charset>UTF-8</charset>        </encoder></appender>
复制代码


其中,我们重点需要了解的是**filter(过滤器)**和 **rollingPolicy(滚动策略)**这两个标签对应的功能。

filter(过滤器)

过滤器主要分为两个常用的种类:ThresholdFilter 和 LevelFilter 的过滤器。


系统定义的拦截器(ThresholdFilter)


过滤掉 ERROR 级别以下的日志不输出到文件中。


<filter class="ch.qos.logback.classic.filter.ThresholdFilter">    <level>ERROR</level></filter>
复制代码


策略拦截器(LevelFilter)


使用匹配规则匹配 level,按照规则进行打印,可以避免输出 Error 级别 之外的日志


<filter class="ch.qos.logback.classic.filter.LevelFilter">            <!--过滤 Error-->            <level>Error</level>            <!--匹配到就允许-->            <onMatch>ACCEPT</onMatch>            <!--没有匹配到就禁止-->            <onMismatch>DENY</onMismatch> </filter>
复制代码
rollingPolicy(滚动策略)

盘点我们常用的策略方式主要就是一下这两种:


TimeBasedRollingPolicy


它根据时间来制定滚动策略.时间滚动策略可以基于时间滚动按时间生成日志,无法控制文件大小。


SizeAndTimeBasedRollingPolicy


        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">            <fileNamePattern>${LOG_BASE_DIR}/log-error.%d{yyyy-MM-dd}.%i.log</fileNamePattern>            <maxFileSize>${LOG_FILE_MAX_SIZE}</maxFileSize>            <maxHistory>${LOG_FILE_MAX_HISTORY}</maxHistory>            <totalSizeCap>${LOG_FILE_TOTAL_SIZE_CAP}</totalSizeCap>        </rollingPolicy>
复制代码


基于大小和时间的滚动策略。这个策略出现的原因就是对时间滚动策略的一个补充,使其不仅按时间进行生成而且考虑到文件大小的原因,因为在基于时间的滚动策略生成的日志文件,只是对一段时间总的日志大小做了限定,但是没有对每个日志文件的大小做限定,这就会造成个别日志文件过大,后期传递,所以就有了这个策略。


注意:totalSizeCap 属性生效需要 logback-classic 依赖与 logback-core 依赖版本大于 1.2.0,原因:ch.qos.logback.core.rolling.helper.TimeBasedArchiveRemover 类存在计算溢出问题。

子节点:logger

案例配置如下。


 <logger name="com.xx.XXController" level="WARN" additivity="false">        <appender-ref ref="console"/> </logger>
复制代码


  • name:用来指定受此 logger 约束的某一个包或者具体的某一个类。

  • level:用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF,还有一个特殊值-INHERITED 或者同义词 NULL,代表强制执行上级的级别。如果未设置此属性,那么当前 logger 将会继承上级的级别。

  • addtivity:是否向上级 logger 传递打印信息。默认是 true。logger 最上级为 root 节点

子节点: root

<root level="debug">  <appender-ref ref="console" />  <appender-ref ref="file" /></root>
复制代码


  • root 节点是必选节点,用来指定最基础的日志输出级别,只有一个 level 属性。level 默认是 DEBUG。

  • level:用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF,不能设置为 INHERITED 或者同义词 NULL

属性节点

定义上下文变量,name 变量名称,value 为值。

logback 的容器上下文

<property name="LOG-LEVEL" value="INFO" />... ...<logger name="com.xx.XXController" level="${LOG-LEVEL}" additivity="false">        <appender-ref ref="console"/> </logger>
复制代码

应用 springboot 的环境变量

从 springboot 配置变量中获取 key 为 source 的值,name 变量名称.


<springProperty scope="context" name="LOG_FILE_MAX_SIZE" source="logging.file.max-size" defaultValue="100MB" /><rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">            <maxFileSize>${LOG_FILE_MAX_SIZE}</maxFileSize></rollingPolicy>
复制代码
划分出不同的 profile 环境下的环境变量
<springProfile name="test">    <!-- configuration to be enabled when the "test" profile is active --></springProfile><springProfile name="dev, test">    <!-- configuration to be enabled when the "dev" or "staging" profiles are active --></springProfile><springProfile name="!prod">    <!-- configuration to be enabled when the "prod" profile is not active --></springProfile>
复制代码

完整案例

<?xml version="1.0" encoding="UTF-8"?><configuration>    <springProperty scope="context" name="LOG_FILE_MAX_SIZE" source="logging.file.max-size" defaultValue="100MB" />    <springProperty scope="context" name="LOG_BASE_DIR" source="logging.file.base-path" defaultValue="/export/Logs/albert.com" />    <springProperty scope="context" name="LOG_FILE_MAX_HISTORY" source="logging.file.max-history" defaultValue="30" />    <springProperty scope="context" name="LOG_FILE_TOTAL_SIZE_CAP" source="logging.file.total-size-cap" defaultValue="20GB" />    <property name="FILE_LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] [%X{TID}] %-5level %logger{36} %F:%L - %msg %ex%n"/>    <property name="LOG-LEVEL" value="INFO" />    <!--日志输出节点-->    <appender name="errorLogFile" class="ch.qos.logback.core.rolling.RollingFileAppender">        <!--日志输出位置-->        <file>${LOG_BASE_DIR}/logfile-error.log</file>        <!--日志级别过滤器-->        <filter class="ch.qos.logback.classic.filter.LevelFilter">            <!--过滤 Error-->            <level>Error</level>            <!--匹配到就允许-->            <onMatch>ACCEPT</onMatch>            <!--没有匹配到就禁止-->            <onMismatch>DENY</onMismatch>        </filter>        <!--按照大小与时间的策略进行归档-->        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">            <fileNamePattern>${LOG_BASE_DIR}/logfile-error.%d{yyyy-MM-dd}.%i.log</fileNamePattern>            <!--归档文件最大大小-->            <maxFileSize>${LOG_FILE_MAX_SIZE}</maxFileSize>            <!--归档文件存储时长,单位天-->            <maxHistory>${LOG_FILE_MAX_HISTORY}</maxHistory>            <!--归档文件总大小约束-->            <totalSizeCap>${LOG_FILE_TOTAL_SIZE_CAP}</totalSizeCap>        </rollingPolicy>        <encoder>            <!-- 打印日志格式 PFTID为pFinder的traceId -->            <pattern>${FILE_LOG_PATTERN}</pattern>            <!-- 此处设置字符集 -->            <charset>UTF-8</charset>        </encoder>    </appender>    <!--日志输出节点-->    <appender name="defaultLogFile" class="ch.qos.logback.core.rolling.RollingFileAppender">        <!--日志输出位置-->        <file>${LOG_BASE_DIR}/logfile-all.log</file>        <!--按照大小与时间的策略进行归档-->        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">            <fileNamePattern>${LOG_BASE_DIR}/logfile-all.%d{yyyy-MM-dd}.%i.log</fileNamePattern>            <!--归档文件最大大小-->            <maxFileSize>${LOG_FILE_MAX_SIZE}</maxFileSize>            <!--归档文件存储时长,单位天-->            <maxHistory>${LOG_FILE_MAX_HISTORY}</maxHistory>            <!--归档文件总大小约束-->            <totalSizeCap>${LOG_FILE_TOTAL_SIZE_CAP}</totalSizeCap>        </rollingPolicy>        <encoder>            <!-- 打印日志格式 PFTID为pFinder的traceId -->            <pattern>${FILE_LOG_PATTERN}</pattern>            <!-- 此处设置字符集 -->            <charset>UTF-8</charset>        </encoder>    </appender>    <root level="${LOG-LEVEL}">        <appender-ref ref="defaultLogFile" />        <appender-ref ref="errorLogFile" />    </root></configuration>
复制代码


发布于: 2022-12-21阅读数: 15
用户头像

洛神灬殇

关注

🏆 InfoQ写作平台-签约作者 🏆 2020-03-25 加入

【个人简介】酷爱计算机科学、醉心编程技术、喜爱健身运动、热衷悬疑推理的“极客达人” 【技术格言】任何足够先进的技术都与魔法无异 【技术范畴】Java领域、Spring生态、MySQL专项、微服务/分布式体系和算法设计等

评论

发布
暂无评论
【Spring专题】「开发指南」夯实实战基础功底之解读logback-spring.xml文件的详解实现_spring_洛神灬殇_InfoQ写作社区