当前位置: 首页 > news >正文

Spring Boot Logback 日志配置详解:从基础到分布式追踪

日志是应用程序不可或缺的组成部分,它不仅能帮助我们调试问题,还能监控系统运行状态。在 Spring Boot 生态中,Logback 凭借其高性能和灵活性成为首选的日志框架。本文将通过一个实际的 Logback 配置文件,详细解析其各个组件的功能和配置技巧。

什么是 Logback?

Logback 是由 Log4j 创始人设计的开源日志组件,是 Log4j 的继任者。它分为三个模块:

  • logback-core:核心组件,提供基础功能
  • logback-classic:实现了 SLF4J API,可直接替换 Log4j
  • logback-access:与 Servlet 容器集成,提供 HTTP 访问日志功能

在 Spring Boot 中,Logback 是默认的日志框架,无需额外依赖即可使用。

完整配置文件解析

<?xml version="1.0" encoding="UTF-8"?>
<!--Copyright 2010-2011 The myBatis TeamLicensed under the Apache License, Version 2.0 (the "License");you may not use this file except in compliance with the License.You may obtain a copy of the License athttp://www.apache.org/licenses/LICENSE-2.0Unless required by applicable law or agreed to in writing, softwaredistributed under the License is distributed on an "AS IS" BASIS,WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.See the License for the specific language governing permissions andlimitations under the License.
-->
<configuration debug="false"><!--定义日志文件的存储地址 勿在 LogBack 的配置中使用相对路径--><springProperty scope="context" name="LOG_HOME" source="HuiChen.log.directory"/><springProperty scope="context" name="APP_NAME" source="spring.application.name" defaultValue="huichen-device-sms-manager"/><springProperty scope="context" name="LOG_LEVEL" source="HuiChen.log.level" defaultValue="debug"/><!-- 彩色日志 --><!-- 彩色日志依赖的渲染类 --><conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter"/><conversionRule conversionWord="wex"converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter"/><conversionRule conversionWord="wEx"converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter"/><!-- 彩色日志格式 --><property name="CONSOLE_LOG_PATTERN"value="${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/><!-- Console 输出设置 --><appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<!--        <encoder>-->
<!--            <pattern> ${CONSOLE_LOG_PATTERN}</pattern>-->
<!--            <charset>utf8</charset>-->
<!--        </encoder>--><encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder"><layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.TraceIdPatternLogbackLayout"><pattern>[%tid] ${CONSOLE_LOG_PATTERN}</pattern></layout><charset>utf-8</charset></encoder></appender><!-- 按照每天生成INFO日志文件 --><appender name="FILEINFO" class="ch.qos.logback.core.rolling.RollingFileAppender"><rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"><!--日志文件输出的文件名--><FileNamePattern>${LOG_HOME}/${APP_NAME}.%d{yyyy-MM-dd}.info.%i.log</FileNamePattern><!--日志文件保留天数--><MaxHistory>30</MaxHistory><!--日志文件最大的大小--><MaxFileSize>10MB</MaxFileSize></rollingPolicy><encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"><!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符--><pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern></encoder></appender><!-- 按照每天生成ERROR日志文件 --><appender name="FILEERROR" class="ch.qos.logback.core.rolling.RollingFileAppender"><rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"><!--日志文件输出的文件名--><FileNamePattern>${LOG_HOME}/${APP_NAME}.%d{yyyy-MM-dd}.error.%i.log</FileNamePattern><!--日志文件保留天数--><MaxHistory>30</MaxHistory><!--日志文件最大的大小--><MaxFileSize>10MB</MaxFileSize></rollingPolicy><encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"><!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符--><pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern></encoder><!-- 此日志文件只记录info级别的 --><filter class="ch.qos.logback.classic.filter.LevelFilter"><level>error</level><onMatch>ACCEPT</onMatch><onMismatch>DENY</onMismatch></filter></appender><!-- skywalking 采集日志 --><appender name="grpc-log" class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.log.GRPCLogClientAppender"><encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder"><layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.mdc.TraceIdMDCPatternLogbackLayout"><Pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%X{tid}] [%thread] %-5level %logger{36} -%msg%n</Pattern></layout></encoder></appender><!--myibatis mongodb log configure--><logger name="com.apache.ibatis" level="TRACE"/><logger name="java.sql.Connection" level="DEBUG"/><logger name="java.sql.Statement" level="DEBUG"/><logger name="java.sql.PreparedStatement" level="DEBUG"/>
<!--    <logger name="org.springframework.data.mongodb.core" level="DEBUG"/><logger name="org.springframework.data.redis.core" level="DEBUG"/><logger name="org.springframework.data.elasticsearch" level="DEBUG"/><logger name="org.springframework.data.neo4j" level="DEBUG"/>--><logger name="com.sms.manager" level="DEBUG"/><!-- 日志输出级别 INFO--><root level="${LOG_LEVEL}"><appender-ref ref="STDOUT"/><appender-ref ref="grpc-log"/><appender-ref ref="FILEINFO"/><appender-ref ref="FILEERROR"/></root><!--日志异步到数据库 --><!--<appender name="DB" class="ch.qos.logback.classic.db.DBAppender">--><!--&lt;!&ndash;日志异步到数据库 &ndash;&gt;--><!--<connectionSource class="ch.qos.logback.core.db.DriverManagerConnectionSource">--><!--&lt;!&ndash;连接池 &ndash;&gt;--><!--<dataSource class="com.mchange.v2.c3p0.ComboPooledDataSource">--><!--<driverClass>com.mysql.jdbc.Driver</driverClass>--><!--<url>jdbc:mysql://baas.ievent.cn:3306/ievent</url>--><!--<user>live</user>--><!--<password>novacloudlive</password>--><!--</dataSource>--><!--</connectionSource>--><!--</appender>-->
</configuration>

下面我们将逐部分解析一个生产级别的 Logback 配置文件,理解其各个组件的作用。

1. 配置文件基本结构

<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="false"><!-- 配置内容 -->
</configuration>
  • debug="false":关闭 Logback 自身的调试日志,生产环境建议关闭

2. 动态属性定义

<springProperty scope="context" name="LOG_HOME" source="HuiChen.log.directory"/>
<springProperty scope="context" name="APP_NAME" source="spring.application.name" defaultValue="huichen-device-sms-manager"/>
<springProperty scope="context" name="LOG_LEVEL" source="HuiChen.log.level" defaultValue="debug"/>

这部分配置通过 <springProperty> 标签将 Spring 环境中的配置注入到 Logback 中,实现了配置的动态化和外部化:

  • LOG_HOME:日志文件存储目录,值来自 Spring 配置的 HuiChen.log.directory
  • APP_NAME:应用名称,默认值为 huichen-device-sms-manager,可通过 spring.application.name 覆盖
  • LOG_LEVEL:全局日志级别,默认 debug,可通过 HuiChen.log.level 配置

这种方式的优势在于:

  • 可以在不同环境(开发、测试、生产)使用不同的配置
  • 无需修改 Logback 配置文件即可调整日志行为
  • 符合 Spring Boot 外部化配置的理念

3. 彩色日志配置

<!-- 彩色日志依赖的渲染类 -->
<conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter"/>
<conversionRule conversionWord="wex"converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter"/>
<conversionRule conversionWord="wEx"converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter"/><!-- 彩色日志格式 -->
<property name="CONSOLE_LOG_PATTERN"value="${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/>

这段配置实现了控制台彩色日志输出:

  • <conversionRule>:定义了三个转换规则,用于日志的彩色渲染和异常信息格式化
  • CONSOLE_LOG_PATTERN:定义了控制台日志的输出格式,其中:
    • %clr(...):用于指定日志元素的颜色
    • %d{...}:日期时间,格式为 yyyy-MM-dd HH:mm:ss.SSS
    • %5p:日志级别,占 5 个字符宽度
    • ${PID:- }:进程 ID
    • %15.15t:线程名,最长 15 个字符
    • %-40.40logger{39}:日志器名称,最长 40 个字符
    • %m%n:日志消息和换行符

彩色日志的优势在于:

  • 不同级别日志用不同颜色显示,便于快速识别
  • 关键信息(如线程名、类名)有颜色区分,提高可读性
  • 异常堆栈信息格式化显示,便于调试

4. 日志输出目的地(Appender)

Appender 定义了日志的输出方式和位置,一个配置文件中可以有多个 Appender。

4.1 控制台输出(STDOUT)
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"><encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder"><layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.TraceIdPatternLogbackLayout"><pattern>[%tid] ${CONSOLE_LOG_PATTERN}</pattern></layout><charset>utf-8</charset></encoder>
</appender>

这是一个输出到控制台的 Appender:

  • name="STDOUT":Appender 的名称,用于后续引用
  • class="ch.qos.logback.core.ConsoleAppender":指定这是控制台输出的 Appender
  • <encoder>:编码器,负责将日志事件转换为字符串
    • LayoutWrappingEncoder:使用自定义布局的编码器
    • TraceIdPatternLogbackLayout:集成了 SkyWalking 的布局,用于添加分布式追踪 ID
    • [%tid]:SkyWalking 追踪 ID,在分布式系统中非常有用
    • charset="utf-8":日志编码格式
4.2 INFO 级别日志文件(FILEINFO)
<appender name="FILEINFO" class="ch.qos.logback.core.rolling.RollingFileAppender"><rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"><!-- 日志文件输出的文件名 --><FileNamePattern>${LOG_HOME}/${APP_NAME}.%d{yyyy-MM-dd}.info.%i.log</FileNamePattern><!-- 日志文件保留天数 --><MaxHistory>30</MaxHistory><!-- 日志文件最大的大小 --><MaxFileSize>10MB</MaxFileSize></rollingPolicy><encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"><pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern></encoder>
</appender>

这是一个滚动输出 INFO 级别日志到文件的 Appender:

  • class="ch.qos.logback.core.rolling.RollingFileAppender":滚动文件输出 Appender,支持日志文件分割
  • <rollingPolicy>:滚动策略,这里使用 SizeAndTimeBasedRollingPolicy,结合了时间和大小的滚动策略
    • FileNamePattern:日志文件命名规则,包含日期和序号
    • MaxHistory:日志文件保留 30 天
    • MaxFileSize:单个日志文件最大 10MB,超过则创建新文件
  • <encoder>:定义了文件日志的格式,包含日期、线程、级别、日志器和消息
4.3 ERROR 级别日志文件(FILEERROR)
<appender name="FILEERROR" class="ch.qos.logback.core.rolling.RollingFileAppender"><rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"><FileNamePattern>${LOG_HOME}/${APP_NAME}.%d{yyyy-MM-dd}.error.%i.log</FileNamePattern><MaxHistory>30</MaxHistory><MaxFileSize>10MB</MaxFileSize></rollingPolicy><encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"><pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern></encoder><filter class="ch.qos.logback.classic.filter.LevelFilter"><level>error</level><onMatch>ACCEPT</onMatch><onMismatch>DENY</onMismatch></filter>
</appender>

这个 Appender 专门用于记录 ERROR 级别日志:

  • 与 FILEINFO 类似,但增加了 <filter> 配置
  • LevelFilter:级别过滤器,只接受 ERROR 级别的日志
    • onMatch>ACCEPT</onMatch>:匹配 ERROR 级别则接受
    • onMismatch>DENY</onMismatch>:不匹配则拒绝

将 ERROR 日志单独存储的好处:

  • 便于快速定位错误,无需在大量日志中筛选
  • 可以设置更长的保留时间,便于问题追溯
  • 不同级别的日志可以有不同的处理策略
4.4 SkyWalking 日志采集(grpc-log)
<appender name="grpc-log" class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.log.GRPCLogClientAppender"><encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder"><layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.mdc.TraceIdMDCPatternLogbackLayout"><Pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%X{tid}] [%thread] %-5level %logger{36} -%msg%n</Pattern></layout></encoder>
</appender>

这个 Appender 用于将日志发送到 SkyWalking APM 系统:

  • GRPCLogClientAppender:通过 gRPC 协议将日志发送到 SkyWalking 服务器
  • TraceIdMDCPatternLogbackLayout:将追踪 ID 放入日志,实现分布式追踪
  • [%X{tid}]:从 MDC(Mapped Diagnostic Context)中获取追踪 ID

集成 SkyWalking 的优势:

  • 实现日志与分布式追踪的关联,便于微服务架构下的问题排查
  • 可以在 SkyWalking 控制台查看全链路日志
  • 追踪 ID 贯穿整个调用链,方便定位跨服务问题

5. 日志级别控制

<!-- myibatis mongodb log configure -->
<logger name="com.apache.ibatis" level="TRACE"/>
<logger name="java.sql.Connection" level="DEBUG"/>
<logger name="java.sql.Statement" level="DEBUG"/>
<logger name="java.sql.PreparedStatement" level="DEBUG"/>
<!-- 
<logger name="org.springframework.data.mongodb.core" level="DEBUG"/>
<logger name="org.springframework.data.redis.core" level="DEBUG"/>
<logger name="org.springframework.data.elasticsearch" level="DEBUG"/>
<logger name="org.springframework.data.neo4j" level="DEBUG"/>
--><logger name="com.sms.manager" level="DEBUG"/><!-- 日志输出级别 -->
<root level="${LOG_LEVEL}"><appender-ref ref="STDOUT"/><appender-ref ref="grpc-log"/><appender-ref ref="FILEINFO"/><appender-ref ref="FILEERROR"/>
</root>

这部分配置控制不同包或类的日志级别:

  • <logger>:针对特定包或类设置日志级别

    • name:指定包或类的全限定名
    • level:日志级别,从低到高为 TRACE < DEBUG < INFO < WARN < ERROR
    • 例如 com.sms.manager 包下的日志被设置为 DEBUG 级别
  • <root>:根日志配置,所有未被特定 logger 配置的类都继承此配置

    • level="${LOG_LEVEL}":使用之前定义的动态属性作为全局日志级别
    • <appender-ref>:引用前面定义的 Appender,表示日志会输出到这些目的地

日志级别的作用:

  • 控制日志输出的详细程度,生产环境通常使用 INFO 级别减少日志量
  • 特定包可以设置更详细的日志级别,便于调试
  • 避免不必要的日志输出,提高系统性能

6. 数据库日志(注释部分)

配置文件中还有一个注释掉的数据库日志 Appender:

<!--
<appender name="DB" class="ch.qos.logback.classic.db.DBAppender"><connectionSource class="ch.qos.logback.core.db.DriverManagerConnectionSource"><dataSource class="com.mchange.v2.c3p0.ComboPooledDataSource"><driverClass>com.mysql.jdbc.Driver</driverClass><url>jdbc:mysql://baas.ievent.cn:3306/ievent</url><user>live</user><password>novacloudlive</password></dataSource></connectionSource>
</appender>
-->

这个 Appender 用于将日志存储到数据库中,适用于需要对日志进行复杂查询和分析的场景。但由于性能影响和配置复杂性,通常在生产环境中不推荐使用,除非有特殊需求。

实际应用中的最佳实践

  1. 环境隔离

    • 开发环境:使用 DEBUG 级别,输出到控制台
    • 生产环境:使用 INFO 级别,输出到文件,限制日志大小和保留时间
  2. 性能考虑

    • 避免在循环中输出大量日志
    • 生产环境避免使用 DEBUG 级别
    • 适当设置日志文件大小和保留时间,避免磁盘空间耗尽
  3. 安全考虑

    • 日志中避免包含敏感信息(密码、令牌等)
    • 确保日志文件有适当的权限控制
    • 敏感操作的日志应特别关注
  4. 分布式系统

    • 集成分布式追踪系统(如 SkyWalking)
    • 确保日志中包含追踪 ID,便于跨服务追踪
    • 统一日志收集和分析(如使用 ELK 栈)

总结

本文详细解析了一个生产级别的 Logback 配置文件,涵盖了动态属性、彩色日志、多目的地输出、日志级别控制和分布式追踪集成等方面。合理配置 Logback 不仅能帮助我们更好地理解系统运行状态,还能在出现问题时快速定位和解决。

Logback 的配置灵活多变,应根据实际需求进行调整。在开发和生产环境中使用不同的配置,既能保证开发效率,又能确保生产系统的稳定运行。

希望本文能帮助你更好地理解和使用 Logback,构建更健壮的日志系统。


文章转载自:

http://JV8Wi5Ie.xkhhy.cn
http://tC8s9CpE.xkhhy.cn
http://tbAX4SEz.xkhhy.cn
http://3yqtjgkG.xkhhy.cn
http://645RScJb.xkhhy.cn
http://1Hrz09LM.xkhhy.cn
http://nMnMbREb.xkhhy.cn
http://53RS0Ai6.xkhhy.cn
http://sr1OdvHk.xkhhy.cn
http://PJF7oG2n.xkhhy.cn
http://ossXMbFK.xkhhy.cn
http://knJkCnZm.xkhhy.cn
http://im6gCujx.xkhhy.cn
http://9fINhHfA.xkhhy.cn
http://63CNAL5z.xkhhy.cn
http://b3xvQgzb.xkhhy.cn
http://ByB7Pjpx.xkhhy.cn
http://TAh7gHGa.xkhhy.cn
http://ZwFnayS1.xkhhy.cn
http://XVnME8N4.xkhhy.cn
http://prwyS4be.xkhhy.cn
http://vWrmUaXa.xkhhy.cn
http://JiSo1Bbc.xkhhy.cn
http://hd2H3NSO.xkhhy.cn
http://SEXY0Yit.xkhhy.cn
http://MXRbwPv6.xkhhy.cn
http://kaFLTkrJ.xkhhy.cn
http://KX4kVHRC.xkhhy.cn
http://uakf3Ajm.xkhhy.cn
http://wAWYa36c.xkhhy.cn
http://www.dtcms.com/a/387349.html

相关文章:

  • 辉视养老方案:重塑老年生活的温馨与安心
  • 通过商业智能(BI)可视化数据分析了解布洛芬的产销情况
  • 健康大数据专业能转行做医疗数据分析吗?
  • antiword为什么在ubuntu22.04上面不乱码,而在mac上出现乱码
  • Paperless-ngx v2.18.4在Ubuntu 24.04上的完整离线安装步骤(非Docker)
  • Ubuntu 18.04 搭建 Kubernetes 1.27.4 集群全流程(附问题排查)
  • Ubuntu 18.04 LTS 安装 6.10.10 内核
  • Windows 11 下使用 WSL2 安装 Ubuntu 22.04 步骤
  • 在 WSL 中通过 Bash 函数快速转换 Windows 路径为 Ansible/WSL 路径
  • 【ubuntu24.04】 nvidia-smi监控GPU 利用率
  • 《嵌入式硬件(十四):基于IMX6ULL的通用目的定时器(GPT)操作》
  • 鸿蒙Next Web调试与维测全攻略:从DevTools到专项测试
  • 基于运行设计域(ODD)的安全论证方法
  • 鸿蒙HarmonyOS界面开发-组件动态创建(一)
  • 网络安全风险评估中元模型构建与实例应用
  • 鸿蒙5.0应用开发——V2装饰器@ObservedV2和@Trace的使用
  • xkInfoScan 是一款集成化的网络信息收集与安全扫描工具,支持 IP / 域名 / URL /信息追踪多维度目标探测
  • 解决 Windows 系统下 TDengine 数据恢复及迁移问题
  • PocketBase 是一个‌开源的轻量级后端框架‌,基于 Go 语言开发
  • 苹果新手机和旧手机怎么传输数据?新手避坑指南
  • Maven 只打包部分模块,跳过单元测试... 常用打包参数
  • 【maven01】依赖管理的工具
  • BP神经网络多输入多输出回归预测+SHAP可解释分析+新数据预测(MATLAB完整源码)
  • MATLAB 时间序列小波周期分析
  • 计算机视觉进阶教学之DNN模块
  • 大模型无需懂MCP:工具调用范式的架构革命与实践指南
  • 剑指offer题单 9.14
  • IIS 站点 http 请求412问题解决
  • Web前端入门:从零开始做网站(视频教程)
  • 本地--Oracle表被锁了该如何处理