Log4j2 JDBC Appender配置:上下文变量转UUID类型方法
问题描述
我有如下PostgreSQL数据库表:
create table audit_read ( level text, account_id uuid, message text );
我希望在日志事件触发时向该表插入记录,因此配置了如下Log4j2 properties文件:
appender.read.type = JDBC appender.read.name = READ logger.read = debug, READ logger.read.name = audit.read logger.read.additivity = false appender.read.connectionSource.connectionString=jdbc:postgresql://localhost:5432/mydatabase appender.read.connectionSource.type = DriverManager appender.read.connectionSource.driverClassName = org.postgresql.Driver appender.read.connectionSource.username = myusername appender.read.connectionSource.password = mypassword appender.read.tableName=runtime_audit.audit_read appender.read.ignoreExceptions=false appender.read.columnConfigs[0].type = COLUMN appender.read.columnConfigs[0].name = level appender.read.columnConfigs[0].pattern = %p appender.read.columnConfigs[0].isUnicode = false appender.read.columnConfigs[1].type = COLUMN appender.read.columnConfigs[1].name = account_id appender.read.columnConfigs[1].pattern = %X{currentUser.id} appender.read.columnConfigs[1].isUnicode = false appender.read.columnConfigs[2].type = COLUMN appender.read.columnConfigs[2].name = message appender.read.columnConfigs[2].pattern = %m appender.read.columnConfigs[2].isUnicode =false
触发日志事件时出现如下错误:
ERROR org.apache.logging.log4j.core.appender.db.DbAppenderLoggingException: Failed to insert record for log event in JDBC manager: org.postgresql.util.PSQLException: ERROR: column "account_id" is of type uuid but expression is of type character varying Hint: You will need to rewrite or cast the expression.
将日志输出到文件时,日志行如下:
INFO - 0c5c1ad7-14e2-4215-8919-15740d8a8d72 - resource X was read
这表明上下文变量已正确填充。我的问题是:如何将上下文变量转换为UUID类型?我查阅了官方文档,猜测需要使用ColumnMapping参数,但不清楚具体配置方式,或者是否可以使用UuidConverter来实现?
解决方案
有两种可行的方式解决这个类型不匹配问题:
方法一:使用ColumnMapping配合UuidConverter
修改account_id对应的列配置,改用ColumnMapping类型,并指定UuidConverter将字符串格式的UUID转换为Java原生UUID类型,让PostgreSQL JDBC驱动能正确识别类型。
修改后的配置片段如下:
appender.read.columnConfigs[1].type = ColumnMapping appender.read.columnConfigs[1].name = account_id appender.read.columnConfigs[1].pattern = %X{currentUser.id} appender.read.columnConfigs[1].converter.type = UuidConverter # 可选:如果上下文变量可能为空,开启该配置 appender.read.columnConfigs[1].converter.allowNull = true
注意:需确保项目依赖的Log4j2版本(log4j-core、log4j-api)在2.10及以上,该版本开始支持UuidConverter。
方法二:SQL层面强制类型转换
如果不想配置转换器,可直接在插入SQL中用CAST函数将字符串转为UUID类型,需要自定义Log4j2的插入语句,而非自动生成。
修改后的JDBC Appender配置如下:
appender.read.tableName=runtime_audit.audit_read # 自定义插入SQL,通过CAST处理UUID转换 appender.read.sql = INSERT INTO runtime_audit.audit_read (level, account_id, message) VALUES (?, CAST(? AS UUID), ?) # 保留原有列配置,需与SQL占位符顺序对应 appender.read.columnConfigs[0].type = COLUMN appender.read.columnConfigs[0].name = level appender.read.columnConfigs[0].pattern = %p appender.read.columnConfigs[0].isUnicode = false appender.read.columnConfigs[1].type = COLUMN appender.read.columnConfigs[1].name = account_id appender.read.columnConfigs[1].pattern = %X{currentUser.id} appender.read.columnConfigs[1].isUnicode = false appender.read.columnConfigs[2].type = COLUMN appender.read.columnConfigs[2].name = message appender.read.columnConfigs[2].pattern = %m appender.read.columnConfigs[2].isUnicode =false
这种方式直接在SQL层处理类型转换,无需额外配置转换器,适合快速解决问题。
内容的提问来源于stack exchange,提问作者Tim
相关产品推荐
相关产品推荐

