Log4J2 2.11.0 -> Log4J2 2.17.1 업그레이드 - Percona 5.7로의 mariaDB JDBC 드라이버에 대해 appender가 파손됨 - 잘못된 형식의 패킷 - maven - 해결됨
위와 같이 업그레이드하려고 합니다.Log4J 2.11.0에서 2.17.1로 변경하면 실행 시 Log4J 데이터베이스 Appender 설정이 완전히 중단되고 Percona 5.7/MySQL 5.7에 로그 엔트리를 쓰려고 할 때 기본 MariaDB JDBC 드라이버가 중단됩니다.
2.11.0은 정상적으로 동작하고 있으며, 이 앱에서는 매우 오랫동안 사용되고 있습니다.
MariaDB JDBC 드라이버를 통해 Percona 5.7(MySQL 5.7)에 로그인하려고 합니다.
Log4J2의 pom.xml을 에서 변경.
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.11.0</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.11.0</version>
</dependency>
로.
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.17.1</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.17.1</version>
</dependency>
my log4j2.xml (2.11.0에서 정상적으로 동작 - 2.17.1에서 변경해야 합니까?) :
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="INFO">
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} %-5p %c{1} - %m %n" />
</Console>
<File name="MyFile" fileName="my.log" immediateFlush="true" append="true">
<PatternLayout pattern=" %d{yyyy-MM-dd HH:mm:ss.SSS} %-5p %c{1} - %m %n"/>
</File>
<JDBC name="MyDB" tableName="db.log">
<ConnectionFactory class="log4J2.utils.Log4J2GetConnection" method="getDatabaseConnection"/>
<Column name="DATED" isEventTimestamp="true" isUnicode="false"/>
<Column name="LOGGER" pattern="%logger" isUnicode="false"/>
<Column name="LEVEL" pattern="%level" isUnicode="false"/>
<Column name="MESSAGE" pattern="%message" isUnicode="false"/>
<Column name="THROWABLE" pattern="%ex{full}" isUnicode="false" />
</JDBC>
</Appenders>
<Loggers>
<Root level="info">
<AppenderRef ref="Console" />
<!--<AppenderRef ref="MyFile"/>-->
<AppenderRef ref="MyDB"/>
</Root>
</Loggers>
</Configuration>
내 연결 팩토리:
package log4J2.utils;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;
import javax.sql.DataSource;
import org.apache.commons.dbcp.DriverManagerConnectionFactory;
import org.apache.commons.dbcp.PoolableConnectionFactory;
import org.apache.commons.dbcp.PoolingDataSource;
import org.apache.commons.pool.impl.GenericObjectPool;
import AppSettings;
/**
*
* @author sv
*/
public class Log4J2GetConnection {
private static interface Singleton {
final Log4J2GetConnection INSTANCE = new Log4J2GetConnection();
}
private final DataSource dataSource;
private Log4J2GetConnection() {
if (AppSettings.getMySQLDataSource() == null) {
AppSettings.resetMySQLDataSource();
}
Properties properties = new Properties();
properties.setProperty("user", AppSettings.getMysqlUser());
properties.setProperty("password", AppSettings.getMysqlPassword());
String connectionString = "jdbc:mariadb://" + AppSettings.getMysqlServer() + ":" + AppSettings.getMysqlPort() + "/" + AppSettings.getMysqlDatabase();
GenericObjectPool pool = new GenericObjectPool();
DriverManagerConnectionFactory connectionFactory = new DriverManagerConnectionFactory(connectionString, 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();
}
}
재컴파일 완료.
2.17.1에서 로그 엔트리를 작성하려고 할 때마다 다음과 같은 예외가 발생합니다.2.11.0에서는 발생하지 않고 2.17.1에서만 발생합니다.
2022-01-18 10:16:31,243 main ERROR Unable to write to database [JdbcManager{name=MyDB, bufferSize=0, tableName=db.log, columnConfigs=[{ name=DATED, layout=null, literal=null, timestamp=true }, { name=LOGGER, layout=%logger, literal=null, timestamp=false }, { name=LEVEL, layout=%level, literal=null, timestamp=false }, { name=MESSAGE, layout=%message, literal=null, timestamp=false }, { name=THROWABLE, layout=%ex{full}, literal=null, timestamp=false }], columnMappings=[]}] for appender [MyDB]. org.apache.logging.log4j.core.appender.db.DbAppenderLoggingException: Failed to insert record for log event in JDBC manager: java.sql.SQLException: Malformed communication packet. [columnConfigs=[{ name=DATED, layout=null, literal=null, timestamp=true }, { name=LOGGER, layout=%logger, literal=null, timestamp=false }, { name=LEVEL, layout=%level, literal=null, timestamp=false }, { name=MESSAGE, layout=%message, literal=null, timestamp=false }, { name=THROWABLE, layout=%ex{full}, literal=null, timestamp=false }], sqlStatement=insert into asteriskcdrdb.application_log (DATED,LOGGER,LEVEL,MESSAGE,THROWABLE) values (?,?,?,?,?), factoryData=FactoryData [connectionSource=factory{ public static java.sql.Connection log4J2.utils.Log4J2GetConnection.getDatabaseConnection() }, tableName=asteriskcdrdb.application_log, columnConfigs=[{ name=DATED, layout=null, literal=null, timestamp=true }, { name=LOGGER, layout=%logger, literal=null, timestamp=false }, { name=LEVEL, layout=%level, literal=null, timestamp=false }, { name=MESSAGE, layout=%message, literal=null, timestamp=false }, { name=THROWABLE, layout=%ex{full}, literal=null, timestamp=false }], columnMappings=[], immediateFail=false, retry=true, reconnectIntervalMillis=5000, truncateStrings=true], connection=jdbc:mysql://172.16.1.13:3306/asteriskcdrdb, UserName=asteriskcdruser, mariadb-jdbc, statement=sql : 'insert into asteriskcdrdb.application_log (DATED,LOGGER,LEVEL,MESSAGE,THROWABLE) values (?,?,?,?,?)', parameters : ['2022-01-18 10:15:59.319','webServer.WebHost','INFO','1iemp3w272hi - WebHost class - Starting jetty...',''], reconnector=null, isBatchSupported=true, columnMetaData={MESSAGE=ColumnMetaData [schemaName=, catalogName=asteriskcdrdb, tableName=application_log, name=MESSAGE, nameKey=MESSAGE, label=MESSAGE, displaySize=65535, type=12, typeName=VARCHAR, className=java.lang.String, precision=196605, scale=0, isStringType=true], LOGGER=ColumnMetaData [schemaName=, catalogName=asteriskcdrdb, tableName=application_log, name=LOGGER, nameKey=LOGGER, label=LOGGER, displaySize=255, type=12, typeName=VARCHAR, className=java.lang.String, precision=765, scale=0, isStringType=true], DATED=ColumnMetaData [schemaName=, catalogName=asteriskcdrdb, tableName=application_log, name=DATED, nameKey=DATED, label=DATED, displaySize=19, type=93, typeName=DATETIME, className=java.sql.Timestamp, precision=19, scale=0, isStringType=false], LEVEL=ColumnMetaData [schemaName=, catalogName=asteriskcdrdb, tableName=application_log, name=LEVEL, nameKey=LEVEL, label=LEVEL, displaySize=10, type=12, typeName=VARCHAR, className=java.lang.String, precision=30, scale=0, isStringType=true], THROWABLE=ColumnMetaData [schemaName=, catalogName=asteriskcdrdb, tableName=application_log, name=THROWABLE, nameKey=THROWABLE, label=THROWABLE, displaySize=65535, type=12, typeName=VARCHAR, className=java.lang.String, precision=196605, scale=0, isStringType=true]}]
at org.apache.logging.log4j.core.appender.db.jdbc.JdbcDatabaseManager.writeInternal(JdbcDatabaseManager.java:871)
at org.apache.logging.log4j.core.appender.db.jdbc.JdbcDatabaseManager.writeThrough(JdbcDatabaseManager.java:898)
at org.apache.logging.log4j.core.appender.db.AbstractDatabaseManager.write(AbstractDatabaseManager.java:264)
at org.apache.logging.log4j.core.appender.db.AbstractDatabaseAppender.append(AbstractDatabaseAppender.java:110)
at org.apache.logging.log4j.core.config.AppenderControl.tryCallAppender(AppenderControl.java:161)
at org.apache.logging.log4j.core.config.AppenderControl.callAppender0(AppenderControl.java:134)
at org.apache.logging.log4j.core.config.AppenderControl.callAppenderPreventRecursion(AppenderControl.java:125)
at org.apache.logging.log4j.core.config.AppenderControl.callAppender(AppenderControl.java:89)
at org.apache.logging.log4j.core.config.LoggerConfig.callAppenders(LoggerConfig.java:542)
at org.apache.logging.log4j.core.config.LoggerConfig.processLogEvent(LoggerConfig.java:500)
at org.apache.logging.log4j.core.config.LoggerConfig.log(LoggerConfig.java:483)
at org.apache.logging.log4j.core.config.LoggerConfig.log(LoggerConfig.java:417)
at org.apache.logging.log4j.core.config.AwaitCompletionReliabilityStrategy.log(AwaitCompletionReliabilityStrategy.java:82)
at org.apache.logging.log4j.core.Logger.log(Logger.java:161)
at org.apache.logging.log4j.spi.AbstractLogger.tryLogMessage(AbstractLogger.java:2205)
at org.apache.logging.log4j.spi.AbstractLogger.logMessageTrackRecursion(AbstractLogger.java:2159)
at org.apache.logging.log4j.spi.AbstractLogger.logMessageSafely(AbstractLogger.java:2142)
at org.apache.logging.log4j.spi.AbstractLogger.logMessage(AbstractLogger.java:2017)
at org.apache.logging.log4j.spi.AbstractLogger.logIfEnabled(AbstractLogger.java:1983)
at org.apache.logging.log4j.spi.AbstractLogger.info(AbstractLogger.java:1320)
at webServer.WebHost.<init>(WebHost.java:58)
at App.main(App.java:255)
Caused by: java.sql.SQLException: Malformed communication packet.
at org.mariadb.jdbc.internal.SQLExceptionMapper.get(SQLExceptionMapper.java:149)
at org.mariadb.jdbc.internal.SQLExceptionMapper.throwException(SQLExceptionMapper.java:106)
at org.mariadb.jdbc.MySQLStatement.executeQueryEpilog(MySQLStatement.java:268)
at org.mariadb.jdbc.MySQLStatement.execute(MySQLStatement.java:296)
at org.mariadb.jdbc.MySQLStatement.executeUpdate(MySQLStatement.java:325)
at org.mariadb.jdbc.MySQLPreparedStatement.executeUpdate(MySQLPreparedStatement.java:159)
at org.apache.commons.dbcp.DelegatingPreparedStatement.executeUpdate(DelegatingPreparedStatement.java:105)
at org.apache.commons.dbcp.DelegatingPreparedStatement.executeUpdate(DelegatingPreparedStatement.java:105)
at org.apache.logging.log4j.core.appender.db.jdbc.JdbcDatabaseManager.writeInternal(JdbcDatabaseManager.java:862)
... 21 more
Caused by: org.mariadb.jdbc.internal.common.QueryException: Malformed communication packet.
at org.mariadb.jdbc.internal.mysql.MySQLProtocol.getResult(MySQLProtocol.java:982)
at org.mariadb.jdbc.internal.mysql.MySQLProtocol.executeQuery(MySQLProtocol.java:1042)
at org.mariadb.jdbc.MySQLStatement.execute(MySQLStatement.java:289)
... 26 more
my pom.xml의 My MariaDB JDBC 아티팩트:
<dependency>
<groupId>org.mariadb.jdbc</groupId>
<artifactId>mariadb-java-client</artifactId>
<version>1.1.8</version>
</dependency>
예: Percona 5.7에서 Log4J 버전 2.17.1에 의한 모든 로깅 시도가 실패하고 MariaDB JDBC 드라이버에 오류가 표시됨
org.apache.logging.log4j.core.appender.db.DbAppenderLoggingException: Failed to insert record for log event in JDBC manager: java.sql.SQLException: Malformed communication packet.
pom.xml에서 Log4J 2.11.0으로 다시 전환하면 MariaDB JDBC 드라이버에서 Percona 5.7로 출력된 통신 패킷은 "부정형"으로 간주되지 않습니다.
어떤 이유로 Log4J 2.17.1은 MariaDB JDBC 드라이버 1.1.8에 영향을 미치고 있으며, Percona 5.7 인스턴스가 JDBC 드라이버로부터 수신한 모든 SQL 통신 패킷을 거부합니다(해당 SQL 삽입 쿼리가 Log4J 2.17.1...).젠장
SQL 쿼리의 원본이 Log4J 2.17.1이 아닌 2.11.0인 경우 통신 패키지는 Percona 5.7에 따라 잘못된 형식이 아니며 Log4J 2.11.0에서 MariaDB JDBC 드라이버를 통해 전송된 로그 삽입 쿼리를 정상적으로 실행합니다.
이 문제를 해결하는 방법에 대한 조언이 있습니까?
감사합니다!
스테판
참고로 Log4J 취약성은 2.12.0부터 시작됩니다.
위의 게시물에 대한 해결책은 먼저 MariaDB JDBC Java 클라이언트를 현재 안정적인 버전으로 업데이트하는 것입니다.Maven의 pom.xml에서 다음을 수행합니다.
<dependency>
<groupId>org.mariadb.jdbc</groupId>
<artifactId>mariadb-java-client</artifactId>
<!--<version>1.1.8</version>-->
<version>2.7.4</version>
</dependency>
MariaDB-java-client의 2.7.4는 2022-01-18 현재 안정적입니다.
그런 다음 commons-dbcp 버전 1.4를 추가하여 연결 팩토리 코드가 올바르게 작동하도록 합니다.pom.xml:
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>1.4</version>
<type>jar</type>
</dependency>
마지막으로 log4j 2.11.0을 2.17.1로 설정합니다.pom.xml:
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<!--<version>2.11.0</version>-->
<version>2.17.1</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<!--<version>2.11.0</version>-->
<version>2.17.1</version>
</dependency>
상기의 조작 후에, 다음의 경우입니다.
db.DbAppenderLoggingException: Failed to insert record for log event in JDBC manager: java.sql.SQLException: Malformed communication packet.
이제 Log4J 2.17.1이 MariaDb Java 클라이언트 2.7.4를 통해 Commons-dbcp 1.4를 사용하여 Percona(MySQL) 5.7에 정상적으로 로깅되어 위의 Log4J 접속 팩토리 코드가 동작하게 되었습니다.
--
편집: 다음은 DBCP1 대신 Apache DBCP2를 사용하여 MariaDB Java 클라이언트 2.7.4를 통해 Log4J2를 Percona 5.7에 연결하기 위한 대체 연결 팩토리 클래스입니다.
package verishare.log4J2.utils;
import java.sql.Connection;
import java.sql.SQLException;
import javax.sql.DataSource;
import org.apache.commons.dbcp2.PoolableConnection;
import org.apache.commons.pool2.ObjectPool;
import AppSettings;
/**
*
* @author sv
*/
public class Log4J2GetConnection {
private static interface Singleton {
final Log4J2GetConnection INSTANCE = new Log4J2GetConnection();
}
private final DataSource dataSource;
private Log4J2GetConnection() {
if (AppSettings.getMySQLDataSource() == null) {
AppSettings.resetMySQLDataSource();
}
String connectionString = "jdbc:mariadb://" + AppSettings.getMysqlServer() + ":" + AppSettings.getMysqlPort() + "/" + AppSettings.getMysqlDatabase();
org.apache.commons.dbcp2.PoolingDataSource<PoolableConnection> workDataSource = null;
try {
org.apache.commons.dbcp2.ConnectionFactory factory = new org.apache.commons.dbcp2.DriverManagerConnectionFactory(connectionString,
AppSettings.getMysqlUser(), AppSettings.getMysqlPassword());
org.apache.commons.dbcp2.PoolableConnectionFactory poolFactory = new org.apache.commons.dbcp2.PoolableConnectionFactory(factory, null);
ObjectPool<PoolableConnection> connectionPool = new org.apache.commons.pool2.impl.GenericObjectPool<>(poolFactory);
poolFactory.setPool(connectionPool);
workDataSource = new org.apache.commons.dbcp2.PoolingDataSource<>(connectionPool);
} catch (Exception ex) {
System.out.println(("Exception in getPoolForConnection:" + ex.toString()));
} finally {
this.dataSource = workDataSource;
}
}
public static Connection getDatabaseConnection() throws SQLException {
return Singleton.INSTANCE.dataSource.getConnection();
}
}
언급URL : https://stackoverflow.com/questions/70752698/log4j2-2-11-0-log4j2-2-17-1-upgrade-appender-broken-for-mariadb-jdbc-driver
'itsource' 카테고리의 다른 글
Java에서 파일을 다른 위치로 이동하려면 어떻게 해야 합니까? (0) | 2022.12.24 |
---|---|
2개의 인덱스의 "OR"을 더 빠른 솔루션으로 대체(UNION)? (0) | 2022.12.24 |
네이티브 XHR을 프로미스하려면 어떻게 해야 하나요? (0) | 2022.12.24 |
오류 "Microsoft Visual C++ 14.0이 필요합니다(vcvarsall.bat을 찾을 수 없습니다)" (0) | 2022.12.24 |
React JS -JS와 .JSX의 비교 (0) | 2022.12.24 |