Spring Boot集成Logback与Log4j2时自定义日志无法写入Kafka问题
Spring Boot 同时集成Logback+Loki与Log4j2+Kafka日志分流问题排查与解决
问题原因
Spring Boot的日志自动配置逻辑会根据classpath中的日志框架jar包,自动选择唯一的核心日志实现,优先级为:Logback > Log4j2 > Java Util Logging。
当你同时引入Logback和Log4j2时,Spring Boot会默认启用Logback作为全局日志系统:
- 自定义代码中通过
org.slf4j.LoggerFactory获取的Logger会绑定到Logback,因此自定义日志只会流向Logback配置的Loki Appender。 - Spring Boot自身的部分核心类,因类加载顺序或依赖隔离特性,仍会使用Log4j2的Logger实例,导致这部分默认日志仅流向Log4j2配置的Kafka Appender,最终出现日志分流的现象。
解决方案
推荐统一使用单个日志框架(优先选Log4j2,因为它对Kafka Appender的支持更成熟),同时配置Kafka和Loki两个Appender,确保所有日志能同时输出到两个目标。
1. 排除Spring Boot默认的Logback依赖
Maven 配置
<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> <!-- 引入Log4j2 starter --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-log4j2</artifactId> </dependency> <!-- 引入Log4j2 Loki Appender依赖 --> <dependency> <groupId>com.github.loki4j</groupId> <artifactId>loki-log4j2-appender</artifactId> <version>0.7.0</version> </dependency>
Gradle 配置
dependencies { implementation('org.springframework.boot:spring-boot-starter-web') { exclude group: 'org.springframework.boot', module: 'spring-boot-starter-logging' } implementation 'org.springframework.boot:spring-boot-starter-log4j2' implementation 'com.github.loki4j:loki-log4j2-appender:0.7.0' }
2. 配置Log4j2双Appender
在src/main/resources/log4j2.xml中配置Kafka和Loki两个Appender,让所有日志同时推送:
<?xml version="1.0" encoding="UTF-8"?> <Configuration status="WARN"> <Appenders> <!-- Kafka Appender 配置 --> <Kafka name="KafkaLog" topic="spring-boot-logs"> <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n"/> <Property name="bootstrap.servers">kafka-1:9092,kafka-2:9092</Property> <Property name="acks">1</Property> <Property name="retries">3</Property> </Kafka> <!-- Loki Appender 配置 --> <Loki name="LokiLog" url="http://loki-server:3100/loki/api/v1/push"> <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n"/> <Label key="app" value="spring-boot-demo"/> <Label key="env" value="production"/> <Batch maxItems="1000" maxBytes="4194304" timeoutMs="5000"/> </Loki> </Appenders> <Loggers> <!-- 根Logger绑定两个Appender --> <Root level="info"> <AppenderRef ref="KafkaLog"/> <AppenderRef ref="LokiLog"/> </Root> <!-- 针对特定包调整日志级别(可选) --> <Logger name="com.yourcompany.demo" level="debug" additivity="false"> <AppenderRef ref="KafkaLog"/> <AppenderRef ref="LokiLog"/> </Logger> <Logger name="org.springframework" level="warn" additivity="false"> <AppenderRef ref="KafkaLog"/> <AppenderRef ref="LokiLog"/> </Logger> </Loggers> </Configuration>
3. 验证效果
启动项目后,自定义业务日志、Spring Boot启动日志及框架内部日志都会同时推送到Kafka指定主题和Grafana Loki,解决分流问题。
注意:不建议同时保留Logback和Log4j2两套日志框架,会增加类冲突风险和维护成本,统一日志框架是最优解。
内容的提问来源于stack exchange,提问作者PatPanda
相关产品推荐
相关产品推荐

