AMG Solution

作業効率UP! Spring + log4jdbcで実行したSQLのログを出力する方法

こんにちは、飯塚です。
 
実行したSQLを再現するために「?」を埋める作業が、面倒くさいことこの上ないと思ったことはありませんか? 特に、条件に日付や時間を含んでいる場合の精神的ストレスは、無視できません。プログラマーとして、こういう面倒な作業の存在とは、闘っていかなくてはなりません!
 
ということで、今回はlog4jdbcで、実行したSQLのログを出力してみようと思います。
 

log4jdbcで、実行したSQLのログを出力

今回やりたいことは、こんな感じです。
 
ログ出力(設定前)

ログ出力(設定後)

log4jdbcというJDBCドライバーを使うことで、実行したSQLをログ出力できます。実行したSQLを即座に確認できれば、開発でも障害対応でも便利なこと間違いなしです。
 

参考ページ

環境

PostgreSQL
9.3

※なお後述しますが、MySQLなど他のDBでも応用できるはずです。

pom.xmlの設定

log4jdbcはログファザードにSLF4jを使っているので、pomにいなければ追加します。

log4jdbc-log4j2の仲間にlog4jdbc-remixがありますが、log4jdbc-remixはもう開発が終了しているので非推奨です。時代はlog4jdbc-log4j2です!
 

persistence.xmlの設定

(変更前)

(変更後)

log4jdbcを使うために、ドライバーとURLの2つだけ変更をします。※database.propertiesでDB接続の設定していても、変更内容は同じです。
 
DriverSpyは、log4jdbc用のドライバーです。JDBC URLに「:log4jdbc」を追加するだけで、有名なドライバー(postgresql.Driver, mysql.jdbc.Driver, OracleDriver…etc)であれば、勝手に読み込んでくれます!
 
ちなみにDriverSpy.javaのソースを見てみると、URLが「jdbc:log4」で始まっていることが確認できた後に、先頭の9文字を切り取っています。(「jdbc:log4jdbc:postgresql」→ 「jdbc:postgresql」)
 

log4jdbc.log4j2.propertiesの設定

以下の内容で src/main/resources/log4jdbc.log4j2.properties を作成します。

Delegatorは和訳すると「委任者」という意味で、デザインパターンの1つです。他のクラスに処理を任せることで、処理を任せる先を意識することなく、何回も使えるという考え方のようです。
 
今回の場合はJDBC SpyのログイベントをSLF4J(Simple Logging Facade for Java) に任せるという意味のようです。
 

logback.xmlの設定

SLF4J からLogback (ログ出力ライブラリ) を使用するための設定です。Lo4j → Logging → Logbackという変遷により、Logbackが現在のスタンダードです。
 
また、ログ出力ライブラリの併用 (Log4j + Logbackなど) は推奨されていないので、Logback一択に切り替えたほうがよさそうです。
 
ログの出力パターンは、実行したSQLと実行時間を出力する「sqltiming」のみDEBUGにしました。大量のログによって処理が遅くなるのを防ぐためです。それぞれの出力パターンの例は補足として下にまとめました。
 

 

ログのレイアウトについて

通常のレイアウトの場合、時間が条件に指定されているSQLは以下のようになります。

この日付と時刻の書式では、SQLをそのまま実行できません。仕方ないので、 上記のlogback.xmlのように正規表現で書式を変換することにしました。

【補足】logback.xml jdbcログ出力例一覧

jdbc.sqlonly

jdbc.sqltiming

jdbc.audit

jdbc.resultset
※単純なSELECT文でも170行ものログが出力されるので、基本的に使わなそうです。

jdbc.resultsettable
※jdbc.sqlonlyやjdbc.sqlonlyと併用しないとログに表示されないようです。

jdbc.connection

hibernate.propertiesの設定

以上の設定だけでもSQLのログは確認できますが、以下のエラーが出力されてしまいます。

まだ実装していないメソッドがあることを教えてくれているだけなので、出力させないようにしたいと思います。
 
以下の内容で src/main/resources/hibernate.properties を作成します。

 

まとめ

以上で設定完了です。これで地道かつ非生産的な作業から解放されました!
 
今回はじめてログ関連の設定を触ってみましたが、INFOレベルであっても読まないログは出力のする必要がない気がしました。もっと必要な情報だけをピンポイントで出力できるようにカスタマイズしたいです。

IIZUKA'S BLOG

飯塚暉の記事

飯塚暉の記事の最新情報をお届けいたします。

SAME CATEGORY BLOG

この記事と同様のカテゴリー記事

マイナビ2019 採用エントリーはじめました。
LOADING