Set resource name using the route pattern from spring.

This provides a better static resorce name than trying to conjure one out of the original URL.
This commit is contained in:
Tyler Benson 2017-10-30 10:07:58 -07:00
parent cfdbf4c230
commit e8bbc849bb
13 changed files with 112 additions and 9 deletions

View File

@ -18,9 +18,13 @@ whitelistedInstructionClasses += whitelistedBranchClasses += [
dependencies {
compile project(':dd-trace')
compile project(':dd-java-agent:tooling')
compile project(':dd-trace-annotations')
compile group: 'net.bytebuddy', name: 'byte-buddy', version: '1.7.6'
compile project(':dd-java-agent:integrations:spring-web')
compile deps.bytebuddy
compile group: 'org.jboss.byteman', name: 'byteman', version: '3.0.10'
compile group: 'com.google.auto.service', name: 'auto-service', version: '1.0-rc3'

View File

@ -0,0 +1,29 @@
//apply plugin: 'version-scan'
//
//versionScan {
// group = 'org.springframework'
// module = 'spring-webmvc'
// legacyModule = "servlet-api"
// versions = "[3.0,)"
// verifyPresent = [
// "javax.servlet.AsyncEvent" : null,
// "javax.servlet.AsyncListener": null,
// ]
//}
apply from: "${rootDir}/gradle/java.gradle"
dependencies {
compileOnly group: 'org.springframework', name: 'spring-webmvc', version: '4.0.0.RELEASE'
compileOnly group: 'javax.servlet', name: 'javax.servlet-api', version: '3.1.0'
// compileOnly group: 'org.springframework', name: 'spring-webmvc', version: '2.5.6'
// compileOnly group: 'javax.servlet', name: 'servlet-api', version: '2.4'
compile project(':dd-trace')
compile project(':dd-java-agent:tooling')
compile deps.bytebuddy
compile deps.opentracing
compile group: 'com.google.auto.service', name: 'auto-service', version: '1.0-rc3'
}

View File

@ -0,0 +1,59 @@
package dd.inst.springweb;
import static net.bytebuddy.matcher.ElementMatchers.hasSuperType;
import static net.bytebuddy.matcher.ElementMatchers.isInterface;
import static net.bytebuddy.matcher.ElementMatchers.isMethod;
import static net.bytebuddy.matcher.ElementMatchers.isPublic;
import static net.bytebuddy.matcher.ElementMatchers.nameStartsWith;
import static net.bytebuddy.matcher.ElementMatchers.named;
import static net.bytebuddy.matcher.ElementMatchers.not;
import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
import com.datadoghq.trace.DDTags;
import com.google.auto.service.AutoService;
import dd.trace.Instrumenter;
import io.opentracing.ActiveSpan;
import io.opentracing.util.GlobalTracer;
import java.sql.PreparedStatement;
import java.util.Map;
import java.util.WeakHashMap;
import javax.servlet.http.HttpServletRequest;
import net.bytebuddy.agent.builder.AgentBuilder;
import net.bytebuddy.asm.Advice;
import org.springframework.web.servlet.HandlerMapping;
@AutoService(Instrumenter.class)
public final class SpringWebInstrumentation implements Instrumenter {
public static final Map<PreparedStatement, String> preparedStatements = new WeakHashMap<>();
@Override
public AgentBuilder instrument(final AgentBuilder agentBuilder) {
return agentBuilder
.type(
not(isInterface())
.and(hasSuperType(named("org.springframework.web.servlet.HandlerAdapter"))))
.transform(
new AgentBuilder.Transformer.ForAdvice()
.advice(
isMethod()
.and(isPublic())
.and(nameStartsWith("handle"))
.and(takesArgument(0, named("javax.servlet.http.HttpServletRequest"))),
SpringWebAdvice.class.getName()));
}
public static class SpringWebAdvice {
@Advice.OnMethodEnter
public static void nameResource(@Advice.Argument(0) final HttpServletRequest request) {
final ActiveSpan span = GlobalTracer.get().activeSpan();
if (span != null) {
final String method = request.getMethod();
final String bestMatchingPattern =
request.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE).toString();
final String resourceName = method + " " + bestMatchingPattern;
span.setTag(DDTags.RESOURCE_NAME, resourceName);
}
}
}
}

View File

@ -23,7 +23,7 @@ import static net.bytebuddy.matcher.ElementMatchers.isBootstrapClassLoader;
import static net.bytebuddy.matcher.ElementMatchers.nameContains;
import static net.bytebuddy.matcher.ElementMatchers.nameStartsWith;
import com.datadoghq.agent.instrumentation.Instrumenter;
import dd.trace.Instrumenter;
import java.lang.instrument.Instrumentation;
import java.util.ServiceLoader;
import lombok.extern.slf4j.Slf4j;
@ -71,6 +71,9 @@ public class TracingAgent {
.with(AgentBuilder.RedefinitionStrategy.RETRANSFORMATION)
.with(new Listener())
.ignore(nameStartsWith("com.datadoghq.agent.integration"))
.or(nameStartsWith("dd.trace"))
.or(nameStartsWith("dd.inst"))
.or(nameStartsWith("dd.deps"))
.or(nameStartsWith("java."))
.or(nameStartsWith("com.sun."))
.or(nameStartsWith("sun."))

View File

@ -4,9 +4,9 @@ import static net.bytebuddy.matcher.ElementMatchers.declaresMethod;
import static net.bytebuddy.matcher.ElementMatchers.hasSuperType;
import static net.bytebuddy.matcher.ElementMatchers.isAnnotatedWith;
import com.datadoghq.agent.instrumentation.Instrumenter;
import com.datadoghq.trace.Trace;
import com.google.auto.service.AutoService;
import dd.trace.Instrumenter;
import io.opentracing.ActiveSpan;
import io.opentracing.tag.Tags;
import io.opentracing.util.GlobalTracer;

View File

@ -8,8 +8,8 @@ import static net.bytebuddy.matcher.ElementMatchers.not;
import static net.bytebuddy.matcher.ElementMatchers.returns;
import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
import com.datadoghq.agent.instrumentation.Instrumenter;
import com.google.auto.service.AutoService;
import dd.trace.Instrumenter;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.util.Map;

View File

@ -6,8 +6,8 @@ import static net.bytebuddy.matcher.ElementMatchers.named;
import static net.bytebuddy.matcher.ElementMatchers.not;
import static net.bytebuddy.matcher.ElementMatchers.takesArguments;
import com.datadoghq.agent.instrumentation.Instrumenter;
import com.google.auto.service.AutoService;
import dd.trace.Instrumenter;
import java.sql.Connection;
import java.sql.Driver;
import java.util.Map;

View File

@ -8,9 +8,9 @@ import static net.bytebuddy.matcher.ElementMatchers.named;
import static net.bytebuddy.matcher.ElementMatchers.not;
import static net.bytebuddy.matcher.ElementMatchers.takesArguments;
import com.datadoghq.agent.instrumentation.Instrumenter;
import com.datadoghq.trace.DDTags;
import com.google.auto.service.AutoService;
import dd.trace.Instrumenter;
import io.opentracing.ActiveSpan;
import io.opentracing.NoopActiveSpanSource;
import io.opentracing.tag.Tags;

View File

@ -8,9 +8,9 @@ import static net.bytebuddy.matcher.ElementMatchers.named;
import static net.bytebuddy.matcher.ElementMatchers.not;
import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
import com.datadoghq.agent.instrumentation.Instrumenter;
import com.datadoghq.trace.DDTags;
import com.google.auto.service.AutoService;
import dd.trace.Instrumenter;
import io.opentracing.ActiveSpan;
import io.opentracing.NoopActiveSpanSource;
import io.opentracing.tag.Tags;

View File

@ -1,4 +1,4 @@
package com.datadoghq.agent.instrumentation;
package dd.trace;
import net.bytebuddy.agent.builder.AgentBuilder;

View File

@ -0,0 +1,5 @@
apply from: "${rootDir}/gradle/java.gradle"
dependencies {
compile deps.bytebuddy
}

View File

@ -29,7 +29,8 @@ ext {
dependencies.create(group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: version.jackson),
dependencies.create(group: 'com.fasterxml.jackson.dataformat', name: 'jackson-dataformat-yaml', version: version.jackson),
],
bytebuddy : dependencies.create(group: 'net.bytebuddy', name: 'byte-buddy', version: '1.7.6'),
// Testing
spock : dependencies.create("org.spockframework:spock-core:${version.spock}", {
exclude group: "org.codehaus.groovy", module: "groovy-all"

View File

@ -2,6 +2,7 @@ rootProject.name = 'dd-trace-java'
include ':dd-trace'
include ':dd-java-agent'
include ':dd-java-agent:tooling'
include ':dd-java-agent-ittests'
include ':dd-trace-examples:async-tracing'
include ':dd-trace-examples:dropwizard-mongo-client'
@ -21,6 +22,7 @@ include ':dd-java-agent:integrations:mongo-async'
include ':dd-java-agent:integrations:okhttp'
include ':dd-java-agent:integrations:servlet-2'
include ':dd-java-agent:integrations:servlet-3'
include ':dd-java-agent:integrations:spring-web'
def setBuildFile(project) {
project.buildFileName = "${project.name}.gradle"