log4jdbc Documentation

repository·master·Indexed 19 days ago

https://github.com/arthurblake/log4jdbc

A JDBC proxy driver that logs SQL statements, execution timings, and JDBC call details using the SLF4J logging facade. It allows for debugging SQL, identifying slow queries, and troubleshooting connection leaks by wrapping existing JDBC drivers. Supports JDK 1.4 through 1.8+ with specific versions for JDBC 3, 4, and 4.3. Key features include the DriverSpy for automatic driver loading, various logging categories (sqlonly, sqltiming, audit, resultset, connection), and the profsql tool for post-processing timing logs.

Tokens
2.6K
Snippets
7
Records
11
Agent score
18%

What's inside log4jdbc

  1. How log4jdbc works

    master

    log4jdbc is a JDBC proxy driver that intercepts JDBC calls to log SQL statements, timing information, and other metadata. It uses the SLF4J (Simple Logging Facade for Java) system to delegate actual logging to your preferred logging framework (such as Logback, Log4j, or java.util.logging).

    By wrapping your existing JDBC driver, it can automatically inject bind arguments into prepared statements for better readability and provide timing statistics to help identify slow queries.

  2. Choose the correct log4jdbc version for your JDK

    master

    Select your version based on your Java Development Kit (JDK) requirements:

    • JDK 1.8+: Use the latest log4jdbc (1.4+). This provides full JDBC 4.3 support. It can also wrap older JDBC drivers.
    • JDK 1.6 or 1.7: Use the JDBC 4 version (log4jdbc4-1.2.jar).
    • JDK 1.4 or 1.5: Use the JDBC 3 version (log4jdbc3-1.2.jar).
  3. Set up SLF4J logging

    master

    Since log4jdbc uses SLF4J, you must include the SLF4J API and a specific logging implementation in your application's classpath.

    1. Add slf4j-api-2.0.7.jar (or the latest version) to your classpath.
    2. Add the JAR for your chosen logging system (e.g., logback-classic, log4j, etc.).
  4. Use log4jdbc with a Data Source by wrapping Connections

    master

    Since log4jdbc does not currently have direct support for DataSource objects, you can manually wrap the Connection object returned by your data source.

    This approach has the advantage of not requiring you to change your JDBC URL or initialize the net.sf.log4jdbc.DriverSpy driver, as the wrapping happens directly in your application code where connections are obtained.

    // get connection from datasource
    Connection conn = dataSource.getConnection();
    
    // wrap the connection with log4jdbc
    conn = new net.sf.log4jdbc.ConnectionSpy(conn);
    
    // now use Connection as normal (but it will be audited by log4jdbc)
  5. Configure the JDBC URL for log4jdbc

    master

    To activate the proxy, you must prepend jdbc:log4jdbc: to your existing JDBC connection URL.

    Example Transformation:

    • Original: jdbc:derby://localhost:1527//db-derby-10.2.2.0-bin/databases/MyDatabase
    • With log4jdbc: jdbc:log4jdbc:derby://localhost:1527//db-derby-10.2.2.0-bin/databases/MyDatabase
    jdbc:log4jdbc:derby://localhost:1527//db-derby-10.2.2.0-bin/databases/MyDatabase
  6. Configure log4jdbc via System Properties or log4jdbc.properties

    master

    log4jdbc options are controlled via system properties. You can set them using the java -D command line option.

    Alternatively, starting with version 1.2 beta 2, you can define these settings in a file named log4jdbc.properties located in your classpath. If both a properties file and system properties are present, the file takes precedence for any overlapping keys.

    java -Dlog4jdbc.drivers=my.funky.DriverClass -classpath ./classes my.funky.Program
  7. Configure the log4jdbc DriverSpy

    master

    To use log4jdbc, change your application's JDBC driver class to net.sf.log4jdbc.DriverSpy.

    The DriverSpy automatically attempts to load several popular drivers (Oracle, MySQL, PostgreSQL, H2, etc.).

    Using custom or additional drivers

    If your driver is not in the supported list, set the log4jdbc.drivers system property with the driver class name(s):

    -Dlog4jdbc.drivers=<driverclass>[,<driverclass>...]

    To disable the automatic loading of popular drivers and only use those you explicitly specify, set:

    -Dlog4jdbc.auto.load.popular.drivers=false
    -Dlog4jdbc.drivers=com.example.CustomDriver
  8. Filter stack traces with log4jdbc.debug.stack.prefix

    master

    When logging at the DEBUG level, log4jdbc includes the class and line number of the caller. Often, this is a connection pool or ORM class rather than your application code.

    To find the actual source of the SQL, set the log4jdbc.debug.stack.prefix system property to your application's package prefix. log4jdbc will then search the stack trace for the first occurrence of a class matching that prefix.

    Example: If your code is in com.mycompany.myapp, use:

    -Dlog4jdbc.debug.stack.prefix=com.mycompany.myapp
  9. Post-process SQL timing logs with profsql

    master

    log4jdbc includes an experimental tool to post-process SQL timing logs (generated from the jdbc.sqltiming log category). The tool produces profiling reports with statistics and identifies the slowest SQL statements.

    To use it, run the provided scripts from the scripts folder, passing the filename of your timing log as an argument.

    # For Unix/Linux
    ./scripts/profsql.sh path/to/your/sqltiming.log
    
    # For Windows
    profsql.cmd path/to/your/sqltiming.log
  10. Reference the log4jdbc logging categories

    master

    log4jdbc uses 5 primary loggers. If all are set to a level lower than ERROR, log4jdbc remains inactive and imposes no performance penalty. If any are set to ERROR or higher, log4jdbc activates and wraps the connections.

    loggerdescription
    jdbc.sqlonlyLogs only SQL. Prepared statements show bind arguments replaced with actual data.
    jdbc.sqltimingLogs SQL and the execution time statistics.
    jdbc.auditLogs ALL JDBC calls except ResultSets. (Very voluminous)
    jdbc.resultsetLogs all calls, including ResultSet objects. (Extremely voluminous)
    jdbc.connectionLogs connection open/close events and connection numbers. Useful for finding leaks.

    Note: log4jdbc.debug is used for internal debugging of the DriverSpy loading process.

  11. Reference log4jdbc configuration properties

    master

    The following system properties and log4jdbc.properties keys control the behavior of log4jdbc. Use these to customize driver loading, SQL dumping, and performance monitoring.

    | property | default | description |
    |:-------------|:------------|:----------------|
    | log4jdbc.spylogdelegator | net.sf.log4jdbc.Slf4jSpyLogDelegator | Optional class name used to override default spy log delegator. Must implement SpyLogDelegator interface. |
    | log4jdbc.drivers | | Comma-separated list of fully qualified class names for JDBC drivers to wrap. |
    | log4jdbc.auto.load.popular.drivers | true | If false, you must manually specify drivers via `log4jdbc.drivers`. |
    | log4jdbc.debug.stack.prefix | | Package prefix used to search the call stack for the first matching class. Helps avoid showing connection pool classes in debug output. |
    | log4jdbc.sqltiming.warn.threshold | | Milliseconds. SQL taking longer than this is logged at WARN level in `sqltiming` log. |
    | log4jdbc.sqltiming.error.threshold | | Milliseconds. SQL taking longer than this is logged at ERROR level in `sqltiming` log. |
    | log4jdbc.dump.booleanastruefalse | false | If true, dumps booleans as 'true'/'false' instead of 1/0. |
    | log4jdbc.dump.sql.maxlinelength | 90 | Max line length for dumped SQL. Set to 0 to disable line breaking. |
    | log4jdbc.dump.fulldebugstacktrace | false | If true, dumps the full stack trace in debug mode. |
    | log4jdbc.dump.sql.select | true | If false, suppresses 'select' SQL. |
    | log4jdbc.dump.sql.insert | true | If false, suppresses 'insert' SQL. |
    | log4jdbc.dump.sql.update | true | If false, suppresses 'update' SQL. |
    | log4jdbc.dump.sql.delete | true | If false, suppresses 'delete' SQL. |
    | log4jdbc.dump.sql.create | true | If false, suppresses 'create' SQL. |
    | log4jdbc.dump.sql.other | true | If false, suppresses all other SQL types. |
    | log4jdbc.dump.sql.addsemicolon | false | If true, adds a semicolon to the end of dumped SQL. |
    | log4jdbc.statement.warn | false | If true, displays warnings when Statements are used in the log. |
    | log4jdbc.trim.sql | true | If false, prevents trimming of logged SQL. |
    | log4jdbc.trim.sql.extrablanklines | true | If false, prevents collapsing contiguous blank lines in logged SQL. |
    | log4jdbc.suppress.generated.keys.exception | false | If true, ignores exceptions from `Statement.getGeneratedKeys()` (useful for Coldfusion). |