log4j2 メッセージをリレーショナル データベースに記録したいと考えています。
JDBC アペンダーのドキュメントはこちらです。これらのソースをデータベース接続プロバイダーとして使用できます。
- ConnectionFactory
- 情報源
- DriverManager
しかし、アプリケーション全体で使用するデータソース Bean (com.jolbox.bonecp.BoneCPDataSource) を使用する方法はありますか?
4 つのステップで実行できます (ステップ 2 と 3 は Web アプリの log4j2 構成です)。
ステップ 1: log4j2.xml ファイル (JDBC アペンダーなし) を作成し、WEB-INF フォルダーに配置します。
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="INFO">
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
</Console>
</Appenders>
<Loggers>
<Root level="info">
<AppenderRef ref="Console"/>
</Root>
</Loggers>
</Configuration>
ステップ 2 : log4j2-web-2.x.jar を WEB-INF/lib に追加します。
ここにmavenリポジトリがあります。そこからjarをダウンロードするか、mavenを使用している場合は依存関係をpom.xmlにコピーして貼り付けることができます。
ステップ 3 : サーブレット API のバージョンに応じて web.xml を構成する
詳細については、log4j2のドキュメントを参照してください。サーブレット 2.5 Web アプリで log4j を構成する方法を次に示します。
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
id="WebApp_ID" version="2.5">
<!-- Logg -->
<listener>
<listener-class>org.apache.logging.log4j.web.Log4jServletContextListener</listener-class>
</listener>
<filter>
<filter-name>log4jServletFilter</filter-name>
<filter-class>org.apache.logging.log4j.web.Log4jServletFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>log4jServletFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
<dispatcher>INCLUDE</dispatcher>
<dispatcher>ERROR</dispatcher>
</filter-mapping>
<!-- /Logg -->
<!-- ... -->
</web-app>
ステップ 4: Spring Bean を作成し、DataSource Bean を注入し、@PostConstruct メソッドで JDBC Appender 構成を動的に追加します。
コードサンプルは次のとおりです(log4j 2.1およびspring 3.5でテスト済み)
import java.sql.Connection;
import java.sql.SQLException;
import javax.annotation.PostConstruct;
import javax.sql.DataSource;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.core.Appender;
import org.apache.logging.log4j.core.LoggerContext;
import org.apache.logging.log4j.core.appender.db.jdbc.ColumnConfig;
import org.apache.logging.log4j.core.appender.db.jdbc.ConnectionSource;
import org.apache.logging.log4j.core.appender.db.jdbc.JdbcAppender;
import org.apache.logging.log4j.core.config.AppenderRef;
import org.apache.logging.log4j.core.config.Configuration;
import org.apache.logging.log4j.core.config.LoggerConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class LogUtils{
@Autowired
private DataSource dataSource;
//inner class
class Connect implements ConnectionSource {
private DataSource dsource;
public Connect(DataSource dsource) {
this.dsource = dsource;
}
@Override
public Connection getConnection() throws SQLException {
return this.dsource.getConnection();
}
}
public LogUtils() {
System.out.println("LogUtils");
}
@PostConstruct
private void init(){
System.out.println("init LogUtils");
final LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
final Configuration config = ctx.getConfiguration();
ColumnConfig[] cc = {
ColumnConfig.createColumnConfig(config, "date", null, null, "true", null, null),
ColumnConfig.createColumnConfig(config, "level", "%level", null, null, null, null),
ColumnConfig.createColumnConfig(config, "logger", "%logger", null, null, null, null),
ColumnConfig.createColumnConfig(config, "message", "%message", null, null, null, null),
ColumnConfig.createColumnConfig(config, "throwable", "%ex{short}", null, null, null, null),
ColumnConfig.createColumnConfig(config, "salarie_id", "%X{SALARIE_ID}", null, null, null, null)
} ;
Appender appender = JdbcAppender.createAppender("databaseAppender", "true", null, new Connect(dataSource), "0", "sicdb.bo_log", cc);
appender.start();
config.addAppender(appender);
LoggerConfig loggerConfig = config.getLoggerConfig(LogManager.ROOT_LOGGER_NAME);
loggerConfig.addAppender(appender, null, null);
ctx.updateLoggers();
}
public DataSource getDataSource() {
return dataSource;
}
public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
}
}
** 制限:ドキュメントへのリンク**
アプリケーションでは、実際の構成とは別にロギングをカスタマイズする必要がある場合があります。Log4j ではこれが可能ですが、いくつかの制限があります。
- 構成ファイルが変更されると、構成が再ロードされ、手動での変更は失われます。
- 実行中の構成を変更するには、呼び出されるすべてのメソッド (addAppender および addLogger) を同期する必要があります。そのため、構成をカスタマイズするための推奨されるアプローチは、標準構成クラスの 1 つを拡張し、setup メソッドをオーバーライドして最初に super.setup() を実行し、次にカスタム Appender、Filter、および LoggerConfig を構成に追加してから登録することです。使用する。