使用Log4j2异步向RabbitMQ发自定义日志遇配置错误求助
问题分析
报错信息显示Logback在解析Log4j2的配置文件,核心原因是Spring Boot 2.7.x默认集成Logback作为日志框架,你的项目未排除Logback依赖,导致系统尝试用Logback解析Log4j2格式的配置文件,从而出现大量"no applicable action"错误。同时还存在依赖缺失、配置路径不匹配、未配置异步日志和JSON格式输出的问题。
解决方案
1. 修正Maven依赖(pom.xml)
排除Spring Boot Starter中的Logback依赖,添加Log4j2相关必要依赖:
<dependencies> <!-- Spring Boot Web Starter,排除Logback --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <exclusions> <exclusion> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-logging</artifactId> </exclusion> </exclusions> </dependency> <!-- Spring Boot Test Starter,排除Logback --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> <exclusions> <exclusion> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-logging</artifactId> </exclusion> </exclusions> </dependency> <!-- Log4j2 Spring Boot Starter,适配Spring Boot --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-log4j2</artifactId> </dependency> <!-- Log4j2 RabbitMQ Appender --> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-rabbitmq</artifactId> <version>2.14.1</version> </dependency> <!-- Log4j2 JSON格式输出依赖 --> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-layout-template-json</artifactId> <version>2.14.1</version> </dependency> <!-- Disruptor,提升Log4j2异步日志性能 --> <dependency> <groupId>com.lmax</groupId> <artifactId>disruptor</artifactId> <version>3.4.4</version> </dependency> <!-- Oracle JDBC驱动 --> <dependency> <groupId>com.oracle.database.jdbc</groupId> <artifactId>ojdbc8</artifactId> <version>19.8.0.0</version> </dependency> </dependencies>
2. 修正application.properties配置
修正日志配置文件路径,确保和实际文件名一致:
# RabbitMQ配置 rabbitmq.in.queue=queue rabbitmq.in.exchange=exchange rabbitmq.in.routingkey=routingkey rabbitmq.in.host=host rabbitmq.in.port=port rabbitmq.in.exchangetype=exchangetype rabbitmq.in.virtualhost=virtualhost rabbitmq.in.username=username rabbitmq.in.password=password listener.prefetchcount=1 listener.maxConcurrentConsumerCount=10 management.health.rabbit.enabled=false # 数据库配置 spring.datasource.url=jdbc:oracle:thin:@localhost:1521:xe spring.datasource.username=test spring.datasource.password=test spring.datasource.driver-class-name=oracle.jdbc.driver.OracleDriver # 日志配置文件路径(匹配实际文件名) logging.config=classpath:log4j2-spring.xml
3. 修改log4j2-spring.xml配置
配置异步Appender、RabbitMQ Appender,并启用JSON格式输出:
<?xml version="1.0" encoding="UTF-8"?> <Configuration status="INFO"> <Appenders> <!-- RabbitMQ Appender,自动声明交换机(可选) --> <RabbitMQ name="rmqAppender" host="${rabbitmq.in.host}" port="${rabbitmq.in.port}" virtualHost="${rabbitmq.in.virtualhost}" username="${rabbitmq.in.username}" password="${rabbitmq.in.password}" exchange="${rabbitmq.in.exchange}" routingKey="${rabbitmq.in.routingkey}" declareExchange="true" exchangeType="${rabbitmq.in.exchangetype}" durable="true"> <!-- JSON格式输出,使用自定义模板 --> <JsonTemplateLayout eventTemplateUri="classpath:log-template.json"/> </RabbitMQ> <!-- 异步Appender,实现日志异步发送到RabbitMQ --> <Async name="AsyncRmqAppender"> <AppenderRef ref="rmqAppender"/> <!-- 异步队列配置,按需调整缓冲区大小 --> <DisruptorBlockingQueue ringBufferSize="1024" waitStrategy="Blocking"/> </Async> </Appenders> <Loggers> <!-- 业务包日志,仅发送到RabbitMQ --> <Logger name="com.example.demo" level="info" additivity="false"> <AppenderRef ref="AsyncRmqAppender"/> </Logger> <!-- 根日志,统一发送到RabbitMQ --> <Root level="info"> <AppenderRef ref="AsyncRmqAppender"/> </Root> </Loggers> </Configuration>
4. 添加自定义JSON模板(log-template.json)
在src/main/resources下创建该文件,定义JSON日志的字段结构:
{ "timestamp": { "$resolver": "timestamp", "pattern": "yyyy-MM-dd'T'HH:mm:ss.SSSXXX" }, "thread": { "$resolver": "thread" }, "level": { "$resolver": "level", "field": "name" }, "logger": { "$resolver": "logger", "field": "name" }, "message": { "$resolver": "message" }, "stackTrace": { "$resolver": "stackTrace", "stringified": true } }
验证示例
使用Log4j2的Logger记录日志:
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 TestController { private static final Logger logger = LogManager.getLogger(TestController.class); @GetMapping("/test-log") public String testLog() { logger.info("这是一条业务测试日志"); logger.error("这是一条错误日志", new RuntimeException("模拟业务异常")); return "日志已发送至RabbitMQ"; } }
访问/test-log接口后,RabbitMQ对应队列将收到JSON格式的异步日志消息。
内容的提问来源于stack exchange,提问作者tejashree parab
相关产品推荐
相关产品推荐

