SpringBoot 3.2.0 基于Logback定制日志框架

news2025/2/5 22:09:23

依赖版本

  • JDK 17
  • Spring Boot 3.2.0

工程源码:Gitee

日志门面和日志实现

日志门面(如Slf4j)就是一个标准,同JDBC一样来制定“规则”,把不同的日志系统的实现进行了具体的抽象化,只提供了统一的日志使用接口。而Logback、log4j等具体的日志系统就如同MySQL驱动、PGSQL驱动一样,才是日志功能的真正实现。

img

SpringBoot默认日志框架

SpringBoot使用Slf4j作为日志门面,Logback作为默认的日志实现。在SpringBoot的pom.xml中,依赖为:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-logging</artifactId>
</dependency>

此依赖在SpringBoot Starter包中包含,所以在SpringBoot项目中导入 spring-boot-starter 后可直接使用:

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
    </dependency>
</dependencies>

打印日志

  1. 基于LoggerFactory创建日志记录器实例
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class LoggingApplication {

    private static final Logger logger = LoggerFactory.getLogger(LoggingApplication.class);

    public static void main(String[] args) {
        logger.info("LoggingApplication start...");
        SpringApplication.run(LoggingApplication.class, args);
        logger.info("LoggingApplication end...");
    }
}

springboot3-logging-factory

  1. 引入lombok依赖,通过注解@Slf4j创建日志记录器实例
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
    </dependency>
</dependencies>
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@Slf4j
@SpringBootApplication
public class LoggingApplication {
    public static void main(String[] args) {
        log.info("LoggingApplication start...");
        SpringApplication.run(LoggingApplication.class, args);
        log.info("LoggingApplication end...");
    }
}

springboot3-logging-lombok

配置Logback

默认配置

SpringBoot推荐将配置文件名称命名为logback-spring.xml表示这是SpringBoot下Logback专用的配置,可以使用SpringBoot 的高级Profile功能,它的内容类似于这样:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <!-- 配置信息 -->
</configuration>

最外层由configuration包裹,一旦编写,那么就会替换默认的配置,所以如果内部什么都不写的话,那么会导致我们的SpringBoot项目没有配置任何日志输出方式,控制台也不会打印日志。

也可在配置文件中指定要使用的日志配置,如application.yml中通过配置 logging.config指定要使用的日志配置。

logging:
  config: classpath:logback-spring.xml

springboot3-logging-noneconfig

基于SpringBoot默认Logback配置进行定制

SpringBoot 的默认Logback文件可在依赖项中找到。路径为:org/springframework/boot/logging/logback/defaults.xml

springboot3-logging-logback-config-default

在配置文件中对默认配置进行引用,及编写定制配置覆盖默认配置。

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <!-- 引用Spring Boot 默认日志配置 -->
    <include resource="org/springframework/boot/logging/logback/defaults.xml"/>

    <!-- 控制台日志打印格式 -->
    <property name="CONSOLE_LOG_PATTERN"
              value="MyLogPattern %clr(%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSS}}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr(${LOGGED_APPLICATION_NAME:-}[%15.15t]){faint} %clr(${LOG_CORRELATION_PATTERN:-}){faint}%clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}"/>

    <!-- 日志输出到控制台 -->
    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>${CONSOLE_LOG_THRESHOLD}</level>
        </filter>
        <encoder>
            <pattern>${CONSOLE_LOG_PATTERN}</pattern>
            <charset>${CONSOLE_LOG_CHARSET}</charset>
        </encoder>
    </appender>

    <!-- 指定日志输出级别 -->
    <root level="INFO">
        <appender-ref ref="CONSOLE"/>
    </root>
</configuration>

springboot3-logging-config-my

配置日志信息输出到文件

logback-spring.xml 添加如下内容:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <!-- 引用Spring Boot 默认日志配置 -->
    <include resource="org/springframework/boot/logging/logback/defaults.xml"/>
    <!-- 日志文件输出位置 -->
    <property name="LOG_PATH" value="./logs"/>
    <!-- 日志文件名 -->
    <property name="LOG_FILE" value="${LOG_PATH}/spring-boot.log"/>

    <!-- 日志输出到文件 -->
    <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>${FILE_LOG_THRESHOLD}</level>
        </filter>
        <encoder>
            <pattern>${FILE_LOG_PATTERN}</pattern>
            <charset>${FILE_LOG_CHARSET}</charset>
        </encoder>
        <file>${LOG_FILE}</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <fileNamePattern>${LOGBACK_ROLLINGPOLICY_FILE_NAME_PATTERN:-${LOG_FILE}.%d{yyyy-MM-dd}.%i.gz}</fileNamePattern>
            <cleanHistoryOnStart>${LOGBACK_ROLLINGPOLICY_CLEAN_HISTORY_ON_START:-false}</cleanHistoryOnStart>
            <maxFileSize>${LOGBACK_ROLLINGPOLICY_MAX_FILE_SIZE:-10MB}</maxFileSize>
            <totalSizeCap>${LOGBACK_ROLLINGPOLICY_TOTAL_SIZE_CAP:-0}</totalSizeCap>
            <maxHistory>${LOGBACK_ROLLINGPOLICY_MAX_HISTORY:-7}</maxHistory>
        </rollingPolicy>
    </appender>

    <!-- 指定日志输出级别,以及启动的Appender -->
    <root level="INFO">
        <appender-ref ref="FILE"/>
    </root>
</configuration>

springboot3-logging-logback-config-tofile

MDC机制

Slf4j官方解释

MDC全称Mapped Diagnostic Context(映射诊断上下文),“映射诊断上下文” 本质上是由日志记录框架维护的映射,其中应用程序代码提供键值对,然后可以由日志记录框架将其插入日志消息中。MDC数据在过滤消息或触发某些操作时也非常有用。

通俗的说就是可以将特定的信息(如请求Id,链路Id),通过MDC机制注入到当前日志线程的上下文中,将信息在日志中记录、输出。

image-20231225104700128

MDC的使用

MDC 常用的三个方法:

  • MDC.put(key,value) 注入值
  • MDC.remove(key) 移除指定的MDC注入信息
  • MDC.clear() 移除所有当前线程的MDC注入信息

MDC注入属性配置:

logback-spring.xml文件的输出格式中添加需要注入的KEY信息与代码注入的信息相对应。假定我需要注入当前用户的Id信息,且设置key为user-id

代码:

import lombok.extern.slf4j.Slf4j;
import org.slf4j.MDC;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

import java.util.UUID;

@Slf4j
@SpringBootApplication
public class LoggingApplication {
    public static void main(String[] args) {
        SpringApplication.run(LoggingApplication.class, args);
        String mdcKey = "user-id";
        log.info("Logging before MDC put...");
        MDC.put("mdcKey", UUID.randomUUID().toString());
        log.info("Logging after MDC put...");
        MDC.clear();
        log.info("Logging after MDC clear...");
    }
}

logback-spring.xml

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <!-- 引用Spring Boot 默认日志配置 -->
    <include resource="org/springframework/boot/logging/logback/defaults.xml"/>

    <!-- 控制台日志打印格式 -->
    <property name="CONSOLE_LOG_PATTERN"
              value="[%X{user-id}] %clr(%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSS}}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr(${LOGGED_APPLICATION_NAME:-}[%15.15t]){faint} %clr(${LOG_CORRELATION_PATTERN:-}){faint}%clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}"/>

    <!-- 日志输出到控制台 -->
    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>${CONSOLE_LOG_THRESHOLD}</level>
        </filter>
        <encoder>
            <pattern>${CONSOLE_LOG_PATTERN}</pattern>
            <charset>${CONSOLE_LOG_CHARSET}</charset>
        </encoder>
    </appender>

    <!-- 指定日志输出级别 -->
    <root level="INFO">
        <appender-ref ref="CONSOLE"/>
    </root>
</configuration>

springboot3-logging-logback-mdc

使用方式:

  1. 通过注册拦截器或过滤器,在业务开始前获取到相关信息(请求Id,操作人Id),将相关信息通过MDC自动注入到当前线程中,实现关键信息记录。
  2. 在创建子线程时,需要通过MDC.getCopyOfContextMap()方法获取到当前线程的MDC注入相关信息,传递给子线程,才能在子线打印日志信息时获取到父线程MDC的注入信息。

Logback参考配置

<?xml version="1.0" encoding="UTF-8" ?>
<configuration>
    <!-- Spring Boot 默认日志配置 -->
    <include resource="org/springframework/boot/logging/logback/defaults.xml"/>
    <!-- 日志文件输出位置 -->
    <property name="LOG_PATH" value="./logs"/>
    <!-- 日志文件名 -->
    <property name="LOG_FILE" value="${LOG_PATH}/spring-boot.log"/>
    <!-- 归档日志名 -->
    <property name="FILE_NAME_PATTERN" value="${LOG_FILE}-%d{yyyyMMdd}.%i.gz"/>
    <!-- 在启动时清除历史日志 -->
    <property name="LOGBACK_ROLLINGPOLICY_CLEAN_HISTORY_ON_START" value="false"/>
    <!-- 单个日志文件最大大小 -->
    <property name="LOGBACK_ROLLINGPOLICY_MAX_FILE_SIZE" value="100MB"/>
    <!-- 日志总大小 -->
    <property name="LOGBACK_ROLLINGPOLICY_TOTAL_SIZE_CAP" value="0"/>
    <!-- 日志保留天数 -->
    <property name="LOGBACK_ROLLINGPOLICY_MAX_HISTORY" value="7"/>
    <!-- 控制台日志编码格式 -->
    <property name="CONSOLE_LOG_CHARSET" value="UTF-8"/>
    <!-- 控制台日志打印格式 -->
    <property name="CONSOLE_LOG_PATTERN"
              value="%clr(%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSS}}){faint} [%X{user-id}] [%X{request-id}] [%X{client-ip}] %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr(${LOGGED_APPLICATION_NAME:-}[%15.15t]){faint} %clr(${LOG_CORRELATION_PATTERN:-}){faint}%clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}"/>
    <!-- 控制台日志输出级别 -->
    <property name="CONSOLE_LOG_THRESHOLD" value="INFO"/>
    <!-- 日志文件输出打印格式 -->
    <property name="FILE_LOG_PATTERN"
              value="%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSS}} [%X{user-id}] [%X{request-id}] [%X{client-ip}] ${LOG_LEVEL_PATTERN:-%5p} ${PID:- } --- ${LOGGED_APPLICATION_NAME:-}[%t] ${LOG_CORRELATION_PATTERN:-}%-40.40logger{39} : %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}"/>
    <!-- 日志文件输出编码格式 -->
    <property name="FILE_LOG_CHARSET" value="UTF-8"/>
    <!-- 日志文件输出级别 -->
    <property name="FILE_LOG_THRESHOLD" value="INFO"/>


    <!-- 日志输出到控制台 -->
    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>${CONSOLE_LOG_THRESHOLD}</level>
        </filter>
        <encoder>
            <pattern>${CONSOLE_LOG_PATTERN}</pattern>
            <charset>${CONSOLE_LOG_CHARSET}</charset>
        </encoder>
    </appender>

    <!-- 日志输出到文件 -->
    <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>${FILE_LOG_THRESHOLD}</level>
        </filter>
        <!-- 日志打印配置 -->
        <encoder>
            <pattern>${FILE_LOG_PATTERN}</pattern>
            <charset>${FILE_LOG_CHARSET}</charset>
        </encoder>
        <!-- 日志文件名 -->
        <file>${LOG_FILE}</file>
        <!-- 日志输出配置 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <!-- 日志归档名 -->
            <fileNamePattern>${FILE_NAME_PATTERN}</fileNamePattern>
            <!-- 在启动时清除日志 -->
            <cleanHistoryOnStart>${LOGBACK_ROLLINGPOLICY_CLEAN_HISTORY_ON_START}</cleanHistoryOnStart>
            <!-- 单个文件大小 -->
            <maxFileSize>${LOGBACK_ROLLINGPOLICY_MAX_FILE_SIZE}</maxFileSize>
            <!-- 日志总大小 -->
            <totalSizeCap>${LOGBACK_ROLLINGPOLICY_TOTAL_SIZE_CAP}</totalSizeCap>
            <!-- 日志保留天数 -->
            <maxHistory>${LOGBACK_ROLLINGPOLICY_MAX_HISTORY}</maxHistory>
        </rollingPolicy>
    </appender>

    <!-- 指定日志输出级别,以及启动的Appender -->
    <root level="INFO">
        <appender-ref ref="CONSOLE"/>
        <appender-ref ref="FILE"/>
    </root>
</configuration>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1336925.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SAP ME21/22/23N 创建增强ME_PROCESS_PO_CUST

增强ME_PROCESS_PO_CUST 二、实现方式&#xff1a;实现的方式可以有很多种&#xff0c;这里讲一下用BADI增强ME_PROCESS_PO_CUST实现的方式 第一步&#xff1a;执行事务码se19,在BAdI Name处输入&#xff1a;ME_PROCESS_PO_CUST&#xff0c;然后点“Create Impl”按钮 第二步…

鸿蒙列表,item组件封装传参问题?@ObjectLink 和@Observerd

鸿蒙列表渲染&#xff0c;封装内容组件&#xff0c;进行item传参会报错&#xff1f; class FoodClass {order_id: number 0food_name: string ""food_price: number 0food_count: number 0 }Entry Component struct Demo07 {State message: string Hello World…

C练习——不创建临时变量,交换两个数值

面试可能会问 方法一&#xff08;有缺陷&#xff0c;int 型数值有上限&#xff0c;ab可能超范围&#xff09; // int 型数值有上限&#xff0c;ab可能超范围 #include <stdio.h> int main() {int a 2;int b 3;printf("交换前&#xff1a;%d %d\n", a, b);a…

SpringBoot整合JWT+Spring Security+Redis实现登录拦截(一)登录认证

一、JWT简介 JWT 全称 JSON Web Token&#xff0c;JWT 主要用于用户登录鉴权&#xff0c;当用户登录之后&#xff0c;返回给前端一个Token&#xff0c;之后用户利用Token进行信息交互。 除了JWT认证之外&#xff0c;比较传统的还有Session认证&#xff0c;如何选择可以查看之前…

基于单片机的语音识别自动避障小车(论文+源码)

1.系统设计 此次基于单片机的语音识别自动避障小车&#xff0c;以STC89C52单片机作为系统的主控制器&#xff0c;利用超声波模块来实现小车与障碍物距离的测量并通过LCD液晶显示&#xff0c;当距离低于阈值时会通过WT588语音模块进行报警提示&#xff0c;并且小车会后退来躲避…

知识付费saas租户平台的核心功能设计:打造高效、个性化的学习体验

在在当今数字化时代&#xff0c;知识付费市场正在迅速崛起&#xff0c;而私域流量的概念也日益受到重视。私域流量指的是企业通过自有渠道获取的、能够自由支配的流量&#xff0c;这种流量具有更高的用户粘性和转化率。因此&#xff0c;打造一个基于私域流量的知识付费小程序平…

【C++】并发:异步操作

&#x1f60f;★,:.☆(&#xffe3;▽&#xffe3;)/$:.★ &#x1f60f; 这篇文章主要介绍并发&#xff1a;异步操作。 学其所用&#xff0c;用其所学。——梁启超 欢迎来到我的博客&#xff0c;一起学习&#xff0c;共同进步。 喜欢的朋友可以关注一下&#xff0c;下次更新不…

Astro无人车发布,颜值与功能兼修

介绍 Astro是云讷科技&#xff08;深圳&#xff09;有限公司推出的一款高度智能化和轻量化的小型无人车&#xff0c;其外观基于Tesla Cybertruck 1:10比例还原&#xff0c;支持ROS机器人软件系统开发和视觉SLAM、激光SLAM、路径规划、深度学习等应用。 在线文档&#xff1a; h…

【Unity6.0+AI】Sentis加载模型识别手写数字案例实现

按照国际惯例,看效果: 素材准备: 自己在PS中绘制黑底白字手写字体,导出jpg,尺寸28*28! 素材设置 基本步骤 准备工作:从 ONNX Model Zoo 下载手写识别 ONNX 模型文件 【下载模型】MNIST 手写数字识别模型 mnist-12.onnx,并将其拖入项目窗口的 Assets 文件夹。 【下载模…

亿赛通电子文档安全管理系统 user JNDI远程命令执行

产品简介 亿赛通电子文档安全管理系统&#xff0c;&#xff08;简称&#xff1a;CDG&#xff09;是一款电子文档安全加密软件&#xff0c;该系统利用驱动层透明加密技术&#xff0c;通过对电子文档的加密保护&#xff0c;防止内部员工泄密和外部人员非法窃取企业核心重要数据资…

Dbeaver如何连接Oceanbase?

Dbeaver & Oceanbase 一、新增驱动二、连接数据库 一、新增驱动 1、新建驱动 点击数据库 -> 驱动管理器 -> 新建 2、设置驱动 驱动名称可随意填写注意驱动类型要是Generichost:port填写实际的host和port 库中新增下载的oceanbase驱动jar包 二、连接数据库 1、找…

RK3568驱动指南|第八篇 设备树插件-第83章 设备树插件驱动分析实验

瑞芯微RK3568芯片是一款定位中高端的通用型SOC&#xff0c;采用22nm制程工艺&#xff0c;搭载一颗四核Cortex-A55处理器和Mali G52 2EE 图形处理器。RK3568 支持4K 解码和 1080P 编码&#xff0c;支持SATA/PCIE/USB3.0 外围接口。RK3568内置独立NPU&#xff0c;可用于轻量级人工…

JAVA web面试大全(全)

摘自&#xff1a; Java技术栈 公众号 一、JVM篇 &#xff08;含&#xff1a;JVM类加载机制&#xff0c;JVM内存模型&#xff0c;垃圾收集机制&#xff0c;类字节码实现机制&#xff0c;JVM调优案例&#xff0c;GC日志详解等&#xff09; 二、Java并发编程 &#xff08;含&am…

微信小程序---API的promise化

1.实现API promise化 npm install --save miniprogram-api-promise1.0.4 2.构建miniprogram_npm&#xff0c;先把miniprogram_npm删除&#xff0c;再点击工具->构建npm 3. 4.页面使用 async getInfo(){const {data:res} await wx.p.request({method:GET,url:https://ap…

项目管理及系统规划

一、项目管理 1.软件工程基本概念 1.1 软件 &#xff08;1&#xff09;什么是软件&#xff1f; 软件一般认为由三部分组成&#xff1a; • 程序&#xff1a;在运行时&#xff0c;能提供所希望的功能和性能的指令集。 • 数据结构&#xff1a;使程序能够正确运行的数据结构 …

少走十年弯路!!!webpack详解

webpack是什么&#xff1f;&#xff1f; 本质上&#xff0c;webpack 是一个用于现代 JavaScript 应用程序的 静态模块打包工具。当 webpack 处理应用程序时&#xff0c;它会在内部从一个或多个入口点构建一个 依赖图(dependency graph)&#xff0c;然后将你项目中所需的每一个模…

【问题系列】同时管理多版本node方案

目录 一、问题描述 二、解决方案 三、详细步骤 3.1 安装NVM&#xff1a; 3.2 运行NVM 3.3 安装Node.js 3.4 切换Node.js版本 3.5 验证安装&#xff1a; 四、拓展 4.1 设置默认 Node.js 版本 4.2 列出已安装的 Node.js 版本 4.3 其他命令介绍 一、问题描述 需要运行…

java:4-7运算符优先级

运算符优先级 运算符有不同的优先级&#xff0c;所谓优先级就是表达式运算中的运算顺序。如右表&#xff0c;上一行运算符总优先于下一行。只有单目运算符&#xff08;第二行&#xff09;、赋值运算符&#xff08;倒数3行&#xff09;是从右向左运算的。一览表, 不要背&#x…

Fiddler抓包,怎么抓抓得好抓得快?

01.什么是 Fiddler? Fiddler 是一个 HTTP 协议调试代理工具&#xff0c;它能够记录并检查所有你的电脑和互联网之间的 HTTP 通讯。Fiddler 提供了电脑端、移动端的抓包、包括 http 协议和 https 协议都可以捕获到报文并进行分析&#xff1b;可以设置断点调试、截取报文进行请…