P6spyでSQLを出力させる

P6spyでSQL出力

P6spyでSQLをログに出力させる手順をメモ。

適用するプロジェクトはEclipseWTPを使用したWebアプリ。
サーバーにTomcat5.5。DBはOracleでデータソースを使用して接続。


1) p6spy.jar を WEB-INF/lib に配置
2) spy.properties を下記のように書き換えてクラスパスの通った場所に配置。(今回はsrc直下)

#################################################################
# P6Spy Options File                                            #
# See documentation for detailed instructions                   #
#################################################################

〜 略

# oracle driver
realdriver=oracle.jdbc.OracleDriver

# mysql Connector/J driver
# realdriver=com.mysql.jdbc.Driver

# informix driver
# realdriver=com.informix.jdbc.IfxDriver

# ibm db2 driver
# realdriver=COM.ibm.db2.jdbc.net.DB2Driver

# the mysql open source driver
#realdriver=org.gjt.mm.mysql.Driver

#specifies another driver to use
realdriver2=
#specifies a third driver to use
realdriver3=

〜 略

# sets the date format using Java's SimpleDateFormat routine
dateformat=yyyy/MM/dd HH:mm:ss

〜 略

#specifies the appender to use for logging
#appender=com.p6spy.engine.logging.appender.Log4jLogger
appender=com.p6spy.engine.logging.appender.StdoutLogger
#appender=com.p6spy.engine.logging.appender.FileLogger

3) server.xml のDB接続設定部を書き換え
driverClassName を com.p6spy.engine.spy.P6SpyDriver に変更する。

      <Context docBase="hoge" path="/hoge" reloadable="true" source="org.eclipse.jst.j2ee.server:sbp">
          <Resource auth="Container" driverClassName="com.p6spy.engine.spy.P6SpyDriver" name="jdbc/HOGE" 
             username="foo" password="bar" type="javax.sql.DataSource" url="jdbc:oracle:thin:@192.168.0.1:1521:hoge"/>
      </Context>


として実行するとコンソールにSQLが出力されるようになる。

が、パラメーター適用前のSQLとパラメーターがバインドされた後のSQL両方が出力される上、resultsetまで出力されてしまう。
spy.properiesにexcludecategoriesがあるのに適用されないし。。。
ログフォーマットもLog4j使っていれば変更できそうなんだけど、
使っていないのでソースを直接修正することにする。
ほしいのはパラメーターバインド後のSQLのみなので以下のように修正。

FormattedLogger.java

public abstract class FormattedLogger {
    protected String lastEntry;

    public void logSQL(int connectionId, String now, long elapsed, String category, String prepared, String sql) {
//	String logEntry = now + "|"+ elapsed + "|"+(connectionId==-1 ? "" : String.valueOf(connectionId))+"|"+category+"|"+prepared+"|"+sql;
	String logEntry = "[SQL]" + now + " ["+category+"] "+sql;
	if (!"resultset".equals(category))
		logText(logEntry);
    }

    public abstract void logText(String text);

    // they also all need to have the last entry thing
    public void setLastEntry(String inVar) {
	lastEntry = inVar;
    }

    public String getLastEntry() {
	return lastEntry;
    }
}

出力結果

[SQL]2011/03/08 13:27:58 [statement] SELECT colmun1 FROM atable WHERE no = 'HOGE' AND no_eda = '00'

シンプルになった。