JavaのWebアプリ開発では定番のSQLログ出力ツール「log4jdbc」ですが、TomcatやApacheを経由しないスタンドアロンなJavaアプリ(バッチ処理やCron実行など)での導入方法に関する情報が意外と少ないため、備忘録としてまとめました。
「発行されたSQL」や「バインド変数の値」、「クエリの実行結果」をコンソールやログファイルに自動出力する設定手順をご紹介します。
背景:System.out.println地獄からの脱却
Cronで動かすバッチプログラムを作成中、以下のような要件がありました。
- Oracle DBにどんなSQLを流したか記録したい
- 取得した値(ResultSet)もログに残したい
これを素直に System.out.println で実装しようとすると、setString のたびにログ出力コードを書いたり、ループ処理で結果を表示したりと、本質的ではないコーディング作業が膨大になってしまいます。
そこで、JDBCドライバーをラップして自動的にログを出力してくれる log4jdbc を導入することにしました。
導入手順
今回はログ出力ライブラリとして SLF4J + Logback を組み合わせる構成で解説します。
1. 必要なライブラリ(JAR)の入手
以下のライブラリをダウンロードし、ビルドパス(Eclipseなら外部JARの追加)に追加します。
※バージョンは環境に合わせて適切なものを選択してください。
- log4jdbc
- ファイル:
log4jdbc3-1.2beta2.jar(JDK1.4系の場合はlog4jdbc3以外を選択) - 入手先:log4jdbc Google Code Archive
- ファイル:
- SLF4J
- ファイル:
slf4j-api-1.6.1.jar - 入手先:SLF4J公式サイト
- ファイル:
- Logback
- ファイル:
logback-classic-0.9.28.jarおよびlogback-core-0.9.28.jar - 入手先:Logback公式サイト
- ファイル:
2. JDBC接続設定の変更
ここが最も重要なポイントです。通常のドライバクラスと接続URLを、log4jdbc経由のものに書き換えます。
変更前(例:Oracleの場合)
Class.forName("oracle.jdbc.driver.OracleDriver");
String url = "jdbc:oracle:thin:@localhost:1521:XE";変更後(log4jdbcを使用)
ドライバクラスを net.sf.log4jdbc.DriverSpy に変更し、URLには jdbc:log4jdbc:oracle... のように log4jdbc: を挿入します。
// ドライバクラスを変更
Class.forName("net.sf.log4jdbc.DriverSpy");
// URLに "log4jdbc:" を挿入する
String url = "jdbc:log4jdbc:oracle:thin:@localhost:1521:XE";3. logback.xml の設定
クラスパスが通っている場所(src直下など)に logback.xml を作成します。 以下は、コンソールとファイルの両方にログを出力する設定例です。
<?xml version="1.0" encoding="UTF-8" ?>
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>[%-5level][%d{yyyy-MM-dd HH:mm:ss}] %class - %msg%n</pattern>
</encoder>
</appender>
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>/logs/webapp.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>/logs/webapp.%d{yyyyMMdd}.log</fileNamePattern>
<maxHistory>30</maxHistory>
</rollingPolicy>
<encoder>
<pattern>[%-5level][%d{yyyy-MM-dd HH:mm:ss}] %class - %msg%n</pattern>
</encoder>
</appender>
<logger name="jdbc.sqltiming" level="INFO" />
<logger name="jdbc.resultsettable" level="INFO" />
<root level="INFO">
<appender-ref ref="STDOUT" />
<appender-ref ref="FILE" />
</root>
</configuration>※ level には debug, info, warn, error などが指定可能です。SQLログは基本的に INFO レベル以上で出力されます。
実行確認
設定が完了したら、Javaアプリケーションを実行してみてください。 SQLが発行されるタイミングで、以下のようなログが自動的に出力されれば成功です。
[INFO ][2026-02-17 10:00:00] jdbc.sqltiming - SELECT * FROM EMP WHERE ID = 100 ...おまけ:任意のログ出力
log4jdbcによるSQLログだけでなく、アプリケーション独自のログを出力したい場合は、各クラスで以下のように定義して使用します。
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class Sample {
// ロガーの定義
private static final Logger log = LoggerFactory.getLogger(Sample.class);
public static void main(String[] args) {
log.debug("It’s debug log"); // logback.xmlのレベル設定に依存
log.info("It’s info log");
log.warn("It’s warn log");
log.error("It’s error log");
}
}