Merge pull request #416 from DataDog/tyler/contributing
Add contributing document and apply formatting.
This commit is contained in:
commit
12e41be258
|
@ -0,0 +1,30 @@
|
|||
### Contributing
|
||||
|
||||
Pull requests for bug fixes are welcome, but before submitting new features or changes to current functionality [open an issue](https://github.com/DataDog/dd-trace-java/issues/new)
|
||||
and discuss your ideas or propose the changes you wish to make. After a resolution is reached a PR can be submitted for review.
|
||||
|
||||
### Code Style
|
||||
|
||||
This project includes a `.editorconfig` file for basic editor settings. This file is supported by most common text editors.
|
||||
|
||||
Java files must be formatted using [google-java-format](https://github.com/google/google-java-format). Please run the following task to ensure files are formatted before committing:
|
||||
|
||||
```shell
|
||||
./gradlew :googleJavaFormat
|
||||
```
|
||||
|
||||
Other source files (Groovy, Scala, etc) should ideally be formatted by Intellij Idea's default formatting, but are not enforced.
|
||||
|
||||
### Intellij Idea
|
||||
|
||||
Suggested plugins and settings:
|
||||
|
||||
* Editor > Code Style > Java/Groovy > Imports
|
||||
* Class count to use import with '*': `10` (some number sufficiently large that is unlikely to matter)
|
||||
* Names count to use static import with '*': `10`
|
||||
* With java use the following import layout (groovy should still use the default) to ensure consistency with google-java-format:
|
||||

|
||||
* [Google Java Format](https://plugins.jetbrains.com/plugin/8527-google-java-format)
|
||||
* [Lombok](https://plugins.jetbrains.com/plugin/6317-lombok-plugin)
|
||||
* [Save Actions](https://plugins.jetbrains.com/plugin/7642-save-actions)
|
||||

|
|
@ -21,11 +21,11 @@ class MuzzlePlugin implements Plugin<Project> {
|
|||
List<URL> userUrls = new ArrayList<>()
|
||||
project.getLogger().info("Creating user classpath for: " + project.getName())
|
||||
for (File f : project.configurations.compileOnly.getFiles()) {
|
||||
project.getLogger().info( '--' + f)
|
||||
project.getLogger().info('--' + f)
|
||||
userUrls.add(f.toURI().toURL())
|
||||
}
|
||||
for (File f : bootstrapProject.sourceSets.main.runtimeClasspath.getFiles()) {
|
||||
project.getLogger().info( '--' + f)
|
||||
project.getLogger().info('--' + f)
|
||||
userUrls.add(f.toURI().toURL())
|
||||
}
|
||||
final ClassLoader userCL = new URLClassLoader(userUrls.toArray(new URL[0]), (ClassLoader) null)
|
||||
|
@ -33,11 +33,11 @@ class MuzzlePlugin implements Plugin<Project> {
|
|||
project.getLogger().info("Creating dd classpath for: " + project.getName())
|
||||
Set<URL> ddUrls = new HashSet<>()
|
||||
for (File f : toolingProject.sourceSets.main.runtimeClasspath.getFiles()) {
|
||||
project.getLogger().info( '--' + f)
|
||||
project.getLogger().info('--' + f)
|
||||
ddUrls.add(f.toURI().toURL())
|
||||
}
|
||||
for(File f : project.sourceSets.main.runtimeClasspath.getFiles()) {
|
||||
project.getLogger().info( '--' + f)
|
||||
for (File f : project.sourceSets.main.runtimeClasspath.getFiles()) {
|
||||
project.getLogger().info('--' + f)
|
||||
ddUrls.add(f.toURI().toURL())
|
||||
}
|
||||
|
||||
|
|
|
@ -9,10 +9,10 @@ import static datadog.trace.agent.test.IntegrationTestUtils.createJarWithClasses
|
|||
class ClassLoadingTest extends Specification {
|
||||
|
||||
/** Assert that we can instrument classloaders which cannot resolve agent advice classes. */
|
||||
def "instrument classloader without agent classes" () {
|
||||
def "instrument classloader without agent classes"() {
|
||||
setup:
|
||||
final URL[] classpath = [createJarWithClasses(ClassToInstrument, Trace)]
|
||||
final URLClassLoader loader = new URLClassLoader(classpath, (ClassLoader)null)
|
||||
final URLClassLoader loader = new URLClassLoader(classpath, (ClassLoader) null)
|
||||
|
||||
when:
|
||||
loader.loadClass("datadog.agent.TracingAgent")
|
||||
|
|
|
@ -54,51 +54,51 @@ class ShadowPackageRenamingTest extends Specification {
|
|||
}
|
||||
|
||||
def "agent jar contains no bootstrap classes"() {
|
||||
setup:
|
||||
final ClassPath agentClasspath = ClassPath.from(IntegrationTestUtils.getAgentClassLoader())
|
||||
setup:
|
||||
final ClassPath agentClasspath = ClassPath.from(IntegrationTestUtils.getAgentClassLoader())
|
||||
|
||||
final ClassPath bootstrapClasspath = ClassPath.from(IntegrationTestUtils.getBootstrapProxy())
|
||||
final Set<String> bootstrapClasses = new HashSet<>()
|
||||
final String[] bootstrapPrefixes = IntegrationTestUtils.getBootstrapPackagePrefixes()
|
||||
final String[] agentPrefixes = IntegrationTestUtils.getAgentPackagePrefixes()
|
||||
final List<String> badBootstrapPrefixes = []
|
||||
final List<String> badAgentPrefixes = []
|
||||
for (ClassPath.ClassInfo info : bootstrapClasspath.getAllClasses()) {
|
||||
bootstrapClasses.add(info.getName())
|
||||
// make sure all bootstrap classes can be loaded from system
|
||||
ClassLoader.getSystemClassLoader().loadClass(info.getName())
|
||||
boolean goodPrefix = false
|
||||
for (int i = 0; i < bootstrapPrefixes.length; ++i) {
|
||||
if (info.getName().startsWith(bootstrapPrefixes[i])) {
|
||||
goodPrefix = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if (!goodPrefix) {
|
||||
badBootstrapPrefixes.add(info.getName())
|
||||
}
|
||||
}
|
||||
final ClassPath bootstrapClasspath = ClassPath.from(IntegrationTestUtils.getBootstrapProxy())
|
||||
final Set<String> bootstrapClasses = new HashSet<>()
|
||||
final String[] bootstrapPrefixes = IntegrationTestUtils.getBootstrapPackagePrefixes()
|
||||
final String[] agentPrefixes = IntegrationTestUtils.getAgentPackagePrefixes()
|
||||
final List<String> badBootstrapPrefixes = []
|
||||
final List<String> badAgentPrefixes = []
|
||||
for (ClassPath.ClassInfo info : bootstrapClasspath.getAllClasses()) {
|
||||
bootstrapClasses.add(info.getName())
|
||||
// make sure all bootstrap classes can be loaded from system
|
||||
ClassLoader.getSystemClassLoader().loadClass(info.getName())
|
||||
boolean goodPrefix = false
|
||||
for (int i = 0; i < bootstrapPrefixes.length; ++i) {
|
||||
if (info.getName().startsWith(bootstrapPrefixes[i])) {
|
||||
goodPrefix = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if (!goodPrefix) {
|
||||
badBootstrapPrefixes.add(info.getName())
|
||||
}
|
||||
}
|
||||
|
||||
final List<ClassPath.ClassInfo> duplicateClassFile = new ArrayList<>()
|
||||
for (ClassPath.ClassInfo classInfo : agentClasspath.getAllClasses()) {
|
||||
if (bootstrapClasses.contains(classInfo.getName())) {
|
||||
duplicateClassFile.add(classInfo)
|
||||
}
|
||||
boolean goodPrefix = false
|
||||
for (int i = 0; i < agentPrefixes.length; ++i) {
|
||||
if (classInfo.getName().startsWith(agentPrefixes[i])) {
|
||||
goodPrefix = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if (!goodPrefix) {
|
||||
badAgentPrefixes.add(classInfo.getName())
|
||||
}
|
||||
}
|
||||
final List<ClassPath.ClassInfo> duplicateClassFile = new ArrayList<>()
|
||||
for (ClassPath.ClassInfo classInfo : agentClasspath.getAllClasses()) {
|
||||
if (bootstrapClasses.contains(classInfo.getName())) {
|
||||
duplicateClassFile.add(classInfo)
|
||||
}
|
||||
boolean goodPrefix = false
|
||||
for (int i = 0; i < agentPrefixes.length; ++i) {
|
||||
if (classInfo.getName().startsWith(agentPrefixes[i])) {
|
||||
goodPrefix = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if (!goodPrefix) {
|
||||
badAgentPrefixes.add(classInfo.getName())
|
||||
}
|
||||
}
|
||||
|
||||
expect:
|
||||
duplicateClassFile == []
|
||||
badBootstrapPrefixes == []
|
||||
badAgentPrefixes == []
|
||||
expect:
|
||||
duplicateClassFile == []
|
||||
badBootstrapPrefixes == []
|
||||
badAgentPrefixes == []
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
package datadog.trace.agent.integration.muzzle
|
||||
|
||||
import datadog.trace.agent.test.IntegrationTestUtils
|
||||
import java.lang.reflect.Field
|
||||
import java.lang.reflect.Method
|
||||
import spock.lang.Specification
|
||||
|
||||
import java.lang.reflect.Field
|
||||
import java.lang.reflect.Method
|
||||
|
||||
class MuzzleBytecodeTransformTest extends Specification {
|
||||
|
||||
|
@ -33,7 +33,7 @@ class MuzzleBytecodeTransformTest extends Specification {
|
|||
if (f.get(instrumenter) == null) {
|
||||
unInitFields.add(instrumenter.getClass())
|
||||
}
|
||||
} catch(NoSuchFieldException | NoSuchMethodException e) {
|
||||
} catch (NoSuchFieldException | NoSuchMethodException e) {
|
||||
unMuzzledClasses.add(instrumenter.getClass())
|
||||
} finally {
|
||||
if (null != f) {
|
||||
|
|
|
@ -5,7 +5,7 @@ plugins {
|
|||
|
||||
apply from: "${rootDir}/gradle/java.gradle"
|
||||
|
||||
excludedClassesConverage += [ 'datadog.trace.bootstrap.*' ]
|
||||
excludedClassesConverage += ['datadog.trace.bootstrap.*']
|
||||
|
||||
dependencies {
|
||||
compile project(':dd-trace-api')
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
apply from: "${rootDir}/gradle/java.gradle"
|
||||
|
||||
excludedClassesConverage += [ 'datadog.trace.agent.tooling.*' ]
|
||||
excludedClassesConverage += ['datadog.trace.agent.tooling.*']
|
||||
|
||||
configurations {
|
||||
// classpath used by the instrumentation muzzle plugin
|
||||
|
|
|
@ -3,7 +3,11 @@ package datadog.trace.agent.tooling;
|
|||
import datadog.trace.bootstrap.DatadogClassLoader;
|
||||
import datadog.trace.bootstrap.PatchLogger;
|
||||
import io.opentracing.util.GlobalTracer;
|
||||
import java.util.*;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.WeakHashMap;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.bytebuddy.matcher.ElementMatcher;
|
||||
|
||||
|
@ -44,7 +48,7 @@ public class ClassLoaderMatcher {
|
|||
private static final Set<String> CLASSLOADER_CLASSES_TO_SKIP;
|
||||
|
||||
static {
|
||||
final Set<String> classesToSkip = new HashSet<String>();
|
||||
final Set<String> classesToSkip = new HashSet<>();
|
||||
classesToSkip.add("org.codehaus.groovy.runtime.callsite.CallSiteClassLoader");
|
||||
classesToSkip.add("sun.reflect.DelegatingClassLoader");
|
||||
classesToSkip.add("jdk.internal.reflect.DelegatingClassLoader");
|
||||
|
@ -55,7 +59,7 @@ public class ClassLoaderMatcher {
|
|||
private SkipClassLoaderMatcher() {}
|
||||
|
||||
@Override
|
||||
public boolean matches(ClassLoader target) {
|
||||
public boolean matches(final ClassLoader target) {
|
||||
if (target == BOOTSTRAP_CLASSLOADER) {
|
||||
// Don't skip bootstrap loader
|
||||
return false;
|
||||
|
@ -63,7 +67,7 @@ public class ClassLoaderMatcher {
|
|||
return shouldSkipClass(target) || shouldSkipInstance(target);
|
||||
}
|
||||
|
||||
private boolean shouldSkipClass(ClassLoader loader) {
|
||||
private boolean shouldSkipClass(final ClassLoader loader) {
|
||||
return CLASSLOADER_CLASSES_TO_SKIP.contains(loader.getClass().getName());
|
||||
}
|
||||
|
||||
|
@ -77,7 +81,7 @@ public class ClassLoaderMatcher {
|
|||
if (null != cached) {
|
||||
return cached.booleanValue();
|
||||
}
|
||||
boolean skip = !delegatesToBootstrap(loader);
|
||||
final boolean skip = !delegatesToBootstrap(loader);
|
||||
if (skip) {
|
||||
log.debug(
|
||||
"skipping classloader instance {} of type {}", loader, loader.getClass().getName());
|
||||
|
@ -87,7 +91,7 @@ public class ClassLoaderMatcher {
|
|||
}
|
||||
}
|
||||
|
||||
private boolean delegatesToBootstrap(ClassLoader loader) {
|
||||
private boolean delegatesToBootstrap(final ClassLoader loader) {
|
||||
boolean delegates = true;
|
||||
if (!loadsExpectedClass(loader, GlobalTracer.class)) {
|
||||
log.debug("loader {} failed to delegate bootstrap opentracing class", loader);
|
||||
|
@ -100,10 +104,10 @@ public class ClassLoaderMatcher {
|
|||
return delegates;
|
||||
}
|
||||
|
||||
private boolean loadsExpectedClass(ClassLoader loader, Class<?> expectedClass) {
|
||||
private boolean loadsExpectedClass(final ClassLoader loader, final Class<?> expectedClass) {
|
||||
try {
|
||||
return loader.loadClass(expectedClass.getName()) == expectedClass;
|
||||
} catch (ClassNotFoundException e) {
|
||||
} catch (final ClassNotFoundException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,7 +12,12 @@ import net.bytebuddy.description.field.FieldList;
|
|||
import net.bytebuddy.description.method.MethodList;
|
||||
import net.bytebuddy.description.type.TypeDescription;
|
||||
import net.bytebuddy.implementation.Implementation;
|
||||
import net.bytebuddy.jar.asm.*;
|
||||
import net.bytebuddy.jar.asm.ClassVisitor;
|
||||
import net.bytebuddy.jar.asm.ClassWriter;
|
||||
import net.bytebuddy.jar.asm.Label;
|
||||
import net.bytebuddy.jar.asm.MethodVisitor;
|
||||
import net.bytebuddy.jar.asm.Opcodes;
|
||||
import net.bytebuddy.jar.asm.Type;
|
||||
import net.bytebuddy.pool.TypePool;
|
||||
|
||||
/** Visit a class and add: a private instrumenationMuzzle field and getter */
|
||||
|
|
|
@ -3,7 +3,10 @@ package datadog.trace.agent.tooling.muzzle;
|
|||
import static datadog.trace.agent.tooling.ClassLoaderMatcher.BOOTSTRAP_CLASSLOADER;
|
||||
|
||||
import datadog.trace.agent.tooling.Utils;
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/** An immutable reference to a jvm class. */
|
||||
public class Reference {
|
||||
|
|
|
@ -3,8 +3,17 @@ package datadog.trace.agent.tooling.muzzle;
|
|||
import datadog.trace.agent.tooling.Utils;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.*;
|
||||
import net.bytebuddy.jar.asm.*;
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Queue;
|
||||
import java.util.Set;
|
||||
import net.bytebuddy.jar.asm.ClassReader;
|
||||
import net.bytebuddy.jar.asm.ClassVisitor;
|
||||
import net.bytebuddy.jar.asm.Label;
|
||||
import net.bytebuddy.jar.asm.MethodVisitor;
|
||||
import net.bytebuddy.jar.asm.Opcodes;
|
||||
|
||||
/** Visit a class and collect all references made by the visited class. */
|
||||
public class ReferenceCreator extends ClassVisitor {
|
||||
|
|
|
@ -3,7 +3,14 @@ package datadog.trace.agent.tooling.muzzle;
|
|||
import static net.bytebuddy.dynamic.loading.ClassLoadingStrategy.BOOTSTRAP_LOADER;
|
||||
|
||||
import datadog.trace.agent.tooling.Utils;
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.WeakHashMap;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/** Matches a set of references against a classloader. */
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
package datadog.trace.agent.test
|
||||
|
||||
import datadog.trace.bootstrap.DatadogClassLoader
|
||||
import datadog.trace.agent.tooling.ClassLoaderMatcher
|
||||
import datadog.trace.bootstrap.DatadogClassLoader
|
||||
import spock.lang.Specification
|
||||
|
||||
|
||||
class ClassLoaderMatcherTest extends Specification {
|
||||
|
||||
def "skip non-delegating classloader"() {
|
||||
|
@ -24,7 +23,7 @@ class ClassLoaderMatcherTest extends Specification {
|
|||
|
||||
def "does not skip empty classloader"() {
|
||||
setup:
|
||||
final ClassLoader emptyLoader = new ClassLoader(){}
|
||||
final ClassLoader emptyLoader = new ClassLoader() {}
|
||||
expect:
|
||||
!ClassLoaderMatcher.skipClassLoader().matches(emptyLoader)
|
||||
}
|
||||
|
@ -37,9 +36,10 @@ class ClassLoaderMatcherTest extends Specification {
|
|||
/*
|
||||
* A URLClassloader which only delegates java.* classes
|
||||
*/
|
||||
|
||||
private static class NonDelegatingClassLoader extends URLClassLoader {
|
||||
NonDelegatingClassLoader() {
|
||||
super(new URL[0], (ClassLoader)null)
|
||||
super(new URL[0], (ClassLoader) null)
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -1,22 +1,20 @@
|
|||
package datadog.trace.agent.test
|
||||
|
||||
import datadog.trace.bootstrap.ExceptionLogger
|
||||
import ch.qos.logback.classic.Level
|
||||
import ch.qos.logback.classic.Logger
|
||||
import ch.qos.logback.core.read.ListAppender
|
||||
import datadog.trace.agent.tooling.ExceptionHandlers
|
||||
import datadog.trace.bootstrap.ExceptionLogger
|
||||
import net.bytebuddy.agent.ByteBuddyAgent
|
||||
import net.bytebuddy.agent.builder.AgentBuilder
|
||||
import net.bytebuddy.dynamic.ClassFileLocator
|
||||
import org.slf4j.LoggerFactory
|
||||
import spock.lang.Shared
|
||||
import spock.lang.Specification
|
||||
|
||||
import static net.bytebuddy.matcher.ElementMatchers.isMethod
|
||||
import static net.bytebuddy.matcher.ElementMatchers.named
|
||||
|
||||
import net.bytebuddy.agent.builder.AgentBuilder
|
||||
import spock.lang.Specification
|
||||
import spock.lang.Shared
|
||||
|
||||
import org.slf4j.LoggerFactory
|
||||
import ch.qos.logback.classic.Logger
|
||||
import ch.qos.logback.core.read.ListAppender
|
||||
import ch.qos.logback.classic.Level
|
||||
|
||||
class ExceptionHandlerTest extends Specification {
|
||||
@Shared
|
||||
ListAppender testAppender = new ListAppender()
|
||||
|
@ -25,7 +23,7 @@ class ExceptionHandlerTest extends Specification {
|
|||
AgentBuilder builder = new AgentBuilder.Default()
|
||||
.disableClassFormatChanges()
|
||||
.with(AgentBuilder.RedefinitionStrategy.RETRANSFORMATION)
|
||||
.type(named(getClass().getName()+'$SomeClass'))
|
||||
.type(named(getClass().getName() + '$SomeClass'))
|
||||
.transform(
|
||||
new AgentBuilder.Transformer.ForAdvice()
|
||||
.with(new AgentBuilder.LocationStrategy.Simple(ClassFileLocator.ForClassLoader.of(BadAdvice.getClassLoader())))
|
||||
|
@ -68,11 +66,11 @@ class ExceptionHandlerTest extends Specification {
|
|||
testAppender.list.get(testAppender.list.size() - 1).getMessage() == "Failed to handle exception in instrumentation"
|
||||
}
|
||||
|
||||
def "exception on non-delegating classloader" () {
|
||||
def "exception on non-delegating classloader"() {
|
||||
setup:
|
||||
int initLogEvents = testAppender.list.size()
|
||||
URL[] classpath = [ SomeClass.getProtectionDomain().getCodeSource().getLocation(),
|
||||
GroovyObject.getProtectionDomain().getCodeSource().getLocation() ]
|
||||
URL[] classpath = [SomeClass.getProtectionDomain().getCodeSource().getLocation(),
|
||||
GroovyObject.getProtectionDomain().getCodeSource().getLocation()]
|
||||
URLClassLoader loader = new URLClassLoader(classpath, (ClassLoader) null)
|
||||
when:
|
||||
loader.loadClass(LoggerFactory.getName())
|
||||
|
|
|
@ -1,9 +1,6 @@
|
|||
package datadog.trace.agent.test
|
||||
|
||||
import datadog.trace.agent.tooling.AgentInstaller
|
||||
|
||||
import static datadog.trace.agent.tooling.ClassLoaderMatcher.BOOTSTRAP_CLASSLOADER
|
||||
|
||||
import datadog.trace.agent.tooling.HelperInjector
|
||||
import datadog.trace.agent.tooling.Utils
|
||||
import net.bytebuddy.agent.ByteBuddyAgent
|
||||
|
@ -11,6 +8,8 @@ import spock.lang.Specification
|
|||
|
||||
import java.lang.reflect.Method
|
||||
|
||||
import static datadog.trace.agent.tooling.ClassLoaderMatcher.BOOTSTRAP_CLASSLOADER
|
||||
|
||||
class HelperInjectionTest extends Specification {
|
||||
|
||||
def "helpers injected to non-delegating classloader"() {
|
||||
|
|
|
@ -2,7 +2,7 @@ dependencies {
|
|||
compile project(':dd-trace-api')
|
||||
compile project(':dd-java-agent:benchmark-integration')
|
||||
compile deps.opentracing
|
||||
|
||||
|
||||
compile group: 'org.eclipse.jetty', name: 'jetty-server', version: '9.4.1.v20170120'
|
||||
compile group: 'org.eclipse.jetty', name: 'jetty-servlet', version: '9.4.1.v20170120'
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@ jacocoTestReport.dependsOn ':dd-java-agent-ittests:test'
|
|||
* Note jarname must end in .zip, or its classes will be on the classpath of
|
||||
* the dd-java-agent jar.
|
||||
*/
|
||||
|
||||
def includeShadowJar(subproject, jarname) {
|
||||
def agent_project = project
|
||||
subproject.afterEvaluate {
|
||||
|
|
|
@ -1,20 +1,20 @@
|
|||
import akka.NotUsed
|
||||
import akka.stream.javadsl.Source
|
||||
import akka.stream.testkit.TestSubscriber.Probe
|
||||
import akka.stream.testkit.javadsl.TestSink
|
||||
import datadog.trace.agent.test.AgentTestRunner
|
||||
import datadog.trace.api.DDSpanTypes
|
||||
import datadog.trace.api.DDTags
|
||||
import io.opentracing.tag.Tags
|
||||
import net.bytebuddy.utility.JavaModule
|
||||
|
||||
import datadog.trace.agent.test.AgentTestRunner
|
||||
import play.inject.guice.GuiceApplicationBuilder
|
||||
import spock.lang.Shared
|
||||
|
||||
import akka.stream.testkit.TestSubscriber.Probe
|
||||
|
||||
import java.util.function.Function
|
||||
|
||||
import static com.lightbend.lagom.javadsl.testkit.ServiceTest.*
|
||||
import static com.lightbend.lagom.javadsl.testkit.ServiceTest.TestServer
|
||||
import static com.lightbend.lagom.javadsl.testkit.ServiceTest.defaultSetup
|
||||
import static com.lightbend.lagom.javadsl.testkit.ServiceTest.startServer
|
||||
import static datadog.trace.agent.test.ListWriterAssert.assertTraces
|
||||
|
||||
class LagomTest extends AgentTestRunner {
|
||||
|
@ -41,30 +41,31 @@ class LagomTest extends AgentTestRunner {
|
|||
|
||||
def setupSpec() {
|
||||
server = startServer(defaultSetup()
|
||||
.withCluster(false)
|
||||
.withPersistence(false)
|
||||
.withCassandra(false)
|
||||
.withJdbc(false)
|
||||
.withConfigureBuilder(
|
||||
new Function<GuiceApplicationBuilder, GuiceApplicationBuilder>() {
|
||||
@Override
|
||||
GuiceApplicationBuilder apply(GuiceApplicationBuilder builder) {
|
||||
return builder
|
||||
.bindings(new ServiceTestModule())
|
||||
}}))
|
||||
.withCluster(false)
|
||||
.withPersistence(false)
|
||||
.withCassandra(false)
|
||||
.withJdbc(false)
|
||||
.withConfigureBuilder(
|
||||
new Function<GuiceApplicationBuilder, GuiceApplicationBuilder>() {
|
||||
@Override
|
||||
GuiceApplicationBuilder apply(GuiceApplicationBuilder builder) {
|
||||
return builder
|
||||
.bindings(new ServiceTestModule())
|
||||
}
|
||||
}))
|
||||
}
|
||||
|
||||
def cleanupSpec() {
|
||||
server.stop()
|
||||
}
|
||||
|
||||
def "normal request traces" () {
|
||||
def "normal request traces"() {
|
||||
setup:
|
||||
EchoService service = server.client(EchoService)
|
||||
|
||||
Source<String, NotUsed> input =
|
||||
Source.from(Arrays.asList("msg1", "msg2", "msg3"))
|
||||
.concat(Source.maybe())
|
||||
.concat(Source.maybe())
|
||||
Source<String, NotUsed> output = service.echo().invoke(input)
|
||||
.toCompletableFuture().get()
|
||||
Probe<String> probe = output.runWith(TestSink.probe(server.system()), server.materializer())
|
||||
|
@ -80,7 +81,7 @@ class LagomTest extends AgentTestRunner {
|
|||
span(0) {
|
||||
serviceName "unnamed-java-app"
|
||||
operationName "akka-http.request"
|
||||
resourceName "GET ws://?/echo"
|
||||
resourceName "GET ws://?/echo"
|
||||
errored false
|
||||
tags {
|
||||
defaultTags()
|
||||
|
@ -100,7 +101,7 @@ class LagomTest extends AgentTestRunner {
|
|||
}
|
||||
}
|
||||
|
||||
def "error traces" () {
|
||||
def "error traces"() {
|
||||
setup:
|
||||
EchoService service = server.client(EchoService)
|
||||
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
import static com.lightbend.lagom.javadsl.api.Service.*;
|
||||
import static com.lightbend.lagom.javadsl.api.Service.named;
|
||||
import static com.lightbend.lagom.javadsl.api.Service.namedCall;
|
||||
|
||||
import akka.NotUsed;
|
||||
import akka.stream.javadsl.Source;
|
||||
import com.lightbend.lagom.javadsl.api.*;
|
||||
import com.lightbend.lagom.javadsl.api.Descriptor;
|
||||
import com.lightbend.lagom.javadsl.api.Service;
|
||||
import com.lightbend.lagom.javadsl.api.ServiceCall;
|
||||
|
||||
public interface EchoService extends Service {
|
||||
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
package datadog.trace.instrumentation.akkahttp;
|
||||
|
||||
import static io.opentracing.log.Fields.ERROR_OBJECT;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.*;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.named;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.returns;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
|
||||
|
||||
import akka.NotUsed;
|
||||
import akka.http.javadsl.model.headers.RawHeader;
|
||||
|
@ -10,7 +12,7 @@ import akka.http.scaladsl.model.HttpRequest;
|
|||
import akka.http.scaladsl.model.HttpResponse;
|
||||
import akka.stream.scaladsl.Flow;
|
||||
import com.google.auto.service.AutoService;
|
||||
import datadog.trace.agent.tooling.*;
|
||||
import datadog.trace.agent.tooling.Instrumenter;
|
||||
import datadog.trace.api.DDSpanTypes;
|
||||
import datadog.trace.api.DDTags;
|
||||
import io.opentracing.Scope;
|
||||
|
@ -92,10 +94,10 @@ public final class AkkaHttpClientInstrumentation extends Instrumenter.Default {
|
|||
.withTag(Tags.HTTP_METHOD.getKey(), request.method().value())
|
||||
.withTag(Tags.HTTP_URL.getKey(), request.getUri().toString());
|
||||
}
|
||||
Scope scope = builder.startActive(false);
|
||||
final Scope scope = builder.startActive(false);
|
||||
|
||||
if (request != null) {
|
||||
AkkaHttpHeaders headers = new AkkaHttpHeaders(request);
|
||||
final AkkaHttpHeaders headers = new AkkaHttpHeaders(request);
|
||||
GlobalTracer.get().inject(scope.span().context(), Format.Builtin.HTTP_HEADERS, headers);
|
||||
// Request is immutable, so we have to assign new value once we update headers
|
||||
request = headers.getRequest();
|
||||
|
@ -111,7 +113,7 @@ public final class AkkaHttpClientInstrumentation extends Instrumenter.Default {
|
|||
@Advice.Return final Future<HttpResponse> responseFuture,
|
||||
@Advice.Enter final Scope scope,
|
||||
@Advice.Thrown final Throwable throwable) {
|
||||
Span span = scope.span();
|
||||
final Span span = scope.span();
|
||||
if (throwable == null) {
|
||||
responseFuture.onComplete(new OnCompleteHandler(span), thiz.system().dispatcher());
|
||||
} else {
|
||||
|
@ -135,12 +137,12 @@ public final class AkkaHttpClientInstrumentation extends Instrumenter.Default {
|
|||
public static class OnCompleteHandler extends AbstractFunction1<Try<HttpResponse>, Void> {
|
||||
private final Span span;
|
||||
|
||||
public OnCompleteHandler(Span span) {
|
||||
public OnCompleteHandler(final Span span) {
|
||||
this.span = span;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void apply(Try<HttpResponse> result) {
|
||||
public Void apply(final Try<HttpResponse> result) {
|
||||
if (result.isSuccess()) {
|
||||
Tags.HTTP_STATUS.set(span, result.get().status().intValue());
|
||||
} else {
|
||||
|
@ -155,7 +157,7 @@ public final class AkkaHttpClientInstrumentation extends Instrumenter.Default {
|
|||
public static class AkkaHttpHeaders implements TextMap {
|
||||
private HttpRequest request;
|
||||
|
||||
public AkkaHttpHeaders(HttpRequest request) {
|
||||
public AkkaHttpHeaders(final HttpRequest request) {
|
||||
this.request = request;
|
||||
}
|
||||
|
||||
|
|
|
@ -4,11 +4,10 @@ import java.util.Collections
|
|||
|
||||
import akka.NotUsed
|
||||
import akka.http.scaladsl.model.{HttpRequest, HttpResponse}
|
||||
import akka.stream.Supervision
|
||||
import akka.stream.scaladsl.Flow
|
||||
import datadog.trace.api.{DDSpanTypes, DDTags}
|
||||
import io.opentracing.Span
|
||||
import io.opentracing.log.Fields.ERROR_OBJECT
|
||||
import io.opentracing.{Scope, Span}
|
||||
import io.opentracing.propagation.Format
|
||||
import io.opentracing.tag.Tags
|
||||
import io.opentracing.util.GlobalTracer
|
||||
|
|
|
@ -1,14 +1,15 @@
|
|||
package datadog.trace.instrumentation.akkahttp;
|
||||
|
||||
import static io.opentracing.log.Fields.ERROR_OBJECT;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.*;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.named;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
|
||||
|
||||
import akka.http.javadsl.model.HttpHeader;
|
||||
import akka.http.scaladsl.model.HttpRequest;
|
||||
import akka.http.scaladsl.model.HttpResponse;
|
||||
import akka.stream.*;
|
||||
import akka.stream.Materializer;
|
||||
import com.google.auto.service.AutoService;
|
||||
import datadog.trace.agent.tooling.*;
|
||||
import datadog.trace.agent.tooling.Instrumenter;
|
||||
import datadog.trace.api.DDSpanTypes;
|
||||
import datadog.trace.api.DDTags;
|
||||
import datadog.trace.context.TraceScope;
|
||||
|
@ -19,7 +20,10 @@ import io.opentracing.propagation.Format;
|
|||
import io.opentracing.propagation.TextMap;
|
||||
import io.opentracing.tag.Tags;
|
||||
import io.opentracing.util.GlobalTracer;
|
||||
import java.util.*;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.bytebuddy.asm.Advice;
|
||||
import net.bytebuddy.description.type.TypeDescription;
|
||||
|
@ -90,13 +94,13 @@ public final class AkkaHttpServerInstrumentation extends Instrumenter.Default {
|
|||
public static void wrapHandler(
|
||||
@Advice.Argument(value = 0, readOnly = false)
|
||||
Function1<HttpRequest, scala.concurrent.Future<HttpResponse>> handler,
|
||||
@Advice.Argument(value = 7) Materializer materializer) {
|
||||
@Advice.Argument(value = 7) final Materializer materializer) {
|
||||
handler = new DatadogAsyncWrapper(handler, materializer.executionContext());
|
||||
}
|
||||
}
|
||||
|
||||
public static class DatadogWrapperHelper {
|
||||
public static Scope createSpan(HttpRequest request) {
|
||||
public static Scope createSpan(final HttpRequest request) {
|
||||
final SpanContext extractedContext =
|
||||
GlobalTracer.get()
|
||||
.extract(Format.Builtin.HTTP_HEADERS, new AkkaHttpServerHeaders(request));
|
||||
|
@ -117,7 +121,7 @@ public final class AkkaHttpServerInstrumentation extends Instrumenter.Default {
|
|||
return scope;
|
||||
}
|
||||
|
||||
public static void finishSpan(Span span, HttpResponse response) {
|
||||
public static void finishSpan(final Span span, final HttpResponse response) {
|
||||
Tags.HTTP_STATUS.set(span, response.status().intValue());
|
||||
|
||||
if (GlobalTracer.get().scopeManager().active() instanceof TraceScope) {
|
||||
|
@ -126,7 +130,7 @@ public final class AkkaHttpServerInstrumentation extends Instrumenter.Default {
|
|||
span.finish();
|
||||
}
|
||||
|
||||
public static void finishSpan(Span span, Throwable t) {
|
||||
public static void finishSpan(final Span span, final Throwable t) {
|
||||
Tags.ERROR.set(span, true);
|
||||
span.log(Collections.singletonMap(ERROR_OBJECT, t));
|
||||
Tags.HTTP_STATUS.set(span, 500);
|
||||
|
@ -141,19 +145,19 @@ public final class AkkaHttpServerInstrumentation extends Instrumenter.Default {
|
|||
public static class DatadogSyncWrapper extends AbstractFunction1<HttpRequest, HttpResponse> {
|
||||
private final Function1<HttpRequest, HttpResponse> userHandler;
|
||||
|
||||
public DatadogSyncWrapper(Function1<HttpRequest, HttpResponse> userHandler) {
|
||||
public DatadogSyncWrapper(final Function1<HttpRequest, HttpResponse> userHandler) {
|
||||
this.userHandler = userHandler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpResponse apply(HttpRequest request) {
|
||||
public HttpResponse apply(final HttpRequest request) {
|
||||
final Scope scope = DatadogWrapperHelper.createSpan(request);
|
||||
try {
|
||||
final HttpResponse response = userHandler.apply(request);
|
||||
scope.close();
|
||||
DatadogWrapperHelper.finishSpan(scope.span(), response);
|
||||
return response;
|
||||
} catch (Throwable t) {
|
||||
} catch (final Throwable t) {
|
||||
scope.close();
|
||||
DatadogWrapperHelper.finishSpan(scope.span(), t);
|
||||
throw t;
|
||||
|
@ -167,19 +171,19 @@ public final class AkkaHttpServerInstrumentation extends Instrumenter.Default {
|
|||
private final ExecutionContext executionContext;
|
||||
|
||||
public DatadogAsyncWrapper(
|
||||
Function1<HttpRequest, Future<HttpResponse>> userHandler,
|
||||
ExecutionContext executionContext) {
|
||||
final Function1<HttpRequest, Future<HttpResponse>> userHandler,
|
||||
final ExecutionContext executionContext) {
|
||||
this.userHandler = userHandler;
|
||||
this.executionContext = executionContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Future<HttpResponse> apply(HttpRequest request) {
|
||||
public Future<HttpResponse> apply(final HttpRequest request) {
|
||||
final Scope scope = DatadogWrapperHelper.createSpan(request);
|
||||
Future<HttpResponse> futureResponse = null;
|
||||
try {
|
||||
futureResponse = userHandler.apply(request);
|
||||
} catch (Throwable t) {
|
||||
} catch (final Throwable t) {
|
||||
scope.close();
|
||||
DatadogWrapperHelper.finishSpan(scope.span(), t);
|
||||
throw t;
|
||||
|
@ -188,14 +192,14 @@ public final class AkkaHttpServerInstrumentation extends Instrumenter.Default {
|
|||
futureResponse.transform(
|
||||
new AbstractFunction1<HttpResponse, HttpResponse>() {
|
||||
@Override
|
||||
public HttpResponse apply(HttpResponse response) {
|
||||
public HttpResponse apply(final HttpResponse response) {
|
||||
DatadogWrapperHelper.finishSpan(scope.span(), response);
|
||||
return response;
|
||||
}
|
||||
},
|
||||
new AbstractFunction1<Throwable, Throwable>() {
|
||||
@Override
|
||||
public Throwable apply(Throwable t) {
|
||||
public Throwable apply(final Throwable t) {
|
||||
DatadogWrapperHelper.finishSpan(scope.span(), t);
|
||||
return t;
|
||||
}
|
||||
|
@ -209,7 +213,7 @@ public final class AkkaHttpServerInstrumentation extends Instrumenter.Default {
|
|||
public static class AkkaHttpServerHeaders implements TextMap {
|
||||
private final HttpRequest request;
|
||||
|
||||
public AkkaHttpServerHeaders(HttpRequest request) {
|
||||
public AkkaHttpServerHeaders(final HttpRequest request) {
|
||||
this.request = request;
|
||||
}
|
||||
|
||||
|
@ -217,7 +221,7 @@ public final class AkkaHttpServerInstrumentation extends Instrumenter.Default {
|
|||
public Iterator<Map.Entry<String, String>> iterator() {
|
||||
final Map<String, String> javaMap = new HashMap<>(request.headers().size());
|
||||
|
||||
for (HttpHeader header : request.getHeaders()) {
|
||||
for (final HttpHeader header : request.getHeaders()) {
|
||||
javaMap.put(header.name(), header.value());
|
||||
}
|
||||
|
||||
|
@ -225,7 +229,7 @@ public final class AkkaHttpServerInstrumentation extends Instrumenter.Default {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void put(String name, String value) {
|
||||
public void put(final String name, final String value) {
|
||||
throw new IllegalStateException("akka http server headers can only be extracted");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -55,9 +55,9 @@ class AkkaHttpClientInstrumentationTest extends AgentTestRunner {
|
|||
@Shared
|
||||
ActorMaterializer materializer = ActorMaterializer.create(system)
|
||||
|
||||
def pool = Http.get(system).<Integer>superPool(materializer)
|
||||
def pool = Http.get(system).<Integer> superPool(materializer)
|
||||
|
||||
def "#route request trace" () {
|
||||
def "#route request trace"() {
|
||||
setup:
|
||||
def url = server.address.resolve("/" + route).toURL()
|
||||
|
||||
|
@ -116,7 +116,7 @@ class AkkaHttpClientInstrumentationTest extends AgentTestRunner {
|
|||
"error" | 500 | true | null
|
||||
}
|
||||
|
||||
def "error request trace" () {
|
||||
def "error request trace"() {
|
||||
setup:
|
||||
def url = new URL("http://localhost:${server.address.port + 1}/test")
|
||||
|
||||
|
@ -153,7 +153,7 @@ class AkkaHttpClientInstrumentationTest extends AgentTestRunner {
|
|||
}
|
||||
}
|
||||
|
||||
def "singleRequest exception trace" () {
|
||||
def "singleRequest exception trace"() {
|
||||
when:
|
||||
// Passing null causes NPE in singleRequest
|
||||
Http.get(system).singleRequest(null, materializer)
|
||||
|
@ -183,14 +183,14 @@ class AkkaHttpClientInstrumentationTest extends AgentTestRunner {
|
|||
}
|
||||
|
||||
|
||||
def "#route pool request trace" () {
|
||||
def "#route pool request trace"() {
|
||||
setup:
|
||||
def url = server.address.resolve("/" + route).toURL()
|
||||
|
||||
CompletionStage<Pair<Try<HttpResponse>, Integer>> sink = Source
|
||||
.<Pair<HttpRequest, Integer>>single(new Pair(HttpRequest.create(url.toString()), 1))
|
||||
.<Pair<HttpRequest, Integer>> single(new Pair(HttpRequest.create(url.toString()), 1))
|
||||
.via(pool)
|
||||
.runWith(Sink.<Pair<Try<HttpResponse>, Integer>>head(), materializer)
|
||||
.runWith(Sink.<Pair<Try<HttpResponse>, Integer>> head(), materializer)
|
||||
|
||||
when:
|
||||
HttpResponse response = sink.toCompletableFuture().get().first().get()
|
||||
|
@ -242,14 +242,14 @@ class AkkaHttpClientInstrumentationTest extends AgentTestRunner {
|
|||
"error" | 500 | true | null
|
||||
}
|
||||
|
||||
def "error request pool trace" () {
|
||||
def "error request pool trace"() {
|
||||
setup:
|
||||
def url = new URL("http://localhost:${server.address.port + 1}/test")
|
||||
|
||||
CompletionStage<Pair<Try<HttpResponse>, Integer>> sink = Source
|
||||
.<Pair<HttpRequest, Integer>>single(new Pair(HttpRequest.create(url.toString()), 1))
|
||||
.<Pair<HttpRequest, Integer>> single(new Pair(HttpRequest.create(url.toString()), 1))
|
||||
.via(pool)
|
||||
.runWith(Sink.<Pair<Try<HttpResponse>, Integer>>head(), materializer)
|
||||
.runWith(Sink.<Pair<Try<HttpResponse>, Integer>> head(), materializer)
|
||||
def response = sink.toCompletableFuture().get().first()
|
||||
|
||||
when:
|
||||
|
|
|
@ -30,7 +30,7 @@ class AkkaHttpServerInstrumentationTest extends AgentTestRunner {
|
|||
AkkaHttpTestSyncWebServer.stop()
|
||||
}
|
||||
|
||||
def "#server 200 request trace" () {
|
||||
def "#server 200 request trace"() {
|
||||
setup:
|
||||
OkHttpClient client = new OkHttpClient.Builder().build()
|
||||
def request = new Request.Builder()
|
||||
|
@ -71,12 +71,12 @@ class AkkaHttpServerInstrumentationTest extends AgentTestRunner {
|
|||
}
|
||||
|
||||
where:
|
||||
server | port
|
||||
"async" | asyncPort
|
||||
"sync" | syncPort
|
||||
server | port
|
||||
"async" | asyncPort
|
||||
"sync" | syncPort
|
||||
}
|
||||
|
||||
def "#server exceptions trace for #endpoint" () {
|
||||
def "#server exceptions trace for #endpoint"() {
|
||||
setup:
|
||||
OkHttpClient client = new OkHttpClient.Builder().build()
|
||||
def request = new Request.Builder()
|
||||
|
@ -110,13 +110,13 @@ class AkkaHttpServerInstrumentationTest extends AgentTestRunner {
|
|||
}
|
||||
|
||||
where:
|
||||
server | port | endpoint | errorMessage
|
||||
"async" | asyncPort | "throw-handler" | "Oh no handler"
|
||||
"async" | asyncPort | "throw-callback" | "Oh no callback"
|
||||
"sync" | syncPort | "throw-handler" | "Oh no handler"
|
||||
server | port | endpoint | errorMessage
|
||||
"async" | asyncPort | "throw-handler" | "Oh no handler"
|
||||
"async" | asyncPort | "throw-callback" | "Oh no callback"
|
||||
"sync" | syncPort | "throw-handler" | "Oh no handler"
|
||||
}
|
||||
|
||||
def "#server 5xx trace" () {
|
||||
def "#server 5xx trace"() {
|
||||
setup:
|
||||
OkHttpClient client = new OkHttpClient.Builder().build()
|
||||
def request = new Request.Builder()
|
||||
|
@ -150,12 +150,12 @@ class AkkaHttpServerInstrumentationTest extends AgentTestRunner {
|
|||
}
|
||||
|
||||
where:
|
||||
server | port
|
||||
"async" | asyncPort
|
||||
"sync" | syncPort
|
||||
server | port
|
||||
"async" | asyncPort
|
||||
"sync" | syncPort
|
||||
}
|
||||
|
||||
def "#server 4xx trace" () {
|
||||
def "#server 4xx trace"() {
|
||||
setup:
|
||||
OkHttpClient client = new OkHttpClient.Builder().build()
|
||||
def request = new Request.Builder()
|
||||
|
@ -188,8 +188,8 @@ class AkkaHttpServerInstrumentationTest extends AgentTestRunner {
|
|||
}
|
||||
|
||||
where:
|
||||
server | port
|
||||
"async" | asyncPort
|
||||
"sync" | syncPort
|
||||
server | port
|
||||
"async" | asyncPort
|
||||
"sync" | syncPort
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import akka.actor.ActorSystem
|
||||
import akka.http.scaladsl.Http
|
||||
import akka.http.scaladsl.Http.ServerBinding
|
||||
import akka.http.scaladsl.model._
|
||||
import akka.http.scaladsl.model.HttpMethods.GET
|
||||
import akka.http.scaladsl.model._
|
||||
import akka.stream.ActorMaterializer
|
||||
import datadog.trace.agent.test.TestUtils
|
||||
import datadog.trace.api.Trace
|
||||
|
@ -37,7 +37,7 @@ object AkkaHttpTestAsyncWebServer {
|
|||
}
|
||||
}
|
||||
|
||||
private var binding :ServerBinding = null
|
||||
private var binding: ServerBinding = null
|
||||
|
||||
def start(): Unit = synchronized {
|
||||
if (null == binding) {
|
||||
|
@ -77,7 +77,7 @@ object AkkaHttpTestSyncWebServer {
|
|||
HttpResponse(entity = "Not found unit test.", status = StatusCodes.NotFound)
|
||||
}
|
||||
|
||||
private var binding :ServerBinding = null
|
||||
private var binding: ServerBinding = null
|
||||
|
||||
def start(): Unit = synchronized {
|
||||
if (null == binding) {
|
||||
|
|
|
@ -13,7 +13,11 @@
|
|||
*/
|
||||
package datadog.trace.instrumentation.aws.v0;
|
||||
|
||||
import static io.opentracing.log.Fields.*;
|
||||
import static io.opentracing.log.Fields.ERROR_KIND;
|
||||
import static io.opentracing.log.Fields.ERROR_OBJECT;
|
||||
import static io.opentracing.log.Fields.EVENT;
|
||||
import static io.opentracing.log.Fields.MESSAGE;
|
||||
import static io.opentracing.log.Fields.STACK;
|
||||
|
||||
import com.amazonaws.AmazonWebServiceResponse;
|
||||
import com.amazonaws.Request;
|
||||
|
|
|
@ -13,7 +13,11 @@
|
|||
*/
|
||||
package datadog.trace.instrumentation.aws.v106;
|
||||
|
||||
import static io.opentracing.log.Fields.*;
|
||||
import static io.opentracing.log.Fields.ERROR_KIND;
|
||||
import static io.opentracing.log.Fields.ERROR_OBJECT;
|
||||
import static io.opentracing.log.Fields.EVENT;
|
||||
import static io.opentracing.log.Fields.MESSAGE;
|
||||
import static io.opentracing.log.Fields.STACK;
|
||||
|
||||
import com.amazonaws.AmazonWebServiceResponse;
|
||||
import com.amazonaws.Request;
|
||||
|
|
|
@ -8,6 +8,6 @@ dependencies {
|
|||
compile deps.opentracing
|
||||
annotationProcessor deps.autoservice
|
||||
implementation deps.autoservice
|
||||
|
||||
|
||||
testCompile project(':dd-java-agent:testing')
|
||||
}
|
||||
|
|
|
@ -13,7 +13,11 @@
|
|||
*/
|
||||
package datadog.trace.instrumentation.datastax.cassandra;
|
||||
|
||||
import static io.opentracing.log.Fields.*;
|
||||
import static io.opentracing.log.Fields.ERROR_KIND;
|
||||
import static io.opentracing.log.Fields.ERROR_OBJECT;
|
||||
import static io.opentracing.log.Fields.EVENT;
|
||||
import static io.opentracing.log.Fields.MESSAGE;
|
||||
import static io.opentracing.log.Fields.STACK;
|
||||
|
||||
import com.datastax.driver.core.BoundStatement;
|
||||
import com.datastax.driver.core.CloseFuture;
|
||||
|
@ -244,7 +248,7 @@ class TracingSession implements Session {
|
|||
public void run() {
|
||||
try {
|
||||
finishSpan(span, future.get());
|
||||
} catch (InterruptedException | ExecutionException e) {
|
||||
} catch (final InterruptedException | ExecutionException e) {
|
||||
finishSpan(span, e);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -40,7 +40,7 @@ class CassandraClientTest extends AgentTestRunner {
|
|||
|
||||
session.execute("DROP KEYSPACE IF EXISTS sync_test")
|
||||
session.execute(
|
||||
"CREATE KEYSPACE sync_test WITH REPLICATION = {'class':'SimpleStrategy', 'replication_factor':3}")
|
||||
"CREATE KEYSPACE sync_test WITH REPLICATION = {'class':'SimpleStrategy', 'replication_factor':3}")
|
||||
session.execute("CREATE TABLE sync_test.users ( id UUID PRIMARY KEY, name text )")
|
||||
session.execute("INSERT INTO sync_test.users (id, name) values (uuid(), 'alice')")
|
||||
session.execute("SELECT * FROM sync_test.users where name = 'alice' ALLOW FILTERING")
|
||||
|
@ -72,15 +72,15 @@ class CassandraClientTest extends AgentTestRunner {
|
|||
|
||||
session.executeAsync("DROP KEYSPACE IF EXISTS async_test").get()
|
||||
session
|
||||
.executeAsync(
|
||||
"CREATE KEYSPACE async_test WITH REPLICATION = {'class':'SimpleStrategy', 'replication_factor':3}")
|
||||
.get()
|
||||
.executeAsync(
|
||||
"CREATE KEYSPACE async_test WITH REPLICATION = {'class':'SimpleStrategy', 'replication_factor':3}")
|
||||
.get()
|
||||
session.executeAsync("CREATE TABLE async_test.users ( id UUID PRIMARY KEY, name text )").get()
|
||||
session.executeAsync("INSERT INTO async_test.users (id, name) values (uuid(), 'alice')").get()
|
||||
TEST_WRITER.waitForTraces(4)
|
||||
session
|
||||
.executeAsync("SELECT * FROM async_test.users where name = 'alice' ALLOW FILTERING")
|
||||
.get()
|
||||
.executeAsync("SELECT * FROM async_test.users where name = 'alice' ALLOW FILTERING")
|
||||
.get()
|
||||
TEST_WRITER.waitForTraces(5)
|
||||
|
||||
def query = "SELECT * FROM async_test.users where name = 'alice' ALLOW FILTERING"
|
||||
|
|
|
@ -39,7 +39,7 @@ class Elasticsearch2NodeClientTest extends AgentTestRunner {
|
|||
|
||||
def settings = Settings.builder()
|
||||
.put("path.home", esWorkingDir.path)
|
||||
// Since we use listeners to close spans this should make our span closing deterministic which is good for tests
|
||||
// Since we use listeners to close spans this should make our span closing deterministic which is good for tests
|
||||
.put("threadpool.listener.size", 1)
|
||||
.put("http.port", httpPort)
|
||||
.put("transport.tcp.port", tcpPort)
|
||||
|
|
|
@ -50,7 +50,7 @@ class Elasticsearch2SpringTemplateTest extends AgentTestRunner {
|
|||
|
||||
def settings = Settings.builder()
|
||||
.put("path.home", esWorkingDir.path)
|
||||
// Since we use listeners to close spans this should make our span closing deterministic which is good for tests
|
||||
// Since we use listeners to close spans this should make our span closing deterministic which is good for tests
|
||||
.put("threadpool.listener.size", 1)
|
||||
.put("http.port", httpPort)
|
||||
.put("transport.tcp.port", tcpPort)
|
||||
|
|
|
@ -51,7 +51,7 @@ class Elasticsearch2TransportClientTest extends AgentTestRunner {
|
|||
|
||||
client = TransportClient.builder().settings(
|
||||
Settings.builder()
|
||||
// Since we use listeners to close spans this should make our span closing deterministic which is good for tests
|
||||
// Since we use listeners to close spans this should make our span closing deterministic which is good for tests
|
||||
.put("threadpool.listener.size", 1)
|
||||
.put("cluster.name", "test-cluster")
|
||||
.build()
|
||||
|
|
|
@ -42,7 +42,7 @@ class Elasticsearch5NodeClientTest extends AgentTestRunner {
|
|||
|
||||
def settings = Settings.builder()
|
||||
.put("path.home", esWorkingDir.path)
|
||||
// Since we use listeners to close spans this should make our span closing deterministic which is good for tests
|
||||
// Since we use listeners to close spans this should make our span closing deterministic which is good for tests
|
||||
.put("thread_pool.listener.size", 1)
|
||||
.put("http.port", httpPort)
|
||||
.put("transport.tcp.port", tcpPort)
|
||||
|
|
|
@ -58,7 +58,7 @@ class Elasticsearch5TransportClientTest extends AgentTestRunner {
|
|||
|
||||
client = new PreBuiltTransportClient(
|
||||
Settings.builder()
|
||||
// Since we use listeners to close spans this should make our span closing deterministic which is good for tests
|
||||
// Since we use listeners to close spans this should make our span closing deterministic which is good for tests
|
||||
.put("thread_pool.listener.size", 1)
|
||||
.put(CLUSTER_NAME_SETTING.getKey(), "test-cluster")
|
||||
.build()
|
||||
|
|
|
@ -41,7 +41,7 @@ class Elasticsearch6NodeClientTest extends AgentTestRunner {
|
|||
|
||||
def settings = Settings.builder()
|
||||
.put("path.home", esWorkingDir.path)
|
||||
// Since we use listeners to close spans this should make our span closing deterministic which is good for tests
|
||||
// Since we use listeners to close spans this should make our span closing deterministic which is good for tests
|
||||
.put("thread_pool.listener.size", 1)
|
||||
.put("http.port", httpPort)
|
||||
.put("transport.tcp.port", tcpPort)
|
||||
|
|
|
@ -55,7 +55,7 @@ class Elasticsearch6TransportClientTest extends AgentTestRunner {
|
|||
|
||||
client = new PreBuiltTransportClient(
|
||||
Settings.builder()
|
||||
// Since we use listeners to close spans this should make our span closing deterministic which is good for tests
|
||||
// Since we use listeners to close spans this should make our span closing deterministic which is good for tests
|
||||
.put("thread_pool.listener.size", 1)
|
||||
.put(CLUSTER_NAME_SETTING.getKey(), "test-cluster")
|
||||
.build()
|
||||
|
|
|
@ -14,7 +14,9 @@ import io.opentracing.Span;
|
|||
import io.opentracing.tag.Tags;
|
||||
import io.opentracing.util.GlobalTracer;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.*;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import net.bytebuddy.asm.Advice;
|
||||
import net.bytebuddy.matcher.ElementMatcher;
|
||||
|
||||
|
@ -34,7 +36,7 @@ public class HystrixCommandInstrumentation extends Instrumenter.Default {
|
|||
|
||||
@Override
|
||||
public Map<ElementMatcher, String> transformers() {
|
||||
Map<ElementMatcher, String> transformers = new HashMap<>();
|
||||
final Map<ElementMatcher, String> transformers = new HashMap<>();
|
||||
transformers.put(
|
||||
isMethod().and(named("run").or(named("getFallback"))), TraceAdvice.class.getName());
|
||||
return transformers;
|
||||
|
|
|
@ -10,7 +10,8 @@ import datadog.trace.agent.tooling.Instrumenter;
|
|||
import datadog.trace.context.TraceScope;
|
||||
import io.opentracing.Scope;
|
||||
import io.opentracing.util.GlobalTracer;
|
||||
import java.util.*;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import net.bytebuddy.asm.Advice;
|
||||
import net.bytebuddy.matcher.ElementMatcher;
|
||||
|
||||
|
|
|
@ -40,7 +40,7 @@ subprojects { subProj ->
|
|||
}
|
||||
}
|
||||
|
||||
excludedClassesConverage += [ 'datadog.trace.instrumentation.*' ]
|
||||
excludedClassesConverage += ['datadog.trace.instrumentation.*']
|
||||
|
||||
dependencies {
|
||||
compile(project(':dd-java-agent:agent-tooling')) {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
apply from: "${rootDir}/gradle/java.gradle"
|
||||
apply plugin: 'scala'
|
||||
|
||||
excludedClassesConverage += [ '*' ]
|
||||
excludedClassesConverage += ['*']
|
||||
|
||||
dependencies {
|
||||
compile project(':dd-trace-api')
|
||||
|
|
|
@ -26,26 +26,28 @@ object AkkaActors {
|
|||
}
|
||||
|
||||
class AkkaActors {
|
||||
|
||||
import AkkaActors._
|
||||
import Greeter._
|
||||
|
||||
implicit val timeout: Timeout = 5.minutes
|
||||
|
||||
@Trace
|
||||
def basicTell() : Unit = {
|
||||
def basicTell(): Unit = {
|
||||
GlobalTracer.get().scopeManager().active().asInstanceOf[TraceScope].setAsyncPropagation(true)
|
||||
howdyGreeter ! WhoToGreet("Akka")
|
||||
howdyGreeter ! Greet
|
||||
}
|
||||
|
||||
@Trace
|
||||
def basicAsk() : Unit = {
|
||||
def basicAsk(): Unit = {
|
||||
GlobalTracer.get().scopeManager().active().asInstanceOf[TraceScope].setAsyncPropagation(true)
|
||||
howdyGreeter ! WhoToGreet("Akka")
|
||||
howdyGreeter ? Greet
|
||||
}
|
||||
|
||||
@Trace
|
||||
def basicForward() : Unit = {
|
||||
def basicForward(): Unit = {
|
||||
GlobalTracer.get().scopeManager().active().asInstanceOf[TraceScope].setAsyncPropagation(true)
|
||||
helloGreeter ! WhoToGreet("Akka")
|
||||
helloGreeter ? Greet
|
||||
|
@ -54,11 +56,15 @@ class AkkaActors {
|
|||
|
||||
object Greeter {
|
||||
def props(message: String, receiverActor: ActorRef): Props = Props(new Greeter(message, receiverActor))
|
||||
|
||||
final case class WhoToGreet(who: String)
|
||||
|
||||
case object Greet
|
||||
|
||||
}
|
||||
|
||||
class Greeter(message: String, receiverActor: ActorRef) extends Actor {
|
||||
|
||||
import Greeter._
|
||||
import Receiver._
|
||||
|
||||
|
@ -67,17 +73,20 @@ class Greeter(message: String, receiverActor: ActorRef) extends Actor {
|
|||
def receive = {
|
||||
case WhoToGreet(who) =>
|
||||
greeting = s"$message, $who"
|
||||
case Greet =>
|
||||
case Greet =>
|
||||
receiverActor ! Greeting(greeting)
|
||||
}
|
||||
}
|
||||
|
||||
object Receiver {
|
||||
def props: Props = Props[Receiver]
|
||||
|
||||
final case class Greeting(greeting: String)
|
||||
|
||||
}
|
||||
|
||||
class Receiver extends Actor with ActorLogging {
|
||||
|
||||
import Receiver._
|
||||
|
||||
def receive = {
|
||||
|
|
|
@ -12,7 +12,7 @@ class ScalaConcurrentTests {
|
|||
* @return Number of expected spans in the trace
|
||||
*/
|
||||
@Trace
|
||||
def traceWithFutureAndCallbacks() : Integer = {
|
||||
def traceWithFutureAndCallbacks(): Integer = {
|
||||
GlobalTracer.get().scopeManager().active().asInstanceOf[TraceScope].setAsyncPropagation(true)
|
||||
val goodFuture: Future[Integer] = Future {
|
||||
tracedChild("goodFuture")
|
||||
|
@ -33,7 +33,7 @@ class ScalaConcurrentTests {
|
|||
}
|
||||
|
||||
@Trace
|
||||
def tracedAcrossThreadsWithNoTrace() :Integer = {
|
||||
def tracedAcrossThreadsWithNoTrace(): Integer = {
|
||||
GlobalTracer.get().scopeManager().active().asInstanceOf[TraceScope].setAsyncPropagation(true)
|
||||
val goodFuture: Future[Integer] = Future {
|
||||
1
|
||||
|
@ -53,7 +53,7 @@ class ScalaConcurrentTests {
|
|||
* @return Number of expected spans in the trace
|
||||
*/
|
||||
@Trace
|
||||
def traceWithPromises() : Integer = {
|
||||
def traceWithPromises(): Integer = {
|
||||
GlobalTracer.get().scopeManager().active().asInstanceOf[TraceScope].setAsyncPropagation(true)
|
||||
val keptPromise = Promise[Boolean]()
|
||||
val brokenPromise = Promise[Boolean]()
|
||||
|
@ -86,7 +86,7 @@ class ScalaConcurrentTests {
|
|||
* @return Number of expected spans in the trace
|
||||
*/
|
||||
@Trace
|
||||
def tracedWithFutureFirstCompletions() :Integer = {
|
||||
def tracedWithFutureFirstCompletions(): Integer = {
|
||||
GlobalTracer.get().scopeManager().active().asInstanceOf[TraceScope].setAsyncPropagation(true)
|
||||
val completedVal = Future.firstCompletedOf(
|
||||
List(
|
||||
|
@ -114,7 +114,7 @@ class ScalaConcurrentTests {
|
|||
GlobalTracer.get().scopeManager().active().asInstanceOf[TraceScope].setAsyncPropagation(true)
|
||||
val f: Future[String] = Future {
|
||||
tracedChild("timeoutChild")
|
||||
while(true) {
|
||||
while (true) {
|
||||
// never actually finish
|
||||
}
|
||||
"done"
|
||||
|
|
|
@ -8,13 +8,19 @@ import static net.bytebuddy.matcher.ElementMatchers.not;
|
|||
import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
|
||||
|
||||
import com.google.auto.service.AutoService;
|
||||
import datadog.trace.agent.tooling.*;
|
||||
import datadog.trace.agent.tooling.Instrumenter;
|
||||
import datadog.trace.bootstrap.CallDepthThreadLocalMap;
|
||||
import datadog.trace.context.TraceScope;
|
||||
import io.opentracing.Scope;
|
||||
import io.opentracing.util.GlobalTracer;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.Executor;
|
||||
|
@ -98,7 +104,7 @@ public final class ExecutorInstrumentation extends Instrumenter.Default {
|
|||
|
||||
// Check for possible prefixes match only if not whitelisted already
|
||||
if (!whitelisted) {
|
||||
for (String name : WHITELISTED_EXECUTORS_PREFIXES) {
|
||||
for (final String name : WHITELISTED_EXECUTORS_PREFIXES) {
|
||||
if (target.getName().startsWith(name)) {
|
||||
whitelisted = true;
|
||||
break;
|
||||
|
@ -126,7 +132,7 @@ public final class ExecutorInstrumentation extends Instrumenter.Default {
|
|||
|
||||
@Override
|
||||
public Map<ElementMatcher, String> transformers() {
|
||||
Map<ElementMatcher, String> transformers = new HashMap<>();
|
||||
final Map<ElementMatcher, String> transformers = new HashMap<>();
|
||||
transformers.put(
|
||||
named("execute").and(takesArgument(0, Runnable.class)), WrapRunnableAdvice.class.getName());
|
||||
transformers.put(
|
||||
|
@ -141,7 +147,6 @@ public final class ExecutorInstrumentation extends Instrumenter.Default {
|
|||
|
||||
public static class WrapRunnableAdvice {
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@Advice.OnMethodEnter(suppress = Throwable.class)
|
||||
public static DatadogWrapper enterJobSubmit(
|
||||
@Advice.Argument(value = 0, readOnly = false) Runnable task) {
|
||||
|
@ -153,7 +158,6 @@ public final class ExecutorInstrumentation extends Instrumenter.Default {
|
|||
return null;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
|
||||
public static void exitJobSubmit(
|
||||
@Advice.Enter final DatadogWrapper wrapper, @Advice.Thrown final Throwable throwable) {
|
||||
|
@ -163,7 +167,6 @@ public final class ExecutorInstrumentation extends Instrumenter.Default {
|
|||
|
||||
public static class WrapCallableAdvice {
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@Advice.OnMethodEnter(suppress = Throwable.class)
|
||||
public static DatadogWrapper enterJobSubmit(
|
||||
@Advice.Argument(value = 0, readOnly = false) Callable<?> task) {
|
||||
|
@ -176,7 +179,6 @@ public final class ExecutorInstrumentation extends Instrumenter.Default {
|
|||
return null;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
|
||||
public static void exitJobSubmit(
|
||||
@Advice.Enter final DatadogWrapper wrapper, @Advice.Thrown final Throwable throwable) {
|
||||
|
@ -186,7 +188,6 @@ public final class ExecutorInstrumentation extends Instrumenter.Default {
|
|||
|
||||
public static class WrapCallableCollectionAdvice {
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@Advice.OnMethodEnter(suppress = Throwable.class)
|
||||
public static Collection<?> wrapJob(
|
||||
@Advice.Argument(value = 0, readOnly = false) Collection<? extends Callable<?>> tasks) {
|
||||
|
@ -196,7 +197,7 @@ public final class ExecutorInstrumentation extends Instrumenter.Default {
|
|||
&& tasks != null
|
||||
&& DatadogWrapper.isTopLevelCall()) {
|
||||
final Collection<Callable<?>> wrappedTasks = new ArrayList<>(tasks.size());
|
||||
for (Callable<?> task : tasks) {
|
||||
for (final Callable<?> task : tasks) {
|
||||
if (task != null && !(task instanceof CallableWrapper)) {
|
||||
wrappedTasks.add(new CallableWrapper<>(task, (TraceScope) scope));
|
||||
}
|
||||
|
@ -207,7 +208,6 @@ public final class ExecutorInstrumentation extends Instrumenter.Default {
|
|||
return null;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
|
||||
public static void checkCancel(
|
||||
@Advice.Enter final Collection<?> wrappedJobs, @Advice.Thrown final Throwable throwable) {
|
||||
|
@ -250,13 +250,11 @@ public final class ExecutorInstrumentation extends Instrumenter.Default {
|
|||
*
|
||||
* @return true iff call is not nested
|
||||
*/
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
public static boolean isTopLevelCall() {
|
||||
return CallDepthThreadLocalMap.incrementCallDepth(ExecutorService.class) <= 0;
|
||||
}
|
||||
|
||||
/** Reset nested calls to executor. */
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
public static void resetNestedCalls() {
|
||||
CallDepthThreadLocalMap.reset(ExecutorService.class);
|
||||
}
|
||||
|
@ -265,8 +263,7 @@ public final class ExecutorInstrumentation extends Instrumenter.Default {
|
|||
* @param task task object
|
||||
* @return true iff given task object should be wrapped
|
||||
*/
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
public static boolean shouldWrapTask(Object task) {
|
||||
public static boolean shouldWrapTask(final Object task) {
|
||||
final Scope scope = GlobalTracer.get().scopeManager().active();
|
||||
return (scope instanceof TraceScope
|
||||
&& ((TraceScope) scope).isAsyncPropagating()
|
||||
|
@ -281,7 +278,6 @@ public final class ExecutorInstrumentation extends Instrumenter.Default {
|
|||
* @param wrapper task wrapper
|
||||
* @param throwable throwable that may have been thrown
|
||||
*/
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
public static void cleanUpOnMethodExit(
|
||||
final DatadogWrapper wrapper, final Throwable throwable) {
|
||||
if (null != wrapper) {
|
||||
|
@ -356,7 +352,7 @@ public final class ExecutorInstrumentation extends Instrumenter.Default {
|
|||
if (o instanceof DatadogWrapper) {
|
||||
return (DatadogWrapper) o;
|
||||
}
|
||||
} catch (IllegalArgumentException | IllegalAccessException e) {
|
||||
} catch (final IllegalArgumentException | IllegalAccessException e) {
|
||||
} finally {
|
||||
field.setAccessible(false);
|
||||
}
|
||||
|
|
|
@ -10,7 +10,12 @@ import com.google.auto.service.AutoService;
|
|||
import datadog.trace.agent.tooling.Instrumenter;
|
||||
import datadog.trace.instrumentation.java.concurrent.ExecutorInstrumentation.ConcurrentUtils;
|
||||
import datadog.trace.instrumentation.java.concurrent.ExecutorInstrumentation.DatadogWrapper;
|
||||
import java.util.*;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.Future;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.bytebuddy.asm.Advice;
|
||||
|
@ -91,7 +96,7 @@ public final class FutureInstrumentation extends Instrumenter.Default {
|
|||
|
||||
@Override
|
||||
public Map<ElementMatcher, String> transformers() {
|
||||
Map<ElementMatcher, String> transformers = new HashMap<>();
|
||||
final Map<ElementMatcher, String> transformers = new HashMap<>();
|
||||
transformers.put(
|
||||
named("cancel").and(returns(boolean.class)), CanceledFutureAdvice.class.getName());
|
||||
return transformers;
|
||||
|
|
|
@ -3,19 +3,20 @@ import datadog.trace.context.TraceScope
|
|||
import io.opentracing.util.GlobalTracer
|
||||
import slick.jdbc.H2Profile.api._
|
||||
|
||||
import scala.concurrent.{Await, Future}
|
||||
import scala.concurrent.duration.Duration
|
||||
import scala.concurrent.{Await, Future}
|
||||
|
||||
class SlickUtils {
|
||||
|
||||
import SlickUtils._
|
||||
|
||||
val database = Database.forURL(Url,
|
||||
user=Username,
|
||||
driver="org.h2.Driver",
|
||||
keepAliveConnection=true,
|
||||
user = Username,
|
||||
driver = "org.h2.Driver",
|
||||
keepAliveConnection = true,
|
||||
// Limit number of threads to hit Slick-specific case when we need to avoid re-wrapping
|
||||
// wrapped runnables.
|
||||
executor=AsyncExecutor("test", numThreads=1, queueSize=1000)
|
||||
executor = AsyncExecutor("test", numThreads = 1, queueSize = 1000)
|
||||
)
|
||||
Await.result(database.run(sqlu"""CREATE ALIAS SLEEP FOR "java.lang.Thread.sleep(long)""""), Duration.Inf)
|
||||
|
||||
|
|
|
@ -14,7 +14,9 @@ import io.opentracing.tag.Tags;
|
|||
import io.opentracing.util.GlobalTracer;
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.*;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Map;
|
||||
import javax.ws.rs.HttpMethod;
|
||||
import javax.ws.rs.Path;
|
||||
import net.bytebuddy.asm.Advice;
|
||||
|
|
|
@ -6,7 +6,7 @@ import static net.bytebuddy.matcher.ElementMatchers.named;
|
|||
import static net.bytebuddy.matcher.ElementMatchers.returns;
|
||||
|
||||
import com.google.auto.service.AutoService;
|
||||
import datadog.trace.agent.tooling.*;
|
||||
import datadog.trace.agent.tooling.Instrumenter;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import javax.ws.rs.client.ClientBuilder;
|
||||
|
@ -36,7 +36,7 @@ public final class JaxRsClientInstrumentation extends Instrumenter.Default {
|
|||
|
||||
@Override
|
||||
public Map<ElementMatcher, String> transformers() {
|
||||
Map<ElementMatcher, String> transformers = new HashMap<>();
|
||||
final Map<ElementMatcher, String> transformers = new HashMap<>();
|
||||
transformers.put(
|
||||
named("build").and(returns(hasSuperType(named("javax.ws.rs.client.Client")))),
|
||||
ClientBuilderAdvice.class.getName());
|
||||
|
|
|
@ -176,19 +176,19 @@ class JDBCInstrumentationTest extends AgentTestRunner {
|
|||
connection.close()
|
||||
|
||||
where:
|
||||
driver | connection | username | query
|
||||
"h2" | new Driver().connect(jdbcUrls.get("h2"), null) | null | "SELECT 3"
|
||||
"derby" | new EmbeddedDriver().connect(jdbcUrls.get("derby"), null)| "APP" | "SELECT 3 FROM SYSIBM.SYSDUMMY1"
|
||||
"hsqldb" | new JDBCDriver().connect(jdbcUrls.get("hsqldb"), null) | "SA" | "SELECT 3 FROM INFORMATION_SCHEMA.SYSTEM_USERS"
|
||||
"h2" | cpDatasources.get("tomcat").get("h2").getConnection() | null | "SELECT 3"
|
||||
"derby" | cpDatasources.get("tomcat").get("derby").getConnection() | "APP" | "SELECT 3 FROM SYSIBM.SYSDUMMY1"
|
||||
"hsqldb" | cpDatasources.get("tomcat").get("hsqldb").getConnection()| "SA" | "SELECT 3 FROM INFORMATION_SCHEMA.SYSTEM_USERS"
|
||||
"h2" | cpDatasources.get("hikari").get("h2").getConnection() | null | "SELECT 3"
|
||||
"derby" | cpDatasources.get("hikari").get("derby").getConnection() | "APP" | "SELECT 3 FROM SYSIBM.SYSDUMMY1"
|
||||
"hsqldb" | cpDatasources.get("hikari").get("hsqldb").getConnection()| "SA" | "SELECT 3 FROM INFORMATION_SCHEMA.SYSTEM_USERS"
|
||||
"h2" | cpDatasources.get("c3p0").get("h2").getConnection() | null | "SELECT 3"
|
||||
"derby" | cpDatasources.get("c3p0").get("derby").getConnection() | "APP" | "SELECT 3 FROM SYSIBM.SYSDUMMY1"
|
||||
"hsqldb" | cpDatasources.get("c3p0").get("hsqldb").getConnection() | "SA" | "SELECT 3 FROM INFORMATION_SCHEMA.SYSTEM_USERS"
|
||||
driver | connection | username | query
|
||||
"h2" | new Driver().connect(jdbcUrls.get("h2"), null) | null | "SELECT 3"
|
||||
"derby" | new EmbeddedDriver().connect(jdbcUrls.get("derby"), null) | "APP" | "SELECT 3 FROM SYSIBM.SYSDUMMY1"
|
||||
"hsqldb" | new JDBCDriver().connect(jdbcUrls.get("hsqldb"), null) | "SA" | "SELECT 3 FROM INFORMATION_SCHEMA.SYSTEM_USERS"
|
||||
"h2" | cpDatasources.get("tomcat").get("h2").getConnection() | null | "SELECT 3"
|
||||
"derby" | cpDatasources.get("tomcat").get("derby").getConnection() | "APP" | "SELECT 3 FROM SYSIBM.SYSDUMMY1"
|
||||
"hsqldb" | cpDatasources.get("tomcat").get("hsqldb").getConnection() | "SA" | "SELECT 3 FROM INFORMATION_SCHEMA.SYSTEM_USERS"
|
||||
"h2" | cpDatasources.get("hikari").get("h2").getConnection() | null | "SELECT 3"
|
||||
"derby" | cpDatasources.get("hikari").get("derby").getConnection() | "APP" | "SELECT 3 FROM SYSIBM.SYSDUMMY1"
|
||||
"hsqldb" | cpDatasources.get("hikari").get("hsqldb").getConnection() | "SA" | "SELECT 3 FROM INFORMATION_SCHEMA.SYSTEM_USERS"
|
||||
"h2" | cpDatasources.get("c3p0").get("h2").getConnection() | null | "SELECT 3"
|
||||
"derby" | cpDatasources.get("c3p0").get("derby").getConnection() | "APP" | "SELECT 3 FROM SYSIBM.SYSDUMMY1"
|
||||
"hsqldb" | cpDatasources.get("c3p0").get("hsqldb").getConnection() | "SA" | "SELECT 3 FROM INFORMATION_SCHEMA.SYSTEM_USERS"
|
||||
}
|
||||
|
||||
@Unroll
|
||||
|
@ -230,15 +230,15 @@ class JDBCInstrumentationTest extends AgentTestRunner {
|
|||
connection.close()
|
||||
|
||||
where:
|
||||
driver | connection | username | query
|
||||
"h2" | new Driver().connect(jdbcUrls.get("h2"), null) | null | "SELECT 3"
|
||||
"derby" | new EmbeddedDriver().connect(jdbcUrls.get("derby"), null)| "APP" | "SELECT 3 FROM SYSIBM.SYSDUMMY1"
|
||||
"h2" | cpDatasources.get("tomcat").get("h2").getConnection() | null | "SELECT 3"
|
||||
"derby" | cpDatasources.get("tomcat").get("derby").getConnection() | "APP" | "SELECT 3 FROM SYSIBM.SYSDUMMY1"
|
||||
"h2" | cpDatasources.get("hikari").get("h2").getConnection() | null | "SELECT 3"
|
||||
"derby" | cpDatasources.get("hikari").get("derby").getConnection() | "APP" | "SELECT 3 FROM SYSIBM.SYSDUMMY1"
|
||||
"h2" | cpDatasources.get("c3p0").get("h2").getConnection() | null | "SELECT 3"
|
||||
"derby" | cpDatasources.get("c3p0").get("derby").getConnection() | "APP" | "SELECT 3 FROM SYSIBM.SYSDUMMY1"
|
||||
driver | connection | username | query
|
||||
"h2" | new Driver().connect(jdbcUrls.get("h2"), null) | null | "SELECT 3"
|
||||
"derby" | new EmbeddedDriver().connect(jdbcUrls.get("derby"), null) | "APP" | "SELECT 3 FROM SYSIBM.SYSDUMMY1"
|
||||
"h2" | cpDatasources.get("tomcat").get("h2").getConnection() | null | "SELECT 3"
|
||||
"derby" | cpDatasources.get("tomcat").get("derby").getConnection() | "APP" | "SELECT 3 FROM SYSIBM.SYSDUMMY1"
|
||||
"h2" | cpDatasources.get("hikari").get("h2").getConnection() | null | "SELECT 3"
|
||||
"derby" | cpDatasources.get("hikari").get("derby").getConnection() | "APP" | "SELECT 3 FROM SYSIBM.SYSDUMMY1"
|
||||
"h2" | cpDatasources.get("c3p0").get("h2").getConnection() | null | "SELECT 3"
|
||||
"derby" | cpDatasources.get("c3p0").get("derby").getConnection() | "APP" | "SELECT 3 FROM SYSIBM.SYSDUMMY1"
|
||||
}
|
||||
|
||||
@Unroll
|
||||
|
@ -279,15 +279,15 @@ class JDBCInstrumentationTest extends AgentTestRunner {
|
|||
connection.close()
|
||||
|
||||
where:
|
||||
driver | connection | username | query
|
||||
"h2" | new Driver().connect(jdbcUrls.get("h2"), null) | null | "SELECT 3"
|
||||
"derby" | new EmbeddedDriver().connect(jdbcUrls.get("derby"), null)| "APP" | "SELECT 3 FROM SYSIBM.SYSDUMMY1"
|
||||
"h2" | cpDatasources.get("tomcat").get("h2").getConnection() | null | "SELECT 3"
|
||||
"derby" | cpDatasources.get("tomcat").get("derby").getConnection() | "APP" | "SELECT 3 FROM SYSIBM.SYSDUMMY1"
|
||||
"h2" | cpDatasources.get("hikari").get("h2").getConnection() | null | "SELECT 3"
|
||||
"derby" | cpDatasources.get("hikari").get("derby").getConnection() | "APP" | "SELECT 3 FROM SYSIBM.SYSDUMMY1"
|
||||
"h2" | cpDatasources.get("c3p0").get("h2").getConnection() | null | "SELECT 3"
|
||||
"derby" | cpDatasources.get("c3p0").get("derby").getConnection() | "APP" | "SELECT 3 FROM SYSIBM.SYSDUMMY1"
|
||||
driver | connection | username | query
|
||||
"h2" | new Driver().connect(jdbcUrls.get("h2"), null) | null | "SELECT 3"
|
||||
"derby" | new EmbeddedDriver().connect(jdbcUrls.get("derby"), null) | "APP" | "SELECT 3 FROM SYSIBM.SYSDUMMY1"
|
||||
"h2" | cpDatasources.get("tomcat").get("h2").getConnection() | null | "SELECT 3"
|
||||
"derby" | cpDatasources.get("tomcat").get("derby").getConnection() | "APP" | "SELECT 3 FROM SYSIBM.SYSDUMMY1"
|
||||
"h2" | cpDatasources.get("hikari").get("h2").getConnection() | null | "SELECT 3"
|
||||
"derby" | cpDatasources.get("hikari").get("derby").getConnection() | "APP" | "SELECT 3 FROM SYSIBM.SYSDUMMY1"
|
||||
"h2" | cpDatasources.get("c3p0").get("h2").getConnection() | null | "SELECT 3"
|
||||
"derby" | cpDatasources.get("c3p0").get("derby").getConnection() | "APP" | "SELECT 3 FROM SYSIBM.SYSDUMMY1"
|
||||
}
|
||||
|
||||
@Unroll
|
||||
|
@ -328,19 +328,19 @@ class JDBCInstrumentationTest extends AgentTestRunner {
|
|||
connection.close()
|
||||
|
||||
where:
|
||||
driver | connection | username | query
|
||||
"h2" | new Driver().connect(jdbcUrls.get("h2"), null) | null | "CREATE TABLE S_H2 (id INTEGER not NULL, PRIMARY KEY ( id ))"
|
||||
"derby" | new EmbeddedDriver().connect(jdbcUrls.get("derby"), null)| "APP" | "CREATE TABLE S_DERBY (id INTEGER not NULL, PRIMARY KEY ( id ))"
|
||||
"hsqldb" | new JDBCDriver().connect(jdbcUrls.get("hsqldb"), null) | "SA" | "CREATE TABLE PUBLIC.S_HSQLDB (id INTEGER not NULL, PRIMARY KEY ( id ))"
|
||||
"h2" | cpDatasources.get("tomcat").get("h2").getConnection() | null | "CREATE TABLE S_H2_TOMCAT (id INTEGER not NULL, PRIMARY KEY ( id ))"
|
||||
"derby" | cpDatasources.get("tomcat").get("derby").getConnection() | "APP" | "CREATE TABLE S_DERBY_TOMCAT (id INTEGER not NULL, PRIMARY KEY ( id ))"
|
||||
"hsqldb" | cpDatasources.get("tomcat").get("hsqldb").getConnection()| "SA" | "CREATE TABLE PUBLIC.S_HSQLDB_TOMCAT (id INTEGER not NULL, PRIMARY KEY ( id ))"
|
||||
"h2" | cpDatasources.get("hikari").get("h2").getConnection() | null | "CREATE TABLE S_H2_HIKARI (id INTEGER not NULL, PRIMARY KEY ( id ))"
|
||||
"derby" | cpDatasources.get("hikari").get("derby").getConnection() | "APP" | "CREATE TABLE S_DERBY_HIKARI (id INTEGER not NULL, PRIMARY KEY ( id ))"
|
||||
"hsqldb" | cpDatasources.get("hikari").get("hsqldb").getConnection()| "SA" | "CREATE TABLE PUBLIC.S_HSQLDB_HIKARI (id INTEGER not NULL, PRIMARY KEY ( id ))"
|
||||
"h2" | cpDatasources.get("c3p0").get("h2").getConnection() | null | "CREATE TABLE S_H2_C3P0 (id INTEGER not NULL, PRIMARY KEY ( id ))"
|
||||
"derby" | cpDatasources.get("c3p0").get("derby").getConnection() | "APP" | "CREATE TABLE S_DERBY_C3P0 (id INTEGER not NULL, PRIMARY KEY ( id ))"
|
||||
"hsqldb" | cpDatasources.get("c3p0").get("hsqldb").getConnection() | "SA" | "CREATE TABLE PUBLIC.S_HSQLDB_C3P0 (id INTEGER not NULL, PRIMARY KEY ( id ))"
|
||||
driver | connection | username | query
|
||||
"h2" | new Driver().connect(jdbcUrls.get("h2"), null) | null | "CREATE TABLE S_H2 (id INTEGER not NULL, PRIMARY KEY ( id ))"
|
||||
"derby" | new EmbeddedDriver().connect(jdbcUrls.get("derby"), null) | "APP" | "CREATE TABLE S_DERBY (id INTEGER not NULL, PRIMARY KEY ( id ))"
|
||||
"hsqldb" | new JDBCDriver().connect(jdbcUrls.get("hsqldb"), null) | "SA" | "CREATE TABLE PUBLIC.S_HSQLDB (id INTEGER not NULL, PRIMARY KEY ( id ))"
|
||||
"h2" | cpDatasources.get("tomcat").get("h2").getConnection() | null | "CREATE TABLE S_H2_TOMCAT (id INTEGER not NULL, PRIMARY KEY ( id ))"
|
||||
"derby" | cpDatasources.get("tomcat").get("derby").getConnection() | "APP" | "CREATE TABLE S_DERBY_TOMCAT (id INTEGER not NULL, PRIMARY KEY ( id ))"
|
||||
"hsqldb" | cpDatasources.get("tomcat").get("hsqldb").getConnection() | "SA" | "CREATE TABLE PUBLIC.S_HSQLDB_TOMCAT (id INTEGER not NULL, PRIMARY KEY ( id ))"
|
||||
"h2" | cpDatasources.get("hikari").get("h2").getConnection() | null | "CREATE TABLE S_H2_HIKARI (id INTEGER not NULL, PRIMARY KEY ( id ))"
|
||||
"derby" | cpDatasources.get("hikari").get("derby").getConnection() | "APP" | "CREATE TABLE S_DERBY_HIKARI (id INTEGER not NULL, PRIMARY KEY ( id ))"
|
||||
"hsqldb" | cpDatasources.get("hikari").get("hsqldb").getConnection() | "SA" | "CREATE TABLE PUBLIC.S_HSQLDB_HIKARI (id INTEGER not NULL, PRIMARY KEY ( id ))"
|
||||
"h2" | cpDatasources.get("c3p0").get("h2").getConnection() | null | "CREATE TABLE S_H2_C3P0 (id INTEGER not NULL, PRIMARY KEY ( id ))"
|
||||
"derby" | cpDatasources.get("c3p0").get("derby").getConnection() | "APP" | "CREATE TABLE S_DERBY_C3P0 (id INTEGER not NULL, PRIMARY KEY ( id ))"
|
||||
"hsqldb" | cpDatasources.get("c3p0").get("hsqldb").getConnection() | "SA" | "CREATE TABLE PUBLIC.S_HSQLDB_C3P0 (id INTEGER not NULL, PRIMARY KEY ( id ))"
|
||||
}
|
||||
|
||||
@Unroll
|
||||
|
@ -380,18 +380,18 @@ class JDBCInstrumentationTest extends AgentTestRunner {
|
|||
connection.close()
|
||||
|
||||
where:
|
||||
driver | connection | username | query
|
||||
"h2" | new Driver().connect(jdbcUrls.get("h2"), null) | null | "CREATE TABLE PS_H2 (id INTEGER not NULL, PRIMARY KEY ( id ))"
|
||||
"derby" | new EmbeddedDriver().connect(jdbcUrls.get("derby"), null)| "APP" | "CREATE TABLE PS_DERBY (id INTEGER not NULL, PRIMARY KEY ( id ))"
|
||||
"h2" | cpDatasources.get("tomcat").get("h2").getConnection() | null | "CREATE TABLE PS_H2_TOMCAT (id INTEGER not NULL, PRIMARY KEY ( id ))"
|
||||
"derby" | cpDatasources.get("tomcat").get("derby").getConnection() | "APP" | "CREATE TABLE PS_DERBY_TOMCAT (id INTEGER not NULL, PRIMARY KEY ( id ))"
|
||||
"h2" | cpDatasources.get("hikari").get("h2").getConnection() | null | "CREATE TABLE PS_H2_HIKARI (id INTEGER not NULL, PRIMARY KEY ( id ))"
|
||||
"derby" | cpDatasources.get("hikari").get("derby").getConnection() | "APP" | "CREATE TABLE PS_DERBY_HIKARI (id INTEGER not NULL, PRIMARY KEY ( id ))"
|
||||
"h2" | cpDatasources.get("c3p0").get("h2").getConnection() | null | "CREATE TABLE PS_H2_C3P0 (id INTEGER not NULL, PRIMARY KEY ( id ))"
|
||||
"derby" | cpDatasources.get("c3p0").get("derby").getConnection() | "APP" | "CREATE TABLE PS_DERBY_C3P0 (id INTEGER not NULL, PRIMARY KEY ( id ))"
|
||||
driver | connection | username | query
|
||||
"h2" | new Driver().connect(jdbcUrls.get("h2"), null) | null | "CREATE TABLE PS_H2 (id INTEGER not NULL, PRIMARY KEY ( id ))"
|
||||
"derby" | new EmbeddedDriver().connect(jdbcUrls.get("derby"), null) | "APP" | "CREATE TABLE PS_DERBY (id INTEGER not NULL, PRIMARY KEY ( id ))"
|
||||
"h2" | cpDatasources.get("tomcat").get("h2").getConnection() | null | "CREATE TABLE PS_H2_TOMCAT (id INTEGER not NULL, PRIMARY KEY ( id ))"
|
||||
"derby" | cpDatasources.get("tomcat").get("derby").getConnection() | "APP" | "CREATE TABLE PS_DERBY_TOMCAT (id INTEGER not NULL, PRIMARY KEY ( id ))"
|
||||
"h2" | cpDatasources.get("hikari").get("h2").getConnection() | null | "CREATE TABLE PS_H2_HIKARI (id INTEGER not NULL, PRIMARY KEY ( id ))"
|
||||
"derby" | cpDatasources.get("hikari").get("derby").getConnection() | "APP" | "CREATE TABLE PS_DERBY_HIKARI (id INTEGER not NULL, PRIMARY KEY ( id ))"
|
||||
"h2" | cpDatasources.get("c3p0").get("h2").getConnection() | null | "CREATE TABLE PS_H2_C3P0 (id INTEGER not NULL, PRIMARY KEY ( id ))"
|
||||
"derby" | cpDatasources.get("c3p0").get("derby").getConnection() | "APP" | "CREATE TABLE PS_DERBY_C3P0 (id INTEGER not NULL, PRIMARY KEY ( id ))"
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Unroll
|
||||
def "connection constructor throwing then generating correct spans after recovery using #driver connection (prepare statement = #prepareStatement)"() {
|
||||
setup:
|
||||
|
@ -454,11 +454,11 @@ class JDBCInstrumentationTest extends AgentTestRunner {
|
|||
}
|
||||
|
||||
where:
|
||||
prepareStatement | driver | driverClass | url | username | query
|
||||
true | "h2" | new Driver() | "jdbc:h2:mem:" + dbName | null | "SELECT 3;"
|
||||
true | "derby" | new EmbeddedDriver() | "jdbc:derby:memory:" + dbName + ";create=true" | "APP" | "SELECT 3 FROM SYSIBM.SYSDUMMY1"
|
||||
false | "h2" | new Driver() | "jdbc:h2:mem:" + dbName | null | "SELECT 3;"
|
||||
false | "derby" | new EmbeddedDriver() | "jdbc:derby:memory:" + dbName + ";create=true" | "APP" | "SELECT 3 FROM SYSIBM.SYSDUMMY1"
|
||||
prepareStatement | driver | driverClass | url | username | query
|
||||
true | "h2" | new Driver() | "jdbc:h2:mem:" + dbName | null | "SELECT 3;"
|
||||
true | "derby" | new EmbeddedDriver() | "jdbc:derby:memory:" + dbName + ";create=true" | "APP" | "SELECT 3 FROM SYSIBM.SYSDUMMY1"
|
||||
false | "h2" | new Driver() | "jdbc:h2:mem:" + dbName | null | "SELECT 3;"
|
||||
false | "derby" | new EmbeddedDriver() | "jdbc:derby:memory:" + dbName + ";create=true" | "APP" | "SELECT 3 FROM SYSIBM.SYSDUMMY1"
|
||||
}
|
||||
|
||||
@Unroll
|
||||
|
|
|
@ -11,7 +11,7 @@ import static net.bytebuddy.matcher.ElementMatchers.not;
|
|||
import static net.bytebuddy.matcher.ElementMatchers.takesArguments;
|
||||
|
||||
import com.google.auto.service.AutoService;
|
||||
import datadog.trace.agent.tooling.*;
|
||||
import datadog.trace.agent.tooling.Instrumenter;
|
||||
import datadog.trace.api.DDSpanTypes;
|
||||
import datadog.trace.api.DDTags;
|
||||
import datadog.trace.instrumentation.jms.util.MessagePropertyTextMap;
|
||||
|
@ -23,7 +23,9 @@ import io.opentracing.propagation.Format;
|
|||
import io.opentracing.tag.Tags;
|
||||
import io.opentracing.util.GlobalTracer;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.*;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import javax.jms.Message;
|
||||
import javax.jms.MessageConsumer;
|
||||
|
|
|
@ -1,7 +1,12 @@
|
|||
package datadog.trace.instrumentation.jsp;
|
||||
|
||||
import static io.opentracing.log.Fields.ERROR_OBJECT;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.*;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.hasSuperType;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.isInterface;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.isPublic;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.named;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.not;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
|
||||
|
||||
import com.google.auto.service.AutoService;
|
||||
import datadog.trace.agent.tooling.Instrumenter;
|
||||
|
|
|
@ -2,7 +2,9 @@ package datadog.trace.instrumentation.jsp;
|
|||
|
||||
import static datadog.trace.agent.tooling.ClassLoaderMatcher.classLoaderHasClasses;
|
||||
import static io.opentracing.log.Fields.ERROR_OBJECT;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.*;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.isPublic;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.named;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.takesArguments;
|
||||
|
||||
import com.google.auto.service.AutoService;
|
||||
import datadog.trace.agent.tooling.Instrumenter;
|
||||
|
|
|
@ -144,10 +144,10 @@ class JSPInstrumentationBasicTests extends AgentTestRunner {
|
|||
res.close()
|
||||
|
||||
where:
|
||||
test | jspFileName | jspClassName | jspClassNamePrefix
|
||||
"no java jsp" | "nojava.jsp" | "nojava_jsp" | ""
|
||||
"basic loop jsp"|"common/loop.jsp" | "loop_jsp" | "common."
|
||||
"invalid HTML markup"|"invalidMarkup.jsp" | "invalidMarkup_jsp" | ""
|
||||
test | jspFileName | jspClassName | jspClassNamePrefix
|
||||
"no java jsp" | "nojava.jsp" | "nojava_jsp" | ""
|
||||
"basic loop jsp" | "common/loop.jsp" | "loop_jsp" | "common."
|
||||
"invalid HTML markup" | "invalidMarkup.jsp" | "invalidMarkup_jsp" | ""
|
||||
}
|
||||
|
||||
def "non-erroneous GET with query string"() {
|
||||
|
@ -368,10 +368,10 @@ class JSPInstrumentationBasicTests extends AgentTestRunner {
|
|||
res.close()
|
||||
|
||||
where:
|
||||
test | jspFileName | jspClassName | exceptionClass | errorMessage
|
||||
"java runtime error" | "runtimeError.jsp" | "runtimeError_jsp" | ArithmeticException | String
|
||||
"invalid write" | "invalidWrite.jsp" | "invalidWrite_jsp" | StringIndexOutOfBoundsException | String
|
||||
"missing query gives null" | "getQuery.jsp" | "getQuery_jsp" | NullPointerException | null
|
||||
test | jspFileName | jspClassName | exceptionClass | errorMessage
|
||||
"java runtime error" | "runtimeError.jsp" | "runtimeError_jsp" | ArithmeticException | String
|
||||
"invalid write" | "invalidWrite.jsp" | "invalidWrite_jsp" | StringIndexOutOfBoundsException | String
|
||||
"missing query gives null" | "getQuery.jsp" | "getQuery_jsp" | NullPointerException | null
|
||||
}
|
||||
|
||||
def "non-erroneous include plain HTML GET"() {
|
||||
|
@ -638,8 +638,8 @@ class JSPInstrumentationBasicTests extends AgentTestRunner {
|
|||
res.close()
|
||||
|
||||
where:
|
||||
test | jspFileName | jspClassName | jspClassNamePrefix
|
||||
"normal" | "compileError.jsp" | "compileError_jsp" | ""
|
||||
"forward"|"forwards/forwardWithCompileError.jsp" | "forwardWithCompileError_jsp" | "forwards."
|
||||
test | jspFileName | jspClassName | jspClassNamePrefix
|
||||
"normal" | "compileError.jsp" | "compileError_jsp" | ""
|
||||
"forward" | "forwards/forwardWithCompileError.jsp" | "forwardWithCompileError_jsp" | "forwards."
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,9 @@ import datadog.trace.agent.test.OkHttpUtils
|
|||
import datadog.trace.agent.test.TestUtils
|
||||
import datadog.trace.api.DDSpanTypes
|
||||
import io.netty.handler.codec.http.HttpResponseStatus
|
||||
import okhttp3.*
|
||||
import okhttp3.OkHttpClient
|
||||
import okhttp3.Request
|
||||
import okhttp3.Response
|
||||
import org.apache.catalina.Context
|
||||
import org.apache.catalina.startup.Tomcat
|
||||
import org.apache.jasper.JasperException
|
||||
|
@ -174,9 +176,9 @@ class JSPInstrumentationForwardTests extends AgentTestRunner {
|
|||
res.close()
|
||||
|
||||
where:
|
||||
forwardTo | forwardFromFileName | forwardDestFileName | jspForwardFromClassName | jspForwardFromClassPrefix | jspForwardDestClassName | jspForwardDestClassPrefix
|
||||
"no java jsp" | "forwards/forwardToNoJavaJsp.jsp" | "nojava.jsp" | "forwardToNoJavaJsp_jsp" | "forwards." | "nojava_jsp" | ""
|
||||
"normal java jsp" | "forwards/forwardToSimpleJava.jsp" | "common/loop.jsp" | "forwardToSimpleJava_jsp" | "forwards." | "loop_jsp" | "common."
|
||||
forwardTo | forwardFromFileName | forwardDestFileName | jspForwardFromClassName | jspForwardFromClassPrefix | jspForwardDestClassName | jspForwardDestClassPrefix
|
||||
"no java jsp" | "forwards/forwardToNoJavaJsp.jsp" | "nojava.jsp" | "forwardToNoJavaJsp_jsp" | "forwards." | "nojava_jsp" | ""
|
||||
"normal java jsp" | "forwards/forwardToSimpleJava.jsp" | "common/loop.jsp" | "forwardToSimpleJava_jsp" | "forwards." | "loop_jsp" | "common."
|
||||
}
|
||||
|
||||
def "non-erroneous GET forward to plain HTML"() {
|
||||
|
|
|
@ -5,7 +5,7 @@ versionScan {
|
|||
module = "kafka-streams"
|
||||
versions = "[0.11.0.0,)"
|
||||
verifyPresent = [
|
||||
'org.apache.kafka.streams.state.internals.OrderedBytes' : null
|
||||
'org.apache.kafka.streams.state.internals.OrderedBytes': null
|
||||
]
|
||||
}
|
||||
|
||||
|
|
|
@ -51,7 +51,7 @@ dependencies {
|
|||
compile deps.opentracing
|
||||
annotationProcessor deps.autoservice
|
||||
implementation deps.autoservice
|
||||
|
||||
|
||||
testCompile project(':dd-java-agent:testing')
|
||||
|
||||
testCompile group: 'com.github.kstyrc', name: 'embedded-redis', version: '0.6'
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
package datadog.trace.instrumentation.lettuce;
|
||||
|
||||
import static datadog.trace.agent.tooling.ClassLoaderMatcher.classLoaderHasClasses;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.*;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.isMethod;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.named;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
|
||||
|
||||
import com.google.auto.service.AutoService;
|
||||
import datadog.trace.agent.tooling.Instrumenter;
|
||||
|
@ -38,7 +40,7 @@ public class LettuceAsyncCommandsInstrumentation extends Instrumenter.Default {
|
|||
|
||||
@Override
|
||||
public Map<ElementMatcher, String> transformers() {
|
||||
Map<ElementMatcher, String> transformers = new HashMap<>();
|
||||
final Map<ElementMatcher, String> transformers = new HashMap<>();
|
||||
transformers.put(
|
||||
isMethod()
|
||||
.and(named("dispatch"))
|
||||
|
|
|
@ -1,7 +1,13 @@
|
|||
package datadog.trace.instrumentation.lettuce;
|
||||
|
||||
import static datadog.trace.agent.tooling.ClassLoaderMatcher.classLoaderHasClasses;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.*;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.isMethod;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.isPrivate;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.nameEndsWith;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.nameStartsWith;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.named;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.returns;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
|
||||
|
||||
import com.google.auto.service.AutoService;
|
||||
import datadog.trace.agent.tooling.Instrumenter;
|
||||
|
@ -42,7 +48,7 @@ public final class LettuceClientInstrumentation extends Instrumenter.Default {
|
|||
|
||||
@Override
|
||||
public Map<ElementMatcher, String> transformers() {
|
||||
Map<ElementMatcher, String> transformers = new HashMap<>();
|
||||
final Map<ElementMatcher, String> transformers = new HashMap<>();
|
||||
transformers.put(
|
||||
isMethod()
|
||||
.and(isPrivate())
|
||||
|
|
|
@ -1,7 +1,12 @@
|
|||
package datadog.trace.instrumentation.lettuce;
|
||||
|
||||
import static datadog.trace.agent.tooling.ClassLoaderMatcher.classLoaderHasClasses;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.*;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.isMethod;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.nameEndsWith;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.nameStartsWith;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.named;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.returns;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
|
||||
|
||||
import com.google.auto.service.AutoService;
|
||||
import datadog.trace.agent.tooling.Instrumenter;
|
||||
|
@ -43,7 +48,7 @@ public class LettuceReactiveCommandsInstrumentation extends Instrumenter.Default
|
|||
|
||||
@Override
|
||||
public Map<ElementMatcher, String> transformers() {
|
||||
Map<ElementMatcher, String> transformers = new HashMap<>();
|
||||
final Map<ElementMatcher, String> transformers = new HashMap<>();
|
||||
transformers.put(
|
||||
isMethod()
|
||||
.and(named("createMono"))
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
package datadog.trace.instrumentation.lettuce;
|
||||
|
||||
import io.lettuce.core.protocol.RedisCommand;
|
||||
import java.util.*;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
public class LettuceInstrumentationUtil {
|
||||
|
||||
|
@ -30,7 +32,7 @@ public class LettuceInstrumentationUtil {
|
|||
* @param commandName a redis command, without any prefixes
|
||||
* @return true if finish the span early (the command will not have a return value)
|
||||
*/
|
||||
public static boolean doFinishSpanEarly(String commandName) {
|
||||
public static boolean doFinishSpanEarly(final String commandName) {
|
||||
return nonInstrumentingCommands.contains(commandName);
|
||||
}
|
||||
|
||||
|
@ -51,7 +53,7 @@ public class LettuceInstrumentationUtil {
|
|||
* @return the redis command with a prefix if it is a command that will crash the trace agent,
|
||||
* otherwise, the original command is returned.
|
||||
*/
|
||||
public static String getCommandResourceName(String actualCommandName) {
|
||||
public static String getCommandResourceName(final String actualCommandName) {
|
||||
if (agentCrashingCommands.contains(actualCommandName)) {
|
||||
return AGENT_CRASHING_COMMAND_PREFIX + actualCommandName;
|
||||
}
|
||||
|
@ -64,7 +66,7 @@ public class LettuceInstrumentationUtil {
|
|||
* @param command the lettuce RedisCommand object
|
||||
* @return the redis command as a string
|
||||
*/
|
||||
public static String getCommandName(RedisCommand command) {
|
||||
public static String getCommandName(final RedisCommand command) {
|
||||
String commandName = "Redis Command";
|
||||
if (command != null) {
|
||||
/*
|
||||
|
|
|
@ -50,9 +50,9 @@ class LettuceAsyncClientTest extends AgentTestRunner {
|
|||
|
||||
@Shared
|
||||
Map<String, String> testHashMap = [
|
||||
firstname: "John",
|
||||
lastname: "Doe",
|
||||
age: "53"
|
||||
firstname: "John",
|
||||
lastname : "Doe",
|
||||
age : "53"
|
||||
]
|
||||
|
||||
RedisClient redisClient
|
||||
|
@ -254,7 +254,7 @@ class LettuceAsyncClientTest extends AgentTestRunner {
|
|||
BiFunction<String, Throwable, String> firstStage = new BiFunction<String, Throwable, String>() {
|
||||
@Override
|
||||
String apply(String res, Throwable throwable) {
|
||||
conds.evaluate{
|
||||
conds.evaluate {
|
||||
assert res == null
|
||||
assert throwable == null
|
||||
}
|
||||
|
@ -264,7 +264,7 @@ class LettuceAsyncClientTest extends AgentTestRunner {
|
|||
Function<String, Object> secondStage = new Function<String, Object>() {
|
||||
@Override
|
||||
Object apply(String input) {
|
||||
conds.evaluate{
|
||||
conds.evaluate {
|
||||
assert input == successStr
|
||||
}
|
||||
return null
|
||||
|
@ -304,7 +304,7 @@ class LettuceAsyncClientTest extends AgentTestRunner {
|
|||
BiConsumer<String, Throwable> biConsumer = new BiConsumer<String, Throwable>() {
|
||||
@Override
|
||||
void accept(String keyRetrieved, Throwable throwable) {
|
||||
conds.evaluate{
|
||||
conds.evaluate {
|
||||
assert keyRetrieved != null
|
||||
}
|
||||
}
|
||||
|
@ -419,7 +419,7 @@ class LettuceAsyncClientTest extends AgentTestRunner {
|
|||
def conds = new AsyncConditions()
|
||||
RedisFuture redisFuture = asyncCommands.del("key1", "key2")
|
||||
boolean completedExceptionally = ((AsyncCommand) redisFuture).completeExceptionally(new IllegalStateException("TestException"))
|
||||
redisFuture.exceptionally ({
|
||||
redisFuture.exceptionally({
|
||||
throwable ->
|
||||
conds.evaluate {
|
||||
assert throwable != null
|
||||
|
@ -466,10 +466,11 @@ class LettuceAsyncClientTest extends AgentTestRunner {
|
|||
def conds = new AsyncConditions()
|
||||
RedisFuture redisFuture = asyncCommands.sadd("SKEY", "1", "2")
|
||||
redisFuture.whenCompleteAsync({
|
||||
res, throwable -> conds.evaluate {
|
||||
assert throwable != null
|
||||
assert throwable instanceof CancellationException
|
||||
}
|
||||
res, throwable ->
|
||||
conds.evaluate {
|
||||
assert throwable != null
|
||||
assert throwable instanceof CancellationException
|
||||
}
|
||||
})
|
||||
|
||||
when:
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import datadog.trace.agent.test.AgentTestRunner
|
||||
import datadog.trace.agent.test.TestUtils
|
||||
import io.lettuce.core.*
|
||||
import io.lettuce.core.ClientOptions
|
||||
import io.lettuce.core.RedisClient
|
||||
import io.lettuce.core.api.StatefulConnection
|
||||
import io.lettuce.core.api.reactive.RedisReactiveCommands
|
||||
import io.lettuce.core.api.sync.RedisCommands
|
||||
|
@ -36,9 +37,9 @@ class LettuceReactiveClientTest extends AgentTestRunner {
|
|||
embeddedDbUri = "redis://" + dbAddr
|
||||
|
||||
redisServer = RedisServer.builder()
|
||||
// bind to localhost to avoid firewall popup
|
||||
// bind to localhost to avoid firewall popup
|
||||
.setting("bind " + HOST)
|
||||
// set max memory to avoid problems in CI
|
||||
// set max memory to avoid problems in CI
|
||||
.setting("maxmemory 128M")
|
||||
.port(port).build()
|
||||
}
|
||||
|
@ -109,7 +110,7 @@ class LettuceReactiveClientTest extends AgentTestRunner {
|
|||
def conds = new AsyncConditions()
|
||||
|
||||
when:
|
||||
reactiveCommands.get("TESTKEY").subscribe { res -> conds.evaluate { assert res == "TESTVAL"} }
|
||||
reactiveCommands.get("TESTKEY").subscribe { res -> conds.evaluate { assert res == "TESTVAL" } }
|
||||
|
||||
then:
|
||||
conds.await()
|
||||
|
@ -143,9 +144,10 @@ class LettuceReactiveClientTest extends AgentTestRunner {
|
|||
|
||||
when:
|
||||
reactiveCommands.get("NON_EXISTENT_KEY").defaultIfEmpty(defaultVal).subscribe {
|
||||
res -> conds.evaluate {
|
||||
assert res == defaultVal
|
||||
}
|
||||
res ->
|
||||
conds.evaluate {
|
||||
assert res == defaultVal
|
||||
}
|
||||
}
|
||||
|
||||
then:
|
||||
|
@ -178,9 +180,10 @@ class LettuceReactiveClientTest extends AgentTestRunner {
|
|||
|
||||
when:
|
||||
reactiveCommands.randomkey().subscribe {
|
||||
res -> conds.evaluate {
|
||||
assert res == "TESTKEY"
|
||||
}
|
||||
res ->
|
||||
conds.evaluate {
|
||||
assert res == "TESTKEY"
|
||||
}
|
||||
}
|
||||
|
||||
then:
|
||||
|
|
|
@ -37,9 +37,9 @@ class LettuceSyncClientTest extends AgentTestRunner {
|
|||
|
||||
@Shared
|
||||
Map<String, String> testHashMap = [
|
||||
firstname: "John",
|
||||
lastname: "Doe",
|
||||
age: "53"
|
||||
firstname: "John",
|
||||
lastname : "Doe",
|
||||
age : "53"
|
||||
]
|
||||
|
||||
RedisClient redisClient
|
||||
|
@ -55,9 +55,9 @@ class LettuceSyncClientTest extends AgentTestRunner {
|
|||
embeddedDbUri = "redis://" + dbAddr
|
||||
|
||||
redisServer = RedisServer.builder()
|
||||
// bind to localhost to avoid firewall popup
|
||||
// bind to localhost to avoid firewall popup
|
||||
.setting("bind " + HOST)
|
||||
// set max memory to avoid problems in CI
|
||||
// set max memory to avoid problems in CI
|
||||
.setting("maxmemory 128M")
|
||||
.port(port).build()
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ versionScan {
|
|||
scanMethods = true
|
||||
versions = "[3.3,)"
|
||||
verifyPresent = [
|
||||
'com.mongodb.async.client.MongoClientSettings$Builder': 'addCommandListener'
|
||||
'com.mongodb.async.client.MongoClientSettings$Builder': 'addCommandListener'
|
||||
]
|
||||
}
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@ class Play26Test extends AgentTestRunner {
|
|||
testServer.stop()
|
||||
}
|
||||
|
||||
def "request traces" () {
|
||||
def "request traces"() {
|
||||
setup:
|
||||
OkHttpClient client = new OkHttpClient.Builder().build()
|
||||
def request = new Request.Builder()
|
||||
|
@ -83,7 +83,7 @@ class Play26Test extends AgentTestRunner {
|
|||
}
|
||||
}
|
||||
|
||||
def "5xx errors trace" () {
|
||||
def "5xx errors trace"() {
|
||||
setup:
|
||||
OkHttpClient client = new OkHttpClient.Builder().build()
|
||||
def request = new Request.Builder()
|
||||
|
@ -132,7 +132,7 @@ class Play26Test extends AgentTestRunner {
|
|||
}
|
||||
}
|
||||
|
||||
def "error thrown in request" () {
|
||||
def "error thrown in request"() {
|
||||
setup:
|
||||
OkHttpClient client = new OkHttpClient.Builder().build()
|
||||
def request = new Request.Builder()
|
||||
|
@ -185,7 +185,7 @@ class Play26Test extends AgentTestRunner {
|
|||
}
|
||||
}
|
||||
|
||||
def "4xx errors trace" () {
|
||||
def "4xx errors trace"() {
|
||||
setup:
|
||||
OkHttpClient client = new OkHttpClient.Builder().build()
|
||||
def request = new Request.Builder()
|
||||
|
|
|
@ -1,21 +1,19 @@
|
|||
import play.api.mvc.Action
|
||||
import play.api.routing.{HandlerDef, Router}
|
||||
import play.api.mvc._
|
||||
import play.api.routing.sird._
|
||||
import java.lang.reflect.Field
|
||||
|
||||
import datadog.trace.api.Trace
|
||||
import play.api.libs.typedmap.TypedKey
|
||||
import play.api.mvc.request.RequestAttrKey
|
||||
import play.api.mvc.{Action, _}
|
||||
import play.api.routing.sird._
|
||||
import play.api.routing.{HandlerDef, Router}
|
||||
|
||||
import scala.concurrent.{Await, Future}
|
||||
import scala.concurrent.duration._
|
||||
import scala.concurrent.{Await, Future}
|
||||
|
||||
|
||||
object Play26TestUtils {
|
||||
def buildTestApp(): play.Application = {
|
||||
// build play.api.Application with desired setting and pass into play.Application for testing
|
||||
val apiApp :play.api.Application = new play.api.inject.guice.GuiceApplicationBuilder()
|
||||
val apiApp: play.api.Application = new play.api.inject.guice.GuiceApplicationBuilder()
|
||||
.requireAtInjectOnConstructors(true)
|
||||
.router(
|
||||
Router.from {
|
||||
|
|
|
@ -3,11 +3,14 @@ package datadog.trace.instrumentation.play;
|
|||
import static datadog.trace.agent.tooling.ClassLoaderMatcher.classLoaderHasClassWithMethod;
|
||||
import static datadog.trace.agent.tooling.ClassLoaderMatcher.classLoaderHasClasses;
|
||||
import static io.opentracing.log.Fields.ERROR_OBJECT;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.*;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.hasSuperType;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.named;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.returns;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
|
||||
|
||||
import akka.japi.JavaPartialFunction;
|
||||
import com.google.auto.service.AutoService;
|
||||
import datadog.trace.agent.tooling.*;
|
||||
import datadog.trace.agent.tooling.Instrumenter;
|
||||
import datadog.trace.api.DDSpanTypes;
|
||||
import datadog.trace.api.DDTags;
|
||||
import datadog.trace.context.TraceScope;
|
||||
|
@ -18,7 +21,10 @@ import io.opentracing.propagation.Format;
|
|||
import io.opentracing.propagation.TextMap;
|
||||
import io.opentracing.tag.Tags;
|
||||
import io.opentracing.util.GlobalTracer;
|
||||
import java.util.*;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.bytebuddy.asm.Advice;
|
||||
import net.bytebuddy.matcher.ElementMatcher;
|
||||
|
@ -66,7 +72,7 @@ public final class PlayInstrumentation extends Instrumenter.Default {
|
|||
|
||||
@Override
|
||||
public Map<ElementMatcher, String> transformers() {
|
||||
Map<ElementMatcher, String> transformers = new HashMap<>();
|
||||
final Map<ElementMatcher, String> transformers = new HashMap<>();
|
||||
transformers.put(
|
||||
named("apply")
|
||||
.and(takesArgument(0, named("play.api.mvc.Request")))
|
||||
|
@ -149,7 +155,7 @@ public final class PlayInstrumentation extends Instrumenter.Default {
|
|||
public static class PlayHeaders implements TextMap {
|
||||
private final Request request;
|
||||
|
||||
public PlayHeaders(Request request) {
|
||||
public PlayHeaders(final Request request) {
|
||||
this.request = request;
|
||||
}
|
||||
|
||||
|
@ -166,7 +172,7 @@ public final class PlayInstrumentation extends Instrumenter.Default {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void put(String s, String s1) {
|
||||
public void put(final String s, final String s1) {
|
||||
throw new IllegalStateException("play headers can only be extracted");
|
||||
}
|
||||
}
|
||||
|
@ -174,18 +180,18 @@ public final class PlayInstrumentation extends Instrumenter.Default {
|
|||
public static class RequestError extends JavaPartialFunction<Throwable, Object> {
|
||||
private final Span span;
|
||||
|
||||
public RequestError(Span span) {
|
||||
public RequestError(final Span span) {
|
||||
this.span = span;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object apply(Throwable t, boolean isCheck) throws Exception {
|
||||
public Object apply(final Throwable t, final boolean isCheck) throws Exception {
|
||||
try {
|
||||
if (GlobalTracer.get().scopeManager().active() instanceof TraceScope) {
|
||||
((TraceScope) GlobalTracer.get().scopeManager().active()).setAsyncPropagation(false);
|
||||
}
|
||||
onError(span, t);
|
||||
} catch (Throwable t2) {
|
||||
} catch (final Throwable t2) {
|
||||
LoggerFactory.getLogger(RequestCallback.class).debug("error in play instrumentation", t);
|
||||
}
|
||||
span.finish();
|
||||
|
@ -203,18 +209,18 @@ public final class PlayInstrumentation extends Instrumenter.Default {
|
|||
public static class RequestCallback extends scala.runtime.AbstractFunction1<Result, Result> {
|
||||
private final Span span;
|
||||
|
||||
public RequestCallback(Span span) {
|
||||
public RequestCallback(final Span span) {
|
||||
this.span = span;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result apply(Result result) {
|
||||
public Result apply(final Result result) {
|
||||
if (GlobalTracer.get().scopeManager().active() instanceof TraceScope) {
|
||||
((TraceScope) GlobalTracer.get().scopeManager().active()).setAsyncPropagation(false);
|
||||
}
|
||||
try {
|
||||
Tags.HTTP_STATUS.set(span, result.header().status());
|
||||
} catch (Throwable t) {
|
||||
} catch (final Throwable t) {
|
||||
log.debug("error in play instrumentation", t);
|
||||
}
|
||||
span.finish();
|
||||
|
|
|
@ -23,7 +23,7 @@ class Play24Test extends AgentTestRunner {
|
|||
testServer.stop()
|
||||
}
|
||||
|
||||
def "request traces" () {
|
||||
def "request traces"() {
|
||||
setup:
|
||||
OkHttpClient client = new OkHttpClient.Builder().build()
|
||||
def request = new Request.Builder()
|
||||
|
@ -59,7 +59,7 @@ class Play24Test extends AgentTestRunner {
|
|||
root.context().tags["component"] == "play-action"
|
||||
}
|
||||
|
||||
def "5xx errors trace" () {
|
||||
def "5xx errors trace"() {
|
||||
setup:
|
||||
OkHttpClient client = new OkHttpClient.Builder().build()
|
||||
def request = new Request.Builder()
|
||||
|
@ -86,7 +86,7 @@ class Play24Test extends AgentTestRunner {
|
|||
root.context().tags["component"] == "play-action"
|
||||
}
|
||||
|
||||
def "error thrown in request" () {
|
||||
def "error thrown in request"() {
|
||||
setup:
|
||||
OkHttpClient client = new OkHttpClient.Builder().build()
|
||||
def request = new Request.Builder()
|
||||
|
@ -116,7 +116,7 @@ class Play24Test extends AgentTestRunner {
|
|||
root.context().tags["component"] == "play-action"
|
||||
}
|
||||
|
||||
def "4xx errors trace" () {
|
||||
def "4xx errors trace"() {
|
||||
setup:
|
||||
OkHttpClient client = new OkHttpClient.Builder().build()
|
||||
def request = new Request.Builder()
|
||||
|
|
|
@ -1,46 +1,44 @@
|
|||
import java.lang.reflect.Field
|
||||
|
||||
import play.api.mvc.Action
|
||||
import play.api.routing.Router
|
||||
import play.api.mvc._
|
||||
import play.api.routing.sird._
|
||||
import datadog.trace.api.Trace
|
||||
import play.api.inject.bind
|
||||
import play.api.mvc.{Action, _}
|
||||
import play.api.routing.Router
|
||||
import play.api.routing.sird._
|
||||
import play.inject.DelegateInjector
|
||||
|
||||
import scala.concurrent.{Await, Future}
|
||||
import scala.concurrent.duration._
|
||||
import play.api.inject.bind
|
||||
|
||||
import scala.concurrent.ExecutionContext.Implicits.global
|
||||
import scala.concurrent.duration._
|
||||
import scala.concurrent.{Await, Future}
|
||||
|
||||
object Play24TestUtils {
|
||||
def buildTestApp(): play.Application = {
|
||||
// build play.api.Application with desired setting and pass into play.Application for testing
|
||||
val apiApp :play.api.Application = new play.api.inject.guice.GuiceApplicationBuilder()
|
||||
.overrides(bind[Router].toInstance(Router.from {
|
||||
case GET(p"/helloplay/$from") => Action { req: RequestHeader =>
|
||||
HandlerSetter.setHandler(req, "/helloplay/:from")
|
||||
val f: Future[String] = Future[String] {
|
||||
TracedWork.doWork()
|
||||
from
|
||||
}
|
||||
Results.Ok(s"hello " + Await.result(f, 5 seconds))
|
||||
val apiApp: play.api.Application = new play.api.inject.guice.GuiceApplicationBuilder()
|
||||
.overrides(bind[Router].toInstance(Router.from {
|
||||
case GET(p"/helloplay/$from") => Action { req: RequestHeader =>
|
||||
HandlerSetter.setHandler(req, "/helloplay/:from")
|
||||
val f: Future[String] = Future[String] {
|
||||
TracedWork.doWork()
|
||||
from
|
||||
}
|
||||
case GET(p"/make-error") => Action { req: RequestHeader =>
|
||||
HandlerSetter.setHandler(req, "/make-error")
|
||||
Results.InternalServerError("Really sorry...")
|
||||
Results.Ok(s"hello " + Await.result(f, 5 seconds))
|
||||
}
|
||||
case GET(p"/make-error") => Action { req: RequestHeader =>
|
||||
HandlerSetter.setHandler(req, "/make-error")
|
||||
Results.InternalServerError("Really sorry...")
|
||||
}
|
||||
case GET(p"/exception") => Action { req: RequestHeader =>
|
||||
HandlerSetter.setHandler(req, "/exception")
|
||||
if (System.currentTimeMillis() > 0) {
|
||||
throw new RuntimeException("oh no")
|
||||
}
|
||||
case GET(p"/exception") => Action { req: RequestHeader =>
|
||||
HandlerSetter.setHandler(req, "/exception")
|
||||
if (System.currentTimeMillis() > 0) {
|
||||
throw new RuntimeException("oh no")
|
||||
}
|
||||
Results.Ok("hello")
|
||||
}
|
||||
case _ => Action {
|
||||
Results.NotFound("Sorry..")
|
||||
}
|
||||
}))
|
||||
Results.Ok("hello")
|
||||
}
|
||||
case _ => Action {
|
||||
Results.NotFound("Sorry..")
|
||||
}
|
||||
}))
|
||||
.build()
|
||||
|
||||
|
||||
|
@ -64,7 +62,7 @@ object HandlerSetter {
|
|||
f.setAccessible(false)
|
||||
}
|
||||
|
||||
private def getField(o: Object, fieldName :String): Object = {
|
||||
private def getField(o: Object, fieldName: String): Object = {
|
||||
val f: Field = o.getClass().getDeclaredField(fieldName)
|
||||
f.setAccessible(true)
|
||||
val result: Object = f.get(o)
|
||||
|
|
|
@ -1,7 +1,14 @@
|
|||
package datadog.trace.instrumentation.ratpack;
|
||||
|
||||
import static datadog.trace.agent.tooling.ClassLoaderMatcher.classLoaderHasClassWithMethod;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.*;
|
||||
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.isStatic;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.named;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.not;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.returns;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.takesArguments;
|
||||
|
||||
import com.google.auto.service.AutoService;
|
||||
import datadog.trace.agent.tooling.Instrumenter;
|
||||
|
@ -63,7 +70,7 @@ public final class RatpackInstrumentation extends Instrumenter.Default {
|
|||
|
||||
@Override
|
||||
public Map<ElementMatcher, String> transformers() {
|
||||
Map<ElementMatcher, String> transformers = new HashMap<>();
|
||||
final Map<ElementMatcher, String> transformers = new HashMap<>();
|
||||
transformers.put(
|
||||
isMethod().and(isStatic()).and(named("buildBaseRegistry")),
|
||||
RatpackServerAdvice.RatpackServerRegistryAdvice.class.getName());
|
||||
|
@ -106,7 +113,7 @@ public final class RatpackInstrumentation extends Instrumenter.Default {
|
|||
|
||||
@Override
|
||||
public Map<ElementMatcher, String> transformers() {
|
||||
Map<ElementMatcher, String> transformers = new HashMap<>();
|
||||
final Map<ElementMatcher, String> transformers = new HashMap<>();
|
||||
transformers.put(
|
||||
named("register").and(takesArguments(ACTION_TYPE_DESCRIPTION)),
|
||||
RatpackServerAdvice.ExecStarterAdvice.class.getName());
|
||||
|
@ -148,7 +155,7 @@ public final class RatpackInstrumentation extends Instrumenter.Default {
|
|||
|
||||
@Override
|
||||
public Map<ElementMatcher, String> transformers() {
|
||||
Map<ElementMatcher, String> transformers = new HashMap<>();
|
||||
final Map<ElementMatcher, String> transformers = new HashMap<>();
|
||||
transformers.put(
|
||||
named("fork").and(returns(named("ratpack.exec.ExecStarter"))),
|
||||
RatpackServerAdvice.ExecutionAdvice.class.getName());
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
package datadog.trace.instrumentation.ratpack.impl;
|
||||
|
||||
import io.opentracing.propagation.TextMap;
|
||||
import java.util.*;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import ratpack.http.Request;
|
||||
import ratpack.util.MultiValueMap;
|
||||
|
||||
|
@ -12,8 +13,8 @@ import ratpack.util.MultiValueMap;
|
|||
public class RatpackRequestExtractAdapter implements TextMap {
|
||||
private final MultiValueMap<String, String> headers;
|
||||
|
||||
RatpackRequestExtractAdapter(Request request) {
|
||||
this.headers = request.getHeaders().asMultiValueMap();
|
||||
RatpackRequestExtractAdapter(final Request request) {
|
||||
headers = request.getHeaders().asMultiValueMap();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -22,7 +23,7 @@ public class RatpackRequestExtractAdapter implements TextMap {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void put(String key, String value) {
|
||||
public void put(final String key, final String value) {
|
||||
throw new UnsupportedOperationException("This class should be used only with Tracer.inject()!");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,7 +33,7 @@ dependencies {
|
|||
|
||||
testCompile group: 'javax.validation', name: 'validation-api', version: '1.1.0.Final'
|
||||
testCompile group: 'org.hibernate', name: 'hibernate-validator', version: '5.4.2.Final'
|
||||
|
||||
|
||||
testCompile group: 'org.spockframework', name: 'spock-spring', version: '1.1-groovy-2.4'
|
||||
|
||||
testCompile group: 'org.springframework', name: 'spring-web', version: '4.3.14.RELEASE'
|
||||
|
|
|
@ -33,8 +33,8 @@ dependencies {
|
|||
testCompile project(':dd-java-agent:testing')
|
||||
|
||||
testCompile group: 'net.spy', name: 'spymemcached', version: '2.12.0'
|
||||
testCompile group: 'org.spockframework', name:'spock-core', version:'1.1-groovy-2.4'
|
||||
testCompile group: 'org.testcontainers', name:'testcontainers', version:'1.7.3'
|
||||
testCompile group: 'org.spockframework', name: 'spock-core', version: '1.1-groovy-2.4'
|
||||
testCompile group: 'org.testcontainers', name: 'testcontainers', version: '1.7.3'
|
||||
}
|
||||
|
||||
configurations.latestDepTestCompile {
|
||||
|
|
|
@ -3,21 +3,21 @@ package datadog.trace.instrumentation.spymemcached;
|
|||
import io.opentracing.Span;
|
||||
import io.opentracing.Tracer;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import net.spy.memcached.internal.*;
|
||||
import net.spy.memcached.internal.BulkGetFuture;
|
||||
|
||||
public class BulkGetCompletionListener extends CompletionListener<BulkGetFuture<?>>
|
||||
implements net.spy.memcached.internal.BulkGetCompletionListener {
|
||||
public BulkGetCompletionListener(Tracer tracer, String methodName) {
|
||||
public BulkGetCompletionListener(final Tracer tracer, final String methodName) {
|
||||
super(tracer, methodName, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onComplete(BulkGetFuture<?> future) {
|
||||
public void onComplete(final BulkGetFuture<?> future) {
|
||||
closeAsyncSpan(future);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void processResult(Span span, BulkGetFuture<?> future)
|
||||
protected void processResult(final Span span, final BulkGetFuture<?> future)
|
||||
throws ExecutionException, InterruptedException {
|
||||
/*
|
||||
Note: for now we do not have an affective way of representing results of bulk operations,
|
||||
|
|
|
@ -1,7 +1,11 @@
|
|||
package datadog.trace.instrumentation.spymemcached;
|
||||
|
||||
import static datadog.trace.agent.tooling.ClassLoaderMatcher.classLoaderHasClassWithMethod;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.*;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.isMethod;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.isPublic;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.named;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.not;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.returns;
|
||||
|
||||
import com.google.auto.service.AutoService;
|
||||
import datadog.trace.agent.tooling.Instrumenter;
|
||||
|
@ -55,7 +59,7 @@ public final class MemcachedClientInstrumentation extends Instrumenter.Default {
|
|||
|
||||
@Override
|
||||
public Map<ElementMatcher, String> transformers() {
|
||||
Map<ElementMatcher, String> transformers = new HashMap<>();
|
||||
final Map<ElementMatcher, String> transformers = new HashMap<>();
|
||||
transformers.put(
|
||||
isMethod()
|
||||
.and(isPublic())
|
||||
|
@ -96,7 +100,7 @@ public final class MemcachedClientInstrumentation extends Instrumenter.Default {
|
|||
@Advice.Origin final Method method,
|
||||
@Advice.Return final OperationFuture future) {
|
||||
if (shouldInjectListener && future != null) {
|
||||
OperationCompletionListener listener =
|
||||
final OperationCompletionListener listener =
|
||||
new OperationCompletionListener(GlobalTracer.get(), method.getName());
|
||||
future.addListener(listener);
|
||||
CallDepthThreadLocalMap.reset(MemcachedClient.class);
|
||||
|
@ -117,7 +121,7 @@ public final class MemcachedClientInstrumentation extends Instrumenter.Default {
|
|||
@Advice.Origin final Method method,
|
||||
@Advice.Return final GetFuture future) {
|
||||
if (shouldInjectListener && future != null) {
|
||||
GetCompletionListener listener =
|
||||
final GetCompletionListener listener =
|
||||
new GetCompletionListener(GlobalTracer.get(), method.getName());
|
||||
future.addListener(listener);
|
||||
CallDepthThreadLocalMap.reset(MemcachedClient.class);
|
||||
|
@ -138,7 +142,7 @@ public final class MemcachedClientInstrumentation extends Instrumenter.Default {
|
|||
@Advice.Origin final Method method,
|
||||
@Advice.Return final BulkFuture future) {
|
||||
if (shouldInjectListener && future != null) {
|
||||
BulkGetCompletionListener listener =
|
||||
final BulkGetCompletionListener listener =
|
||||
new BulkGetCompletionListener(GlobalTracer.get(), method.getName());
|
||||
future.addListener(listener);
|
||||
CallDepthThreadLocalMap.reset(MemcachedClient.class);
|
||||
|
|
|
@ -22,11 +22,11 @@ import java.util.concurrent.BlockingQueue
|
|||
import java.util.concurrent.ExecutorService
|
||||
import java.util.concurrent.locks.ReentrantLock
|
||||
|
||||
import static datadog.trace.agent.test.ListWriterAssert.assertTraces
|
||||
import static CompletionListener.COMPONENT_NAME
|
||||
import static CompletionListener.OPERATION_NAME
|
||||
import static CompletionListener.SERVICE_NAME
|
||||
import static CompletionListener.SPAN_TYPE
|
||||
import static datadog.trace.agent.test.ListWriterAssert.assertTraces
|
||||
import static datadog.trace.agent.test.TestUtils.runUnderTrace
|
||||
import static net.spy.memcached.ConnectionFactoryBuilder.Protocol.BINARY
|
||||
|
||||
|
@ -124,16 +124,16 @@ class SpymemcachedTest extends AgentTestRunner {
|
|||
|
||||
// Add some keys to test on later:
|
||||
def valuesToSet = [
|
||||
"test-get": "get test",
|
||||
"test-get-2": "get test 2",
|
||||
"test-append": "append test",
|
||||
"test-get" : "get test",
|
||||
"test-get-2" : "get test 2",
|
||||
"test-append" : "append test",
|
||||
"test-prepend": "prepend test",
|
||||
"test-delete": "delete test",
|
||||
"test-delete" : "delete test",
|
||||
"test-replace": "replace test",
|
||||
"test-touch": "touch test",
|
||||
"test-cas": "cas test",
|
||||
"test-decr": "200",
|
||||
"test-incr": "100"
|
||||
"test-touch" : "touch test",
|
||||
"test-cas" : "cas test",
|
||||
"test-decr" : "200",
|
||||
"test-incr" : "100"
|
||||
]
|
||||
runUnderTrace("setup") {
|
||||
valuesToSet.each { k, v -> assert memcached.set(key(k), expiration, v).get() }
|
||||
|
@ -152,7 +152,7 @@ class SpymemcachedTest extends AgentTestRunner {
|
|||
assertTraces(TEST_WRITER, 1) {
|
||||
trace(0, 2) {
|
||||
getParentSpan(it, 0)
|
||||
getSpan(it, 1, "get", null,"hit")
|
||||
getSpan(it, 1, "get", null, "hit")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -167,7 +167,7 @@ class SpymemcachedTest extends AgentTestRunner {
|
|||
assertTraces(TEST_WRITER, 1) {
|
||||
trace(0, 2) {
|
||||
getParentSpan(it, 0)
|
||||
getSpan(it, 1, "get", null,"miss")
|
||||
getSpan(it, 1, "get", null, "miss")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -223,7 +223,7 @@ class SpymemcachedTest extends AgentTestRunner {
|
|||
assertTraces(TEST_WRITER, 1) {
|
||||
trace(0, 2) {
|
||||
getParentSpan(it, 0)
|
||||
getSpan(it, 1, "getBulk", null,null)
|
||||
getSpan(it, 1, "getBulk", null, null)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -271,7 +271,7 @@ class SpymemcachedTest extends AgentTestRunner {
|
|||
assertTraces(TEST_WRITER, 1) {
|
||||
trace(0, 3) {
|
||||
getParentSpan(it, 0)
|
||||
getSpan(it, 1, "get", null,"hit")
|
||||
getSpan(it, 1, "get", null, "hit")
|
||||
getSpan(it, 2, "add")
|
||||
}
|
||||
}
|
||||
|
@ -305,7 +305,7 @@ class SpymemcachedTest extends AgentTestRunner {
|
|||
assertTraces(TEST_WRITER, 1) {
|
||||
trace(0, 3) {
|
||||
getParentSpan(it, 0)
|
||||
getSpan(it, 1, "get", null,"miss")
|
||||
getSpan(it, 1, "get", null, "miss")
|
||||
getSpan(it, 2, "delete")
|
||||
}
|
||||
}
|
||||
|
@ -337,7 +337,7 @@ class SpymemcachedTest extends AgentTestRunner {
|
|||
assertTraces(TEST_WRITER, 1) {
|
||||
trace(0, 3) {
|
||||
getParentSpan(it, 0)
|
||||
getSpan(it, 1, "get", null,"hit")
|
||||
getSpan(it, 1, "get", null, "hit")
|
||||
getSpan(it, 2, "replace")
|
||||
}
|
||||
}
|
||||
|
@ -370,7 +370,7 @@ class SpymemcachedTest extends AgentTestRunner {
|
|||
assertTraces(TEST_WRITER, 1) {
|
||||
trace(0, 4) {
|
||||
getParentSpan(it, 0)
|
||||
getSpan(it, 1, "get", null,"hit")
|
||||
getSpan(it, 1, "get", null, "hit")
|
||||
getSpan(it, 2, "append")
|
||||
getSpan(it, 3, "gets")
|
||||
}
|
||||
|
@ -389,7 +389,7 @@ class SpymemcachedTest extends AgentTestRunner {
|
|||
assertTraces(TEST_WRITER, 1) {
|
||||
trace(0, 4) {
|
||||
getParentSpan(it, 0)
|
||||
getSpan(it, 1, "get", null,"hit")
|
||||
getSpan(it, 1, "get", null, "hit")
|
||||
getSpan(it, 2, "prepend")
|
||||
getSpan(it, 3, "gets")
|
||||
}
|
||||
|
@ -503,7 +503,7 @@ class SpymemcachedTest extends AgentTestRunner {
|
|||
assertTraces(TEST_WRITER, 1) {
|
||||
trace(0, 3) {
|
||||
getParentSpan(it, 0)
|
||||
getSpan(it, 1, "get", null,"hit")
|
||||
getSpan(it, 1, "get", null, "hit")
|
||||
getSpan(it, 2, "decr")
|
||||
}
|
||||
}
|
||||
|
@ -552,7 +552,7 @@ class SpymemcachedTest extends AgentTestRunner {
|
|||
assertTraces(TEST_WRITER, 1) {
|
||||
trace(0, 3) {
|
||||
getParentSpan(it, 0)
|
||||
getSpan(it, 1, "get", null,"hit")
|
||||
getSpan(it, 1, "get", null, "hit")
|
||||
getSpan(it, 2, "incr")
|
||||
}
|
||||
}
|
||||
|
@ -590,7 +590,7 @@ class SpymemcachedTest extends AgentTestRunner {
|
|||
keyPrefix + k
|
||||
}
|
||||
|
||||
def longString(char c='s' as char) {
|
||||
def longString(char c = 's' as char) {
|
||||
char[] chars = new char[250]
|
||||
Arrays.fill(chars, 's' as char)
|
||||
return new String(chars)
|
||||
|
@ -622,7 +622,7 @@ class SpymemcachedTest extends AgentTestRunner {
|
|||
}
|
||||
}
|
||||
|
||||
def getSpan(TraceAssert trace, int index, String operation, String error=null, String result=null) {
|
||||
def getSpan(TraceAssert trace, int index, String operation, String error = null, String result = null) {
|
||||
return trace.span(index) {
|
||||
if (index > 0) {
|
||||
childOf(trace.span(0))
|
||||
|
@ -632,7 +632,7 @@ class SpymemcachedTest extends AgentTestRunner {
|
|||
operationName OPERATION_NAME
|
||||
resourceName operation
|
||||
spanType SPAN_TYPE
|
||||
errored (error != null && error != "canceled")
|
||||
errored(error != null && error != "canceled")
|
||||
|
||||
tags {
|
||||
defaultTags()
|
||||
|
|
|
@ -16,7 +16,12 @@
|
|||
*/
|
||||
package datadog.trace.agent;
|
||||
|
||||
import java.io.*;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStream;
|
||||
import java.lang.instrument.Instrumentation;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
|
@ -91,8 +96,8 @@ public class TracingAgent {
|
|||
* @param toolingJar jar to use for the classpath of the datadog classloader
|
||||
* @return Datadog Classloader
|
||||
*/
|
||||
private static ClassLoader createDatadogClassLoader(File bootstrapJar, File toolingJar)
|
||||
throws Exception {
|
||||
private static ClassLoader createDatadogClassLoader(
|
||||
final File bootstrapJar, final File toolingJar) throws Exception {
|
||||
final ClassLoader agentParent;
|
||||
final String javaVersion = System.getProperty("java.version");
|
||||
if (javaVersion.startsWith("1.7") || javaVersion.startsWith("1.8")) {
|
||||
|
@ -101,9 +106,9 @@ public class TracingAgent {
|
|||
// platform classloader is parent of system in java 9+
|
||||
agentParent = getPlatformClassLoader();
|
||||
}
|
||||
Class<?> loaderClass =
|
||||
final Class<?> loaderClass =
|
||||
ClassLoader.getSystemClassLoader().loadClass("datadog.trace.bootstrap.DatadogClassLoader");
|
||||
Constructor constructor =
|
||||
final Constructor constructor =
|
||||
loaderClass.getDeclaredConstructor(URL.class, URL.class, ClassLoader.class);
|
||||
return (ClassLoader)
|
||||
constructor.newInstance(
|
||||
|
@ -111,8 +116,8 @@ public class TracingAgent {
|
|||
}
|
||||
|
||||
/** Extract sourcePath out of loader to a temporary file named destName. */
|
||||
private static File extractToTmpFile(ClassLoader loader, String sourcePath, String destName)
|
||||
throws Exception {
|
||||
private static File extractToTmpFile(
|
||||
final ClassLoader loader, final String sourcePath, final String destName) throws Exception {
|
||||
final String destPrefix;
|
||||
final String destSuffix;
|
||||
{
|
||||
|
@ -171,7 +176,7 @@ public class TracingAgent {
|
|||
public static void main(final String... args) {
|
||||
try {
|
||||
System.out.println(getAgentVersion());
|
||||
} catch (Exception e) {
|
||||
} catch (final Exception e) {
|
||||
System.out.println("Failed to parse agent version");
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
import datadog.trace.agent.test.AgentTestRunner
|
||||
import datadog.trace.agent.test.TestUtils
|
||||
import io.opentracing.Tracer
|
||||
|
||||
import java.lang.reflect.Field
|
||||
|
||||
import datadog.trace.agent.test.AgentTestRunner
|
||||
|
||||
class AgentTestRunnerTest extends AgentTestRunner {
|
||||
private static final ClassLoader BOOTSTRAP_CLASSLOADER = null
|
||||
private static final ClassLoader OT_LOADER
|
||||
|
|
|
@ -6,7 +6,7 @@ import io.opentracing.util.GlobalTracer
|
|||
|
||||
class TraceCorrelationTest extends AgentTestRunner {
|
||||
|
||||
def "access trace correlation only under trace" () {
|
||||
def "access trace correlation only under trace"() {
|
||||
when:
|
||||
Scope scope = GlobalTracer.get().buildSpan("myspan").startActive(true)
|
||||
DDSpan span = (DDSpan) scope.span()
|
||||
|
|
|
@ -2,9 +2,9 @@ package muzzle
|
|||
|
||||
import datadog.trace.agent.test.AgentTestRunner
|
||||
import datadog.trace.agent.test.TestUtils
|
||||
import datadog.trace.agent.tooling.muzzle.Reference
|
||||
import datadog.trace.agent.tooling.muzzle.ReferenceCreator
|
||||
import datadog.trace.agent.tooling.muzzle.ReferenceMatcher
|
||||
import datadog.trace.agent.tooling.muzzle.Reference
|
||||
|
||||
class AdviceReferenceVisitorTest extends AgentTestRunner {
|
||||
|
||||
|
@ -25,12 +25,12 @@ class AdviceReferenceVisitorTest extends AgentTestRunner {
|
|||
Reference[] refs = ReferenceCreator.createReferencesFrom(AdviceClass.getName(), this.getClass().getClassLoader()).values().toArray(new Reference[0])
|
||||
ReferenceMatcher refMatcher = new ReferenceMatcher(refs)
|
||||
ClassLoader safeClassloader = new URLClassLoader([TestUtils.createJarWithClasses(AdviceClass$A,
|
||||
AdviceClass$SomeInterface,
|
||||
AdviceClass$SomeImplementation)] as URL[],
|
||||
(ClassLoader) null)
|
||||
AdviceClass$SomeInterface,
|
||||
AdviceClass$SomeImplementation)] as URL[],
|
||||
(ClassLoader) null)
|
||||
ClassLoader unsafeClassloader = new URLClassLoader([TestUtils.createJarWithClasses(AdviceClass$SomeInterface,
|
||||
AdviceClass$SomeImplementation)] as URL[],
|
||||
(ClassLoader) null)
|
||||
AdviceClass$SomeImplementation)] as URL[],
|
||||
(ClassLoader) null)
|
||||
|
||||
expect:
|
||||
refMatcher.getMismatchedReferenceSources(safeClassloader).size() == 0
|
||||
|
|
|
@ -24,7 +24,7 @@ dependencies {
|
|||
|
||||
compile project(':dd-trace-ot')
|
||||
compile project(':dd-java-agent:agent-tooling')
|
||||
|
||||
|
||||
annotationProcessor deps.autoservice
|
||||
implementation deps.autoservice
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@ testSets {
|
|||
dependencies {
|
||||
annotationProcessor deps.autoservice
|
||||
implementation deps.autoservice
|
||||
|
||||
|
||||
compile project(':dd-trace-api')
|
||||
compile deps.opentracing
|
||||
compile group: 'io.opentracing.contrib', name: 'opentracing-tracerresolver', version: '0.1.0'
|
||||
|
|
|
@ -4,7 +4,10 @@ import com.fasterxml.jackson.annotation.JsonIgnore;
|
|||
import datadog.opentracing.decorators.AbstractDecorator;
|
||||
import datadog.trace.api.DDTags;
|
||||
import datadog.trace.api.sampling.PrioritySampling;
|
||||
import java.util.*;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
@ -115,15 +118,15 @@ public class DDSpanContext implements io.opentracing.SpanContext {
|
|||
}
|
||||
|
||||
public String getTraceId() {
|
||||
return this.traceId;
|
||||
return traceId;
|
||||
}
|
||||
|
||||
public String getParentId() {
|
||||
return this.parentId;
|
||||
return parentId;
|
||||
}
|
||||
|
||||
public String getSpanId() {
|
||||
return this.spanId;
|
||||
return spanId;
|
||||
}
|
||||
|
||||
public String getServiceName() {
|
||||
|
@ -135,9 +138,7 @@ public class DDSpanContext implements io.opentracing.SpanContext {
|
|||
}
|
||||
|
||||
public String getResourceName() {
|
||||
return this.resourceName == null || this.resourceName.isEmpty()
|
||||
? this.operationName
|
||||
: this.resourceName;
|
||||
return resourceName == null || resourceName.isEmpty() ? operationName : resourceName;
|
||||
}
|
||||
|
||||
public void setResourceName(final String resourceName) {
|
||||
|
@ -170,7 +171,7 @@ public class DDSpanContext implements io.opentracing.SpanContext {
|
|||
|
||||
public void setSamplingPriority(final int newPriority) {
|
||||
if (trace != null) {
|
||||
DDSpan rootSpan = trace.getRootSpan();
|
||||
final DDSpan rootSpan = trace.getRootSpan();
|
||||
if (null != rootSpan && rootSpan.context() != this) {
|
||||
rootSpan.context().setSamplingPriority(newPriority);
|
||||
return;
|
||||
|
@ -197,7 +198,7 @@ public class DDSpanContext implements io.opentracing.SpanContext {
|
|||
/** @return the sampling priority of this span's trace, or null if no priority has been set */
|
||||
public int getSamplingPriority() {
|
||||
if (trace != null) {
|
||||
DDSpan rootSpan = trace.getRootSpan();
|
||||
final DDSpan rootSpan = trace.getRootSpan();
|
||||
if (null != rootSpan && rootSpan.context() != this) {
|
||||
return rootSpan.context().getSamplingPriority();
|
||||
}
|
||||
|
@ -217,7 +218,7 @@ public class DDSpanContext implements io.opentracing.SpanContext {
|
|||
*/
|
||||
public boolean lockSamplingPriority() {
|
||||
if (trace != null) {
|
||||
DDSpan rootSpan = trace.getRootSpan();
|
||||
final DDSpan rootSpan = trace.getRootSpan();
|
||||
if (null != rootSpan && rootSpan.context() != this) {
|
||||
return rootSpan.context().lockSamplingPriority();
|
||||
}
|
||||
|
@ -236,11 +237,11 @@ public class DDSpanContext implements io.opentracing.SpanContext {
|
|||
}
|
||||
|
||||
public void setBaggageItem(final String key, final String value) {
|
||||
this.baggageItems.put(key, value);
|
||||
baggageItems.put(key, value);
|
||||
}
|
||||
|
||||
public String getBaggageItem(final String key) {
|
||||
return this.baggageItems.get(key);
|
||||
return baggageItems.get(key);
|
||||
}
|
||||
|
||||
public Map<String, String> getBaggageItems() {
|
||||
|
@ -252,17 +253,17 @@ public class DDSpanContext implements io.opentracing.SpanContext {
|
|||
*/
|
||||
@Override
|
||||
public Iterable<Map.Entry<String, String>> baggageItems() {
|
||||
return this.baggageItems.entrySet();
|
||||
return baggageItems.entrySet();
|
||||
}
|
||||
|
||||
@JsonIgnore
|
||||
public PendingTrace getTrace() {
|
||||
return this.trace;
|
||||
return trace;
|
||||
}
|
||||
|
||||
@JsonIgnore
|
||||
public DDTracer getTracer() {
|
||||
return this.tracer;
|
||||
return tracer;
|
||||
}
|
||||
|
||||
public Map<String, Number> getMetrics() {
|
||||
|
@ -270,7 +271,7 @@ public class DDSpanContext implements io.opentracing.SpanContext {
|
|||
return metrics == null ? EMPTY_METRICS : metrics;
|
||||
}
|
||||
|
||||
public void setMetric(String key, Number value) {
|
||||
public void setMetric(final String key, final Number value) {
|
||||
if (metrics.get() == null) {
|
||||
metrics.compareAndSet(null, new ConcurrentHashMap<String, Number>());
|
||||
}
|
||||
|
@ -306,7 +307,7 @@ public class DDSpanContext implements io.opentracing.SpanContext {
|
|||
}
|
||||
|
||||
if (addTag) {
|
||||
this.tags.put(tag, value);
|
||||
tags.put(tag, value);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -265,7 +265,7 @@ class DDSpanBuilderTest extends Specification {
|
|||
span.context().@tags == extractedContext.tags
|
||||
|
||||
where:
|
||||
extractedContext | _
|
||||
extractedContext | _
|
||||
new ExtractedContext("1", "2", 0, [:], [:]) | _
|
||||
new ExtractedContext("3", "4", 1, ["asdf": "qwer"], ["zxcv": "1234"]) | _
|
||||
}
|
||||
|
|
|
@ -59,7 +59,7 @@ class SpanDecoratorTest extends Specification {
|
|||
"service" | "other-service" | "other-service"
|
||||
Tags.PEER_SERVICE.key | "some-service" | "new-service"
|
||||
Tags.PEER_SERVICE.key | "other-service" | "other-service"
|
||||
|
||||
|
||||
mapping = ["some-service": "new-service"]
|
||||
}
|
||||
|
||||
|
|
|
@ -22,10 +22,10 @@ class DDSpanContextTest extends Specification {
|
|||
|
||||
where:
|
||||
name | extra | tags
|
||||
DDTags.SERVICE_NAME | "some.tag=asdf, " | ["some.tag": "asdf", (DDTags.SPAN_TYPE):"fakeType", (DDTags.THREAD_NAME): Thread.currentThread().name, (DDTags.THREAD_ID): Thread.currentThread().id]
|
||||
DDTags.RESOURCE_NAME | "some.tag=asdf, " | ["some.tag": "asdf", (DDTags.SPAN_TYPE):"fakeType", (DDTags.THREAD_NAME): Thread.currentThread().name, (DDTags.THREAD_ID): Thread.currentThread().id]
|
||||
DDTags.SPAN_TYPE | "some.tag=asdf, " | ["some.tag": "asdf", (DDTags.SPAN_TYPE):"fakeType", (DDTags.THREAD_NAME): Thread.currentThread().name, (DDTags.THREAD_ID): Thread.currentThread().id]
|
||||
"some.tag" | "" | [ (DDTags.SPAN_TYPE):"fakeType", (DDTags.THREAD_NAME): Thread.currentThread().name, (DDTags.THREAD_ID): Thread.currentThread().id]
|
||||
DDTags.SERVICE_NAME | "some.tag=asdf, " | ["some.tag": "asdf", (DDTags.SPAN_TYPE): "fakeType", (DDTags.THREAD_NAME): Thread.currentThread().name, (DDTags.THREAD_ID): Thread.currentThread().id]
|
||||
DDTags.RESOURCE_NAME | "some.tag=asdf, " | ["some.tag": "asdf", (DDTags.SPAN_TYPE): "fakeType", (DDTags.THREAD_NAME): Thread.currentThread().name, (DDTags.THREAD_ID): Thread.currentThread().id]
|
||||
DDTags.SPAN_TYPE | "some.tag=asdf, " | ["some.tag": "asdf", (DDTags.SPAN_TYPE): "fakeType", (DDTags.THREAD_NAME): Thread.currentThread().name, (DDTags.THREAD_ID): Thread.currentThread().id]
|
||||
"some.tag" | "" | [(DDTags.SPAN_TYPE): "fakeType", (DDTags.THREAD_NAME): Thread.currentThread().name, (DDTags.THREAD_ID): Thread.currentThread().id]
|
||||
}
|
||||
|
||||
def "special tags set certain values"() {
|
||||
|
|
|
@ -3,6 +3,6 @@
|
|||
apply plugin: 'scala'
|
||||
|
||||
compileTestGroovy {
|
||||
classpath = classpath.plus(files(compileTestScala.destinationDir))
|
||||
dependsOn compileTestScala
|
||||
classpath = classpath.plus(files(compileTestScala.destinationDir))
|
||||
dependsOn compileTestScala
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue