Log4J2 JdbcAppender 没有编写正确的 INSERT 语句
Log4J2 JdbcAppender doesn't compose correct INSERT statement
我正在尝试在我的 Spring 应用程序中使用这个合并的 JDBC 记录器登录 PostgreSQL 数据库。
主要思想来自这里:
@Component
public class JdbcAppenderConfiguration implements
ApplicationListener<ContextRefreshedEvent> {
private static Logger LOGGER =
LogManager.getLogger(JdbcAppenderConfiguration.class);
private final DataSource dataSource;
public JdbcAppenderConfiguration(DataSource dataSource) {
this.dataSource = dataSource;
}
@Override
public void onApplicationEvent(ContextRefreshedEvent event) {
final LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
final ColumnConfig[] cc = {
ColumnConfig.newBuilder()
.setConfiguration(ctx.getConfiguration())
.setName("level")
.setPattern("%level")
.setUnicode(false)
.build()
};
final Appender appender = JdbcAppender
.newBuilder()
.setName("databaseAppender")
.setIgnoreExceptions(false)
.setConnectionSource(new ConnectionFactory(dataSource))
.setTableName("logs2")
.setColumnConfigs(cc)
.build();
appender.start();
ctx.getConfiguration().addAppender(appender);
final LoggerConfig loggerConfig =
ctx.getConfiguration()
.getLoggerConfig(LogManager.ROOT_LOGGER_NAME);
loggerConfig.addAppender(appender, null, null);
ctx.updateLoggers();
}
}
和连接工厂:
public class ConnectionFactory extends AbstractConnectionSource {
private final DataSource dataSource;
public ConnectionFactory(DataSource dataSource) {
AssertUtils.notNull(dataSource, "dataSource");
this.dataSource = dataSource;
}
@Override
public Connection getConnection() throws SQLException {
return dataSource.getConnection();
}
}
但是在记录时我得到这个错误:
2020-12-12 08:03:05,860 restartedMain ERROR Unable to write to
database [JdbcManager{name=databaseAppender, bufferSize=0,
tableName=logs2, columnConfigs=[{ name=level, layout=%level,
literal=null, timestamp=false }], columnMappings=null}] for appender
[databaseAppender].
org.apache.logging.log4j.core.appender.db.DbAppenderLoggingException:
Failed to insert record for log event in JDBC manager:
org.postgresql.util.PSQLException: ERROR: syntax error at or near ")"
Pozice: 20 [columnConfigs=[{ name=level, layout=%level, literal=null,
timestamp=false }], sqlStatement=insert into logs2 () values (?),
factoryData=FactoryData
[connectionSource=ConnectionFactory@ca2c455,
tableName=logs2, columnConfigs=[{ name=level, layout=%level,
literal=null, timestamp=false }], columnMappings=null,
immediateFail=false, retry=true, reconnectIntervalMillis=5000,
truncateStrings=true], connection=HikariProxyConnection@1535828764
wrapping org.postgresql.jdbc.PgConnection@603942ae,
statement=HikariProxyPreparedStatement@1512335087 wrapping insert into
logs2 () values ('INFO'), reconnector=null, isBatchSupported=true,
columnMetaData={}]
无效 SQL INSERT 语句有问题:
sqlStatement=insert into logs2 () values (?),
问题:您知道为什么 log4J 不能正确/完整地编写命令吗?我的代码有什么问题?
这是 Log4j2 中的错误。
我在 IntelliJ 中建立了一个快速项目,添加了 log4j2 2.14 api 和核心 JAR 以及数据库驱动程序 JAR 和 运行 你的代码,我能够重现格式不正确的INSERT
错误消息中的声明。
我使用 IntelliJ 下载 log4j2 源 JAR 并将其附加,然后逐步完成将 INSERT
语句放在一起的代码。将列名添加到 SQL 字符串的方法称为 appendColumnNames
并且在 class JdbcDatabaseManager
中。
它包含以下代码,为清楚起见,我对其进行了缩写:
if (data.columnMappings != null) {
for (final ColumnMapping colMapping : data.columnMappings) {
// append column from colMapping
}
if (data.columnConfigs != null) {
for (final ColumnConfig colConfig : data.columnConfigs) {
// append column from colConfig
}
}
}
在这种情况下,我们可以看到如果 ColumnMapping
是 null
,则不会使用 ColumnConfig
中的列名。这种行为是不正确的:您应该只能指定 ColumnConfig
s。第二个 if
不应嵌套在第一个中。
Log4j2 支持使用 ColumnMapping
s 以及 ColumnConfig
s 来指定要写入日志记录的列 table,因此一种解决方法是改用它们。另一种解决方法是添加行
.setColumnMappings(new ColumnMapping[0])
为了你的建设JdbcAppender
。我对您的代码进行了此更改,Log4j2 生成了正确的 SQL 字符串。
我正在尝试在我的 Spring 应用程序中使用这个合并的 JDBC 记录器登录 PostgreSQL 数据库。
主要思想来自这里:
@Component
public class JdbcAppenderConfiguration implements
ApplicationListener<ContextRefreshedEvent> {
private static Logger LOGGER =
LogManager.getLogger(JdbcAppenderConfiguration.class);
private final DataSource dataSource;
public JdbcAppenderConfiguration(DataSource dataSource) {
this.dataSource = dataSource;
}
@Override
public void onApplicationEvent(ContextRefreshedEvent event) {
final LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
final ColumnConfig[] cc = {
ColumnConfig.newBuilder()
.setConfiguration(ctx.getConfiguration())
.setName("level")
.setPattern("%level")
.setUnicode(false)
.build()
};
final Appender appender = JdbcAppender
.newBuilder()
.setName("databaseAppender")
.setIgnoreExceptions(false)
.setConnectionSource(new ConnectionFactory(dataSource))
.setTableName("logs2")
.setColumnConfigs(cc)
.build();
appender.start();
ctx.getConfiguration().addAppender(appender);
final LoggerConfig loggerConfig =
ctx.getConfiguration()
.getLoggerConfig(LogManager.ROOT_LOGGER_NAME);
loggerConfig.addAppender(appender, null, null);
ctx.updateLoggers();
}
}
和连接工厂:
public class ConnectionFactory extends AbstractConnectionSource {
private final DataSource dataSource;
public ConnectionFactory(DataSource dataSource) {
AssertUtils.notNull(dataSource, "dataSource");
this.dataSource = dataSource;
}
@Override
public Connection getConnection() throws SQLException {
return dataSource.getConnection();
}
}
但是在记录时我得到这个错误:
2020-12-12 08:03:05,860 restartedMain ERROR Unable to write to database [JdbcManager{name=databaseAppender, bufferSize=0, tableName=logs2, columnConfigs=[{ name=level, layout=%level, literal=null, timestamp=false }], columnMappings=null}] for appender [databaseAppender]. org.apache.logging.log4j.core.appender.db.DbAppenderLoggingException: Failed to insert record for log event in JDBC manager: org.postgresql.util.PSQLException: ERROR: syntax error at or near ")" Pozice: 20 [columnConfigs=[{ name=level, layout=%level, literal=null, timestamp=false }], sqlStatement=insert into logs2 () values (?), factoryData=FactoryData [connectionSource=ConnectionFactory@ca2c455, tableName=logs2, columnConfigs=[{ name=level, layout=%level, literal=null, timestamp=false }], columnMappings=null, immediateFail=false, retry=true, reconnectIntervalMillis=5000, truncateStrings=true], connection=HikariProxyConnection@1535828764 wrapping org.postgresql.jdbc.PgConnection@603942ae, statement=HikariProxyPreparedStatement@1512335087 wrapping insert into logs2 () values ('INFO'), reconnector=null, isBatchSupported=true, columnMetaData={}]
无效 SQL INSERT 语句有问题:
sqlStatement=insert into logs2 () values (?),
问题:您知道为什么 log4J 不能正确/完整地编写命令吗?我的代码有什么问题?
这是 Log4j2 中的错误。
我在 IntelliJ 中建立了一个快速项目,添加了 log4j2 2.14 api 和核心 JAR 以及数据库驱动程序 JAR 和 运行 你的代码,我能够重现格式不正确的INSERT
错误消息中的声明。
我使用 IntelliJ 下载 log4j2 源 JAR 并将其附加,然后逐步完成将 INSERT
语句放在一起的代码。将列名添加到 SQL 字符串的方法称为 appendColumnNames
并且在 class JdbcDatabaseManager
中。
它包含以下代码,为清楚起见,我对其进行了缩写:
if (data.columnMappings != null) {
for (final ColumnMapping colMapping : data.columnMappings) {
// append column from colMapping
}
if (data.columnConfigs != null) {
for (final ColumnConfig colConfig : data.columnConfigs) {
// append column from colConfig
}
}
}
在这种情况下,我们可以看到如果 ColumnMapping
是 null
,则不会使用 ColumnConfig
中的列名。这种行为是不正确的:您应该只能指定 ColumnConfig
s。第二个 if
不应嵌套在第一个中。
Log4j2 支持使用 ColumnMapping
s 以及 ColumnConfig
s 来指定要写入日志记录的列 table,因此一种解决方法是改用它们。另一种解决方法是添加行
.setColumnMappings(new ColumnMapping[0])
为了你的建设JdbcAppender
。我对您的代码进行了此更改,Log4j2 生成了正确的 SQL 字符串。