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

Spring Boot 3.5.3 集成 Log4j2 日志系统

在 Spring Boot 3.5.3 中,要将默认的 Logback 替换为 Log4j2,需要以下步骤:

1. 添加 Log4j2 依赖

在 pom.xml中排除默认的 Logback 依赖并添加 Log4j2 依赖:

<dependencies><!-- 排除默认的 Logback --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId><exclusions><exclusion><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-logging</artifactId></exclusion></exclusions></dependency><!-- 添加 Log4j2 Starter --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-log4j2</artifactId></dependency><!-- 可选:日志配置刷新支持 --><dependency><groupId>org.apache.logging.log4j</groupId><artifactId>log4j-liquibase</artifactId></dependency>
</dependencies>

2. 创建 Log4j2 配置文件

在 src/main/resources目录下创建 log4j2.xml文件:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN" monitorInterval="30"><Appenders><!-- 控制台输出 --><Console name="Console" target="SYSTEM_OUT"><PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/></Console><!-- 文件输出 --><RollingFile name="File" fileName="logs/application.log"filePattern="logs/application-%d{yyyy-MM-dd}-%i.log"><PatternLayout><Pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n</Pattern></PatternLayout><Policies><!-- 每天滚动 --><TimeBasedTriggeringPolicy /><!-- 文件大小达到100MB时滚动 --><SizeBasedTriggeringPolicy size="100 MB"/></Policies><!-- 保留最近7天的日志 --><DefaultRolloverStrategy max="7"/></RollingFile><!-- 异步日志配置 --><Async name="Async" bufferSize="262144"><AppenderRef ref="File"/></Async></Appenders><Loggers><!-- Spring Boot 核心日志 --><Logger name="org.springframework" level="INFO"/><Logger name="org.apache" level="WARN"/><!-- Hibernate 日志 --><Logger name="org.hibernate.SQL" level="DEBUG" additivity="false"><AppenderRef ref="Console"/></Logger><Logger name="org.hibernate.type.descriptor.sql" level="TRACE" additivity="false"><AppenderRef ref="Console"/></Logger><!-- 自定义包日志级别 --><Logger name="com.myapp" level="DEBUG"/><!-- Root 日志设置 --><Root level="INFO"><AppenderRef ref="Console"/><AppenderRef ref="Async"/> <!-- 使用异步文件输出 --></Root></Loggers>
</Configuration>

3. 添加 application.yml 配置

在 application.yml中添加 Log4j2 相关配置:

spring:application:name: my-applicationlogging:config: classpath:log4j2.xmllevel:root: infoorg.springframework.web: debugcom.myapp.service: trace# 启用日志配置热更新log4j2:watch: trueshutdown-hook: disableshutdown-timeout: 30

4. 添加日志工具类

创建日志工具类以简化使用:

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;public class LogUtil {private LogUtil() {}public static Logger getLogger() {// 获取调用此方法的上层类名return LogManager.getLogger(Thread.currentThread().getStackTrace()[2].getClassName());}// 方法入参日志(使用MDC添加上下文信息)public static void logMethodEntry(Object... params) {Logger logger = getLogger();if(logger.isTraceEnabled()) {String methodName = Thread.currentThread().getStackTrace()[2].getMethodName();logger.trace("Entering: {} with params: {}", methodName, params);}}
}

5. 高级功能配置

5.1 日志脱敏配置

添加敏感信息脱敏配置类:

import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.core.config.plugins.Plugin;
import org.apache.logging.log4j.core.pattern.ConverterKeys;
import org.apache.logging.log4j.core.pattern.LogEventPatternConverter;@Plugin(name = "SafeConverter", category = "Converter")
@ConverterKeys({"safe"})
public class SafeConverter extends LogEventPatternConverter {// 敏感信息正则匹配private static final String SENSITIVE_PATTERN = "\\b(?:password|passwd|pwd|secret|token|key|card|ccn|phone|tel|id)\\b[^=]*=\\s*['\"]?([^'\",\\s]+)";protected SafeConverter() {super("safe", "safe");}public static SafeConverter newInstance(String[] options) {return new SafeConverter();}@Overridepublic void format(LogEvent event, StringBuilder toAppendTo) {String message = event.getMessage().getFormattedMessage();toAppendTo.append(message.replaceAll(SENSITIVE_PATTERN, "$1=***"));}
}

在 log4j2.xml中使用:

<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %safe{%msg}%n"/>

5.2 日志指标监控

添加 Log4j2 指标采集:

import io.micrometer.core.instrument.MeterRegistry;
import org.apache.logging.log4j.LogManager;
import org.springframework.context.annotation.Configuration;import javax.annotation.PostConstruct;@Configuration
public class LogMetricsConfig {private final MeterRegistry meterRegistry;public LogMetricsConfig(MeterRegistry meterRegistry) {this.meterRegistry = meterRegistry;}@PostConstructpublic void init() {// 采集ERROR级别的日志计数meterRegistry.gauge("log.error.count", LogManager.getRootLogger(), logger -> logger instanceof org.apache.logging.log4j.core.Logger ? ((org.apache.logging.log4j.core.Logger) logger).getCount().get() : 0);}
}

5.3 日志集中式管理

添加 Logstash 或 ELK 支持:

<!-- pom.xml 添加依赖 -->
<dependency><groupId>net.logstash.logback</groupId><artifactId>logstash-logback-encoder</artifactId><version>7.3</version>
</dependency>

配置 Logstash Appender:

<Appenders><!-- Logstash TCP 输出 --><LogstashTcpSocket name="Logstash" host="logstash.mycompany.com" port="5000"><JsonLayout compact="true" eventEol="true"><KeyValuePair key="appName" value="${spring:spring.application.name}"/><KeyValuePair key="environment" value="${spring:spring.profiles.active}"/></JsonLayout></LogstashTcpSocket>
</Appenders><Loggers><Root level="INFO"><AppenderRef ref="Logstash"/></Root>
</Loggers>

6. Spring Boot 配置类

添加日志相关的配置管理:

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.core.LoggerContext;
import org.springframework.boot.context.event.ApplicationStartedEvent;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.event.EventListener;import java.net.URI;@Configuration
public class LogConfig {/*** 应用启动后重新加载日志配置*/@EventListener(ApplicationStartedEvent.class)public void reloadLogConfig() {LoggerContext context = (LoggerContext) LogManager.getContext(false);context.setConfigLocation(URI.create("classpath:log4j2.xml"));context.reconfigure();}
}

7. 日志性能优化

7.1 异步日志配置优化

<!-- log4j2.xml -->
<AsyncLogger name="com.myapp" level="debug" additivity="false"><AppenderRef ref="Console"/><AppenderRef ref="File"/><!-- 队列大小 --><AsyncQueueSize>262144</AsyncQueueSize><!-- 等待策略 --><AsyncWaitStrategy type="Block"/>
</AsyncLogger>

7.2 日志开关控制器

import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.core.LoggerContext;
import org.apache.logging.log4j.core.config.Configurator;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
public class LogController {@GetMapping("/log/level")public String changeLogLevel(String logger, String level) {LoggerContext context = (LoggerContext) LogManager.getContext(false);// 设置特定日志级别if ("root".equalsIgnoreCase(logger)) {Configurator.setRootLevel(Level.valueOf(level));} else {Configurator.setLevel(logger, Level.valueOf(level));}context.reconfigure();return "Log level updated: " + logger + " -> " + level;}
}

8. 验证日志配置

创建测试控制器验证日志输出:

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
public class LogTestController {private static final Logger logger = LogManager.getLogger(LogTestController.class);@GetMapping("/test/log")public String testLog() {logger.trace("This is a TRACE message");logger.debug("This is a DEBUG message");logger.info("This is an INFO message");logger.warn("This is a WARN message");logger.error("This is an ERROR message");return "Log messages generated!";}
}

访问 http://localhost:8080/test/log后,检查控制台和日志文件验证输出。

配置总结

功能

配置位置

说明

基础配置

log4j2.xml

定义日志格式、输出目的地等

级别控制

application.yml

设置不同包的日志级别

热更新

logging.log4j2.watch

配置自动检测配置变化

异步日志

Async Appender

提高日志性能

日志脱敏

SafeConverter

保护敏感信息

日志监控

Micrometer

采集日志指标

远程日志

LogstashTcpSocket

集成ELK栈

此配置提供了:

  1. 灵活的日志级别控制

  2. 高性能的异步日志处理

  3. 敏感信息保护

  4. 监控和管理功能

http://www.xdnf.cn/news/1429165.html

相关文章:

  • 从spring MVC角度理解HTTP协议及Request-Response模式
  • 异常处理小妙招——1.别把“数据库黑话”抛给用户:论异常封装的重要性
  • 图像 OSD层数据 显示--OSD LOGO单色黑色显示,按区域大小申请MMZ内存的优缺点分析
  • 2022版Unity创建时没有2D灯光(2D Light),没有Global LIght2D怎么办?
  • Java集合遍历的方法有哪些
  • 使用Spark计算WordCount
  • 美团 LongCat 开源大模型60 亿参数 MoE 架构,赋能开发者加速 AI 应用落地
  • vue2中如何使用Ant Design Vue 中的 Tooltip 文字提示
  • 242. 有效的字母异位词| 349. 两个数组的交集
  • 通信中FDD和TDD的区别
  • 【JavaEE】多线程案例
  • 使用 Python 的 SymPy 进行符号计算
  • 机器学习回顾——决策树详解
  • 详解Grafana k6 的阈值(Thresholds)
  • FPGA时序分析(三)--基础知识
  • Leetcode_206.反转链表(递归)
  • 【嵌入式电机控制#进阶7】V/F强拖启动
  • 变频器实习DAY41 单元测试介绍
  • 前端实现解析【导入】数据后调用批量处理接口
  • Redis有哪些部署方案?了解哨兵机制吗?
  • AI文档产品与传统OCR软件的根本区别是什么?
  • 手写Muduo网络库核心代码2--Poller、EPollPoller详细讲解
  • 百度智能云,除了AI还有啥?
  • 线程特定存储
  • Go语言开发合并文件小工具
  • go命令行工具:如何在现有的工程里加入使用cobra
  • 苹果手机文本转音频,自行制作背诵素材
  • Redis 持久化机制详解
  • 《WINDOWS 环境下32位汇编语言程序设计》第10章 内存管理和文件操作(2)
  • 文华财经wh6波段多空指标-变色K做多做空信号,抄底逃顶主图幅图