EclipseLinkを利用した、DB2の拡張クライアント情報の設定方法がなかったので、設定方法をブログに載せます。
1.SessionEventAdapterの実装
postAcquireConnectionメソッドは、DBコネクションを取得した後に呼び出されます。preReleaseConnectionメソッドは、DBコネクションを開放するときに呼び出されます。postAcquireConnectionメソッドの24~26行目で、拡張クライアント情報を設定しています。preReleaseConnectionの39~41行目で、拡張クライアント情報を初期化しています。
図 1. SessionEventAdapterの実装例(CustomSessionEventAdapter.java)
package com.wordpress.okulejp.sesstion; import java.sql.Connection; import java.sql.SQLException; import java.util.Map; import java.util.logging.Logger; import javax.faces.context.FacesContext; import javax.servlet.http.HttpServletRequest; import org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor; import org.eclipse.persistence.sessions.SessionEvent; import org.eclipse.persistence.sessions.SessionEventAdapter; public class CustomSessionEventAdapter extends SessionEventAdapter { @Override public void postAcquireConnection(SessionEvent event) { Logger logger = Logger.getLogger(this.getClass().getName()); logger.fine("postAcquireConnection start"); try { FacesContext fc = FacesContext.getCurrentInstance(); Map<String,Object> sessionMap = fc.getExternalContext().getSessionMap(); Connection con= ((DatabaseAccessor) event.getResult()).getConnection(); HttpServletRequest request = (HttpServletRequest) fc.getExternalContext().getRequest(); con.setClientInfo("ApplicationName", (String) sessionMap.get("ApplicationName")); con.setClientInfo("ClientUser", request.getRemoteUser()); con.setClientInfo("ClientHostname", request.getRemoteAddr()); } catch(SQLException ex) { throw new RuntimeException(ex.getMessage()); } logger.fine("postAcquireConnection end"); } @Override public void preReleaseConnection(SessionEvent event) { Logger logger = Logger.getLogger(this.getClass().getName()); logger.fine("preReleaseConnection start"); try { java.sql.Connection con= ((DatabaseAccessor) event.getResult()).getConnection(); con.setClientInfo("ApplicationName", null); con.setClientInfo("ClientUser", null); con.setClientInfo("ClientHostname", null); } catch(SQLException ex) { throw new RuntimeException(ex.getMessage()); } logger.fine("preReleaseConnection end"); } }
2.persistence.xmlの設定
9行目で、実装したSessionEventAdapterを呼び出す設定をしています。
図 2. persistence.xml
<?xml version="1.0" encoding="UTF-8"?> <persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"> <persistence-unit name="ngsPU" transaction-type="JTA"> <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider> <jta-data-source>jdbc/db2</jta-data-source> <exclude-unlisted-classes>false</exclude-unlisted-classes> <properties> <property name="eclipselink.session-event-listener" value="com.wordpress.okulejp.sesstion.CustomSessionEventAdapter"/> <property name="eclipselink.logging.level" value="FINE"/> <property name="eclipselink.logging.level.sql" value="FINE"/> <property name="eclipselink.logging.parameters" value="true"/> </properties> </persistence-unit> </persistence>
3.DB2監査ログ
12~14行目で、CustomSessionEventAdapter.javaで設定した拡張クライアント情報が出力されています。またDB2監査ログの設定しだいで、42~52行目のようにSQLパラメータの出力も可能です。
(※注意10,13行目で、IPアドレスを「*」でマスキングしてありますが、実際に監査ログには値が出力されます。)
図 3. DB2監査ログ出力結果
timestamp=2012-12-19-10.50.32.423000; category=EXECUTE; audit event=STATEMENT; event correlator=55; event status=0; database=MYDB; userid=OKULE; authid=ADMIN; session authid=ADMIN; application id=192.168.*.*.54300.121219013706; application name=db2jcc_application; client userid=test_id; client workstation name=192.168.*.*; client application name=test_appName; package schema=OKULE; package name=SYSSH200; package section=1; local transaction id=0xd7064d0000000000; global transaction id=0x0000000000000000000000000000000000000000; uow id=25; activity id=1; statement invocation id=0; statement nesting level=0; activity type=WRITE_DML; statement text=UPDATE DB2_AUDIT_TEST SET UPDATE_PROGRAM_ID = ? , UPDATE_USER_ID = ? , UPDATE_TIMESTAMP = SYSDATE WHERE ID = ?; statement isolation level=CS; Compilation Environment Description isolation: CS query optimization: 5 min dec div 3: NO degree: 1 SQL rules: DB2 refresh age: +00000000000000.000000 resolution timestamp: 2012-12-19-10.50.30.000000 federated asynchrony: 0 temporal business time: 0000-00-00-00.00.00.000000000000 temporal system time: 0000-00-00-00.00.00.000000000000 schema: OKULE maintained table type: SYSTEM; rows modified=1; rows returned=0; value index = 1 type = VARCHAR data = MA0304; extended indicator = 0; value index = 2 type = VARCHAR data = admin; extended indicator = 0; value index = 3 type = VARCHAR data = k3; extended indicator = 0; local start time=2012-12-19-10.50.30.772729;
4.参考URL
IBM Data Server Driver for JDBC and SQLJ によるクライアント情報プロパティーのサポート
Java Persistence API (JPA) Extensions Reference for EclipseLink session-event-listener
©中條勝徳 and okulejp.com, 2012.