Skip to content

Commit 7b1e65f

Browse files
authored
Merge pull request #144 from DataDog/tyler/spring-web
Set resource name using the route pattern from spring.
2 parents cfdbf4c + c2d1eba commit 7b1e65f

File tree

16 files changed

+147
-9
lines changed

16 files changed

+147
-9
lines changed

dd-java-agent-ittests/dd-java-agent-ittests.gradle

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,37 @@ test {
6060
if (project.hasProperty("disableShadowRelocate") && disableShadowRelocate) {
6161
exclude 'com/datadoghq/agent/ShadowPackageRenamingTest.class'
6262
}
63+
64+
useJUnit {
65+
excludeCategories 'com.datadoghq.agent.integration.ExpensiveTest'
66+
}
67+
}
68+
69+
task expensiveTest(type: Test) {
70+
jvmArgs "-Ddd.trace.configurationFile=${project.buildDir}/resources/test/dd-trace.yaml"
71+
jvmArgs "-Ddd.slf4j.simpleLogger.defaultLogLevel=debug"
72+
jvmArgs "-Dorg.slf4j.simpleLogger.defaultLogLevel=debug"
73+
jvmArgs "-Ddd.deps.org.jboss.byteman.verbose=true"
74+
jvmArgs "-Dorg.jboss.byteman.verbose=true"
75+
76+
doFirst {
77+
// Defining here to allow jacoco to be first on the command line.
78+
jvmArgs "-javaagent:${project(':dd-java-agent').tasks.shadowJar.archivePath}"
79+
}
80+
81+
testLogging {
82+
events "started"
83+
}
84+
85+
if (project.hasProperty("disableShadowRelocate") && disableShadowRelocate) {
86+
exclude 'com/datadoghq/agent/ShadowPackageRenamingTest.class'
87+
}
88+
89+
useJUnit {
90+
includeCategories 'com.datadoghq.agent.integration.ExpensiveTest'
91+
}
6392
}
93+
test.finalizedBy expensiveTest
6494

6595
test.dependsOn project(':dd-java-agent').shadowJar
6696

dd-java-agent-ittests/src/test/java/com/datadoghq/agent/integration/CassandraIntegrationTest.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,10 @@
1212
import org.junit.After;
1313
import org.junit.Before;
1414
import org.junit.Test;
15+
import org.junit.experimental.categories.Category;
1516

1617
/** Created by gpolaert on 6/2/17. */
18+
@Category(ExpensiveTest.class)
1719
public class CassandraIntegrationTest {
1820

1921
@Before
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
package com.datadoghq.agent.integration;
2+
3+
interface ExpensiveTest {}

dd-java-agent/dd-java-agent.gradle

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,13 @@ whitelistedInstructionClasses += whitelistedBranchClasses += [
1818

1919
dependencies {
2020
compile project(':dd-trace')
21+
compile project(':dd-java-agent:tooling')
2122
compile project(':dd-trace-annotations')
2223

23-
compile group: 'net.bytebuddy', name: 'byte-buddy', version: '1.7.6'
24+
25+
compile project(':dd-java-agent:integrations:spring-web')
26+
27+
compile deps.bytebuddy
2428
compile group: 'org.jboss.byteman', name: 'byteman', version: '3.0.10'
2529

2630
compile group: 'com.google.auto.service', name: 'auto-service', version: '1.0-rc3'
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
//apply plugin: 'version-scan'
2+
//
3+
//versionScan {
4+
// group = 'org.springframework'
5+
// module = 'spring-webmvc'
6+
// legacyModule = "servlet-api"
7+
// versions = "[3.0,)"
8+
// verifyPresent = [
9+
// "javax.servlet.AsyncEvent" : null,
10+
// "javax.servlet.AsyncListener": null,
11+
// ]
12+
//}
13+
14+
apply from: "${rootDir}/gradle/java.gradle"
15+
16+
dependencies {
17+
compileOnly group: 'org.springframework', name: 'spring-webmvc', version: '4.0.0.RELEASE'
18+
compileOnly group: 'javax.servlet', name: 'javax.servlet-api', version: '3.1.0'
19+
// compileOnly group: 'org.springframework', name: 'spring-webmvc', version: '2.5.6'
20+
// compileOnly group: 'javax.servlet', name: 'servlet-api', version: '2.4'
21+
22+
compile project(':dd-trace')
23+
compile project(':dd-java-agent:tooling')
24+
25+
compile deps.bytebuddy
26+
compile deps.opentracing
27+
28+
compile group: 'com.google.auto.service', name: 'auto-service', version: '1.0-rc3'
29+
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
package dd.inst.springweb;
2+
3+
import static net.bytebuddy.matcher.ElementMatchers.hasSuperType;
4+
import static net.bytebuddy.matcher.ElementMatchers.isInterface;
5+
import static net.bytebuddy.matcher.ElementMatchers.isMethod;
6+
import static net.bytebuddy.matcher.ElementMatchers.isPublic;
7+
import static net.bytebuddy.matcher.ElementMatchers.nameStartsWith;
8+
import static net.bytebuddy.matcher.ElementMatchers.named;
9+
import static net.bytebuddy.matcher.ElementMatchers.not;
10+
import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
11+
12+
import com.datadoghq.trace.DDTags;
13+
import com.google.auto.service.AutoService;
14+
import dd.trace.Instrumenter;
15+
import io.opentracing.ActiveSpan;
16+
import io.opentracing.util.GlobalTracer;
17+
import java.sql.PreparedStatement;
18+
import java.util.Map;
19+
import java.util.WeakHashMap;
20+
import javax.servlet.http.HttpServletRequest;
21+
import net.bytebuddy.agent.builder.AgentBuilder;
22+
import net.bytebuddy.asm.Advice;
23+
import org.springframework.web.servlet.HandlerMapping;
24+
25+
@AutoService(Instrumenter.class)
26+
public final class SpringWebInstrumentation implements Instrumenter {
27+
public static final Map<PreparedStatement, String> preparedStatements = new WeakHashMap<>();
28+
29+
@Override
30+
public AgentBuilder instrument(final AgentBuilder agentBuilder) {
31+
return agentBuilder
32+
.type(
33+
not(isInterface())
34+
.and(hasSuperType(named("org.springframework.web.servlet.HandlerAdapter"))))
35+
.transform(
36+
new AgentBuilder.Transformer.ForAdvice()
37+
.advice(
38+
isMethod()
39+
.and(isPublic())
40+
.and(nameStartsWith("handle"))
41+
.and(takesArgument(0, named("javax.servlet.http.HttpServletRequest"))),
42+
SpringWebAdvice.class.getName()));
43+
}
44+
45+
public static class SpringWebAdvice {
46+
47+
@Advice.OnMethodEnter
48+
public static void nameResource(@Advice.Argument(0) final HttpServletRequest request) {
49+
final ActiveSpan span = GlobalTracer.get().activeSpan();
50+
if (span != null) {
51+
final String method = request.getMethod();
52+
final String bestMatchingPattern =
53+
request.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE).toString();
54+
final String resourceName = method + " " + bestMatchingPattern;
55+
span.setTag(DDTags.RESOURCE_NAME, resourceName);
56+
}
57+
}
58+
}
59+
}

dd-java-agent/src/main/java/com/datadoghq/agent/TracingAgent.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
import static net.bytebuddy.matcher.ElementMatchers.nameContains;
2424
import static net.bytebuddy.matcher.ElementMatchers.nameStartsWith;
2525

26-
import com.datadoghq.agent.instrumentation.Instrumenter;
26+
import dd.trace.Instrumenter;
2727
import java.lang.instrument.Instrumentation;
2828
import java.util.ServiceLoader;
2929
import lombok.extern.slf4j.Slf4j;
@@ -71,6 +71,9 @@ public static void addByteBuddy(final Instrumentation inst) {
7171
.with(AgentBuilder.RedefinitionStrategy.RETRANSFORMATION)
7272
.with(new Listener())
7373
.ignore(nameStartsWith("com.datadoghq.agent.integration"))
74+
.or(nameStartsWith("dd.trace"))
75+
.or(nameStartsWith("dd.inst"))
76+
.or(nameStartsWith("dd.deps"))
7477
.or(nameStartsWith("java."))
7578
.or(nameStartsWith("com.sun."))
7679
.or(nameStartsWith("sun."))

dd-java-agent/src/main/java/com/datadoghq/agent/instrumentation/annotation/TraceAnnotationInstrumentation.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@
44
import static net.bytebuddy.matcher.ElementMatchers.hasSuperType;
55
import static net.bytebuddy.matcher.ElementMatchers.isAnnotatedWith;
66

7-
import com.datadoghq.agent.instrumentation.Instrumenter;
87
import com.datadoghq.trace.Trace;
98
import com.google.auto.service.AutoService;
9+
import dd.trace.Instrumenter;
1010
import io.opentracing.ActiveSpan;
1111
import io.opentracing.tag.Tags;
1212
import io.opentracing.util.GlobalTracer;

dd-java-agent/src/main/java/com/datadoghq/agent/instrumentation/jdbc/ConnectionInstrumentation.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@
88
import static net.bytebuddy.matcher.ElementMatchers.returns;
99
import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
1010

11-
import com.datadoghq.agent.instrumentation.Instrumenter;
1211
import com.google.auto.service.AutoService;
12+
import dd.trace.Instrumenter;
1313
import java.sql.Connection;
1414
import java.sql.PreparedStatement;
1515
import java.util.Map;

dd-java-agent/src/main/java/com/datadoghq/agent/instrumentation/jdbc/DriverInstrumentation.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66
import static net.bytebuddy.matcher.ElementMatchers.not;
77
import static net.bytebuddy.matcher.ElementMatchers.takesArguments;
88

9-
import com.datadoghq.agent.instrumentation.Instrumenter;
109
import com.google.auto.service.AutoService;
10+
import dd.trace.Instrumenter;
1111
import java.sql.Connection;
1212
import java.sql.Driver;
1313
import java.util.Map;

0 commit comments

Comments
 (0)