2010. április 27., kedd

JDBC loggolás jdbcdslog segítségével

Találtam egy remek kis eszközt, amely képes loggolni a JDBC rétegben történt eseményeket. Az SQL-ek mellett eltárolja a lekérdezések eredményeit is, így pontosan képet kaphatunk arról, hogy mi is történik valójában az adatbázis rétegben. Az alkalmzás a jdbcdslog nevet viseli, és a Google Code szolgáltatáson keresztül érhető el nyílt forráskóddal.
Telepítése pár lépésben:
  • Az aktuális verzió beszerezhető az oldalról. Érdemes a "distribution" kiadást letölteni, mert abban van pár függőség is csomagolva.
  • Az Apache Log4j-re épül a logger, így azt is érdemes beszerezni.
  • Mivel a példa-program a legegyszerűbb módozatot mutatja be, így én a jdbcdslog forrását bemásoltam az alkalmazásomba, illetve a slf4j-api-1.5.10.jar, slf4j-log4j12-1.5.10.jar, log4j-1.2.16.jar jar-okat importáltam. (A jdbcdslog forrásában van hiba, azokat érdemes figyelmen kívül hagyni fordításkor!)
A telepítésről bővebben.
Ezután következhet a kapcsolódás megírása. A dolog nyitja abban rejlik, hogy a JDBC kéréseket a jdbcdslog proxyzza át a JDBC providernek, ehhez a kapcsolatot át kell adni a loggernek.
Connection conn = null;
try {
    PropertyConfigurator.configure(Main.class.getResource("log4j.properties").getFile());
    conn = DriverManager.getConnection("jdbc:mysql://localhost/mysql", "root", "password");
    Connection loggingConnection = ConnectionLoggingProxy.wrap(conn);
    Statement statement = loggingConnection.createStatement();
    statement.executeQuery("SELECT * FROM user");
    ResultSet resultSet = statement.getResultSet();
    while (resultSet.next()) {
        System.out.println(resultSet.getString("User"));
    }
    statement.close();
    resultSet.close();
} catch (Exception e) {
} finally {
    if (conn != null) {
        try {
            conn.close();
        } catch (Exception e) {}
    }
}
A Log4j beállítása a log4j.properties fájlban történik, ennek rejtelmeibe nem mélyednék bele, az egy külön bejegyzést igényelne.
#Create logger named A1
log4j.rootLogger=DEBUG, A1
#Write log to test.log over FileAppender
log4j.appender.A1=org.apache.log4j.FileAppender
log4j.appender.A1.File=test.log
log4j.appender.A1.Append=true
#Set the layout to PatternLayout and set pattern
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
log4j.appender.A1.layout.ConversionPattern=%4d{dd MMM yyyy HH:mm:ss,SSS} %-5p - %c: %m\n
Futtatva kódunkat az alábbi eredményt kapjuk. Én egy frissen telepített MySQL adatbázis mysql táblájából olvastam ki a felhasználókat.
root
root
root
A test.log tartalma:
27 Apr 2010 14:36:43,992 DEBUG - org.jdbcdslog.LogUtils: createLogEntry()
27 Apr 2010 14:36:43,993 INFO  - org.jdbcdslog.StatementLogger: java.sql.Statement.executeQuery SELECT * FROM user 110 ms.
27 Apr 2010 14:36:43,999 INFO  - org.jdbcdslog.ResultSetLogger: java.sql.ResultSet.next {'localhost', 'root', '*080C34F746094F116AE54467CF39EA994A0FF57F', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', '', [B@4f80d6, [B@4f80d6, [B@4f80d6, 0, 0, 0, 0}
27 Apr 2010 14:36:44,003 INFO  - org.jdbcdslog.ResultSetLogger: java.sql.ResultSet.next {'linux-brsg', 'root', '', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', '', [B@4f80d6, [B@4f80d6, [B@4f80d6, 0, 0, 0, 0}
27 Apr 2010 14:36:44,004 INFO  - org.jdbcdslog.ResultSetLogger: java.sql.ResultSet.next {'127.0.0.1', 'root', '', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', '', [B@4f80d6, [B@4f80d6, [B@4f80d6, 0, 0, 0, 0}
27 Apr 2010 14:36:44,007 INFO  - org.jdbcdslog.ResultSetLogger: java.sql.ResultSet.next {'localhost', '', '', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', '', [B@4f80d6, [B@4f80d6, [B@4f80d6, 0, 0, 0, 0}
27 Apr 2010 14:36:44,008 INFO  - org.jdbcdslog.ResultSetLogger: java.sql.ResultSet.next {'linux-brsg', '', '', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', '', [B@4f80d6, [B@4f80d6, [B@4f80d6, 0, 0, 0, 0}
Perzisztes réteg használata esetén természetesen az itt vázol megoldás nem kivitelezhető, de szerencsére a fejlesztők két további módszert is építettek az alkalmazásba. Van lehetőség "JDBC Driver" és "JDBC DataSource" proxyzásra is, ezeket választva csak a kapcsolódási URL-t kell módosítani, az alkalmazásunk érintetlen marad.

1 megjegyzés:

  1. Én erre a P6Spy-t használtam, nagyon régi, tök jól működik, és szintén képes teljesen transzparensen jelen lenni úgy, hogy nem kell az alkalmazást bántani, csak az URL-t.

    VálaszTörlés