When developing applications using databases it can be interesing to know what is happening at the JDBC level exactly. In this post a solution and integration into JBoss AS 7.2 is shown.
There are many reasons for that:
- Wanting to know what exactly your ORM framework of choice is doing
- Verifying correct transaction management
- Measuring execution time
To help with that datasource proxies were created that can log those activities you are interested in. After all these projects log4jdbc-log4j2 includes all the features the others had and even extends on them. For the goal of this post the possibility to be configured as a datasource is the most important one. This is needed to integrate with container managed datasources.
The following steps will be necessary to enable JDBC tracing for JBoss AS datssources:
- Add a JBoss AS module for log4jdbc-log4j2
- Add a datasource driver to the JBoss configuration
- Adjust the JDBC URL
- Configure log4jdbc-log4j2 logging in JBoss AS
log4jdbc-log4j2 provides different artifacts for different JDBC versions. For Java 7, which is a good fit for JBoss AS 7.2, the newest jdbc4.1 version should be used (1.15 when writing this article).
Add a JBoss AS module for log4jdbc-log4j2
JBoss AS is built upon JBoss Modules which provides a modular (hierarchical) class loading and execution environment. Each module only sees those modules it has registered dependencies for. Every part of JBoss AS is part of a module, even the deployed applications built a module hierarchy. JBoss AS detects the correct dependencies of these applications to container provided modules and adds them dynamically as described in Implicit module dependencies for deployments.
log4jdbc-log4j2 also needs to be packaged as a module to be usable by other JBoss AS modules. First the module structure needs to be created including the jar file downloaded before:
1 2 |
|
Second a module descriptor is needed at modules/net/sf/log4jdbc/main/module.xml
:
1 2 3 4 5 6 7 8 9 10 11 12 |
|
The lines of this module descriptor need explanation. In the first line the name
of the module is specified so other modules will be able to depend on it. The resources
section lists the java libraries and classes of the module, path is relative to the module.xml. The depdendencies
section lists the modules this module depends on. javax.api
and javax.transaction.api
provide classes needed by JDBC drivers and datasources, so they are added. org.slf4j
is the well known logging facade. log4jdbc-log4j2 normally works with log4j2 as suggested by the name, but can also be configured to use slf4j which is the better option to integrate with JBoss AS. A slf4j compatible logging facade is part of JBoss AS and enables logging cofiguration as part of the container.
Optional dependencies for every other database driver module, that might be used together with the proxy, have to be added for log4jdbc-log4j2 to be able to load and delegate to its classes. Marking them as optional makes them available but allows the module to load if any of them is not available. With that it is possible to add the dependencies even if the driver is not available in some configuration.
For log4jdbc-log4j2 to use slf4j globally it has to be configured by means of a system property. To add this permanently to the JBoss configuration add the following line to the end of bin/standalone.conf
1
|
|
Add a Datasource driver to the JBoss configuration
Before changing the JBoss configuration a backup should be created.
1
|
|
Now the following changes should be done:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
|
- Replace
jdbc:h2
withjdbc:log4jdbc:h2
in the datasource connection url. This should work with every other JDBC URL, of course. Anh2
datasource is part of the JBoss standard configuration which is the reason this is used here. - The datasource driver needs to be replaced with
log4jdbc
which is the name the new datasource driver will be given in the next change.- Normale log4jdbc-log4j2 detects the real driver by the jdbc URL and delegates to it automatically. If that does not work this can be configured in the log4jdbc-log4j2 configuration manually.
- Add a datasource driver named
log4jdbc
. This driver is not more than a registration of the datasoure classnet.sf.log4jdbc.sql.jdbcapi.DataSource
of thenet.sf.log4jdbc
module that was created before.
Example Log Output
The following shows the log output of a JPA2 Hibernate application doing an INSERT and a SELECT having all of the jdbc
loggers activated. Log lines from [stdout]
are the hibernate log lines enabled by the hibernate properties hibernate.show_sql
and hibernate.format_sql
.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 |
|
Adjust the logging configuration
Since the jdbc
loggers provide overlapping information the logging should be configured to match ones needs.
In the following log4jdbc-log4j2 logging is restricted to jdbc.timing
output. For details of the logging configuration see the log4jdbc-log4j2 documentation and especially the section for the slf4j loggers like jdbc.sqlonly
, jdbc.sqltiming
and so forth.
Add the following lines next to the other logger elements in the JBoss configuration:
1 2 3 4 5 6 |
|
Of course you can use the JBoss CLI if you like.
To turn of the JDBC tracing completely and remove the overhead it is enough to set jdbc logging completely to FATAL
by removing the second logger element added before, no need to undo all the rest of the configuration made above.