Log4j2通过JDBC Appender无法将日志持久化至SQLite数据库
问题描述
基于Spring Boot 3.3.1 + Maven的应用,使用SQLite数据库存储业务数据(Spring Data JPA实体持久化正常),但Log4j2的JDBC Appender无法将日志写入APPLICATION_LOG表,应用运行无报错,日志表无数据。
相关配置与环境:
- Java 21(Windows Semeru JVM)
- 数据库文件
data.db位于项目根目录,执行mvn clean package后从该目录运行jar包 - log4j2.xml配置存于
src/main/resources,使用DriverManager连接SQLite(无连接池) APPLICATION_LOG表结构:
CREATE TABLE APPLICATION_LOG ( EVENT_ID INTEGER PRIMARY KEY AUTOINCREMENT, EVENT_DATE TIMESTAMP NOT NULL, LEVEL TEXT, LOGGER TEXT, MESSAGE TEXT, THROWABLE TEXT );
- pom.xml已引入log4j-api、log4j-core、sqlite-jdbc、hibernate-community-dialects依赖,版本由Spring Boot父POM管理
- application.properties配置业务数据源正常
排查与修复方案
1. 修正Log4j2 JDBC Appender配置(SQLite适配)
SQLite的自增字段与时间戳处理有特殊要求,原配置存在两个关键问题:
EVENT_ID字段指定literal="NULL"会与SQLite的AUTOINCREMENT逻辑冲突,SQLite要求自增字段插入时不指定值,直接移除该列配置即可isEventTimestamp="true"生成的时间格式可能与SQLite的TIMESTAMP类型不兼容,显式指定时间格式确保匹配
修改后的log4j2.xml:
<?xml version="1.0" encoding="UTF-8"?> <Configuration strict="true" name="config"> <Appenders> <JDBC name="database" tableName="APPLICATION_LOG"> <DriverManager> <connectionString>jdbc:sqlite:data.db</connectionString> <driverClassName>org.sqlite.JDBC</driverClassName> </DriverManager> <!-- 显式指定时间格式,适配SQLite TIMESTAMP --> <Column name="EVENT_DATE" pattern="%d{yyyy-MM-dd HH:mm:ss.SSS}" /> <Column name="LEVEL" pattern="%level" /> <Column name="LOGGER" pattern="%logger" /> <Column name="MESSAGE" pattern="%message" /> <Column name="THROWABLE" pattern="%ex{full}" /> <ThresholdFilter level="TRACE" onMatch="ACCEPT" onMismatch="DENY" /> </JDBC> <!-- 添加Console Appender用于调试,确认Log4j2是否生效 --> <Console name="Console" target="SYSTEM_OUT"> <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %message%n"/> </Console> </Appenders> <Loggers> <Root level="TRACE"> <AppenderRef ref="database" /> <AppenderRef ref="Console" /> </Root> </Loggers> </Configuration>
2. 强制Spring Boot使用Log4j2(排除默认Logback)
Spring Boot默认集成Logback,若未排除,log4j2.xml配置不会生效,这是无报错但日志不写入的核心原因之一。修改pom.xml:
<!-- 排除Spring Boot默认的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,自动整合SLF4J与Log4j2 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-log4j2</artifactId> </dependency>
3. 验证数据库路径与权限
运行jar包时,程序的工作目录是执行java -jar命令的目录,需确保:
- 该目录下存在
data.db文件 - 当前用户对该文件有读写权限
可在代码中添加输出确认工作目录:
System.out.println("当前工作目录:" + System.getProperty("user.dir"));
4. 开启Log4j2调试日志排查
添加JVM启动参数-Dlog4j2.debug=true,启动后查看控制台输出,可确认:
- Log4j2是否成功加载配置文件
- JDBC Appender是否初始化成功
- 生成的INSERT SQL语句是否正确
- 数据库连接是否正常
5. 确保SQLite JDBC驱动兼容Java 21
Spring Boot 3.3.1管理的sqlite-jdbc版本可能已适配Java 21,若仍有问题,可手动指定最新兼容版本:
<dependency> <groupId>org.xerial</groupId> <artifactId>sqlite-jdbc</artifactId> <version>3.46.0.0</version> </dependency>
内容的提问来源于stack exchange,提问作者Miguel
相关产品推荐
相关产品推荐

