游乐游手机版
首页/AI教程/文章详情

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

时间:2026-06-16 15:51
使用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
上一篇提示工程 RAG 微调 LLM应用开发三大层次 下一篇年6月TIOBE编程语言排行榜TOP15
本站内容用于信息整理与展示,如有侵权或内容问题请及时联系处理。

相关推荐

补充同频道和同主题内容,方便继续浏览更多相关内容。

同类最新

继续查看同栏目最近更新的文章。

更多
Windows Docker Desktop RabbitMQ生产级部署完整指南
AI教程 · 2026-06-29

Windows Docker Desktop RabbitMQ生产级部署完整指南

前言 在 Windows 本地开发环境中,直接安装 RabbitMQ 确实颇为周折:需要单独配置 Erlang 运行环境、手动管理环境变量、服务启停全凭手工操作。更令人困扰的是,版本兼容冲突、端口占用、环境不一致等问题层出不穷。笔者见过不少开发者为搭建环境就得耗费整整半天时间。 相比之下,借助 Do

AI搜索重构制造业采购逻辑的阿里云企业级GEOCMS优化实践
AI教程 · 2026-06-29

AI搜索重构制造业采购逻辑的阿里云企业级GEOCMS优化实践

先分享一个切实感受。过去两年,我们与福建制造企业合作较为频繁,发现一个非常突出的现象:超过80%的企业官网,产品参数仍然存放在PDF或图片中。AI爬虫?根本无法抓取。这些企业技术实力不弱、资质证照齐全、应用案例也丰富,但在AI搜索这一全新战场上,它们几乎处于隐身状态。 一、一个正在发生的行业变化 A

阿里云Token Plan团队版功能价格与省钱购买指南
AI教程 · 2026-06-29

阿里云Token Plan团队版功能价格与省钱购买指南

阿里云百炼近期推出了名为“Token Plan 团队版”的全新服务,这一服务专为企业与开发者量身打造,定位为AI大模型订阅平台。通过引入Credits作为统一计量单位,将文本生成、图像生成等多模态AI能力纳入单一计费体系,同时无缝兼容主流AI编程工具及智能体(Agent)生态系统。其核心亮点包括:全

阿里云物联网.NET Core客户端位置信息上报
AI教程 · 2026-06-29

阿里云物联网.NET Core客户端位置信息上报

阿里云物联网平台的位置服务并非一个完全独立的功能模块。位置信息可包含二维坐标与三维坐标,而位置数据的来源本质上是借助设备属性进行上传。换言之,若要让设备上报位置,您需先将其视为一个普通属性进行处理。 1)添加二维位置数据 操作过程十分简洁。进入数据分析 → 空间数据可视化 → 二维数据,点击添加,将

年阿里云服务器选型配置与网站部署全攻略
AI教程 · 2026-06-29

年阿里云服务器选型配置与网站部署全攻略

2026年,阿里云服务器生态已高度成熟,形成了清晰的轻量应用服务器与ECS云服务器两大产品阵营。无论你是计划搭建个人博客、企业官网,还是运营电商平台、进行应用开发,基本都能找到理想的解决方案。本指南将从服务器选型、配置选择、部署流程到安全运维,系统梳理2026年最实用的操作要点,帮助你少走弯路,让网