Logging in DBCP

為{幸葍}努か 提交于 2019-12-03 17:35:36

问题


I'm using Apache Commons DBCP. There is a task to track the inner behavior of the DBCP - number of active and idle connections.

I found out that DBCP lacks any such logging at all. Yes, tt is possible to write the code that outputs the status of the BasicDataSource when connection is borrowed from the pool. However there is no way to track the status of the BasicDataSource when connection is returned or closed, because connection object knows nothing about the pool.

Any ideas?


回答1:


I think aspects may be the solution to your quandry. Check out:

  • http://static.springsource.org/spring/docs/current/spring-framework-reference/html/aop.html#aop-introduction-spring-defn
  • http://www.ibm.com/developerworks/java/library/j-ajdt/
  • http://www.eclipse.org/aspectj/doc/released/progguide/index.html

Basically, you can write an aspect or two that will "latch onto" the execution of some methods inside DBCP.

Something like:

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.ProceedingJoinPoint;

@Aspect
public class AroundExample {

  @Around("org.apache.commons.dbcp.PoolingDataSource.getConnection()")
  public Object doBasicPStuff(ProceedingJoinPoint pjp) throws Throwable {
    // write code to do what you want
    final PoolingDataSource ds = (PoolingDataSource) pjp.getThis();
    // log whatever you want

    // let it finish
    Object retVal = pjp.proceed();
    // stop stopwatch
    return retVal;
  }

}

That's just a tiny example. Aspects are really powerful and there's a bunch of different ways to do what you want. The code depends on whether you're using Spring or not, and what exactly you wanna log.

P.S. I haven't tested the above code.




回答2:


DBCP's BasicDataSource contains a few protected methods that actually create the pools and the pool factories. You can subclass it and override those methods to change the behavior; for example, to get a hold of the pool factory or replace it with your own. Once you have that pool, you can then get at the pool state within your code.




回答3:


AOP is the way to go for tracking connection usage from the pool. However, its not very straight forward. You need to do the following:

  1. Create a ConnectionWrapper class that wraps (Decorator pattern) Connection and overrride the close() method to additionally log the connection id, thread id and action 'close'
  2. Intercept the getConnection() method of the datasource.
  3. In that method, log the connection id, thread id and action 'open'
  4. In the same method, decorate the original connection and return your ConnectionWrapper instance

With this setup, you can track both the borrow & return of the connection from/to the pool.




回答4:


If you have access to the DataSource object, you can cast it to BasicDataSource and get the maxIdle and maxActive connections using getNumActive() and getNumIdle() methods.



来源:https://stackoverflow.com/questions/3597219/logging-in-dbcp

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!