logback自定义生成DB日志(java环境)

目的:

未来在生成日志写入数据库中加一个特殊的字段,官方老版本提供的DBAppender无法实现,并且好巧不巧,在新版本这个实现也被删除了,所以重写一个实现。

1. 安装依赖

  1. 安装logback maven依赖

注意:

  1. logback至少要升级到1.2.9,因为在此之前有漏洞
  2. 后续版本删除了项目中所有与数据库(JDBC)相关的代码,需要额外安装关于数据库和logback协同的依赖

如果是springboot我们就不需要安装core依赖,因为springboot内置的日志就是logback。

xml 复制代码
<!--        logback DB依赖-->
<!-- https://mvnrepository.com/artifact/ch.qos.logback/logback-core -->

<dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-core</artifactId>
    <version>1.4.14</version>
</dependency>

 <dependency>
            <groupId>ch.qos.logback.db</groupId>
            <artifactId>logback-core-db</artifactId>
            <version>1.2.11.1</version>
  </dependency>

2. 实现CustomDBAppender。

如果是老版本的话,在logback中是有一个DBAppender extends DBAppenderBase,在后续版本中貌似已经被移除需要手动实现。

当然这和我们没关系,本来就是要自定义,手动实现未尝不可。

  1. 我们注意到主要有getGeneratedKeysMethod(),getInsertSQL(),subAppend(),secondarySubAppend()方法,我们简单说下作用。
  • getGeneratedKeysMethod()这个方法用于获取 PreparedStatement.getGeneratedKeys 方法的反射引用,这主要用于获取数据库插入操作生成的主键值。

    这在日志事件插入数据库并需要获取插入记录的主键时非常有用。

  • getInsertSQL()此方法应返回用于插入日志事件到数据库的 SQL 语句。这是一个核心方法,因为它直接定义了如何将日志数据存储到数据库中。

    根据你的数据库表结构和需要存储的日志信息,编写并返回相应的 SQL 插入语句。

  • subAppend(ILoggingEvent event, Connection connection, PreparedStatement preparedStatement)这个方法实现了将日志事件数据绑定到预编译的 SQL 语句(PreparedStatement)并执行插入操作的逻辑

    它是日志事件存储过程的核心部分。

  • secondarySubAppend(ILoggingEvent event, Connection connection, long eventId)这个方法用于执行与主插入操作相关的次要数据库操作,例如插入日志事件的异常信息或自定义属性。eventId 通常是主日志事件插入操作生成的主键

    如果你的日志记录需求包括存储额外的事件相关信息(如异常信息),你应该在这里实现这些信息的数据库插入逻辑。

  1. 弄清基本作用,过程就很简单了,我们不需要获取主键,日志sql写死
  2. getGeneratedKeysMethod()方法直接返回null就行
powershell 复制代码
protected Method getGeneratedKeysMethod() {
        return null;
    }
  1. getInsertSQL()就是在原来官方sql基础上,删了4个arg,删掉了reference_flag(如果不考虑复杂的日志功能的话),添加了podname
powershell 复制代码
@Override
    protected String getInsertSQL() {
        return "INSERT INTO logging_event (timestmp, formatted_message, logger_name, level_string, thread_name, reference_flag, caller_filename, caller_class, caller_method, caller_line, pod_name) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
    }
  1. secondarySubAppend(ILoggingEvent iLoggingEvent, Connection connection, long l),也直接不用管就行,如果没有其他相关逻辑的话。
powershell 复制代码
protected void secondarySubAppend(ILoggingEvent iLoggingEvent, Connection connection, long l) throws Throwable {
        
    }
  1. 一共就实现了getInsertSQL(),subAppend()两个方法,是不是特别简单?

  2. 配置logback.xml

xml 复制代码
<configuration>

<!-- Console appender -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    <encoder>
        <pattern>%d{yyyy-MM-dd HH:mm:ss} %-5level %logger{36} - %msg%n</pattern>
    </encoder>
</appender>

<!-- DB appender -->
<appender name="DB" class="com.chen.behindimagesmanage.config.CustomDBAppender">
    <connectionSource class="ch.qos.logback.core.db.DriverManagerConnectionSource">
        <driverClass>com.mysql.cj.jdbc.Driver</driverClass>
        <url>jdbc:mysql://192.168.0.254:3306/image_manage?serverTimezone=Asia/Shanghai
        </url>
        <user>root</user>
        <password>123456</password>
    </connectionSource>
</appender>

<!-- Root logger -->
<root level="INFO">
    <appender-ref ref="STDOUT" />
    <appender-ref ref="DB" />
</root>

</configuration>

总结:

实际上这个东西的核心就是设置一个预编译的sql,也就是实现subAppend(ILoggingEvent event, Connection connection, PreparedStatement stmt)方法,就是jdbc的简单应用,理解过程就很简单。

相关推荐
程序员清风13 小时前
快手二面:乐观锁是怎么用它来处理多线程问题的?
java·后端·面试
曦樂~13 小时前
【Qt】信号与槽(Signal and Slot)- 简易计算器
开发语言·数据库·qt
一线大码13 小时前
SpringBoot 优雅实现接口的多实现类方式
java·spring boot·后端
花伤情犹在13 小时前
Java Stream 高级应用:优雅地扁平化(FlatMap)递归树形结构数据
java·stream·function·flatmap
yaoxin52112314 小时前
212. Java 函数式编程风格 - Java 编程风格转换:命令式 vs 函数式(以循环为例)
java·开发语言
ZYMFZ14 小时前
python面向对象
前端·数据库·python
摇滚侠14 小时前
Spring Boot 3零基础教程,WEB 开发 Thymeleaf 属性优先级 行内写法 变量选择 笔记42
java·spring boot·笔记
滑水滑成滑头14 小时前
**发散创新:多智能体系统的探索与实践**随着人工智能技术的飞速发展,多智能体系统作为当今研究的热点领域,正受到越来越多关注
java·网络·人工智能·python
摇滚侠14 小时前
Spring Boot 3零基础教程,WEB 开发 Thymeleaf 总结 热部署 常用配置 笔记44
java·spring boot·笔记
十年小站14 小时前
一、新建一个SpringBoot3项目
java·spring boot