Merge pull request #310 from DataDog/tyler/jacoco
Apply jacoco to every java project
This commit is contained in:
commit
e3aae4e869
|
|
@ -53,7 +53,3 @@ tasks.withType(Test) {
|
|||
parent.subprojects.collect { it.tasks.withType(Test) } each {
|
||||
test.shouldRunAfter it
|
||||
}
|
||||
|
||||
// Jacoco must be applied after the test javaagent config block above,
|
||||
// otherwise the javaagent args conflict. (It's order dependent and added LIFO)
|
||||
apply from: "${rootDir}/gradle/jacoco.gradle"
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ public class IntegrationTestUtils {
|
|||
classloaderField = tracingAgentClass.getDeclaredField("AGENT_CLASSLOADER");
|
||||
classloaderField.setAccessible(true);
|
||||
return (ClassLoader) classloaderField.get(null);
|
||||
} catch (Exception e) {
|
||||
} catch (final Exception e) {
|
||||
throw new IllegalStateException(e);
|
||||
} finally {
|
||||
if (null != classloaderField) {
|
||||
|
|
@ -141,29 +141,19 @@ public class IntegrationTestUtils {
|
|||
return className.replace('.', '/') + ".class";
|
||||
}
|
||||
|
||||
public static String[] getBootstrapPackagePrefixes() {
|
||||
try {
|
||||
Field f =
|
||||
getAgentClassLoader()
|
||||
.loadClass("datadog.trace.agent.tooling.Utils")
|
||||
.getField("BOOTSTRAP_PACKAGE_PREFIXES");
|
||||
return (String[]) f.get(null);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
public static String[] getBootstrapPackagePrefixes() throws Exception {
|
||||
final Field f =
|
||||
getAgentClassLoader()
|
||||
.loadClass("datadog.trace.agent.tooling.Utils")
|
||||
.getField("BOOTSTRAP_PACKAGE_PREFIXES");
|
||||
return (String[]) f.get(null);
|
||||
}
|
||||
|
||||
public static String[] getAgentPackagePrefixes() {
|
||||
try {
|
||||
Field f =
|
||||
getAgentClassLoader()
|
||||
.loadClass("datadog.trace.agent.tooling.Utils")
|
||||
.getField("AGENT_PACKAGE_PREFIXES");
|
||||
return (String[]) f.get(null);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
public static String[] getAgentPackagePrefixes() throws Exception {
|
||||
final Field f =
|
||||
getAgentClassLoader()
|
||||
.loadClass("datadog.trace.agent.tooling.Utils")
|
||||
.getField("AGENT_PACKAGE_PREFIXES");
|
||||
return (String[]) f.get(null);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,10 @@ plugins {
|
|||
|
||||
apply from: "${rootDir}/gradle/java.gradle"
|
||||
|
||||
whitelistedInstructionClasses += whitelistedBranchClasses += [
|
||||
'datadog.trace.bootstrap.*'
|
||||
]
|
||||
|
||||
dependencies {
|
||||
compile project(':dd-trace-api')
|
||||
compile deps.opentracing
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
package datadog.trace.bootstrap;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.WeakHashMap;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
/**
|
||||
|
|
@ -11,36 +11,37 @@ import java.util.concurrent.atomic.AtomicInteger;
|
|||
* #incrementCallDepth at the beginning of each constructor.
|
||||
*/
|
||||
public class CallDepthThreadLocalMap {
|
||||
private static final ThreadLocal<Map<Object, CallDepthThreadLocalMap>> INSTANCES =
|
||||
new ThreadLocal<>();
|
||||
private static final ThreadLocal<Map<Key, AtomicInteger>> TLS =
|
||||
new ThreadLocal<Map<Key, AtomicInteger>>() {
|
||||
@Override
|
||||
public Map<Key, AtomicInteger> initialValue() {
|
||||
return new HashMap<>();
|
||||
}
|
||||
};
|
||||
|
||||
public static CallDepthThreadLocalMap get(Object o) {
|
||||
if (INSTANCES.get() == null) {
|
||||
INSTANCES.set(new WeakHashMap<Object, CallDepthThreadLocalMap>());
|
||||
}
|
||||
if (!INSTANCES.get().containsKey(o)) {
|
||||
INSTANCES.get().put(o, new CallDepthThreadLocalMap());
|
||||
}
|
||||
return INSTANCES.get().get(o);
|
||||
}
|
||||
|
||||
private final ThreadLocal<AtomicInteger> tls = new ThreadLocal<>();
|
||||
|
||||
private CallDepthThreadLocalMap() {}
|
||||
|
||||
public int incrementCallDepth() {
|
||||
AtomicInteger depth = tls.get();
|
||||
public static int incrementCallDepth(final Key k) {
|
||||
final Map<Key, AtomicInteger> map = TLS.get();
|
||||
AtomicInteger depth = map.get(k);
|
||||
if (depth == null) {
|
||||
depth = new AtomicInteger(0);
|
||||
tls.set(depth);
|
||||
map.put(k, depth);
|
||||
return 0;
|
||||
} else {
|
||||
return depth.incrementAndGet();
|
||||
}
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
tls.remove();
|
||||
INSTANCES.get().remove(this);
|
||||
public static void reset(final Key k) {
|
||||
final Map<Key, AtomicInteger> map = TLS.get();
|
||||
if (map != null) {
|
||||
map.remove(k);
|
||||
}
|
||||
}
|
||||
|
||||
public enum Key {
|
||||
CLASSLOADER,
|
||||
CONNECTION,
|
||||
PREPARED_STATEMENT,
|
||||
STATEMENT
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,35 @@
|
|||
package datadog.trace.bootstrap
|
||||
|
||||
import spock.lang.Specification
|
||||
|
||||
class CallDepthThreadLocalMapTest extends Specification {
|
||||
|
||||
def "test CallDepthThreadLocalMap"() {
|
||||
setup:
|
||||
def k1 = CallDepthThreadLocalMap.Key.CLASSLOADER
|
||||
def k2 = CallDepthThreadLocalMap.Key.CONNECTION
|
||||
|
||||
expect:
|
||||
CallDepthThreadLocalMap.incrementCallDepth(k1) == 0
|
||||
CallDepthThreadLocalMap.incrementCallDepth(k2) == 0
|
||||
|
||||
CallDepthThreadLocalMap.incrementCallDepth(k1) == 1
|
||||
CallDepthThreadLocalMap.incrementCallDepth(k2) == 1
|
||||
|
||||
when:
|
||||
CallDepthThreadLocalMap.reset(k1)
|
||||
|
||||
then:
|
||||
CallDepthThreadLocalMap.incrementCallDepth(k2) == 2
|
||||
|
||||
when:
|
||||
CallDepthThreadLocalMap.reset(k2)
|
||||
|
||||
then:
|
||||
CallDepthThreadLocalMap.incrementCallDepth(k1) == 0
|
||||
CallDepthThreadLocalMap.incrementCallDepth(k2) == 0
|
||||
|
||||
CallDepthThreadLocalMap.incrementCallDepth(k1) == 1
|
||||
CallDepthThreadLocalMap.incrementCallDepth(k2) == 1
|
||||
}
|
||||
}
|
||||
|
|
@ -1,10 +1,15 @@
|
|||
apply from: "${rootDir}/gradle/java.gradle"
|
||||
|
||||
whitelistedInstructionClasses += whitelistedBranchClasses += [
|
||||
'datadog.trace.agent.tooling.*'
|
||||
]
|
||||
|
||||
dependencies {
|
||||
compile project(':dd-java-agent:agent-bootstrap')
|
||||
compile deps.bytebuddy
|
||||
compile deps.bytebuddyagent
|
||||
compile deps.autoservice
|
||||
annotationProcessor deps.autoservice
|
||||
implementation deps.autoservice
|
||||
|
||||
compileOnly project(':dd-trace-ot')
|
||||
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ public interface Instrumenter {
|
|||
protected final boolean enabled;
|
||||
|
||||
public Configurable(final String instrumentationName, final String... additionalNames) {
|
||||
this.instrumentationNames = new HashSet(Arrays.asList(additionalNames));
|
||||
this.instrumentationNames = new HashSet<>(Arrays.asList(additionalNames));
|
||||
instrumentationNames.add(instrumentationName);
|
||||
|
||||
// If default is enabled, we want to enable individually,
|
||||
|
|
|
|||
|
|
@ -6,13 +6,8 @@ description = 'dd-java-agent'
|
|||
|
||||
apply from: "${rootDir}/gradle/java.gradle"
|
||||
apply from: "${rootDir}/gradle/publish.gradle"
|
||||
apply from: "${rootDir}/gradle/jacoco.gradle"
|
||||
jacocoTestReport.dependsOn ':dd-java-agent-ittests:test'
|
||||
|
||||
whitelistedInstructionClasses += whitelistedBranchClasses += [
|
||||
'datadog.agent.*',
|
||||
'datadog.agent.decorators.*',
|
||||
]
|
||||
jacocoTestReport.dependsOn ':dd-java-agent-ittests:test'
|
||||
|
||||
/*
|
||||
* Include subproject's shadowJar in the dd-java-agent jar.
|
||||
|
|
|
|||
|
|
@ -31,4 +31,6 @@ dependencies {
|
|||
|
||||
compile deps.bytebuddy
|
||||
compile deps.opentracing
|
||||
annotationProcessor deps.autoservice
|
||||
implementation deps.autoservice
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,7 +33,8 @@ dependencies {
|
|||
|
||||
compile deps.bytebuddy
|
||||
compile deps.opentracing
|
||||
compile deps.autoservice
|
||||
annotationProcessor deps.autoservice
|
||||
implementation deps.autoservice
|
||||
|
||||
testCompile project(':dd-java-agent:testing')
|
||||
// Include httpclient instrumentation for testing because it is a dependency for aws-sdk.
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ class SpanDecorator {
|
|||
private static final Map<String, String> SERVICE_NAMES = new ConcurrentHashMap<>();
|
||||
private static final Map<Class, String> OPERATION_NAMES = new ConcurrentHashMap<>();
|
||||
|
||||
static void onRequest(final Request request, final Span span) {
|
||||
static void onRequest(final Request<?> request, final Span span) {
|
||||
Tags.COMPONENT.set(span, COMPONENT_NAME);
|
||||
Tags.HTTP_METHOD.set(span, request.getHttpMethod().name());
|
||||
Tags.HTTP_URL.set(span, request.getEndpoint().toString());
|
||||
|
|
@ -52,9 +52,9 @@ class SpanDecorator {
|
|||
|
||||
try {
|
||||
final StringBuilder params = new StringBuilder("{");
|
||||
final Map<String, List<Object>> requestParams = request.getParameters();
|
||||
final Map<String, List<String>> requestParams = request.getParameters();
|
||||
boolean firstKey = true;
|
||||
for (final Entry<String, List<Object>> entry : requestParams.entrySet()) {
|
||||
for (final Entry<String, List<String>> entry : requestParams.entrySet()) {
|
||||
if (!firstKey) {
|
||||
params.append(",");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,8 @@ dependencies {
|
|||
|
||||
compile deps.bytebuddy
|
||||
compile deps.opentracing
|
||||
compile deps.autoservice
|
||||
annotationProcessor deps.autoservice
|
||||
implementation deps.autoservice
|
||||
|
||||
testCompile project(':dd-java-agent:testing')
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package datadog.trace.instrumentation.classloaders;
|
||||
|
||||
import static datadog.trace.agent.tooling.ClassLoaderMatcher.classLoaderHasClasses;
|
||||
import static datadog.trace.bootstrap.CallDepthThreadLocalMap.Key.CLASSLOADER;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.failSafe;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.isConstructor;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.isSubTypeOf;
|
||||
|
|
@ -45,7 +46,7 @@ public final class ClassLoaderInstrumentation extends Instrumenter.Configurable
|
|||
public static int constructorEnter() {
|
||||
// We use this to make sure we only apply the exit instrumentation
|
||||
// after the constructors are done calling their super constructors.
|
||||
return CallDepthThreadLocalMap.get(ClassLoader.class).incrementCallDepth();
|
||||
return CallDepthThreadLocalMap.incrementCallDepth(CLASSLOADER);
|
||||
}
|
||||
|
||||
// Not sure why, but adding suppress causes a verify error.
|
||||
|
|
@ -53,7 +54,7 @@ public final class ClassLoaderInstrumentation extends Instrumenter.Configurable
|
|||
public static void constructorExit(
|
||||
@Advice.This final ClassLoader cl, @Advice.Enter final int depth) {
|
||||
if (depth == 0) {
|
||||
CallDepthThreadLocalMap.get(ClassLoader.class).reset();
|
||||
CallDepthThreadLocalMap.reset(CLASSLOADER);
|
||||
|
||||
try {
|
||||
final Field field = GlobalTracer.class.getDeclaredField("tracer");
|
||||
|
|
|
|||
|
|
@ -33,6 +33,8 @@ dependencies {
|
|||
|
||||
compile deps.bytebuddy
|
||||
compile deps.opentracing
|
||||
annotationProcessor deps.autoservice
|
||||
implementation deps.autoservice
|
||||
|
||||
testCompile project(':dd-java-agent:testing')
|
||||
testCompile group: 'com.datastax.cassandra', name: 'cassandra-driver-core', version: '3.2.0'
|
||||
|
|
|
|||
|
|
@ -28,6 +28,8 @@ dependencies {
|
|||
compile deps.bytebuddy
|
||||
compile deps.opentracing
|
||||
compile deps.autoservice
|
||||
annotationProcessor deps.autoservice
|
||||
implementation deps.autoservice
|
||||
|
||||
testCompile project(':dd-java-agent:testing')
|
||||
testCompile project(':dd-java-agent:instrumentation:java-concurrent')
|
||||
|
|
|
|||
|
|
@ -35,6 +35,8 @@ class HystrixTest extends AgentTestRunner {
|
|||
operation(command)
|
||||
}
|
||||
expect:
|
||||
TRANSFORMED_CLASSES.contains("com.netflix.hystrix.strategy.concurrency.HystrixContextScheduler\$ThreadPoolWorker")
|
||||
TRANSFORMED_CLASSES.contains("HystrixTest\$1")
|
||||
result == "Hello!"
|
||||
|
||||
assertTraces(TEST_WRITER, 1) {
|
||||
|
|
@ -106,6 +108,8 @@ class HystrixTest extends AgentTestRunner {
|
|||
operation(command)
|
||||
}
|
||||
expect:
|
||||
TRANSFORMED_CLASSES.contains("com.netflix.hystrix.strategy.concurrency.HystrixContextScheduler\$ThreadPoolWorker")
|
||||
TRANSFORMED_CLASSES.contains("HystrixTest\$2")
|
||||
result == "Fallback!"
|
||||
|
||||
assertTraces(TEST_WRITER, 1) {
|
||||
|
|
|
|||
|
|
@ -15,6 +15,10 @@ subprojects { subProj ->
|
|||
}
|
||||
}
|
||||
|
||||
whitelistedInstructionClasses += whitelistedBranchClasses += [
|
||||
'datadog.trace.instrumentation.*'
|
||||
]
|
||||
|
||||
dependencies {
|
||||
compile(project(':dd-java-agent:agent-tooling')) {
|
||||
exclude module: ':dd-java-agent:agent-bootstrap'
|
||||
|
|
|
|||
|
|
@ -1,6 +1,10 @@
|
|||
apply from: "${rootDir}/gradle/java.gradle"
|
||||
apply plugin: 'scala'
|
||||
|
||||
whitelistedInstructionClasses += whitelistedBranchClasses += [
|
||||
'*'
|
||||
]
|
||||
|
||||
dependencies {
|
||||
compile project(':dd-trace-api')
|
||||
compile project(':dd-trace-ot')
|
||||
|
|
|
|||
|
|
@ -1,12 +1,11 @@
|
|||
import akka.actor.{Actor, ActorLogging, ActorRef, ActorSystem, Props}
|
||||
import akka.pattern.ask
|
||||
import akka.util.Timeout
|
||||
import datadog.trace.api.Trace
|
||||
import datadog.trace.context.TraceScope
|
||||
import akka.pattern.ask
|
||||
import io.opentracing.util.GlobalTracer
|
||||
|
||||
import scala.concurrent.duration._
|
||||
import akka.actor.{Actor, ActorLogging, ActorRef, ActorSystem, Props}
|
||||
import akka.routing.Broadcast
|
||||
import akka.util.Timeout
|
||||
|
||||
// ! == send-message
|
||||
object AkkaActors {
|
||||
|
|
@ -84,7 +83,6 @@ class Receiver extends Actor with ActorLogging {
|
|||
def receive = {
|
||||
case Greeting(greeting) => {
|
||||
AkkaActors.tracedChild(greeting)
|
||||
"done"
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,8 @@ dependencies {
|
|||
|
||||
compile deps.bytebuddy
|
||||
compile deps.opentracing
|
||||
compile deps.autoservice
|
||||
annotationProcessor deps.autoservice
|
||||
implementation deps.autoservice
|
||||
|
||||
testCompile project(':dd-java-agent:testing')
|
||||
testCompile project(':dd-java-agent:instrumentation:trace-annotation')
|
||||
|
|
|
|||
|
|
@ -16,7 +16,12 @@ 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.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.Executor;
|
||||
|
|
@ -78,8 +83,7 @@ public final class ExecutorInstrumentation extends Instrumenter.Configurable {
|
|||
"akka.dispatch.ExecutionContexts$sameThreadExecutionContext$",
|
||||
"play.api.libs.streams.Execution$trampoline$"
|
||||
};
|
||||
WHITELISTED_EXECUTORS =
|
||||
Collections.unmodifiableSet(new HashSet<String>(Arrays.asList(whitelist)));
|
||||
WHITELISTED_EXECUTORS = Collections.unmodifiableSet(new HashSet<>(Arrays.asList(whitelist)));
|
||||
}
|
||||
|
||||
public ExecutorInstrumentation() {
|
||||
|
|
@ -93,7 +97,7 @@ public final class ExecutorInstrumentation extends Instrumenter.Configurable {
|
|||
.and(
|
||||
new ElementMatcher<TypeDescription>() {
|
||||
@Override
|
||||
public boolean matches(TypeDescription target) {
|
||||
public boolean matches(final TypeDescription target) {
|
||||
final boolean whitelisted = WHITELISTED_EXECUTORS.contains(target.getName());
|
||||
if (!whitelisted) {
|
||||
log.debug("Skipping executor instrumentation for {}", target.getName());
|
||||
|
|
@ -157,13 +161,13 @@ public final class ExecutorInstrumentation extends Instrumenter.Configurable {
|
|||
public static class WrapCallableAdvice {
|
||||
@Advice.OnMethodEnter(suppress = Throwable.class)
|
||||
public static DatadogWrapper wrapJob(
|
||||
@Advice.Argument(value = 0, readOnly = false) Callable task) {
|
||||
@Advice.Argument(value = 0, readOnly = false) Callable<?> task) {
|
||||
final Scope scope = GlobalTracer.get().scopeManager().active();
|
||||
if (scope instanceof TraceScope
|
||||
&& ((TraceScope) scope).isAsyncPropagating()
|
||||
&& task != null
|
||||
&& !(task instanceof DatadogWrapper)) {
|
||||
task = new CallableWrapper(task, (TraceScope) scope);
|
||||
task = new CallableWrapper<>(task, (TraceScope) scope);
|
||||
return (CallableWrapper) task;
|
||||
}
|
||||
return null;
|
||||
|
|
@ -184,11 +188,11 @@ public final class ExecutorInstrumentation extends Instrumenter.Configurable {
|
|||
@Advice.Argument(value = 0, readOnly = false) Collection<? extends Callable<?>> tasks) {
|
||||
final Scope scope = GlobalTracer.get().scopeManager().active();
|
||||
if (scope instanceof TraceScope && ((TraceScope) scope).isAsyncPropagating()) {
|
||||
Collection<Callable<?>> wrappedTasks = new ArrayList<>(tasks.size());
|
||||
for (Callable task : tasks) {
|
||||
final Collection<Callable<?>> wrappedTasks = new ArrayList<>(tasks.size());
|
||||
for (Callable<?> task : tasks) {
|
||||
if (task != null) {
|
||||
if (!(task instanceof CallableWrapper)) {
|
||||
task = new CallableWrapper(task, (TraceScope) scope);
|
||||
task = new CallableWrapper<>(task, (TraceScope) scope);
|
||||
}
|
||||
wrappedTasks.add(task);
|
||||
}
|
||||
|
|
@ -203,7 +207,7 @@ public final class ExecutorInstrumentation extends Instrumenter.Configurable {
|
|||
public static void checkCancel(
|
||||
@Advice.Enter final Collection<?> wrappedJobs, @Advice.Thrown final Throwable throwable) {
|
||||
if (null != wrappedJobs && null != throwable) {
|
||||
for (Object wrapper : wrappedJobs) {
|
||||
for (final Object wrapper : wrappedJobs) {
|
||||
if (wrapper instanceof DatadogWrapper) {
|
||||
((DatadogWrapper) wrapper).cancel();
|
||||
}
|
||||
|
|
@ -217,7 +221,7 @@ public final class ExecutorInstrumentation extends Instrumenter.Configurable {
|
|||
public abstract static class DatadogWrapper {
|
||||
protected final TraceScope.Continuation continuation;
|
||||
|
||||
public DatadogWrapper(TraceScope scope) {
|
||||
public DatadogWrapper(final TraceScope scope) {
|
||||
continuation = scope.capture();
|
||||
log.debug("created continuation {} from scope {}", continuation, scope);
|
||||
}
|
||||
|
|
@ -234,7 +238,7 @@ public final class ExecutorInstrumentation extends Instrumenter.Configurable {
|
|||
public static class RunnableWrapper extends DatadogWrapper implements Runnable {
|
||||
private final Runnable delegatee;
|
||||
|
||||
public RunnableWrapper(Runnable toWrap, TraceScope scope) {
|
||||
public RunnableWrapper(final Runnable toWrap, final TraceScope scope) {
|
||||
super(scope);
|
||||
delegatee = toWrap;
|
||||
}
|
||||
|
|
@ -255,7 +259,7 @@ public final class ExecutorInstrumentation extends Instrumenter.Configurable {
|
|||
public static class CallableWrapper<T> extends DatadogWrapper implements Callable<T> {
|
||||
private final Callable<T> delegatee;
|
||||
|
||||
public CallableWrapper(Callable<T> toWrap, TraceScope scope) {
|
||||
public CallableWrapper(final Callable<T> toWrap, final TraceScope scope) {
|
||||
super(scope);
|
||||
delegatee = toWrap;
|
||||
}
|
||||
|
|
@ -274,14 +278,14 @@ public final class ExecutorInstrumentation extends Instrumenter.Configurable {
|
|||
|
||||
/** Utils for pulling DatadogWrapper out of Future instances. */
|
||||
public static class ConcurrentUtils {
|
||||
private static Map<Class<?>, Field> fieldCache = new ConcurrentHashMap<>();
|
||||
private static String[] wrapperFields = {"runnable", "callable"};
|
||||
private static final Map<Class<?>, Field> fieldCache = new ConcurrentHashMap<>();
|
||||
private static final String[] wrapperFields = {"runnable", "callable"};
|
||||
|
||||
public static boolean safeToWrap(Future<?> f) {
|
||||
public static boolean safeToWrap(final Future<?> f) {
|
||||
return null != getDatadogWrapper(f);
|
||||
}
|
||||
|
||||
public static DatadogWrapper getDatadogWrapper(Future<?> f) {
|
||||
public static DatadogWrapper getDatadogWrapper(final Future<?> f) {
|
||||
final Field field;
|
||||
if (fieldCache.containsKey(f.getClass())) {
|
||||
field = fieldCache.get(f.getClass());
|
||||
|
|
@ -293,7 +297,7 @@ public final class ExecutorInstrumentation extends Instrumenter.Configurable {
|
|||
if (field != null) {
|
||||
try {
|
||||
field.setAccessible(true);
|
||||
Object o = field.get(f);
|
||||
final Object o = field.get(f);
|
||||
if (o instanceof DatadogWrapper) {
|
||||
return (DatadogWrapper) o;
|
||||
}
|
||||
|
|
@ -312,7 +316,7 @@ public final class ExecutorInstrumentation extends Instrumenter.Configurable {
|
|||
try {
|
||||
field = clazz.getDeclaredField(wrapperFields[i]);
|
||||
break;
|
||||
} catch (Exception e) {
|
||||
} catch (final Exception e) {
|
||||
}
|
||||
}
|
||||
clazz = clazz.getSuperclass();
|
||||
|
|
|
|||
|
|
@ -13,7 +13,8 @@ dependencies {
|
|||
|
||||
compile deps.bytebuddy
|
||||
compile deps.opentracing
|
||||
compile deps.autoservice
|
||||
annotationProcessor deps.autoservice
|
||||
implementation deps.autoservice
|
||||
|
||||
compile project(':dd-java-agent:agent-tooling')
|
||||
|
||||
|
|
|
|||
|
|
@ -18,7 +18,8 @@ dependencies {
|
|||
|
||||
compile deps.bytebuddy
|
||||
compile deps.opentracing
|
||||
compile deps.autoservice
|
||||
annotationProcessor deps.autoservice
|
||||
implementation deps.autoservice
|
||||
|
||||
compile project(':dd-java-agent:agent-tooling')
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,8 @@ apply from: "${rootDir}/gradle/java.gradle"
|
|||
dependencies {
|
||||
compile project(':dd-java-agent:agent-tooling')
|
||||
compile deps.bytebuddy
|
||||
compile deps.autoservice
|
||||
annotationProcessor deps.autoservice
|
||||
implementation deps.autoservice
|
||||
|
||||
testCompile group: 'org.jboss.modules', name: 'jboss-modules', version: '1.3.10.Final'
|
||||
testCompile project(':dd-java-agent:testing')
|
||||
|
|
|
|||
|
|
@ -5,5 +5,6 @@ dependencies {
|
|||
|
||||
compile deps.bytebuddy
|
||||
compile deps.opentracing
|
||||
compile deps.autoservice
|
||||
annotationProcessor deps.autoservice
|
||||
implementation deps.autoservice
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package datadog.trace.instrumentation.jdbc;
|
||||
|
||||
import static datadog.trace.bootstrap.CallDepthThreadLocalMap.Key.CONNECTION;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.failSafe;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.isConstructor;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.isInterface;
|
||||
|
|
@ -58,7 +59,7 @@ public final class ConnectionInstrumentation extends Instrumenter.Configurable {
|
|||
public static int constructorEnter() {
|
||||
// We use this to make sure we only apply the exit instrumentation
|
||||
// after the constructors are done calling their super constructors.
|
||||
return CallDepthThreadLocalMap.get(Connection.class).incrementCallDepth();
|
||||
return CallDepthThreadLocalMap.incrementCallDepth(CONNECTION);
|
||||
}
|
||||
|
||||
// Since we're instrumenting the constructor, we can't add onThrowable.
|
||||
|
|
@ -67,12 +68,12 @@ public final class ConnectionInstrumentation extends Instrumenter.Configurable {
|
|||
@Advice.Enter final int depth, @Advice.This final Connection connection)
|
||||
throws SQLException {
|
||||
if (depth == 0) {
|
||||
CallDepthThreadLocalMap.get(Connection.class).reset();
|
||||
CallDepthThreadLocalMap.reset(CONNECTION);
|
||||
final String url = connection.getMetaData().getURL();
|
||||
if (url != null) {
|
||||
// Remove end of url to prevent passwords from leaking:
|
||||
final String sanitizedURL = url.replaceAll("[?;].*", "");
|
||||
final String type = url.split(":")[1];
|
||||
final String type = url.split(":", -1)[1];
|
||||
String user = connection.getMetaData().getUserName();
|
||||
if (user != null && user.trim().equals("")) {
|
||||
user = null;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package datadog.trace.instrumentation.jdbc;
|
||||
|
||||
import static datadog.trace.bootstrap.CallDepthThreadLocalMap.Key.PREPARED_STATEMENT;
|
||||
import static io.opentracing.log.Fields.ERROR_OBJECT;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.failSafe;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.isInterface;
|
||||
|
|
@ -51,8 +52,7 @@ public final class PreparedStatementInstrumentation extends Instrumenter.Configu
|
|||
|
||||
@Advice.OnMethodEnter(suppress = Throwable.class)
|
||||
public static Scope startSpan(@Advice.This final PreparedStatement statement) {
|
||||
final int callDepth =
|
||||
CallDepthThreadLocalMap.get(PreparedStatement.class).incrementCallDepth();
|
||||
final int callDepth = CallDepthThreadLocalMap.incrementCallDepth(PREPARED_STATEMENT);
|
||||
if (callDepth > 0) {
|
||||
return null;
|
||||
}
|
||||
|
|
@ -99,7 +99,7 @@ public final class PreparedStatementInstrumentation extends Instrumenter.Configu
|
|||
span.log(Collections.singletonMap(ERROR_OBJECT, throwable));
|
||||
}
|
||||
scope.close();
|
||||
CallDepthThreadLocalMap.get(PreparedStatement.class).reset();
|
||||
CallDepthThreadLocalMap.reset(PREPARED_STATEMENT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package datadog.trace.instrumentation.jdbc;
|
||||
|
||||
import static datadog.trace.bootstrap.CallDepthThreadLocalMap.Key.STATEMENT;
|
||||
import static io.opentracing.log.Fields.ERROR_OBJECT;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.failSafe;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.isInterface;
|
||||
|
|
@ -52,7 +53,7 @@ public final class StatementInstrumentation extends Instrumenter.Configurable {
|
|||
@Advice.OnMethodEnter(suppress = Throwable.class)
|
||||
public static Scope startSpan(
|
||||
@Advice.Argument(0) final String sql, @Advice.This final Statement statement) {
|
||||
final int callDepth = CallDepthThreadLocalMap.get(Statement.class).incrementCallDepth();
|
||||
final int callDepth = CallDepthThreadLocalMap.incrementCallDepth(STATEMENT);
|
||||
if (callDepth > 0) {
|
||||
return null;
|
||||
}
|
||||
|
|
@ -100,7 +101,7 @@ public final class StatementInstrumentation extends Instrumenter.Configurable {
|
|||
span.log(Collections.singletonMap(ERROR_OBJECT, throwable));
|
||||
}
|
||||
scope.close();
|
||||
CallDepthThreadLocalMap.get(Statement.class).reset();
|
||||
CallDepthThreadLocalMap.reset(STATEMENT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,7 +27,8 @@ dependencies {
|
|||
|
||||
compile deps.bytebuddy
|
||||
compile deps.opentracing
|
||||
compile deps.autoservice
|
||||
annotationProcessor deps.autoservice
|
||||
implementation deps.autoservice
|
||||
|
||||
testCompile project(':dd-java-agent:testing')
|
||||
testCompile group: 'com.github.kstyrc', name: 'embedded-redis', version: '0.6'
|
||||
|
|
|
|||
|
|
@ -27,7 +27,8 @@ dependencies {
|
|||
|
||||
compile deps.bytebuddy
|
||||
compile deps.opentracing
|
||||
compile deps.autoservice
|
||||
annotationProcessor deps.autoservice
|
||||
implementation deps.autoservice
|
||||
|
||||
testCompile project(':dd-java-agent:testing')
|
||||
testCompile group: 'org.eclipse.jetty', name: 'jetty-server', version: '8.0.0.v20110901'
|
||||
|
|
|
|||
|
|
@ -18,7 +18,8 @@ dependencies {
|
|||
|
||||
compile deps.bytebuddy
|
||||
compile deps.opentracing
|
||||
compile deps.autoservice
|
||||
annotationProcessor deps.autoservice
|
||||
implementation deps.autoservice
|
||||
|
||||
compile project(':dd-java-agent:agent-tooling')
|
||||
|
||||
|
|
|
|||
|
|
@ -22,7 +22,8 @@ dependencies {
|
|||
|
||||
compile deps.bytebuddy
|
||||
compile deps.opentracing
|
||||
compile deps.autoservice
|
||||
annotationProcessor deps.autoservice
|
||||
implementation deps.autoservice
|
||||
|
||||
compile project(':dd-java-agent:agent-tooling')
|
||||
|
||||
|
|
|
|||
|
|
@ -27,6 +27,8 @@ dependencies {
|
|||
|
||||
compile deps.bytebuddy
|
||||
compile deps.opentracing
|
||||
annotationProcessor deps.autoservice
|
||||
implementation deps.autoservice
|
||||
|
||||
testCompile project(':dd-java-agent:testing')
|
||||
testCompile group: 'org.apache.kafka', name: 'kafka-clients', version: '0.11.0.0'
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ public final class KafkaConsumerInstrumentation extends Instrumenter.Configurabl
|
|||
@Advice.OnMethodExit(suppress = Throwable.class)
|
||||
public static void wrap(@Advice.Return(readOnly = false) Iterable<ConsumerRecord> iterable) {
|
||||
if (iterable != null) {
|
||||
iterable = new TracingIterable(iterable, "kafka.consume", ConsumeScopeAction.INSTANCE);
|
||||
iterable = new TracingIterable<>(iterable, "kafka.consume", ConsumeScopeAction.INSTANCE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -83,7 +83,7 @@ public final class KafkaConsumerInstrumentation extends Instrumenter.Configurabl
|
|||
public static void wrap(@Advice.Return(readOnly = false) Iterator<ConsumerRecord> iterator) {
|
||||
if (iterator != null) {
|
||||
iterator =
|
||||
new TracingIterable.TracingIterator(
|
||||
new TracingIterable.TracingIterator<>(
|
||||
iterator, "kafka.consume", ConsumeScopeAction.INSTANCE);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -67,9 +67,10 @@ public class TracingIterable<T> implements Iterable<T> {
|
|||
decorator.decorate(spanBuilder, next);
|
||||
currentScope = spanBuilder.startActive(true);
|
||||
}
|
||||
} finally {
|
||||
return next;
|
||||
} catch (final Exception e) {
|
||||
log.debug("Error during decoration", e);
|
||||
}
|
||||
return next;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -27,6 +27,8 @@ dependencies {
|
|||
|
||||
compile deps.bytebuddy
|
||||
compile deps.opentracing
|
||||
annotationProcessor deps.autoservice
|
||||
implementation deps.autoservice
|
||||
|
||||
testCompile project(':dd-java-agent:testing')
|
||||
// Include kafka-clients instrumentation for tests.
|
||||
|
|
|
|||
|
|
@ -27,6 +27,8 @@ dependencies {
|
|||
|
||||
compile deps.bytebuddy
|
||||
compile deps.opentracing
|
||||
annotationProcessor deps.autoservice
|
||||
implementation deps.autoservice
|
||||
|
||||
testCompile project(':dd-trace-ot')
|
||||
testCompile group: 'org.mongodb', name: 'mongo-java-driver', version: '3.4.2'
|
||||
|
|
|
|||
|
|
@ -23,4 +23,6 @@ dependencies {
|
|||
|
||||
compile deps.bytebuddy
|
||||
compile deps.opentracing
|
||||
annotationProcessor deps.autoservice
|
||||
implementation deps.autoservice
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,6 +32,8 @@ dependencies {
|
|||
|
||||
compile deps.bytebuddy
|
||||
compile deps.opentracing
|
||||
annotationProcessor deps.autoservice
|
||||
implementation deps.autoservice
|
||||
|
||||
testCompile project(':dd-java-agent:testing')
|
||||
testCompile group: 'com.squareup.okhttp3', name: 'okhttp', version: '3.0.0'
|
||||
|
|
|
|||
|
|
@ -3,7 +3,8 @@ apply from: "${rootDir}/gradle/java.gradle"
|
|||
dependencies {
|
||||
compile project(':dd-java-agent:agent-tooling')
|
||||
compile deps.bytebuddy
|
||||
compile deps.autoservice
|
||||
annotationProcessor deps.autoservice
|
||||
implementation deps.autoservice
|
||||
|
||||
testCompile group: 'org.osgi', name: 'org.osgi.core', version: '4.0.0'
|
||||
testCompile project(':dd-java-agent:testing')
|
||||
|
|
|
|||
|
|
@ -14,7 +14,8 @@ dependencies {
|
|||
compile project(':dd-java-agent:agent-tooling')
|
||||
compile deps.bytebuddy
|
||||
compile deps.opentracing
|
||||
compile deps.autoservice
|
||||
annotationProcessor deps.autoservice
|
||||
implementation deps.autoservice
|
||||
|
||||
testCompile group: 'org.scala-lang', name: 'scala-library', version: '2.11.12'
|
||||
testCompile group: 'com.typesafe.play', name: 'play_2.11', version: '2.4.0'
|
||||
|
|
|
|||
|
|
@ -26,6 +26,10 @@ compileMain_java8Java {
|
|||
sourceCompatibility = 1.8
|
||||
targetCompatibility = 1.8
|
||||
}
|
||||
configurations {
|
||||
main_java8AnnotationProcessor.extendsFrom lombok
|
||||
main_java8Implementation.extendsFrom lombok
|
||||
}
|
||||
|
||||
apply plugin: 'org.unbroken-dome.test-sets'
|
||||
|
||||
|
|
@ -43,7 +47,9 @@ dependencies {
|
|||
|
||||
main_java8Compile deps.bytebuddy
|
||||
main_java8Compile deps.opentracing
|
||||
main_java8Compile deps.autoservice
|
||||
|
||||
annotationProcessor deps.autoservice
|
||||
implementation deps.autoservice
|
||||
|
||||
compileOnly sourceSets.main_java8.compileClasspath
|
||||
|
||||
|
|
|
|||
|
|
@ -19,7 +19,8 @@ dependencies {
|
|||
|
||||
compile deps.bytebuddy
|
||||
compile deps.opentracing
|
||||
compile deps.autoservice
|
||||
annotationProcessor deps.autoservice
|
||||
implementation deps.autoservice
|
||||
|
||||
testCompile project(':dd-java-agent:testing')
|
||||
testCompile group: 'org.eclipse.jetty', name: 'jetty-server', version: '7.0.0.v20091005'
|
||||
|
|
|
|||
|
|
@ -38,14 +38,14 @@ public class HttpServletRequestExtractAdapter implements TextMap {
|
|||
final HttpServletRequest httpServletRequest) {
|
||||
final Map<String, List<String>> headersResult = new HashMap<>();
|
||||
|
||||
final Enumeration<String> headerNamesIt = httpServletRequest.getHeaderNames();
|
||||
final Enumeration<?> headerNamesIt = httpServletRequest.getHeaderNames();
|
||||
while (headerNamesIt.hasMoreElements()) {
|
||||
final String headerName = headerNamesIt.nextElement();
|
||||
final String headerName = headerNamesIt.nextElement().toString();
|
||||
|
||||
final Enumeration<String> valuesIt = httpServletRequest.getHeaders(headerName);
|
||||
final Enumeration<?> valuesIt = httpServletRequest.getHeaders(headerName);
|
||||
final List<String> valuesList = new ArrayList<>(1);
|
||||
while (valuesIt.hasMoreElements()) {
|
||||
valuesList.add(valuesIt.nextElement());
|
||||
valuesList.add(valuesIt.nextElement().toString());
|
||||
}
|
||||
|
||||
headersResult.put(headerName, valuesList);
|
||||
|
|
|
|||
|
|
@ -29,7 +29,8 @@ dependencies {
|
|||
|
||||
compile deps.bytebuddy
|
||||
compile deps.opentracing
|
||||
compile deps.autoservice
|
||||
annotationProcessor deps.autoservice
|
||||
implementation deps.autoservice
|
||||
|
||||
testCompile project(':dd-java-agent:testing')
|
||||
testCompile project(':dd-java-agent:instrumentation:jetty-8') // See if there's any conflicts.
|
||||
|
|
|
|||
|
|
@ -42,7 +42,8 @@ dependencies {
|
|||
compile project(':dd-java-agent:agent-tooling')
|
||||
compile deps.bytebuddy
|
||||
compile deps.opentracing
|
||||
compile deps.autoservice
|
||||
annotationProcessor deps.autoservice
|
||||
implementation deps.autoservice
|
||||
|
||||
testCompile project(':dd-java-agent:instrumentation:jetty-8')
|
||||
testCompile project(':dd-java-agent:testing')
|
||||
|
|
|
|||
|
|
@ -23,7 +23,8 @@ dependencies {
|
|||
|
||||
compile deps.bytebuddy
|
||||
compile deps.opentracing
|
||||
compile deps.autoservice
|
||||
annotationProcessor deps.autoservice
|
||||
implementation deps.autoservice
|
||||
|
||||
testCompile project(':dd-java-agent:testing')
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,8 @@ dependencies {
|
|||
|
||||
compile deps.bytebuddy
|
||||
compile deps.opentracing
|
||||
compile deps.autoservice
|
||||
annotationProcessor deps.autoservice
|
||||
implementation deps.autoservice
|
||||
|
||||
testCompile project(':dd-java-agent:testing')
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package datadog.trace.agent.test;
|
|||
|
||||
import ch.qos.logback.classic.Level;
|
||||
import ch.qos.logback.classic.Logger;
|
||||
import com.google.common.collect.Sets;
|
||||
import datadog.opentracing.DDSpan;
|
||||
import datadog.opentracing.DDTracer;
|
||||
import datadog.trace.agent.tooling.AgentInstaller;
|
||||
|
|
@ -12,6 +13,8 @@ import io.opentracing.Tracer;
|
|||
import java.lang.instrument.ClassFileTransformer;
|
||||
import java.lang.instrument.Instrumentation;
|
||||
import java.util.List;
|
||||
import java.util.ServiceLoader;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.Phaser;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import net.bytebuddy.agent.ByteBuddyAgent;
|
||||
|
|
@ -57,6 +60,8 @@ public abstract class AgentTestRunner extends Specification {
|
|||
// loads opentracing before bootstrap classpath is setup
|
||||
// so we declare tracer as an object and cast when needed.
|
||||
protected static final Object TEST_TRACER;
|
||||
|
||||
protected static final Set<String> TRANSFORMED_CLASSES = Sets.newConcurrentHashSet();
|
||||
private static final AtomicInteger INSTRUMENTATION_ERROR_COUNT = new AtomicInteger();
|
||||
|
||||
private static final Instrumentation instrumentation;
|
||||
|
|
@ -101,6 +106,7 @@ public abstract class AgentTestRunner extends Specification {
|
|||
final ClassLoader contextLoader = Thread.currentThread().getContextClassLoader();
|
||||
try {
|
||||
Thread.currentThread().setContextClassLoader(AgentTestRunner.class.getClassLoader());
|
||||
assert ServiceLoader.load(Instrumenter.class).iterator().hasNext();
|
||||
activeTransformer =
|
||||
AgentInstaller.installBytebuddyAgent(instrumentation, new ErrorCountingListener());
|
||||
} finally {
|
||||
|
|
@ -142,7 +148,9 @@ public abstract class AgentTestRunner extends Specification {
|
|||
final ClassLoader classLoader,
|
||||
final JavaModule module,
|
||||
final boolean loaded,
|
||||
final DynamicType dynamicType) {}
|
||||
final DynamicType dynamicType) {
|
||||
TRANSFORMED_CLASSES.add(typeDescription.getActualName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onIgnored(
|
||||
|
|
|
|||
|
|
@ -1,5 +1,13 @@
|
|||
apply from: "${rootDir}/gradle/java.gradle"
|
||||
|
||||
minimumBranchCoverage = 0.5
|
||||
minimumInstructionCoverage = 0.6
|
||||
whitelistedInstructionClasses += whitelistedBranchClasses += [
|
||||
'datadog.trace.agent.test.*Assert',
|
||||
'datadog.trace.agent.test.AgentTestRunner.1',
|
||||
'datadog.trace.agent.test.TestUtils'
|
||||
]
|
||||
|
||||
dependencies {
|
||||
compile deps.bytebuddy
|
||||
compile deps.bytebuddyagent
|
||||
|
|
@ -7,9 +15,13 @@ dependencies {
|
|||
compile deps.opentracing
|
||||
compile deps.spock
|
||||
compile deps.testLogging
|
||||
compile deps.guava
|
||||
|
||||
compile project(':dd-trace-ot')
|
||||
compile project(':dd-java-agent:agent-tooling')
|
||||
|
||||
annotationProcessor deps.autoservice
|
||||
implementation deps.autoservice
|
||||
|
||||
compile deps.groovy
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
apply from: "${rootDir}/gradle/java.gradle"
|
||||
apply from: "${rootDir}/gradle/publish.gradle"
|
||||
apply from: "${rootDir}/gradle/jacoco.gradle"
|
||||
|
||||
description = 'dd-trace-api'
|
||||
dependencies {
|
||||
|
|
|
|||
|
|
@ -3,9 +3,9 @@ buildscript {
|
|||
jcenter()
|
||||
}
|
||||
dependencies {
|
||||
classpath "io.franzbecker:gradle-lombok:1.8"
|
||||
classpath "org.jfrog.buildinfo:build-info-extractor-gradle:4.4.18"
|
||||
classpath "com.jfrog.bintray.gradle:gradle-bintray-plugin:1.7.3"
|
||||
classpath "io.franzbecker:gradle-lombok:1.13"
|
||||
classpath "org.jfrog.buildinfo:build-info-extractor-gradle:4.7.2"
|
||||
classpath "com.jfrog.bintray.gradle:gradle-bintray-plugin:1.8.0"
|
||||
classpath "net.ltgt.gradle:gradle-errorprone-plugin:0.0.13"
|
||||
classpath 'org.unbroken-dome.gradle-plugins:gradle-testsets-plugin:1.4.5'
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,15 +6,12 @@ description = 'dd-trace-ot'
|
|||
|
||||
apply from: "${rootDir}/gradle/java.gradle"
|
||||
apply from: "${rootDir}/gradle/publish.gradle"
|
||||
apply from: "${rootDir}/gradle/jacoco.gradle"
|
||||
minimumBranchCoverage = 0.3
|
||||
minimumInstructionCoverage = 0.5
|
||||
|
||||
minimumBranchCoverage = 0.5
|
||||
minimumInstructionCoverage = 0.6
|
||||
whitelistedInstructionClasses += whitelistedBranchClasses += [
|
||||
'datadog.opentracing.decorators.*',
|
||||
'datadog.trace.common.writer.ListWriter',
|
||||
'datadog.trace.common.util.Clock',
|
||||
'datadog.trace.api.DDTags',
|
||||
'datadog.trace.common.util.ConfigUtils',
|
||||
'datadog.trace.common.sampling.PrioritySampling'
|
||||
]
|
||||
|
||||
|
|
@ -28,7 +25,8 @@ testSets {
|
|||
}
|
||||
|
||||
dependencies {
|
||||
compile deps.autoservice
|
||||
annotationProcessor deps.autoservice
|
||||
implementation deps.autoservice
|
||||
|
||||
compile project(':dd-trace-api')
|
||||
compile deps.opentracing
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package datadog.opentracing.decorators;
|
|||
|
||||
import datadog.opentracing.DDSpanContext;
|
||||
import io.opentracing.tag.Tags;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
|
|
@ -11,18 +12,19 @@ import java.util.Map;
|
|||
*/
|
||||
public class OperationDecorator extends AbstractDecorator {
|
||||
|
||||
static final Map<String, String> MAPPINGS =
|
||||
new HashMap<String, String>() {
|
||||
{
|
||||
// Component name <> Operation name
|
||||
put("apache-httpclient", "apache.http");
|
||||
put("java-aws-sdk", "aws.http");
|
||||
// FIXME: JMS ops card is low (jms-send or jms-receive), may be this mapping is useless
|
||||
put("java-jms", "jms");
|
||||
put("okhttp", "okhttp.http");
|
||||
// Cassandra, Mongo, JDBC are set via DBTypeDecorator
|
||||
}
|
||||
};
|
||||
static final Map<String, String> MAPPINGS;
|
||||
|
||||
static {
|
||||
final Map<String, String> mappings = new HashMap<>();
|
||||
// Component name <> Operation name
|
||||
mappings.put("apache-httpclient", "apache.http");
|
||||
mappings.put("java-aws-sdk", "aws.http");
|
||||
// FIXME: JMS ops card is low (jms-send or jms-receive), may be this mapping is useless
|
||||
mappings.put("java-jms", "jms");
|
||||
mappings.put("okhttp", "okhttp.http");
|
||||
// Cassandra, Mongo, JDBC are set via DBTypeDecorator
|
||||
MAPPINGS = Collections.unmodifiableMap(mappings);
|
||||
}
|
||||
|
||||
public OperationDecorator() {
|
||||
super();
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import java.util.Deque;
|
|||
import java.util.concurrent.ConcurrentLinkedDeque;
|
||||
|
||||
public class ContextualScopeManager implements ScopeManager {
|
||||
final ThreadLocal<Scope> tlsScope = new ThreadLocal<>();
|
||||
static final ThreadLocal<Scope> tlsScope = new ThreadLocal<>();
|
||||
final Deque<ScopeContext> scopeContexts = new ConcurrentLinkedDeque<>();
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@ public class ContinuableScope implements Scope, TraceScope {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void setAsyncPropagation(boolean value) {
|
||||
public void setAsyncPropagation(final boolean value) {
|
||||
isAsyncPropagating.set(value);
|
||||
}
|
||||
|
||||
|
|
@ -87,6 +87,7 @@ public class ContinuableScope implements Scope, TraceScope {
|
|||
*
|
||||
* @return The new continuation, or null if this scope is not async propagating.
|
||||
*/
|
||||
@Override
|
||||
public Continuation capture() {
|
||||
if (isAsyncPropagating()) {
|
||||
return new Continuation();
|
||||
|
|
@ -108,6 +109,7 @@ public class ContinuableScope implements Scope, TraceScope {
|
|||
trace.registerContinuation(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ContinuableScope activate() {
|
||||
if (used.compareAndSet(false, true)) {
|
||||
return new ContinuableScope(scopeManager, openCount, this, spanUnderScope, finishOnClose);
|
||||
|
|
|
|||
|
|
@ -83,12 +83,14 @@ public class DDTraceConfig extends Properties {
|
|||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
final String[] tokens = str.split(",");
|
||||
final String[] tokens = str.split(",", -1);
|
||||
final Map<String, Object> map = new HashMap<>(tokens.length + 1, 1f);
|
||||
|
||||
for (final String token : tokens) {
|
||||
final String[] keyValue = token.split(":");
|
||||
map.put(keyValue[0].trim(), keyValue[1].trim());
|
||||
final String[] keyValue = token.split(":", -1);
|
||||
if (keyValue.length == 2) {
|
||||
map.put(keyValue[0].trim(), keyValue[1].trim());
|
||||
}
|
||||
}
|
||||
return Collections.unmodifiableMap(map);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,64 +0,0 @@
|
|||
package datadog.trace.common;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.fasterxml.jackson.annotation.JsonValue;
|
||||
|
||||
public class Service {
|
||||
|
||||
private final String name;
|
||||
private final String appName;
|
||||
private final Service.AppType appType;
|
||||
|
||||
public Service(final String name, final String appName, final AppType appType) {
|
||||
this.name = name;
|
||||
this.appName = appName;
|
||||
this.appType = appType;
|
||||
}
|
||||
|
||||
@JsonIgnore
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@JsonProperty("app")
|
||||
public String getAppName() {
|
||||
return appName;
|
||||
}
|
||||
|
||||
@JsonProperty("app_type")
|
||||
public AppType getAppType() {
|
||||
return appType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Service { "
|
||||
+ "name='"
|
||||
+ name
|
||||
+ "\', appName='"
|
||||
+ appName
|
||||
+ "', appType="
|
||||
+ appType
|
||||
+ " }";
|
||||
}
|
||||
|
||||
public enum AppType {
|
||||
WEB("web"),
|
||||
DB("db"),
|
||||
CUSTOM("custom"),
|
||||
CACHE("cache"),
|
||||
WORKER("worker");
|
||||
|
||||
private final String type;
|
||||
|
||||
AppType(final String type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
@JsonValue
|
||||
public String toString() {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -10,6 +10,7 @@ import java.io.InputStreamReader;
|
|||
import java.io.OutputStream;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
|
@ -82,7 +83,8 @@ public class DDApi {
|
|||
String responseString = null;
|
||||
{
|
||||
final BufferedReader responseReader =
|
||||
new BufferedReader(new InputStreamReader(httpCon.getInputStream()));
|
||||
new BufferedReader(
|
||||
new InputStreamReader(httpCon.getInputStream(), StandardCharsets.UTF_8));
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
|
||||
String line = null;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
package datadog.trace.common.writer;
|
||||
|
||||
import datadog.opentracing.DDSpan;
|
||||
import java.util.LinkedList;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
|
|
@ -10,7 +10,7 @@ import java.util.concurrent.TimeoutException;
|
|||
|
||||
/** List writer used by tests mostly */
|
||||
public class ListWriter extends CopyOnWriteArrayList<List<DDSpan>> implements Writer {
|
||||
private final List<CountDownLatch> latches = new LinkedList<>();
|
||||
private final List<CountDownLatch> latches = new ArrayList<>();
|
||||
|
||||
public List<DDSpan> firstTrace() {
|
||||
return get(0);
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import datadog.opentracing.PendingTrace
|
|||
import datadog.trace.common.writer.ListWriter
|
||||
import io.opentracing.Scope
|
||||
import io.opentracing.Span
|
||||
import io.opentracing.noop.NoopSpan
|
||||
import spock.lang.Specification
|
||||
import spock.lang.Subject
|
||||
import spock.lang.Unroll
|
||||
|
|
@ -25,6 +26,21 @@ class ScopeManagerTest extends Specification {
|
|||
scopeManager.tlsScope.remove()
|
||||
}
|
||||
|
||||
def "non-ddspan activation results in a simple scope"() {
|
||||
when:
|
||||
def scope = scopeManager.activate(NoopSpan.INSTANCE, true)
|
||||
|
||||
then:
|
||||
scopeManager.active() == scope
|
||||
scope instanceof SimpleScope
|
||||
|
||||
when:
|
||||
scope.close()
|
||||
|
||||
then:
|
||||
scopeManager.active() == null
|
||||
}
|
||||
|
||||
def "threadlocal is empty"() {
|
||||
setup:
|
||||
def builder = tracer.buildSpan("test")
|
||||
|
|
|
|||
|
|
@ -8,6 +8,25 @@ import spock.lang.Specification
|
|||
|
||||
class RateByServiceSamplerTest extends Specification {
|
||||
|
||||
def "invalid rate -> 1"() {
|
||||
setup:
|
||||
RateByServiceSampler serviceSampler = new RateByServiceSampler()
|
||||
ObjectMapper serializer = new ObjectMapper()
|
||||
String response = '{"rate_by_service": {"service:,env:":' + rate + '}}'
|
||||
serviceSampler.onResponse("traces", serializer.readTree(response))
|
||||
expect:
|
||||
serviceSampler.baseSampler.sampleRate == expectedRate
|
||||
|
||||
where:
|
||||
rate | expectedRate
|
||||
null | 1
|
||||
1 | 1
|
||||
0 | 1
|
||||
-5 | 1
|
||||
5 | 1
|
||||
0.5 | 0.5
|
||||
}
|
||||
|
||||
def "rate by service name"() {
|
||||
setup:
|
||||
RateByServiceSampler serviceSampler = new RateByServiceSampler()
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ plugins {
|
|||
|
||||
apply plugin: 'application'
|
||||
apply from: "${rootDir}/gradle/java.gradle"
|
||||
apply from: "${rootDir}/gradle/jacoco.gradle"
|
||||
|
||||
version = 'demo'
|
||||
description = 'dropwizard-mongo-client'
|
||||
|
|
|
|||
|
|
@ -7,12 +7,12 @@ public class Book {
|
|||
|
||||
private final String title;
|
||||
private final int numberPages;
|
||||
private final String IsbnCode;
|
||||
private final String isbnCode;
|
||||
|
||||
public Book(final String isbnCode, final String title, final int numberPages) {
|
||||
this.title = title;
|
||||
this.numberPages = numberPages;
|
||||
IsbnCode = isbnCode;
|
||||
this.isbnCode = isbnCode;
|
||||
}
|
||||
|
||||
public Book(final Document d) {
|
||||
|
|
@ -21,7 +21,7 @@ public class Book {
|
|||
|
||||
@JsonProperty("ISBN")
|
||||
public String getIsbnCode() {
|
||||
return IsbnCode;
|
||||
return isbnCode;
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
|
|
@ -33,6 +33,6 @@ public class Book {
|
|||
}
|
||||
|
||||
public Document toDocument() {
|
||||
return new Document("isbn", IsbnCode).append("title", title).append("page", numberPages);
|
||||
return new Document("isbn", isbnCode).append("title", title).append("page", numberPages);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ plugins {
|
|||
|
||||
apply plugin: 'application'
|
||||
apply from: "${rootDir}/gradle/java.gradle"
|
||||
apply from: "${rootDir}/gradle/jacoco.gradle"
|
||||
|
||||
version = 'demo'
|
||||
description = 'rest-spark'
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ plugins {
|
|||
}
|
||||
|
||||
apply from: "${rootDir}/gradle/java.gradle"
|
||||
apply from: "${rootDir}/gradle/jacoco.gradle"
|
||||
|
||||
version = 'demo'
|
||||
description = 'spring-boot-jdbc-redis'
|
||||
|
|
|
|||
|
|
@ -1,5 +1,9 @@
|
|||
apply plugin: "jacoco"
|
||||
|
||||
jacoco {
|
||||
toolVersion = "0.8.0"
|
||||
}
|
||||
|
||||
jacocoTestReport {
|
||||
dependsOn test
|
||||
reports {
|
||||
|
|
@ -9,11 +13,21 @@ jacocoTestReport {
|
|||
}
|
||||
}
|
||||
|
||||
project.ext.whitelistedBranchClasses = []
|
||||
project.ext.whitelistedInstructionClasses = []
|
||||
if (project.parent.hasProperty("whitelistedBranchClasses")) {
|
||||
project.ext.whitelistedBranchClasses = parent.whitelistedBranchClasses
|
||||
} else {
|
||||
project.ext.whitelistedBranchClasses = []
|
||||
}
|
||||
|
||||
project.ext.minimumBranchCoverage = 0.6
|
||||
project.ext.minimumInstructionCoverage = 0.6
|
||||
if (project.parent.hasProperty("whitelistedInstructionClasses")) {
|
||||
project.ext.whitelistedInstructionClasses = parent.whitelistedInstructionClasses
|
||||
} else {
|
||||
project.ext.whitelistedInstructionClasses = []
|
||||
}
|
||||
|
||||
// defaults can be overridden per project:
|
||||
project.ext.minimumBranchCoverage = 0.9
|
||||
project.ext.minimumInstructionCoverage = 0.9
|
||||
|
||||
afterEvaluate {
|
||||
jacocoTestCoverageVerification {
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ lombok { // optional: values below are the defaults
|
|||
|
||||
apply plugin: "net.ltgt.errorprone"
|
||||
tasks.withType(JavaCompile) {
|
||||
options.compilerArgs += ['-Xep:FutureReturnValueIgnored:OFF']
|
||||
// workaround for: https://github.com/google/error-prone/issues/780
|
||||
options.compilerArgs += ['-Xep:ParameterName:OFF']
|
||||
}
|
||||
|
|
@ -152,6 +153,7 @@ tasks.withType(Test) {
|
|||
|
||||
apply from: "$rootDir/gradle/checkstyle.gradle"
|
||||
apply from: "$rootDir/gradle/codenarc.gradle"
|
||||
apply from: "$rootDir/gradle/jacoco.gradle"
|
||||
|
||||
plugins.withType(BasePlugin) {
|
||||
project.afterEvaluate {
|
||||
|
|
|
|||
Loading…
Reference in New Issue