Andy
Andy

Reputation: 8908

How do I profile all database activity in a Java Spring/Hibernate application?

I would like to record (almost) all database activity for HTTP requests in a Spring/Hibernate web application using an @Aspect and HandlerInterceptor.

Ideally, I could wrap the @Aspect @Around calls to java.sql.Statement.execute, but since that class is Java and may not use the same class loader, I have to settle for second best.

I have an @Aspect working for calls to JdbcTemplate using the execution(* org.springframework.jdbc.core.JdbcOperations.*(String, ..)) pointcut as explained here, but I also need any database activity invoked by Hibernate.

Does anybody have advice on this? I'm up for any suggestions.

Upvotes: 0

Views: 1082

Answers (2)

Manish Kr. Shukla
Manish Kr. Shukla

Reputation: 4477

Well, if you actually want to profile all the database operations, that are being performed, A simplistic approach would be to go for logging them. Instead of using AOP,i rather suggest you to use a offshelf TPL known as Log4JDBC.

Basically, all you must do is replace your datasource declaration with something like this :

<bean id="dataSource" class="net.sf.log4jdbc.Log4jdbcProxyDataSource" >

Once this is done, you just need to setup your loggers to log relative log messages. The various loggers available with log4Jdbc are

jdbc.sqlonly: Logs only SQL
jdbc.sqltiming: Logs the SQL, post-execution, including timing execution statistics
jdbc.audit: Logs ALL JDBC calls except for ResultSets
jdbc.resultset: all calls to ResultSet objects are logged
jdbc.connection: Logs connection open and close events

For e.g. :

<logger name="jdbc.sqltiming" additivity ="false">             
     <level value="info" />                
 </logger>  
 <logger name="jdbc.resultset" additivity ="false">              
     <level value="error" />        
 </logger>  
 <logger name="jdbc.audit" additivity ="false">
     <level value="error" />        
 </logger>   
 <logger name="jdbc.sqlonly" additivity ="false">              
     <level value="error" />        
 </logger>   
 <logger name="jdbc.resultsettable" additivity ="false">           
     <level value="error" />       
 </logger>           
 <logger name="jdbc.connection" additivity ="false">              
     <level value="error" />        
 </logger>  
 <logger name="jdbc.resultsettable" additivity ="false">            
     <level value="error" />        
 </logger>

More details can be found at the Log4JDBC official Site.

You can find the hibernate specific setup here.

I have successfully implemented it in an application using JdbcTemplate.

Upvotes: 1

kriegaex
kriegaex

Reputation: 67297

My suggestion is to use AspectJ instead of Spring AOP. Its usage from within Spring applications is well documented. You would have then full AOP power, e.g. you can use call() pointcuts and many more instead of only execution(), apply your aspects to classes which are not Spring Beans and so forth.

Upvotes: 1

Related Questions