当前位置: 首页
AI教程
SLF4J集成Log4j2实现日志存储到MySQL

SLF4J集成Log4j2实现日志存储到MySQL

热心网友 时间:2026-06-16
转载

使用Log4j2的JDBCAppender可将SLF4J Log4j2日志写入MySQL。需配置表名、Connection工厂类及工厂方法,通过DBCP连接池或自定义工厂获取连接。注意框架加载时序与连接管理,确保连接有效并避免初始化冲突,同时处理连接泄漏与异常,保证日志写入可靠性。

最近在折腾 Spring Boot 项目的日志存储方案,踩了不少坑。尤其是想把日志直接写入数据库时,尝试了几种方式,最终发现 Log4j2 的 JDBC Appender 是一个比较实用的选择。

项目使用的 Spring Boot 版本是 2.2.3.RELEASE,日志框架方面,门面采用 SLF4J 1.7.30,具体实现则选择了 JUL 和 Log4j 2.12.1(记得排除自带的 Logback)。此外还需要 log4j-slf4j 桥接包,版本同样为 2.12.1。

参考官方文档,整体实现思路其实比较清晰。

\

官方文档表述得很直接:核心就是获取一个 java.sql.Connection,并且官方还提供了一个现成的配置示例。

Appenders 配置详解

首先看 Appenders 的配置。关键属性不多:tableName 指定数据库表名,class 指定获取 Connection 的工厂类,method 对应工厂类中的具体方法名。

在每个 Column 标签中,可以配置三种模式:literal 用来写死 SQL 字面量(例如数据库序列),pattern 用于从日志事件中提取字段,isEventTimestamp 用来标记时间戳字段。

下面是配置示例代码:



    
        
            
            
            
            
            
            
            
        
    
    
        
            
        
    

获取 Connection 的实现方式

Connection 的获取方式,官方也给出了一个完整示例,使用了 Apache DBCP 连接池。关键在于:Log4j2 只负责调用你提供的工厂方法,而连接池管理、事务控制、自动重连等都需要自己处理。

示例代码如下:

package net.example.db;

import ja va.sql.Connection;
import ja va.sql.SQLException;
import ja va.util.Properties;

import ja vax.sql.DataSource;

import org.apache.commons.dbcp.DriverManagerConnectionFactory;
import org.apache.commons.dbcp.PoolableConnection;
import org.apache.commons.dbcp.PoolableConnectionFactory;
import org.apache.commons.dbcp.PoolingDataSource;
import org.apache.commons.pool.impl.GenericObjectPool;

public class ConnectionFactory {
    private static interface Singleton {
        final ConnectionFactory INSTANCE = new ConnectionFactory();
    }

    private final DataSource dataSource;

    private ConnectionFactory() {
        Properties properties = new Properties();
        properties.setProperty("user", "logging");
        properties.setProperty("password", "abc123");

        GenericObjectPool pool = new GenericObjectPool();
        DriverManagerConnectionFactory connectionFactory = new DriverManagerConnectionFactory(
                "jdbc:mysql://example.org:3306/exampleDb", properties);
        new PoolableConnectionFactory(connectionFactory, pool, null, "SELECT 1", 3, false, false,
                Connection.TRANSACTION_READ_COMMITTED);

        this.dataSource = new PoolingDataSource(pool);
    }

    public static Connection getDatabaseConnection() throws SQLException {
        return Singleton.INSTANCE.dataSource.getConnection();
    }
}

这样配置似乎就完成了?别急,有几个关键坑必须提前说清楚。

第一,尽管 Log4j2 给出了连接池的使用建议,但它本身并不管理连接池、事务和自动重连。也就是说,你提供的 Connection 工厂方法必须在任何情况下都能返回一个有效连接。如果连接被关闭,框架不会自动重连,你需要自己编写逻辑来检测并重建连接。

第二,这一点在实际项目中尤其容易遇到。很多项目已经集成了 Druid 等数据库连接池,但 Log4j2 写入日志时,这些框架可能尚未加载完成(或未完成初始化),结果导致日志写入失败,程序却默默吞掉了异常。使用前一定要仔细考虑框架的加载时机。

再分享一个我自己在项目中使用的简单实现,比官方的 DBCP 示例更容易理解:

import ja va.sql.Connection;
import ja va.sql.DriverManager;
import ja va.sql.SQLException;

public class ConnectionFactory {
    private static Connection connection = null;

    public static Connection getDatabaseConnection() {
        try {
            if (connection == null || connection.isClosed()) {
                synchronized (ConnectionFactory.class) {
                    if (connection == null || connection.isClosed()) {
                        connection = DriverManager.getConnection(
                            "jdbc:mysql://**.**.cn:3306/**?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai",
                            "**", "**");
                    }
                }
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return connection;
    }
}

对应的建表 SQL 也直接明了:

create table tbl_log (
    ID int auto_increment primary key,
    EVENT_DATE datetime null,
    LEVEL varchar(20) null,
    LOGGER varchar(20) null,
    MESSAGE text null,
    THROWABLE text null
);

最后看看实际运行的效果:

整体思路并不复杂,但细节稍不注意就容易翻车。尤其是框架加载时序和连接管理这两部分,建议在实际项目中多测试几遍再上线。

来源:https://cloud.tencent.com.cn/developer/article/2689555

游乐网为非赢利性网站,所展示的游戏/软件/文章内容均来自于互联网或第三方用户上传分享,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系youleyoucom@outlook.com。

同类文章
更多
Claude Code 必知的14个高效工作流,让你的开发效率提升300%

Claude Code 必知的14个高效工作流,让你的开发效率提升300%

Claude Code 常用工作流 先分享几项核心判断:Claude Code 真正强大的地方,并非仅仅在于它能编写代码——而是它让“编码”这件事本身变得更加高效且可控。你大概率遇到过这类场景:接手一个陌生项目,花了一整天才能理清架构;线上出现报错,翻遍日志也找不到根本原因;想要重构遗留代码,又担心

时间:2026-07-09 17:49
阿里云通义AIGC平台完全指南:设计师AI生产力革命

阿里云通义AIGC平台完全指南:设计师AI生产力革命

一、写在前面:为什么设计师需要关注AIGC? 如果你还在手动一张一张制作海报、反复修改客户口中“感觉不对”的配色方案、为电商详情页准备几十张不同场景的产品图——那么你一定经历过这些痛点: 创意瓶颈:脑海中有画面,但手绘无法呈现 重复劳动:调整尺寸、更换背景、批量生成变体消耗了大量时间精力 成本焦虑:

时间:2026-07-09 16:48
零基础毕设代码二次开发:3文件定位法及Vue/Java修改对照表

零基础毕设代码二次开发:3文件定位法及Vue/Java修改对照表

每年一到毕业季,计算机专业的同学总会陷入一个共同的怪圈:从 GitHub 上扒下来一套代码,或者用 AI 生成一个项目,看起来挺完整的,可导师一句“加个筛选条件”或“换个页面颜色”,瞬间就懵了——不敢改,不会改,怕改崩。是不是很熟悉? 一、为什么AI生成的毕设代码你 "不敢改 "? 1 1 毕业生的三大

时间:2026-07-09 16:46
反向海淘订单系统:状态机与分布式事务实战设计

反向海淘订单系统:状态机与分布式事务实战设计

先分享一个反直觉的结论:反向海淘订单管理的真正挑战,往往不在于业务逻辑本身,而在于状态流转。一个订单的生命周期拉长到跨国运输,中间涉及的环节多、系统多、参与者多,状态稍有错乱就可能引发连锁事故。Taocarts团队在实践中踩了不少坑,最终沉淀下来的这套状态机与分布式事务方案,成功解决了这一复杂难题。

时间:2026-07-09 16:46
AI并未抢走程序员饭碗而是更新了编程菜单

AI并未抢走程序员饭碗而是更新了编程菜单

AI并未大规模替代程序员,而是改变了职业结构。重复性编码岗位需求下降35%至15%,而AIAgent开发等岗位需求激增187%。开发者焦虑从“被替代”转向“跟不上变化”,60%程序员已使用AI辅助编程。人的核心价值转向架构设计、技术决策和审查AI生成代码,AI技能带来16%薪资溢价。

时间:2026-07-09 16:46
热门专题
更多
刀塔传奇破解版无限钻石下载大全 刀塔传奇破解版无限钻石下载大全
洛克王国正式正版手游下载安装大全 洛克王国正式正版手游下载安装大全
思美人手游下载专区 思美人手游下载专区
好玩的阿拉德之怒游戏下载合集 好玩的阿拉德之怒游戏下载合集
不思议迷宫手游下载合集 不思议迷宫手游下载合集
百宝袋汉化组游戏最新合集 百宝袋汉化组游戏最新合集
jsk游戏合集30款游戏大全 jsk游戏合集30款游戏大全
宾果消消消原版下载大全 宾果消消消原版下载大全
  • 热门数据榜