Skip to content

Commit fec7eac

Browse files
committed
Apache DBCP2: Add a span when waiting on the pool
1 parent daa7de1 commit fec7eac

10 files changed

+375
-15
lines changed

dd-java-agent/instrumentation/jdbc/build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ dependencies {
2727
testImplementation group: 'com.h2database', name: 'h2', version: '[1.3.168,1.3.169]'// first jdk 1.6 compatible
2828
testImplementation group: 'org.apache.derby', name: 'derby', version: '10.6.1.0'
2929
testImplementation group: 'org.hsqldb', name: 'hsqldb', version: '2.0.0'
30+
testImplementation group: 'org.apache.commons', name: 'commons-dbcp2', version: '2.10.0'
3031

3132
testImplementation group: 'org.apache.tomcat', name: 'tomcat-jdbc', version: '7.0.19'
3233
// tomcat needs this to run
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
package datadog.trace.instrumentation.jdbc;
2+
3+
import static datadog.trace.agent.tooling.bytebuddy.matcher.NameMatchers.named;
4+
import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.startSpan;
5+
import static net.bytebuddy.matcher.ElementMatchers.takesArguments;
6+
7+
import com.google.auto.service.AutoService;
8+
import datadog.trace.agent.tooling.Instrumenter;
9+
import datadog.trace.agent.tooling.InstrumenterModule;
10+
import datadog.trace.bootstrap.CallDepthThreadLocalMap;
11+
import datadog.trace.bootstrap.instrumentation.api.AgentSpan;
12+
import net.bytebuddy.asm.Advice;
13+
14+
@AutoService(InstrumenterModule.class)
15+
public final class Dbcp2LinkedBlockingDequeInstrumentation extends InstrumenterModule.Tracing
16+
implements Instrumenter.ForKnownTypes, Instrumenter.HasMethodAdvice {
17+
18+
public Dbcp2LinkedBlockingDequeInstrumentation() {
19+
super("jdbc-datasource");
20+
}
21+
22+
@Override
23+
public String[] knownMatchingTypes() {
24+
return new String[] {
25+
"org.apache.commons.pool2.impl.LinkedBlockingDeque", // standalone
26+
"org.apache.tomcat.dbcp.pool2.impl.LinkedBlockingDeque" // bundled with Tomcat
27+
};
28+
}
29+
30+
@Override
31+
public void methodAdvice(MethodTransformer transformer) {
32+
transformer.applyAdvice(
33+
named("pollFirst").and(takesArguments(1)),
34+
Dbcp2LinkedBlockingDequeInstrumentation.class.getName() + "$PollFirstAdvice");
35+
}
36+
37+
public static class PollFirstAdvice {
38+
private static final String POOL_WAITING = "pool.waiting";
39+
40+
@Advice.OnMethodEnter(suppress = Throwable.class)
41+
public static AgentSpan onEnter() {
42+
if (CallDepthThreadLocalMap.getCallDepth(Dbcp2LinkedBlockingDequeInstrumentation.class) > 0) {
43+
return startSpan("dbcp2", POOL_WAITING);
44+
} else {
45+
return null;
46+
}
47+
}
48+
49+
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
50+
public static void onExit(@Advice.Enter final AgentSpan span) {
51+
if (span != null) {
52+
span.finish();
53+
}
54+
}
55+
}
56+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package datadog.trace.instrumentation.jdbc;
2+
3+
import static datadog.trace.agent.tooling.bytebuddy.matcher.NameMatchers.named;
4+
5+
import com.google.auto.service.AutoService;
6+
import datadog.trace.agent.tooling.Instrumenter;
7+
import datadog.trace.agent.tooling.InstrumenterModule;
8+
import datadog.trace.bootstrap.CallDepthThreadLocalMap;
9+
import net.bytebuddy.asm.Advice;
10+
11+
@AutoService(InstrumenterModule.class)
12+
public final class Dbcp2ManagedConnectionInstrumentation extends InstrumenterModule.Tracing
13+
implements Instrumenter.ForKnownTypes, Instrumenter.HasMethodAdvice {
14+
15+
public Dbcp2ManagedConnectionInstrumentation() {
16+
super("jdbc-datasource");
17+
}
18+
19+
@Override
20+
public String[] knownMatchingTypes() {
21+
return new String[] {
22+
"org.apache.commons.dbcp2.managed.ManagedConnection", // standalone
23+
"org.apache.tomcat.dbcp.dbcp2.managed.ManagedConnection" // bundled with Tomcat
24+
};
25+
}
26+
27+
@Override
28+
public void methodAdvice(MethodTransformer transformer) {
29+
transformer.applyAdvice(
30+
named("updateTransactionStatus"),
31+
Dbcp2ManagedConnectionInstrumentation.class.getName() + "$UpdateTransactionStatusAdvice");
32+
}
33+
34+
public static class UpdateTransactionStatusAdvice {
35+
@Advice.OnMethodEnter(suppress = Throwable.class)
36+
public static void onEnter() {
37+
CallDepthThreadLocalMap.incrementCallDepth(Dbcp2LinkedBlockingDequeInstrumentation.class);
38+
}
39+
40+
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
41+
public static void onExit() {
42+
CallDepthThreadLocalMap.decrementCallDepth(Dbcp2LinkedBlockingDequeInstrumentation.class);
43+
}
44+
}
45+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package datadog.trace.instrumentation.jdbc;
2+
3+
import static datadog.trace.agent.tooling.bytebuddy.matcher.NameMatchers.named;
4+
5+
import com.google.auto.service.AutoService;
6+
import datadog.trace.agent.tooling.Instrumenter;
7+
import datadog.trace.agent.tooling.InstrumenterModule;
8+
import datadog.trace.bootstrap.CallDepthThreadLocalMap;
9+
import net.bytebuddy.asm.Advice;
10+
11+
@AutoService(InstrumenterModule.class)
12+
public final class Dbcp2PerUserPoolDataSourceInstrumentation extends InstrumenterModule.Tracing
13+
implements Instrumenter.ForKnownTypes, Instrumenter.HasMethodAdvice {
14+
15+
public Dbcp2PerUserPoolDataSourceInstrumentation() {
16+
super("jdbc-datasource");
17+
}
18+
19+
@Override
20+
public String[] knownMatchingTypes() {
21+
return new String[] {
22+
"org.apache.commons.dbcp2.datasources.PerUserPoolDataSource", // standalone
23+
"org.apache.tomcat.dbcp.dbcp2.datasources.PerUserPoolDataSource" // bundled with Tomcat
24+
};
25+
}
26+
27+
@Override
28+
public void methodAdvice(MethodTransformer transformer) {
29+
transformer.applyAdvice(
30+
named("getPooledConnectionAndInfo"),
31+
Dbcp2PerUserPoolDataSourceInstrumentation.class.getName()
32+
+ "$GetPooledConnectionAndInfoAdvice");
33+
}
34+
35+
public static class GetPooledConnectionAndInfoAdvice {
36+
@Advice.OnMethodEnter(suppress = Throwable.class)
37+
public static void onEnter() {
38+
CallDepthThreadLocalMap.incrementCallDepth(Dbcp2LinkedBlockingDequeInstrumentation.class);
39+
}
40+
41+
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
42+
public static void onExit() {
43+
CallDepthThreadLocalMap.decrementCallDepth(Dbcp2LinkedBlockingDequeInstrumentation.class);
44+
}
45+
}
46+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package datadog.trace.instrumentation.jdbc;
2+
3+
import static datadog.trace.agent.tooling.bytebuddy.matcher.NameMatchers.named;
4+
5+
import com.google.auto.service.AutoService;
6+
import datadog.trace.agent.tooling.Instrumenter;
7+
import datadog.trace.agent.tooling.InstrumenterModule;
8+
import datadog.trace.bootstrap.CallDepthThreadLocalMap;
9+
import net.bytebuddy.asm.Advice;
10+
11+
@AutoService(InstrumenterModule.class)
12+
public final class Dbcp2PoolingDataSourceInstrumentation extends InstrumenterModule.Tracing
13+
implements Instrumenter.ForKnownTypes, Instrumenter.HasMethodAdvice {
14+
15+
public Dbcp2PoolingDataSourceInstrumentation() {
16+
super("jdbc-datasource");
17+
}
18+
19+
@Override
20+
public String[] knownMatchingTypes() {
21+
return new String[] {
22+
"org.apache.commons.dbcp2.PoolingDataSource", // standalone
23+
"org.apache.tomcat.dbcp.dbcp2.PoolingDataSource" // bundled with Tomcat
24+
};
25+
}
26+
27+
@Override
28+
public void methodAdvice(MethodTransformer transformer) {
29+
transformer.applyAdvice(
30+
named("getConnection"),
31+
Dbcp2PoolingDataSourceInstrumentation.class.getName() + "$GetConnectionAdvice");
32+
}
33+
34+
public static class GetConnectionAdvice {
35+
@Advice.OnMethodEnter(suppress = Throwable.class)
36+
public static void onEnter() {
37+
CallDepthThreadLocalMap.incrementCallDepth(Dbcp2LinkedBlockingDequeInstrumentation.class);
38+
}
39+
40+
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
41+
public static void onExit() {
42+
CallDepthThreadLocalMap.decrementCallDepth(Dbcp2LinkedBlockingDequeInstrumentation.class);
43+
}
44+
}
45+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package datadog.trace.instrumentation.jdbc;
2+
3+
import static datadog.trace.agent.tooling.bytebuddy.matcher.NameMatchers.named;
4+
5+
import com.google.auto.service.AutoService;
6+
import datadog.trace.agent.tooling.Instrumenter;
7+
import datadog.trace.agent.tooling.InstrumenterModule;
8+
import datadog.trace.bootstrap.CallDepthThreadLocalMap;
9+
import net.bytebuddy.asm.Advice;
10+
11+
@AutoService(InstrumenterModule.class)
12+
public final class Dbcp2PoolingDriverInstrumentation extends InstrumenterModule.Tracing
13+
implements Instrumenter.ForKnownTypes, Instrumenter.HasMethodAdvice {
14+
15+
public Dbcp2PoolingDriverInstrumentation() {
16+
super("jdbc-datasource");
17+
}
18+
19+
@Override
20+
public String[] knownMatchingTypes() {
21+
return new String[] {
22+
"org.apache.commons.dbcp2.PoolingDriver", // standalone
23+
"org.apache.tomcat.dbcp.dbcp2.PoolingDriver" // bundled with Tomcat
24+
};
25+
}
26+
27+
@Override
28+
public void methodAdvice(MethodTransformer transformer) {
29+
transformer.applyAdvice(
30+
named("connect"), Dbcp2PoolingDriverInstrumentation.class.getName() + "$ConnectAdvice");
31+
}
32+
33+
public static class ConnectAdvice {
34+
@Advice.OnMethodEnter(suppress = Throwable.class)
35+
public static void onEnter() {
36+
CallDepthThreadLocalMap.incrementCallDepth(Dbcp2LinkedBlockingDequeInstrumentation.class);
37+
}
38+
39+
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
40+
public static void onExit() {
41+
CallDepthThreadLocalMap.decrementCallDepth(Dbcp2LinkedBlockingDequeInstrumentation.class);
42+
}
43+
}
44+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package datadog.trace.instrumentation.jdbc;
2+
3+
import static datadog.trace.agent.tooling.bytebuddy.matcher.NameMatchers.named;
4+
5+
import com.google.auto.service.AutoService;
6+
import datadog.trace.agent.tooling.Instrumenter;
7+
import datadog.trace.agent.tooling.InstrumenterModule;
8+
import datadog.trace.bootstrap.CallDepthThreadLocalMap;
9+
import net.bytebuddy.asm.Advice;
10+
11+
@AutoService(InstrumenterModule.class)
12+
public final class Dbcp2SharedPoolDataSourceInstrumentation extends InstrumenterModule.Tracing
13+
implements Instrumenter.ForKnownTypes, Instrumenter.HasMethodAdvice {
14+
15+
public Dbcp2SharedPoolDataSourceInstrumentation() {
16+
super("jdbc-datasource");
17+
}
18+
19+
@Override
20+
public String[] knownMatchingTypes() {
21+
return new String[] {
22+
"org.apache.commons.dbcp2.datasources.SharePoolDataSource", // standalone
23+
"org.apache.tomcat.dbcp.dbcp2.datasources.SharedPoolPoolDataSource" // bundled with Tomcat
24+
};
25+
}
26+
27+
@Override
28+
public void methodAdvice(MethodTransformer transformer) {
29+
transformer.applyAdvice(
30+
named("getPooledConnectionAndInfo"),
31+
Dbcp2SharedPoolDataSourceInstrumentation.class.getName()
32+
+ "$GetPooledConnectionAndInfoAdvice");
33+
}
34+
35+
public static class GetPooledConnectionAndInfoAdvice {
36+
@Advice.OnMethodEnter(suppress = Throwable.class)
37+
public static void onEnter() {
38+
CallDepthThreadLocalMap.incrementCallDepth(Dbcp2LinkedBlockingDequeInstrumentation.class);
39+
}
40+
41+
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
42+
public static void onExit() {
43+
CallDepthThreadLocalMap.decrementCallDepth(Dbcp2LinkedBlockingDequeInstrumentation.class);
44+
}
45+
}
46+
}

0 commit comments

Comments
 (0)