Spring-cloud-sleuth: Support for Spring JDBC template

Created on 4 Dec 2015  路  12Comments  路  Source: spring-cloud/spring-cloud-sleuth

Most helpful comment

What would you think about an aspect based approach on JDBCTemplate method invocations? Could name the span something like jdbc:/jdbcTemplateMethodName. While it wouldn't be able to distinguish between two calls, it would be useful for applications where an http call has a small number of db requests attached.

Any thoughts before I spend some time working on this?

All 12 comments

Nothing in progress right now. Contributions would be gratefully accepted.

Possibly we could go down to the driver level (and get support for JPA as well that way) as well. Zipkin (and Brave) already have some MySQL driver support for instance.

I will more look Zipkin and Brave support for Driver or atleast Datasource level.
BTW, off-topic from JDBC support, Sleuth also doesn't provide support for STOMP messages over websockets using Spring websocket. I have written interceptor to provide support in case of STOMP messages and will create Pull Request when I am fully sure it is correctly doing its work.

@dsyer
In recent weeks, I have looked into many JDBC drivers and connection pool libraries, None is supporting elegant way of adding hooks for intercepting database calls. MySQL provide StatementInterceptorV2. MongoDB has some event support but at connection level. Apache Tomcat connectionpool has JDBCInterceptor, not sure if anyone will use Apache Tomcat JDBC pool.

Any pointers/suggestions how to proceed with this or initial support for MySQL and Apache Tomcat JDBC pool is nice to have for now.

Will doing similar to p6spy a nice to have or it is just over kill for tracing db calls?

my2p

StatementInterceptorV2 is tough, iirc, as it needs to be supplied in the
JDBC url. This means it needs to look up static state, if I'm not mistaken.
Here's an example:
https://github.com/openzipkin/brave/blob/master/brave-mysql/src/main/java/com/github/kristofa/brave/mysql/MySQLStatementInterceptor.java

Another choice is to instrument at a higher level, such as JOOQ. Here's an
example of that:
https://github.com/openzipkin/zipkin-java/blob/master/zipkin-java-server/src/main/java/io/zipkin/server/brave/JDBCTracerConfiguration.java

Both of the above are modeled after finagle-mysql, which is a
protocol-level driver
https://github.com/twitter/finagle/blob/develop/finagle-mysql/src/main/scala/com/twitter/finagle/Mysql.scala#L48

All of the above are logging relatively high-level data, such as the type
of statement and whether or not it finished. These are a good start for
latency analysis.

@adriancole Thanks for the pointer. Does that mean instrument most of the libraries will be the solution for JDBC tracing viz. JOOQ, Dalesbred, Spring JDBC etc.(written support for last two though :)) like wrapping up these libraries or connection pools which have this kind of support.

there are tradeoffs to each decision.

Picking integrations explicitly is less magical code, albeit repetitive.
Using JOOQ (or anything with a nice interceptor abstraction), you can write
succinct (usually <100loc) integration. I'll call this the library approach.

Seeking out a single portable solution across all the libraries (and
versions therein) is its own problem space. I'll call this the agent
approach.

For example, pinpoint has a sophisticated JDBC library plugin thing which
other things extend. This is substantially more harder to test and higher
maintenance code, but the end effect is a black-box which drops in
anywhere:
https://github.com/naver/pinpoint/tree/master/bootstrap-core/src/main/java/com/navercorp/pinpoint/bootstrap/plugin/jdbc

I guess we can close this one...

FYI this is hard to hook into (as it deals at JDBC driver level), but might be a way-out

https://github.com/p6spy/p6spy

It has a implementation in Brave folks could take a look at.
https://github.com/openzipkin/brave/tree/master/brave-p6spy

What would you think about an aspect based approach on JDBCTemplate method invocations? Could name the span something like jdbc:/jdbcTemplateMethodName. While it wouldn't be able to distinguish between two calls, it would be useful for applications where an http call has a small number of db requests attached.

Any thoughts before I spend some time working on this?

ok, simplest pass first, ill need to change up the injection strategy but i just dropped this into a sample app:

package sample;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.sleuth.Span;
import org.springframework.cloud.sleuth.Tracer;
import org.springframework.cloud.sleuth.util.SpanNameUtil;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class JdbcTemplateSleuthAspect {
  Tracer tracer;

  @Autowired
  public JdbcTemplateSleuthAspect(Tracer tracer) {
    this.tracer = tracer;
  }

  @Around("execution (* org.springframework.jdbc.core.JdbcTemplate.*(..))")
  public Object traceJdbcCall(final ProceedingJoinPoint pjp) throws Throwable {
    String spanName = SpanNameUtil.toLowerHyphen(pjp.getSignature().getName());
    Span span = this.tracer.createSpan("jdbc:/" + spanName);
    try {
      return pjp.proceed();
    }
    finally {
      this.tracer.close(span);
    }
  }
}

@jmcshane , can you please tell me how you wired Tracer, we are planning to implement DT (Distributed Tracing) for Non boot ( Spring MVC) application. trying for help on how to ingest Tracer and invoke sleuth framework.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

tony-clarke-amdocs picture tony-clarke-amdocs  路  21Comments

msmsimondean picture msmsimondean  路  19Comments

FranPregernik picture FranPregernik  路  23Comments

purple52 picture purple52  路  24Comments

elgohr picture elgohr  路  21Comments