未来在生成日志写入数据库中加一个特殊的字段,官方老版本提供的DBAppender无法实现,并且好巧不巧,在新版本这个实现也被删除了,所以重写一个实现。
注意:
- logback至少要升级到1.2.9,因为在此之前有漏洞
- 后续版本删除了项目中所有与数据库(JDBC)相关的代码,需要额外安装关于数据库和logback协同的依赖
如果是springboot我们就不需要安装core依赖,因为springboot内置的日志就是logback。
<dependency>
<groupId>ch.qos.logbackgroupId>
<artifactId>logback-coreartifactId>
<version>1.4.14version>
dependency>
<dependency>
<groupId>ch.qos.logback.dbgroupId>
<artifactId>logback-core-dbartifactId>
<version>1.2.11.1version>
dependency>
如果是老版本的话,在logback中是有一个DBAppender extends DBAppenderBase,在后续版本中貌似已经被移除需要手动实现。
getGeneratedKeysMethod()
:这个方法用于获取 PreparedStatement.getGeneratedKeys 方法的反射引用,这主要用于获取数据库插入操作生成的主键值。
这在日志事件插入数据库并需要获取插入记录的主键时非常有用。
getInsertSQL()
:此方法应返回用于插入日志事件到数据库的 SQL 语句。这是一个核心方法,因为它直接定义了如何将日志数据存储到数据库中。
根据你的数据库表结构和需要存储的日志信息,编写并返回相应的 SQL 插入语句。
subAppend(ILoggingEvent event, Connection connection, PreparedStatement preparedStatement)
:这个方法实现了将日志事件数据绑定到预编译的 SQL 语句(PreparedStatement)并执行插入操作的逻辑。
它是日志事件存储过程的核心部分。
secondarySubAppend(ILoggingEvent event, Connection connection, long eventId)
:这个方法用于执行与主插入操作相关的次要数据库操作,例如插入日志事件的异常信息或自定义属性。eventId 通常是主日志事件插入操作生成的主键。
如果你的日志记录需求包括存储额外的事件相关信息(如异常信息),你应该在这里实现这些信息的数据库插入逻辑。
protected Method getGeneratedKeysMethod() {
return null;
}
@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 (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
}
secondarySubAppend(ILoggingEvent iLoggingEvent, Connection connection, long l)
,也直接不用管就行,如果没有其他相关逻辑的话。protected void secondarySubAppend(ILoggingEvent iLoggingEvent, Connection connection, long l) throws Throwable {
}
一共就实现了getInsertSQL(),subAppend()两个方法,是不是特别简单?
配置logback.xml
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} %-5level %logger{36} - %msg%npattern>
encoder>
appender>
<appender name="DB" class="com.chen.behindimagesmanage.config.CustomDBAppender">
<connectionSource class="ch.qos.logback.core.db.DriverManagerConnectionSource">
<driverClass>com.mysql.cj.jdbc.DriverdriverClass>
<url>jdbc:mysql://192.168.0.254:3306/image_manage?serverTimezone=Asia/Shanghai
url>
<user>rootuser>
<password>123456password>
connectionSource>
appender>
<root level="INFO">
<appender-ref ref="STDOUT" />
<appender-ref ref="DB" />
root>
configuration>
实际上这个东西的核心就是设置一个预编译的sql,也就是实现subAppend(ILoggingEvent event, Connection connection, PreparedStatement stmt)方法,就是jdbc的简单应用,理解过程就很简单。