diff --git a/dd-java-agent-ittests/pom.xml b/dd-java-agent-ittests/pom.xml index 67d890a31e9..c858a7638b8 100644 --- a/dd-java-agent-ittests/pom.xml +++ b/dd-java-agent-ittests/pom.xml @@ -4,7 +4,7 @@ com.datadoghq dd-trace-java - 0.0.7-SNAPSHOT + 0.0.8-SNAPSHOT dd-java-agent-ittests @@ -15,7 +15,7 @@ - 0.0.7-SNAPSHOT + 0.0.8-SNAPSHOT @@ -94,7 +94,7 @@ com.amazonaws aws-java-sdk - 1.11.132 + 1.11.119 test @@ -120,6 +120,22 @@ test + + + + + + + + + + + + + + + + @@ -141,17 +157,56 @@ maven-surefire-plugin 2.19 - - *Test.java - + + + + + *Test.java + - -javaagent:${M2_REPO}/com/datadoghq/dd-java-agent/${project.version}/dd-java-agent-${project.version}.jar + -javaagent:${M2_REPO}/com/datadoghq/dd-java-agent/${project.version}/dd-java-agent-${project.version}.jar -Dorg.jboss.byteman.verbose + + org.apache.maven.plugins + maven-shade-plugin + 2.4.3 + + + package + + shade + + + + + + + + + + + otarules.btm + + + + io.opentracing.contrib.agent.AnnotationsTracingAgent + io.opentracing.contrib.agent.AnnotationsTracingAgent + + true + true + ./${project.artifactId}.jar + + + + + + + diff --git a/dd-java-agent-ittests/src/test/java/com/datadoghq/trace/instrument/AAgentIntegration.java b/dd-java-agent-ittests/src/test/java/com/datadoghq/trace/instrument/AAgentIntegration.java index fde44f62203..42dd61f4f38 100644 --- a/dd-java-agent-ittests/src/test/java/com/datadoghq/trace/instrument/AAgentIntegration.java +++ b/dd-java-agent-ittests/src/test/java/com/datadoghq/trace/instrument/AAgentIntegration.java @@ -2,12 +2,15 @@ import org.junit.Before; -import io.opentracing.mock.MockTracer; +import com.datadoghq.trace.DDTracer; +import com.datadoghq.trace.writer.ListWriter; + import io.opentracing.util.GlobalTracer; public class AAgentIntegration { - protected static MockTracer tracer = new MockTracer(); + protected static ListWriter writer = new ListWriter(); + protected static DDTracer tracer = new DDTracer(writer); @Before public void beforeTest() throws Exception { @@ -16,7 +19,7 @@ public void beforeTest() throws Exception { }catch(Exception e){ //DO NOTHING IF ALREADY REGISTERED } - tracer.reset(); + writer.start(); } } diff --git a/dd-java-agent-ittests/src/test/java/com/datadoghq/trace/instrument/AWSInstrumentationTest.java b/dd-java-agent-ittests/src/test/java/com/datadoghq/trace/instrument/AWSInstrumentationTest.java index 62b747e4b27..3f2a2d2731b 100644 --- a/dd-java-agent-ittests/src/test/java/com/datadoghq/trace/instrument/AWSInstrumentationTest.java +++ b/dd-java-agent-ittests/src/test/java/com/datadoghq/trace/instrument/AWSInstrumentationTest.java @@ -10,21 +10,16 @@ public class AWSInstrumentationTest { - @Test - public void test() { - - // Build AWS client with TracingRequestHandler e.g. - AmazonS3ClientBuilder builder = AmazonS3ClientBuilder.standard(); - builder.withRegion(Regions.US_EAST_1); - builder.build(); - - assertThat(builder.getRequestHandlers()).isNotNull(); - assertThat(builder.getRequestHandlers().size()).isEqualTo(1); - assertThat(builder.getRequestHandlers().get(0).getClass()).isEqualTo(TracingRequestHandler.class); - } - - - public static void main(String[] args) { - new AWSInstrumentationTest().test(); - } + @Test + public void test() { + + // Build AWS client with TracingRequestHandler e.g. + AmazonS3ClientBuilder builder = AmazonS3ClientBuilder.standard(); + builder.withRegion(Regions.US_EAST_1); + builder.build(); + + assertThat(builder.getRequestHandlers()).isNotNull(); + assertThat(builder.getRequestHandlers().size()).isEqualTo(1); + assertThat(builder.getRequestHandlers().get(0).getClass()).isEqualTo(TracingRequestHandler.class); + } } diff --git a/dd-java-agent-ittests/src/test/java/com/datadoghq/trace/instrument/ApacheHTTPClientTest.java b/dd-java-agent-ittests/src/test/java/com/datadoghq/trace/instrument/ApacheHTTPClientTest.java index 4587d8a991d..f402a902be7 100644 --- a/dd-java-agent-ittests/src/test/java/com/datadoghq/trace/instrument/ApacheHTTPClientTest.java +++ b/dd-java-agent-ittests/src/test/java/com/datadoghq/trace/instrument/ApacheHTTPClientTest.java @@ -33,7 +33,7 @@ public void test() throws Exception{ result.append(line); } - assertThat(tracer.finishedSpans().size()).isEqualTo(2); + assertThat(writer.firstTrace().size()).isEqualTo(2); } } diff --git a/dd-java-agent-ittests/src/test/java/com/datadoghq/trace/instrument/CassandraIntegrationTest.java b/dd-java-agent-ittests/src/test/java/com/datadoghq/trace/instrument/CassandraIntegrationTest.java new file mode 100644 index 00000000000..e700720e4cf --- /dev/null +++ b/dd-java-agent-ittests/src/test/java/com/datadoghq/trace/instrument/CassandraIntegrationTest.java @@ -0,0 +1,51 @@ +//package com.datadoghq.trace.instrument; +// +//import com.datastax.driver.core.Cluster; +//import com.datastax.driver.core.Session; +//import org.apache.cassandra.exceptions.ConfigurationException; +//import org.apache.thrift.transport.TTransportException; +//import org.cassandraunit.utils.EmbeddedCassandraServerHelper; +//import org.junit.After; +//import org.junit.Before; +//import org.junit.Test; +// +//import java.io.IOException; +//import java.util.concurrent.ExecutionException; +// +//import static org.assertj.core.api.Assertions.assertThat; +// +///** +// * Created by gpolaert on 6/2/17. +// */ +//public class CassandraIntegrationTest { +// +// +// @Before +// public void start() throws InterruptedException, TTransportException, ConfigurationException, IOException { +// EmbeddedCassandraServerHelper.startEmbeddedCassandra(20000L); +// } +// +// @After +// public void stop() { +// EmbeddedCassandraServerHelper.cleanEmbeddedCassandra(); +// } +// +// +// @Test +// public void testNewSessionSync() throws ClassNotFoundException { +// Cluster cluster = EmbeddedCassandraServerHelper.getCluster(); +// Session session = cluster.newSession(); +// assertThat(session).isInstanceOf(Class.forName("io.opentracing.contrib.cassandra.TracingSession")); +// +// +// } +// +// @Test +// public void testNewSessionAsync() throws ClassNotFoundException, ExecutionException, InterruptedException { +// Cluster cluster = EmbeddedCassandraServerHelper.getCluster(); +// Session session = cluster.connectAsync().get(); +// assertThat(session).isInstanceOf(Class.forName("io.opentracing.contrib.cassandra.TracingSession")); +// +// +// } +//} diff --git a/dd-java-agent-ittests/src/test/java/io/opentracing/contrib/agent/TraceAnnotationsManagerTest.java b/dd-java-agent-ittests/src/test/java/io/opentracing/contrib/agent/TraceAnnotationsManagerTest.java index dd624a6f2fd..7c3bd476939 100644 --- a/dd-java-agent-ittests/src/test/java/io/opentracing/contrib/agent/TraceAnnotationsManagerTest.java +++ b/dd-java-agent-ittests/src/test/java/io/opentracing/contrib/agent/TraceAnnotationsManagerTest.java @@ -19,35 +19,31 @@ public void testAnnotations() { //Test single span in new trace SayTracedHello.sayHello(); - assertThat(tracer.finishedSpans().size()).isEqualTo(1); - assertThat(tracer.finishedSpans().get(0).operationName()).isEqualTo("SAY_HELLO"); - assertThat(tracer.finishedSpans().get(0).tags().get("service-name")).isEqualTo("test"); + assertThat(writer.firstTrace().size()).isEqualTo(1); + assertThat(writer.firstTrace().get(0).getOperationName()).isEqualTo("SAY_HELLO"); + assertThat(writer.firstTrace().get(0).getServiceName()).isEqualTo("test"); - tracer.reset(); + writer.start(); //Test new trace with 2 children spans SayTracedHello.sayHELLOsayHA(); - assertThat(tracer.finishedSpans().size()).isEqualTo(3); - assertThat(tracer.finishedSpans().get(0).operationName()).isEqualTo("SAY_HELLO"); - assertThat(tracer.finishedSpans().get(0).tags().get("service-name")).isEqualTo("test"); + assertThat(writer.firstTrace().size()).isEqualTo(3); + long parentId = writer.firstTrace().get(0).context().getTraceId(); - long traceId = tracer.finishedSpans().get(0).context().traceId(); - long parentId = tracer.finishedSpans().get(0).parentId(); + assertThat(writer.firstTrace().get(0).getOperationName()).isEqualTo("NEW_TRACE"); + assertThat(writer.firstTrace().get(0).getParentId()).isEqualTo(0);//ROOT / no parent + assertThat(writer.firstTrace().get(0).context().getParentId()).isEqualTo(0); + assertThat(writer.firstTrace().get(0).getServiceName()).isEqualTo("test2"); - assertThat(tracer.finishedSpans().get(1).operationName()).isEqualTo("SAY_HA"); - assertThat(tracer.finishedSpans().get(1).parentId()).isEqualTo(parentId); - assertThat(tracer.finishedSpans().get(1).context().traceId()).isEqualTo(traceId); - assertThat(tracer.finishedSpans().get(1).tags().get("span-type")).isEqualTo("DB"); - assertThat(tracer.finishedSpans().get(1).tags().get("service-name")).isEqualTo("test"); + assertThat(writer.firstTrace().get(1).getOperationName()).isEqualTo("SAY_HELLO"); + assertThat(writer.firstTrace().get(1).getServiceName()).isEqualTo("test"); + assertThat(writer.firstTrace().get(1).getParentId()).isEqualTo(parentId); - assertThat(tracer.finishedSpans().get(2).operationName()).isEqualTo("NEW_TRACE"); - assertThat(tracer.finishedSpans().get(2).parentId()).isEqualTo(0);//ROOT / no parent - assertThat(tracer.finishedSpans().get(2).context().traceId()).isEqualTo(traceId); - assertThat(tracer.finishedSpans().get(2).tags().get("service-name")).isEqualTo("test2"); + assertThat(writer.firstTrace().get(2).getOperationName()).isEqualTo("SAY_HA"); + assertThat(writer.firstTrace().get(2).getParentId()).isEqualTo(parentId); + assertThat(writer.firstTrace().get(2).context().getSpanType()).isEqualTo("DB"); - - System.out.println(tracer.finishedSpans()); - tracer.reset(); + writer.start(); } } \ No newline at end of file diff --git a/dd-java-agent/README.md b/dd-java-agent/README.md index a62baf253ba..6583171127b 100644 --- a/dd-java-agent/README.md +++ b/dd-java-agent/README.md @@ -108,9 +108,10 @@ Modern web application frameworks such as Dropwizard or Spring Boot are automati ### Databases | DB | Versions | Comments | | ------------- |:-------------:| ----- | -|Spring JDBC| 4.x | Please check the following [JDBC instrumentation](#jdbc-instrumentation) section | -|Hibernate| 5.x | Please check the following [JDBC instrumentation](#jdbc-instrumentation) section | +| Spring JDBC| 4.x | Please check the following [JDBC instrumentation](#jdbc-instrumentation) section | +| Hibernate| 5.x | Please check the following [JDBC instrumentation](#jdbc-instrumentation) section | | MongoDB | 3.x | Intercepts all the calls from the MongoDB client | +| Cassandra | 3.2.x | Intercepts all the calls from the Cassandra client | #### JDBC instrumentation diff --git a/dd-java-agent/pom.xml b/dd-java-agent/pom.xml index 9e4d41b958b..9ff58014030 100644 --- a/dd-java-agent/pom.xml +++ b/dd-java-agent/pom.xml @@ -4,7 +4,7 @@ com.datadoghq dd-trace-java - 0.0.7-SNAPSHOT + 0.0.8-SNAPSHOT dd-java-agent @@ -16,16 +16,16 @@ - 0.0.7-SNAPSHOT + 0.0.8-SNAPSHOT - 0.22.0 - 0.0.12 - 0.0.8 - 0.0.1 - 0.0.4 - 0.0.1 - 0.0.1 - 0.0.1 + 0.1.0 + 0.0.9 + 0.0.2 + 0.0.5 + 0.0.2 + 0.0.2 + 0.0.2 + 0.0.2 1.7 @@ -124,6 +124,25 @@ + + + io.opentracing.contrib + opentracing-cassandra-driver + ${ot.contrib.cassandra.version} + + + com.datastax.cassandra + cassandra-driver-core + + + + + com.datastax.cassandra + cassandra-driver-core + 3.2.0 + provided + + io.opentracing.contrib diff --git a/dd-java-agent/src/main/java/io/opentracing/contrib/agent/TraceAnnotationsManager.java b/dd-java-agent/src/main/java/io/opentracing/contrib/agent/TraceAnnotationsManager.java index 6ea2231211a..22d1f0afed8 100644 --- a/dd-java-agent/src/main/java/io/opentracing/contrib/agent/TraceAnnotationsManager.java +++ b/dd-java-agent/src/main/java/io/opentracing/contrib/agent/TraceAnnotationsManager.java @@ -180,18 +180,8 @@ public static void loadAnnotationsRules(String... scannedPackages) { CURRENT_SPAN_EXISTS+ buildSpan(javassistMethod)+ buildWithTags(javassistMethod)+ - CHILD_OF_CURRENT_SPAN+ START; - RuleScript script = createRuleScript("Child of ",cc, javassistMethod, Location.create(LocationType.ENTRY,""),ruleText); - generatedScripts.append(script).append("\n"); - - //AT ENTRY: new trace - ruleText = - CURRENT_SPAN_NOT_EXISTS+ - buildSpan(javassistMethod)+ - buildWithTags(javassistMethod)+ - START; - script = createRuleScript("New trace ",cc, javassistMethod, Location.create(LocationType.ENTRY,""),ruleText); + RuleScript script = createRuleScript("Start Active Span ",cc, javassistMethod, Location.create(LocationType.ENTRY,""),ruleText); generatedScripts.append(script).append("\n"); //AT EXIT @@ -227,7 +217,7 @@ private static RuleScript createRuleScript( RuleScript ruleScript = new RuleScript( ruleNamePrefix+loc+" "+javassistMethod.getLongName(), - "^"+cc.getName(), + cc.getName(), false, false, javassistMethod.getName() + Descriptor.toString(javassistMethod.getSignature()), @@ -259,19 +249,16 @@ private static void loadRules(URI uri, final List scriptNames, scriptNames.add(uri.toString()); } - private static String CURRENT_SPAN_EXISTS = "IF currentSpan() != null\n"; - private static String CURRENT_SPAN_NOT_EXISTS = "IF currentSpan() == null\n"; + private static String CURRENT_SPAN_EXISTS = "IF TRUE\n"; - private static String BUILD_SPAN = "DO\n"+"activateSpan(getTracer().buildSpan(\""; + private static String BUILD_SPAN = "DO\n"+"getTracer().buildSpan(\""; private static String CLOSE_PARENTHESIS = "\")"; - private static String CHILD_OF_CURRENT_SPAN = ".asChildOf(currentSpan())"; - private static String START = ".start());"; + private static String START = ".startActive();"; - private static String EXIT_RULE = "IF currentSpan() != null\n"+ + private static String EXIT_RULE = "IF getTracer().activeSpan() != null\n"+ "DO\n"+ - "currentSpan().finish();\n"+ - "deactivateCurrentSpan();"; + "getTracer().activeSpan().deactivate();\n"; private static String buildSpan(CtMethod javassistMethod){ try { diff --git a/dd-java-agent/src/main/java/io/opentracing/contrib/agent/helper/CassandraHelper.java b/dd-java-agent/src/main/java/io/opentracing/contrib/agent/helper/CassandraHelper.java new file mode 100644 index 00000000000..3c847bbfb1c --- /dev/null +++ b/dd-java-agent/src/main/java/io/opentracing/contrib/agent/helper/CassandraHelper.java @@ -0,0 +1,49 @@ +package io.opentracing.contrib.agent.helper; + +import com.datastax.driver.core.Session; +import io.opentracing.Tracer; +import io.opentracing.contrib.agent.OpenTracingHelper; +import org.jboss.byteman.rule.Rule; + +import java.lang.reflect.Constructor; + + +public class CassandraHelper extends OpenTracingHelper { + + private static final String LOG_PREFIX = "OTARULES - Cassandra contrib - "; + + protected CassandraHelper(Rule rule) { + super(rule); + } + + /** + * @param session The session to be patched + */ + public Session patch(Session session) { + + + debug(LOG_PREFIX + "Try to patch the session"); + + try { + + Tracer tracer = getTracer(); + Class clazz = Class.forName("io.opentracing.contrib.cassandra.TracingSession"); + Constructor constructor = clazz.getDeclaredConstructor(Session.class, Tracer.class); + constructor.setAccessible(true); + Object newSession = constructor.newInstance(session, tracer); + debug(LOG_PREFIX + "Session patched"); + return (Session) newSession; + + } catch (Exception e) { + err(LOG_PREFIX + "Session not patched, " + e.getMessage()); + errTraceException(e); + } + + return session; + + + + } + + +} \ No newline at end of file diff --git a/dd-java-agent/src/main/resources/dd-trace-authorized-versions.yaml b/dd-java-agent/src/main/resources/dd-trace-authorized-versions.yaml index 48f0981e79e..74b3194bbe7 100644 --- a/dd-java-agent/src/main/resources/dd-trace-authorized-versions.yaml +++ b/dd-java-agent/src/main/resources/dd-trace-authorized-versions.yaml @@ -31,5 +31,8 @@ mongo-java-driver: opentracing-api: key: opentracing-api valid_versions: 0\.2.* +cassandra-driver-core: + key: cassandra + valid_versions: 3\.2.* \ No newline at end of file diff --git a/dd-java-agent/src/main/resources/otarules.btm b/dd-java-agent/src/main/resources/otarules.btm index cdbf08a64b4..779a66c3c6b 100644 --- a/dd-java-agent/src/main/resources/otarules.btm +++ b/dd-java-agent/src/main/resources/otarules.btm @@ -6,7 +6,7 @@ METHOD build() HELPER io.opentracing.contrib.agent.OpenTracingHelper BIND listener:io.opentracing.contrib.mongo.TracingCommandListener = - new io.opentracing.contrib.mongo.TracingCommandListener(); + new io.opentracing.contrib.mongo.TracingCommandListener(getTracer()); AT ENTRY IF TRUE DO @@ -18,8 +18,9 @@ ENDRULE RULE AWS SDK Client instrumentation 1 CLASS ^com.amazonaws.client.builder.AwsClientBuilder METHOD build() +HELPER io.opentracing.contrib.agent.OpenTracingHelper BIND - requestTracerHandler:io.opentracing.contrib.aws.TracingRequestHandler = new io.opentracing.contrib.aws.TracingRequestHandler(); + requestTracerHandler:io.opentracing.contrib.aws.TracingRequestHandler = new io.opentracing.contrib.aws.TracingRequestHandler(getTracer()); requests:java.util.List = new java.util.ArrayList(); AT ENTRY IF $this.requestHandlers == null @@ -31,8 +32,9 @@ ENDRULE RULE AWS SDK Client instrumentation 2 CLASS ^com.amazonaws.client.builder.AwsClientBuilder METHOD build() +HELPER io.opentracing.contrib.agent.OpenTracingHelper BIND - requestTracerHandler:io.opentracing.contrib.aws.TracingRequestHandler = new io.opentracing.contrib.aws.TracingRequestHandler(); + requestTracerHandler:io.opentracing.contrib.aws.TracingRequestHandler = new io.opentracing.contrib.aws.TracingRequestHandler(getTracer()); AT ENTRY IF $this.requestHandlers != null AND $this.requestHandlers.get(0).getClass().getCanonicalName() != "io.opentracing.contrib.aws.TracingRequestHandler" DO @@ -55,3 +57,17 @@ IF TRUE DO return tracingClientExec; ENDRULE + + +# -------------------------------------------------------- +# Cassandra +RULE Cassandra +CLASS com.datastax.driver.core.Cluster$Manager +METHOD newSession() +HELPER io.opentracing.contrib.agent.helper.CassandraHelper +#BIND +AT EXIT +IF TRUE +DO + $! = patch($!); +ENDRULE diff --git a/dd-trace-annotations/pom.xml b/dd-trace-annotations/pom.xml index 42e2409247e..ba1d19d583a 100644 --- a/dd-trace-annotations/pom.xml +++ b/dd-trace-annotations/pom.xml @@ -4,11 +4,11 @@ com.datadoghq dd-trace-java - 0.0.7-SNAPSHOT + 0.0.8-SNAPSHOT com.datadoghq dd-trace-annotations - 0.0.7-SNAPSHOT + 0.0.8-SNAPSHOT dd-trace-annotations http://maven.apache.org diff --git a/dd-trace-examples/async-tracing/pom.xml b/dd-trace-examples/async-tracing/pom.xml index a065708efe9..2e5994de4e7 100644 --- a/dd-trace-examples/async-tracing/pom.xml +++ b/dd-trace-examples/async-tracing/pom.xml @@ -4,7 +4,7 @@ com.datadoghq dd-trace-examples - 0.0.7-SNAPSHOT + 0.0.8-SNAPSHOT async-tracing @@ -12,7 +12,7 @@ - 0.0.7-SNAPSHOT + 0.0.8-SNAPSHOT 0.0.5 diff --git a/dd-trace-examples/async-tracing/src/main/java/com/datadoghq/asyncpatterns/examples/ExampleRunnable.java b/dd-trace-examples/async-tracing/src/main/java/com/datadoghq/asyncpatterns/examples/ExampleRunnable.java deleted file mode 100644 index 95f7e39d2eb..00000000000 --- a/dd-trace-examples/async-tracing/src/main/java/com/datadoghq/asyncpatterns/examples/ExampleRunnable.java +++ /dev/null @@ -1,75 +0,0 @@ -package com.datadoghq.asyncpatterns.examples; - -import io.opentracing.NoopSpan; -import io.opentracing.Span; -import io.opentracing.Tracer; -import io.opentracing.contrib.spanmanager.DefaultSpanManager; -import io.opentracing.contrib.spanmanager.SpanManager; -import io.opentracing.contrib.spanmanager.SpanManager.ManagedSpan; -import io.opentracing.contrib.tracerresolver.TracerResolver; - -class ExampleRunnable implements Runnable { - private final SpanManager spanManager; - private final Span currentSpanFromCaller; - public static final Tracer tracer = TracerResolver.resolveTracer(); - - ExampleRunnable(SpanManager spanManager) { - this(spanManager, NoopSpan.INSTANCE); - } - - private ExampleRunnable(SpanManager spanManager, Span currentSpanFromCaller) { - this.spanManager = spanManager; - this.currentSpanFromCaller = currentSpanFromCaller; - } - - ExampleRunnable withCurrentSpan() { - return new ExampleRunnable(spanManager, spanManager.current().getSpan()); - } - - @Override - public void run() { - try (ManagedSpan parent = spanManager.activate(currentSpanFromCaller)) { - - myMethod(); - - // Any background code that requires tracing - // and may use spanManager.current().getSpan() - - } catch(Exception e){ - e.printStackTrace(); - } - } - - public void myMethod(){ - - try (Span appSpan = tracer.buildSpan("myMethod").asChildOf(spanManager.current().getSpan()).start(); // start appSpan - ManagedSpan managed = spanManager.activate(appSpan)) { - - Thread.sleep(100); - - } catch(Exception e){ - e.printStackTrace(); - } - - } - - - public static void main(String[] args) throws Throwable{ - - SpanManager spanManager = DefaultSpanManager.getInstance(); - ExampleRunnable runnable = new ExampleRunnable(spanManager); - - try (Span appSpan = tracer.buildSpan("main").start(); // start appSpan - ManagedSpan managed = spanManager.activate(appSpan)) { // update current Span - - Thread.sleep(100); - - Thread example = new Thread(runnable.withCurrentSpan()); - example.start(); - example.join(); - - } // managed.deactivate() + appSpan.finish() - - - } -} \ No newline at end of file diff --git a/dd-trace-examples/async-tracing/src/main/java/com/datadoghq/asyncpatterns/examples/ExampleThreadpool.java b/dd-trace-examples/async-tracing/src/main/java/com/datadoghq/asyncpatterns/examples/ExampleThreadpool.java deleted file mode 100644 index 4993904e97e..00000000000 --- a/dd-trace-examples/async-tracing/src/main/java/com/datadoghq/asyncpatterns/examples/ExampleThreadpool.java +++ /dev/null @@ -1,51 +0,0 @@ -package com.datadoghq.asyncpatterns.examples; - -import java.util.concurrent.Callable; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.Future; - -import io.opentracing.Span; -import io.opentracing.Tracer; -import io.opentracing.contrib.spanmanager.DefaultSpanManager; -import io.opentracing.contrib.spanmanager.SpanManager; -import io.opentracing.contrib.spanmanager.SpanManager.ManagedSpan; -import io.opentracing.contrib.spanmanager.concurrent.SpanPropagatingExecutorService; -import io.opentracing.contrib.tracerresolver.TracerResolver; - -public class ExampleThreadpool { - - public static final Tracer tracer = TracerResolver.resolveTracer(); - - public static class TracedCall implements Callable { - SpanManager spanManager = DefaultSpanManager.getInstance(); - - @Override - public String call() { - try(Span appSpan = tracer.buildSpan(Thread.currentThread().getName()).asChildOf(spanManager.current().getSpan()).start(); - ManagedSpan managed = spanManager.activate(appSpan)){ - Thread.sleep(100); - }catch(Exception e){ - e.printStackTrace(); - } - return Thread.currentThread().getName(); - } - } - - public static void main(String[] args) throws Throwable{ - SpanManager spanManager = DefaultSpanManager.getInstance(); - ExecutorService threadpool = new SpanPropagatingExecutorService(Executors.newFixedThreadPool(2), spanManager); - - - try (Span appSpan = tracer.buildSpan("main").start(); - ManagedSpan current = spanManager.activate(appSpan)) { - - // scheduling the traced call: - Future result = threadpool.submit(new TracedCall()); - Future result2 = threadpool.submit(new TracedCall()); - - result.get(); - result2.get(); - } - } -} diff --git a/dd-trace-examples/dropwizard-mongo-client/pom.xml b/dd-trace-examples/dropwizard-mongo-client/pom.xml index f1d54137166..cdfb644c2d5 100644 --- a/dd-trace-examples/dropwizard-mongo-client/pom.xml +++ b/dd-trace-examples/dropwizard-mongo-client/pom.xml @@ -5,7 +5,7 @@ com.datadoghq dd-trace-examples - 0.0.7-SNAPSHOT + 0.0.8-SNAPSHOT dropwizard-mongo-client @@ -14,7 +14,7 @@ - 0.0.7-SNAPSHOT + 0.0.8-SNAPSHOT diff --git a/dd-trace-examples/dropwizard-mongo-client/src/main/java/com/example/helloworld/client/TracedClient.java b/dd-trace-examples/dropwizard-mongo-client/src/main/java/com/example/helloworld/client/TracedClient.java index ee9ce1a821d..0f55fb70f00 100644 --- a/dd-trace-examples/dropwizard-mongo-client/src/main/java/com/example/helloworld/client/TracedClient.java +++ b/dd-trace-examples/dropwizard-mongo-client/src/main/java/com/example/helloworld/client/TracedClient.java @@ -2,6 +2,7 @@ import java.io.IOException; +import io.opentracing.contrib.agent.Trace; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.Response; @@ -14,7 +15,14 @@ */ public class TracedClient { + public static void main(String[] args) throws Exception{ + executeCall(); + System.out.println("After execute"); + } + + @Trace(tagsKV={"service-name","TracedClient"}) + private static void executeCall() throws IOException { OkHttpClient client = new OkHttpClient().newBuilder().build(); Request request = new Request.Builder() diff --git a/dd-trace-examples/dropwizard-mongo-client/src/main/resources/dd-trace.yaml b/dd-trace-examples/dropwizard-mongo-client/src/main/resources/dd-trace.yaml index 90050545f6a..bc6406af2f0 100644 --- a/dd-trace-examples/dropwizard-mongo-client/src/main/resources/dd-trace.yaml +++ b/dd-trace-examples/dropwizard-mongo-client/src/main/resources/dd-trace.yaml @@ -22,8 +22,8 @@ sampler: # Skip some traces if the root span tag values matches some regexp patterns # skipTagsPatterns: {"http.url": ".*/demo/add.*"} -# Enable custom tracing (Custom annotations for now) -enableCustomTracing: true +# Enable custom annotation tracing over a selected set of packages +enableCustomAnnotationTracingOver: ["com.example"] # Disable some instrumentations # disabledInstrumentations: ["apache http", "mongo", "jetty", "tomcat", ...] \ No newline at end of file diff --git a/dd-trace-examples/pom.xml b/dd-trace-examples/pom.xml index 570758bbb38..b8843b79a23 100644 --- a/dd-trace-examples/pom.xml +++ b/dd-trace-examples/pom.xml @@ -3,7 +3,7 @@ dd-trace-java com.datadoghq - 0.0.7-SNAPSHOT + 0.0.8-SNAPSHOT 4.0.0 diff --git a/dd-trace-examples/spring-boot-jdbc/pom.xml b/dd-trace-examples/spring-boot-jdbc/pom.xml index 26e9a7a91d2..d4f22d4cbf7 100644 --- a/dd-trace-examples/spring-boot-jdbc/pom.xml +++ b/dd-trace-examples/spring-boot-jdbc/pom.xml @@ -5,7 +5,7 @@ com.datadoghq dd-trace-examples - 0.0.7-SNAPSHOT + 0.0.8-SNAPSHOT spring-boot-jdbc diff --git a/dd-trace/pom.xml b/dd-trace/pom.xml index ab09e23dc2f..10ee92f06ab 100644 --- a/dd-trace/pom.xml +++ b/dd-trace/pom.xml @@ -5,7 +5,7 @@ com.datadoghq dd-trace-java - 0.0.7-SNAPSHOT + 0.0.8-SNAPSHOT dd-trace diff --git a/dd-trace/src/main/java/com/datadoghq/trace/DDActiveSpan.java b/dd-trace/src/main/java/com/datadoghq/trace/DDActiveSpan.java new file mode 100644 index 00000000000..a3d672b3117 --- /dev/null +++ b/dd-trace/src/main/java/com/datadoghq/trace/DDActiveSpan.java @@ -0,0 +1,80 @@ +package com.datadoghq.trace; + +import com.fasterxml.jackson.annotation.JsonIgnore; + +import io.opentracing.ActiveSpan; + +/** + * Base implementation for opentracing {@link ActiveSpan} + */ +public class DDActiveSpan extends DDBaseSpan implements ActiveSpan{ + + protected final DDActiveSpan parent; + protected boolean deactivated = false; + + protected DDActiveSpan(DDActiveSpan parent,DDSpan span) { + super(span.startTimeMicro, span.context()); + this.startTimeNano = span.startTimeNano; + this.durationNano = span.durationNano; + this.parent = parent; + } + + protected DDActiveSpan(DDActiveSpan parent,long timestampMicro, DDSpanContext context) { + super(timestampMicro, context); + this.parent = parent; + } + + /** + * @return the generating parent if not null + */ + @JsonIgnore + public DDActiveSpan getParent() { + return parent; + } + + /** + * @return true if the span has already been deactivated + */ + @JsonIgnore + public boolean isDeactivated() { + return deactivated; + } + + @Override + public void deactivate() { + DDTracer tracer = context().getTracer(); + if(tracer!=null){ + tracer.deactivate(this); + } + finish(); + deactivated = true; + } + + @Override + public Continuation capture() { + return new DDContinuation(); + } + + @Override + protected ActiveSpan thisInstance() { + return this; + } + + public class DDContinuation implements Continuation{ + + @Override + public ActiveSpan activate() { + //Reactivate the current span + context().getTracer().makeActive(DDActiveSpan.this); + + //And return the encapsulating ActiveSpan + return DDActiveSpan.this; + } + + } + + @Override + public void close() { + deactivate(); + } +} diff --git a/dd-trace/src/main/java/com/datadoghq/trace/DDBaseSpan.java b/dd-trace/src/main/java/com/datadoghq/trace/DDBaseSpan.java new file mode 100644 index 00000000000..9feaa6a3660 --- /dev/null +++ b/dd-trace/src/main/java/com/datadoghq/trace/DDBaseSpan.java @@ -0,0 +1,325 @@ +package com.datadoghq.trace; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.concurrent.TimeUnit; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.fasterxml.jackson.annotation.JsonGetter; +import com.fasterxml.jackson.annotation.JsonIgnore; + +import io.opentracing.BaseSpan; + +@SuppressWarnings("rawtypes") +public abstract class DDBaseSpan implements BaseSpan { + + /** + * StartTime stores the creation time of the span in milliseconds + */ + protected long startTimeMicro; + /** + * StartTimeNano stores the only the nanoseconds for more accuracy + */ + protected long startTimeNano; + /** + * The duration in nanoseconds computed using the startTimeMicro and startTimeNano + */ + protected long durationNano; + /** + * The context attached to the span + */ + protected final DDSpanContext context; + + private final static Logger logger = LoggerFactory.getLogger(DDBaseSpan.class); + + /** + * A simple constructor. + * Currently, users have + * + * @param timestampMicro if set, use this time instead of the auto-generated time + * @param context the context + */ + protected DDBaseSpan( + long timestampMicro, + DDSpanContext context) { + + this.context = context; + + // record the start time in nano (current milli + nano delta) + if (timestampMicro == 0L) { + this.startTimeMicro = TimeUnit.MILLISECONDS.toMicros(System.currentTimeMillis()); + } else { + this.startTimeMicro = timestampMicro; + } + this.startTimeNano = System.nanoTime(); + + // track each span of the trace + this.context.getTrace().add(this); + + } + + public final void finish() { + this.durationNano = System.nanoTime() - startTimeNano; + afterFinish(); + } + + public final void finish(long stoptimeMicros) { + this.durationNano = TimeUnit.MICROSECONDS.toNanos(stoptimeMicros - this.startTimeMicro); + afterFinish(); + } + + /** + * Close the span. If the current span is the parent, check if each child has also been closed + * If not, warned it + */ + protected final void afterFinish() { + logger.debug("{} - Closing the span.", this); + + // warn if one of the parent's children is not finished + if (this.isRootSpan()) { + List> spans = this.context().getTrace(); + + for (DDBaseSpan span : spans) { + if (((DDBaseSpan) span).getDurationNano() == 0L) { + logger.warn("{} - The parent span is marked as finished but this span isn't. You have to close each children.", this); + } + } + this.context.getTracer().write(this.context.getTrace()); + logger.debug("{} - Write the trace", this); + } + } + + /** + * Check if the span is the root parent. It means that the traceId is the same as the spanId + * + * @return true if root, false otherwise + */ + protected final boolean isRootSpan() { + + if (context().getTrace().isEmpty()) { + return false; + } + // First item of the array AND tracer set + DDBaseSpan first = context().getTrace().get(0); + return first.context().getSpanId() == this.context().getSpanId() && this.context.getTracer() != null; + } + + + /* (non-Javadoc) + * @see io.opentracing.BaseSpan#setTag(java.lang.String, java.lang.String) + */ + @Override + public final S setTag(String tag, String value) { + this.context().setTag(tag, (Object) value); + return thisInstance(); + } + + + /* (non-Javadoc) + * @see io.opentracing.BaseSpan#setTag(java.lang.String, boolean) + */ + @Override + public final S setTag(String tag, boolean value) { + this.context().setTag(tag, (Object) value); + return thisInstance(); + } + + + /* (non-Javadoc) + * @see io.opentracing.BaseSpan#setTag(java.lang.String, java.lang.Number) + */ + @Override + public final S setTag(String tag, Number value) { + this.context().setTag(tag, (Object) value); + return thisInstance(); + } + + + /* (non-Javadoc) + * @see io.opentracing.BaseSpan#context() + */ + @Override + public final DDSpanContext context() { + return this.context; + } + + /* (non-Javadoc) + * @see io.opentracing.BaseSpan#getBaggageItem(java.lang.String) + */ + @Override + public final String getBaggageItem(String key) { + return this.context.getBaggageItem(key); + } + + /* (non-Javadoc) + * @see io.opentracing.BaseSpan#setBaggageItem(java.lang.String, java.lang.String) + */ + @Override + public final S setBaggageItem(String key, String value) { + this.context.setBaggageItem(key, value); + return thisInstance(); + } + + /* (non-Javadoc) + * @see io.opentracing.BaseSpan#setOperationName(java.lang.String) + */ + @Override + public final S setOperationName(String operationName) { + this.context().setOperationName(operationName); + return thisInstance(); + } + + /* (non-Javadoc) + * @see io.opentracing.BaseSpan#log(java.util.Map) + */ + @Override + public final S log(Map map) { + logger.debug("`log` method is not implemented. Doing nothing"); + return thisInstance(); + } + + /* (non-Javadoc) + * @see io.opentracing.BaseSpan#log(long, java.util.Map) + */ + @Override + public final S log(long l, Map map) { + logger.debug("`log` method is not implemented. Doing nothing"); + return thisInstance(); + } + + /* (non-Javadoc) + * @see io.opentracing.BaseSpan#log(java.lang.String) + */ + @Override + public final S log(String s) { + logger.debug("`log` method is not implemented. Provided log: {}",s); + return thisInstance(); + } + + /* (non-Javadoc) + * @see io.opentracing.BaseSpan#log(long, java.lang.String) + */ + @Override + public final S log(long l, String s) { + logger.debug("`log` method is not implemented. Provided log: {}",s); + return thisInstance(); + } + + + /* (non-Javadoc) + * @see io.opentracing.BaseSpan#log(java.lang.String, java.lang.Object) + */ + @Override + public final S log(String s, Object o) { + logger.debug("`log` method is not implemented. Provided log: {}",s); + return thisInstance(); + } + + /* (non-Javadoc) + * @see io.opentracing.BaseSpan#log(long, java.lang.String, java.lang.Object) + */ + @Override + public final S log(long l, String s, Object o) { + logger.debug("`log` method is not implemented. Provided log: {}",s); + return thisInstance(); + } + + public final S setServiceName(String serviceName) { + this.context().setServiceName(serviceName); + return thisInstance(); + } + + public final S setResourceName(String resourceName) { + this.context().setResourceName(resourceName); + return thisInstance(); + } + + public final S setSpanType(String type) { + this.context().setSpanType(type); + return thisInstance(); + } + + protected abstract S thisInstance(); + + //Getters and JSON serialisation instructions + + /** + * Meta merges baggage and tags (stringified values) + * + * @return merged context baggage and tags + */ + @JsonGetter + public Map getMeta() { + Map meta = new HashMap(); + for (Entry entry : context().getBaggageItems().entrySet()) { + meta.put(entry.getKey(), entry.getValue()); + } + for (Entry entry : getTags().entrySet()) { + meta.put(entry.getKey(), String.valueOf(entry.getValue())); + } + return meta; + } + + @JsonGetter("start") + public long getStartTime() { + return startTimeMicro * 1000L; + } + + @JsonGetter("duration") + public long getDurationNano() { + return durationNano; + } + + @JsonGetter("service") + public String getServiceName() { + return context.getServiceName(); + } + + @JsonGetter("trace_id") + public long getTraceId() { + return context.getTraceId(); + } + + @JsonGetter("span_id") + public long getSpanId() { + return context.getSpanId(); + } + + @JsonGetter("parent_id") + public long getParentId() { + return context.getParentId(); + } + + @JsonGetter("resource") + public String getResourceName() { + return context.getResourceName(); + } + + @JsonGetter("name") + public String getOperationName() { + return context.getOperationName(); + } + + @JsonIgnore + public Map getTags() { + return this.context().getTags(); + } + @JsonGetter + public String getType() { + return context.getSpanType(); + } + + @JsonGetter + public int getError() { + return context.getErrorFlag() ? 1 : 0; + } + + @Override + public String toString() { + return context.toString(); + } +} diff --git a/dd-trace/src/main/java/com/datadoghq/trace/DDSpan.java b/dd-trace/src/main/java/com/datadoghq/trace/DDSpan.java index 9e1b87610bc..0845e105f40 100644 --- a/dd-trace/src/main/java/com/datadoghq/trace/DDSpan.java +++ b/dd-trace/src/main/java/com/datadoghq/trace/DDSpan.java @@ -1,16 +1,6 @@ package com.datadoghq.trace; -import com.fasterxml.jackson.annotation.JsonGetter; -import com.fasterxml.jackson.annotation.JsonIgnore; import io.opentracing.Span; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.concurrent.TimeUnit; /** * Represents an in-flight span in the opentracing system. @@ -18,27 +8,7 @@ *

Spans are created by the {@link DDTracer#buildSpan}. * This implementation adds some features according to the DD agent. */ -public class DDSpan implements io.opentracing.Span { - - - /** - * StartTime stores the creation time of the span in milliseconds - */ - private long startTimeMicro; - /** - * StartTimeNano stores the only the nanoseconds for more accuracy - */ - private long startTimeNano; - /** - * The duration in nanoseconds computed using the startTimeMicro and startTimeNano - */ - private long durationNano; - /** - * The context attached to the span - */ - private final DDSpanContext context; - - private final static Logger logger = LoggerFactory.getLogger(DDSpan.class); +public class DDSpan extends DDBaseSpan implements Span { /** * A simple constructor. @@ -50,276 +20,12 @@ public class DDSpan implements io.opentracing.Span { protected DDSpan( long timestampMicro, DDSpanContext context) { - - this.context = context; - - // record the start time in nano (current milli + nano delta) - if (timestampMicro == 0L) { - this.startTimeMicro = TimeUnit.MILLISECONDS.toMicros(System.currentTimeMillis()); - } else { - this.startTimeMicro = timestampMicro; - } - this.startTimeNano = System.nanoTime(); - - // track each span of the trace - this.context.getTrace().add(this); - - } - - /* (non-Javadoc) - * @see io.opentracing.Span#finish() - */ - public void finish() { - this.durationNano = System.nanoTime() - startTimeNano; - afterFinish(); - } - - /* (non-Javadoc) - * @see io.opentracing.Span#finish(long) - */ - public void finish(long stoptimeMicros) { - this.durationNano = TimeUnit.MICROSECONDS.toNanos(stoptimeMicros - this.startTimeMicro); - afterFinish(); - } - - /** - * Close the span. If the current span is the parent, check if each child has also been closed - * If not, warned it - */ - protected void afterFinish() { - logger.debug("{} - Closing the span.", this); - - // warn if one of the parent's children is not finished - if (this.isRootSpan()) { - List spans = this.context.getTrace(); - - for (Span span : spans) { - if (((DDSpan) span).getDurationNano() == 0L) { - logger.warn("{} - The parent span is marked as finished but this span isn't. You have to close each children.", this); - } - } - this.context.getTracer().write(this.context.getTrace()); - logger.debug("{} - Write the trace", this); - } - } - - /* (non-Javadoc) - * @see io.opentracing.Span#close() - */ - public void close() { - this.finish(); - } - - /** - * Check if the span is the root parent. It means that the traceId is the same as the spanId - * - * @return true if root, false otherwise - */ - private boolean isRootSpan() { - - if (context().getTrace().isEmpty()) { - return false; - } - // First item of the array AND tracer set - DDSpan first = (DDSpan) context().getTrace().get(0); - return first.context.getSpanId() == this.context.getSpanId() && this.context.getTracer() != null; - } - - /* (non-Javadoc) - * @see io.opentracing.Span#setTag(java.lang.String, java.lang.String) - */ - public Span setTag(String tag, String value) { - this.context().setTag(tag, (Object) value); - return this; - } - - /* (non-Javadoc) - * @see io.opentracing.Span#setTag(java.lang.String, boolean) - */ - public Span setTag(String tag, boolean value) { - this.context().setTag(tag, (Object) value); - return this; - } - - /* (non-Javadoc) - * @see io.opentracing.Span#setTag(java.lang.String, java.lang.Number) - */ - public Span setTag(String tag, Number value) { - this.context().setTag(tag, (Object) value); - return this; - } - - - /* (non-Javadoc) - * @see io.opentracing.Span#context() - */ - public DDSpanContext context() { - return this.context; - } - - /* (non-Javadoc) - * @see io.opentracing.Span#setBaggageItem(java.lang.String, java.lang.String) - */ - public Span setBaggageItem(String key, String value) { - this.context.setBaggageItem(key, value); - return this; - } - - /* (non-Javadoc) - * @see io.opentracing.Span#getBaggageItem(java.lang.String) - */ - public String getBaggageItem(String key) { - return this.context.getBaggageItem(key); + super(timestampMicro,context); } - /* (non-Javadoc) - * @see io.opentracing.Span#setOperationName(java.lang.String) - */ - public Span setOperationName(String operationName) { - this.context().setOperationName(operationName); - return this; - } - - /* (non-Javadoc) - * @see io.opentracing.Span#log(java.lang.String, java.lang.Object) - */ - public Span log(Map map) { - logger.debug("`log` method is not implemented. Doing nothing"); - return this; - } - - /* (non-Javadoc) - * @see io.opentracing.Span#log(java.lang.String, java.lang.Object) - */ - public Span log(long l, Map map) { - logger.debug("`log` method is not implemented. Doing nothing"); - return this; - } - - /* (non-Javadoc) - * @see io.opentracing.Span#log(java.lang.String, java.lang.Object) - */ - public Span log(String s) { - logger.debug("`log` method is not implemented. Provided log: {}",s); - return this; - } - - /* (non-Javadoc) - * @see io.opentracing.Span#log(java.lang.String, java.lang.Object) - */ - public Span log(long l, String s) { - logger.debug("`log` method is not implemented. Provided log: {}",s); - return this; - } - - /* (non-Javadoc) - * @see io.opentracing.Span#log(java.lang.String, java.lang.Object) - */ - public Span log(String s, Object o) { - logger.debug("`log` method is not implemented. Provided log: {}",s); - return this; - } - - /* (non-Javadoc) - * @see io.opentracing.Span#log(long, java.lang.String, java.lang.Object) - */ - public Span log(long l, String s, Object o) { - logger.debug("`log` method is not implemented. Provided log: {}",s); - return this; - } - - - //Getters and JSON serialisation instructions - - /** - * Meta merges baggage and tags (stringified values) - * - * @return merged context baggage and tags - */ - @JsonGetter - public Map getMeta() { - Map meta = new HashMap(); - for (Entry entry : context().getBaggageItems().entrySet()) { - meta.put(entry.getKey(), entry.getValue()); - } - for (Entry entry : getTags().entrySet()) { - meta.put(entry.getKey(), String.valueOf(entry.getValue())); - } - return meta; - } - - @JsonGetter("start") - public long getStartTime() { - return startTimeMicro * 1000L; - } - - @JsonGetter("duration") - public long getDurationNano() { - return durationNano; - } - - @JsonGetter("service") - public String getServiceName() { - return context.getServiceName(); - } - - @JsonGetter("trace_id") - public long getTraceId() { - return context.getTraceId(); - } - - @JsonGetter("span_id") - public long getSpanId() { - return context.getSpanId(); - } - - @JsonGetter("parent_id") - public long getParentId() { - return context.getParentId(); - } - - @JsonGetter("resource") - public String getResourceName() { - return context.getResourceName(); - } - - @JsonGetter("name") - public String getOperationName() { - return context.getOperationName(); - } - - @JsonIgnore - public Map getTags() { - return this.context().getTags(); - } - @JsonGetter - public String getType() { - return context.getSpanType(); - } - - @JsonGetter - public int getError() { - return context.getErrorFlag() ? 1 : 0; - } - - @Override - public String toString() { - return context.toString(); - } - - - public Span setServiceName(String serviceName) { - this.context().setServiceName(serviceName); - return this; - } - public Span setResourceName(String resourceName) { - this.context().setResourceName(resourceName); - return this; - } - - public Span setSpanType(String type) { - this.context().setSpanType(type); - return this; - } + @Override + protected DDSpan thisInstance() { + return this; + } } diff --git a/dd-trace/src/main/java/com/datadoghq/trace/DDSpanContext.java b/dd-trace/src/main/java/com/datadoghq/trace/DDSpanContext.java index 8c1dc7b5f57..645021744b4 100644 --- a/dd-trace/src/main/java/com/datadoghq/trace/DDSpanContext.java +++ b/dd-trace/src/main/java/com/datadoghq/trace/DDSpanContext.java @@ -1,12 +1,16 @@ package com.datadoghq.trace; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + import com.datadoghq.trace.integration.DDSpanContextDecorator; import com.fasterxml.jackson.annotation.JsonIgnore; -import io.opentracing.Span; -import io.opentracing.tag.Tags; -import java.util.*; +import io.opentracing.tag.Tags; /** * SpanContext represents Span state that must propagate to descendant Spans and across process boundaries. @@ -44,7 +48,7 @@ public class DDSpanContext implements io.opentracing.SpanContext { /** * The collection of all span related to this one */ - private final List trace; + private final List> trace; /** * Each span have an operation name describing the current span */ @@ -70,7 +74,7 @@ public DDSpanContext( boolean errorFlag, String spanType, Map tags, - List trace, + List> trace, DDTracer tracer) { this.traceId = traceId; @@ -93,7 +97,7 @@ public DDSpanContext( this.tags = tags; if (trace == null) { - this.trace = new ArrayList(); + this.trace = new ArrayList>(); } else { this.trace = trace; } @@ -156,7 +160,7 @@ public Iterable> baggageItems() { } @JsonIgnore - public List getTrace() { + public List> getTrace() { return this.trace; } diff --git a/dd-trace/src/main/java/com/datadoghq/trace/DDTracer.java b/dd-trace/src/main/java/com/datadoghq/trace/DDTracer.java index 778b95d4da8..fd66b987ce6 100644 --- a/dd-trace/src/main/java/com/datadoghq/trace/DDTracer.java +++ b/dd-trace/src/main/java/com/datadoghq/trace/DDTracer.java @@ -1,19 +1,27 @@ package com.datadoghq.trace; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import com.datadoghq.trace.integration.DDSpanContextDecorator; import com.datadoghq.trace.propagation.Codec; import com.datadoghq.trace.propagation.HTTPCodec; import com.datadoghq.trace.sampling.AllSampler; import com.datadoghq.trace.sampling.Sampler; -import com.datadoghq.trace.writer.DDAgentWriter; +import com.datadoghq.trace.writer.LoggingWriter; import com.datadoghq.trace.writer.Writer; + +import io.opentracing.ActiveSpan; +import io.opentracing.BaseSpan; import io.opentracing.Span; import io.opentracing.SpanContext; import io.opentracing.propagation.Format; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.*; /** @@ -45,7 +53,7 @@ public class DDTracer implements io.opentracing.Tracer { private final CodecRegistry registry; public static final String UNASSIGNED_DEFAULT_SERVICE_NAME = "unnamed-java-app"; - public static final Writer UNASSIGNED_WRITER = new DDAgentWriter(); + public static final Writer UNASSIGNED_WRITER = new LoggingWriter(); public static final Sampler UNASSIGNED_SAMPLER = new AllSampler(); /** @@ -132,11 +140,11 @@ public SpanContext extract(Format format, T carrier) { * * @param trace a list of the spans related to the same trace */ - public void write(List trace) { + public void write(List> trace) { if (trace.isEmpty()) { return; } - if (this.sampler.sample((DDSpan) trace.get(0))) { + if (this.sampler.sample(trace.get(0))) { this.writer.write(trace); } } @@ -144,6 +152,52 @@ public void write(List trace) { public void close() { writer.close(); } + + private final ThreadLocal currentActiveSpan = new ThreadLocal(); + + @Override + public DDActiveSpan activeSpan() { + return currentActiveSpan.get(); + } + + /** + * Set the newly created active span as the active one from the Tracer's perspective + * + * @param activeSpan + */ + protected void makeActive(DDActiveSpan activeSpan){ + //We cannot make active a preably deactivated span + if(activeSpan!=null && activeSpan.isDeactivated()) + currentActiveSpan.set(null); + else + currentActiveSpan.set(activeSpan); + } + + /** + * Deactivate the current span (if active) and make the parent active (again) + * + * @param activeSpan + */ + protected void deactivate(DDActiveSpan activeSpan){ + DDActiveSpan current = activeSpan(); + if(current==activeSpan){ + //The parent becomes the active span + makeActive(activeSpan.getParent()); + } + } + + @Override + public DDActiveSpan makeActive(Span span) { + if(!(span instanceof DDSpan)) + throw new IllegalArgumentException("Cannot transform a non DDSpan into a DDActiveSpan. Provided class: "+span.getClass()); + + //Wrap the provided manual span into an active one with the current parent + DDActiveSpan activeSpan = new DDActiveSpan(activeSpan(),(DDSpan)span); + + makeActive(activeSpan); + + return activeSpan; + } /** * Spans are built using this builder @@ -163,29 +217,56 @@ public class DDSpanBuilder implements SpanBuilder { private String resourceName; private boolean errorFlag; private String spanType; + private boolean ignoreActiveSpan = false; - /** - * This method actually build the span according to the builder settings - * DD-Agent requires a serviceName. If it has not been provided, the method will throw a RuntimeException - * - * @return An fresh span - */ - public DDSpan start() { - - // build the context - DDSpanContext context = buildSpanContext(); - DDSpan span = new DDSpan(this.timestamp, context); + @Override + public SpanBuilder ignoreActiveSpan() { + this.ignoreActiveSpan = true; + return this; + } - logger.debug("{} - Starting a new span.", span); + @Override + public DDActiveSpan startActive() { + //Set the active span as parent if ignoreActiveSpan==true + DDActiveSpan activeParent = null; + if(!ignoreActiveSpan){ + DDActiveSpan current = activeSpan(); + if(current!=null){ + activeParent = current; + + //Ensure parent inheritance + asChildOf(activeParent); + } + } + + //Create the active span + DDActiveSpan activeSpan = new DDActiveSpan(activeParent,this.timestamp, buildSpanContext()); + logger.debug("{} - Starting a new active span.", activeSpan); + + makeActive(activeSpan); + + return activeSpan; + } + @Override + public DDSpan startManual() { + DDSpan span = new DDSpan(this.timestamp, buildSpanContext()); + logger.debug("{} - Starting a new manuel span.", span); return span; } + @Override + @Deprecated + public DDSpan start() { + return startManual(); + } + @Override public DDTracer.DDSpanBuilder withTag(String tag, Number number) { return withTag(tag, (Object) number); } + @Override public DDTracer.DDSpanBuilder withTag(String tag, String string) { if (tag.equals(DDTags.SERVICE_NAME)) { return withServiceName(string); @@ -198,15 +279,17 @@ public DDTracer.DDSpanBuilder withTag(String tag, String string) { } } + @Override public DDTracer.DDSpanBuilder withTag(String tag, boolean bool) { return withTag(tag, (Object) bool); } + public DDSpanBuilder(String operationName) { this.operationName = operationName; } - + @Override public DDTracer.DDSpanBuilder withStartTimestamp(long timestampMillis) { this.timestamp = timestampMillis; return this; @@ -239,15 +322,18 @@ public Iterable> baggageItems() { return parent.baggageItems(); } - public DDTracer.DDSpanBuilder asChildOf(Span span) { + @Override + public DDTracer.DDSpanBuilder asChildOf(BaseSpan span) { return asChildOf(span == null ? null : span.context()); } + @Override public DDTracer.DDSpanBuilder asChildOf(SpanContext spanContext) { this.parent = spanContext; return this; } + @Override public DDTracer.DDSpanBuilder addReference(String referenceType, SpanContext spanContext) { logger.debug("`addReference` method is not implemented. Doing nothing"); return this; @@ -301,18 +387,18 @@ private DDSpanContext buildSpanContext() { // some attributes are inherited from the parent context = new DDSpanContext( this.parent == null ? generatedId : p.getTraceId(), - generatedId, - this.parent == null ? 0L : p.getSpanId(), - serviceName, - operationName, - this.resourceName, - this.parent == null ? null : p.getBaggageItems(), - errorFlag, - spanType, - this.tags, - this.parent == null ? null : p.getTrace(), - DDTracer.this - ); + generatedId, + this.parent == null ? 0L : p.getSpanId(), + serviceName, + operationName, + this.resourceName, + this.parent == null ? null : p.getBaggageItems(), + errorFlag, + spanType, + this.tags, + this.parent == null ? null : p.getTrace(), + DDTracer.this + ); return context; } diff --git a/dd-trace/src/main/java/com/datadoghq/trace/sampling/ASampler.java b/dd-trace/src/main/java/com/datadoghq/trace/sampling/ASampler.java index 8b674cfc74e..38d00be2b08 100644 --- a/dd-trace/src/main/java/com/datadoghq/trace/sampling/ASampler.java +++ b/dd-trace/src/main/java/com/datadoghq/trace/sampling/ASampler.java @@ -5,9 +5,7 @@ import java.util.Map.Entry; import java.util.regex.Pattern; -import com.datadoghq.trace.DDSpan; - -import io.opentracing.Span; +import com.datadoghq.trace.DDBaseSpan; public abstract class ASampler implements Sampler{ @@ -15,28 +13,25 @@ public abstract class ASampler implements Sampler{ * Sample tags */ protected Map skipTagsPatterns = new HashMap(); - + @Override - public boolean sample(Span span) { - if(span instanceof DDSpan){ - DDSpan ddSpan = (DDSpan) span; - - //Filter by tag values - for(Entry entry: skipTagsPatterns.entrySet()){ - Object value = ddSpan.getTags().get(entry.getKey()); - if(value != null){ - String strValue = String.valueOf(value); - Pattern skipPattern = entry.getValue(); - if(skipPattern.matcher(strValue).matches()){ - return false; - } + public boolean sample(DDBaseSpan span) { + + //Filter by tag values + for(Entry entry: skipTagsPatterns.entrySet()){ + Object value = span.getTags().get(entry.getKey()); + if(value != null){ + String strValue = String.valueOf(value); + Pattern skipPattern = entry.getValue(); + if(skipPattern.matcher(strValue).matches()){ + return false; } } } - + return doSample(span); } - + /** * Pattern based skipping of tag values * @@ -46,7 +41,7 @@ public boolean sample(Span span) { public void addSkipTagPattern(String tag,Pattern skipPattern){ skipTagsPatterns.put(tag, skipPattern); } - - protected abstract boolean doSample(Span span); + + protected abstract boolean doSample(DDBaseSpan span); } diff --git a/dd-trace/src/main/java/com/datadoghq/trace/sampling/AllSampler.java b/dd-trace/src/main/java/com/datadoghq/trace/sampling/AllSampler.java index af8cb7d7562..25bd06e8fe0 100644 --- a/dd-trace/src/main/java/com/datadoghq/trace/sampling/AllSampler.java +++ b/dd-trace/src/main/java/com/datadoghq/trace/sampling/AllSampler.java @@ -1,6 +1,6 @@ package com.datadoghq.trace.sampling; -import io.opentracing.Span; +import com.datadoghq.trace.DDBaseSpan; /** * Sampler that always says yes... @@ -8,7 +8,7 @@ public class AllSampler extends ASampler { @Override - public boolean doSample(Span span) { + public boolean doSample(DDBaseSpan span) { return true; } diff --git a/dd-trace/src/main/java/com/datadoghq/trace/sampling/RateSampler.java b/dd-trace/src/main/java/com/datadoghq/trace/sampling/RateSampler.java index e96c02c9592..48b718299ea 100644 --- a/dd-trace/src/main/java/com/datadoghq/trace/sampling/RateSampler.java +++ b/dd-trace/src/main/java/com/datadoghq/trace/sampling/RateSampler.java @@ -4,10 +4,9 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import com.datadoghq.trace.DDBaseSpan; import com.google.auto.service.AutoService; -import io.opentracing.Span; - /** * This sampler sample the traces at a predefined rate. @@ -45,7 +44,7 @@ public RateSampler(double sampleRate) { } @Override - public boolean doSample(Span span) { + public boolean doSample(DDBaseSpan span) { boolean sample = Math.random() <= this.sampleRate; logger.debug("{} - Span is sampled: {}", span, sample); return sample; diff --git a/dd-trace/src/main/java/com/datadoghq/trace/sampling/Sampler.java b/dd-trace/src/main/java/com/datadoghq/trace/sampling/Sampler.java index 16f6ed92087..29d158098ca 100644 --- a/dd-trace/src/main/java/com/datadoghq/trace/sampling/Sampler.java +++ b/dd-trace/src/main/java/com/datadoghq/trace/sampling/Sampler.java @@ -1,7 +1,7 @@ package com.datadoghq.trace.sampling; -import io.opentracing.Span; +import com.datadoghq.trace.DDBaseSpan; /** * Main interface to sample a collection of traces. @@ -14,6 +14,6 @@ public interface Sampler { * @param span the parent span with its context * @return true when the trace/spans has to be reported/written */ - boolean sample(Span span); + boolean sample(DDBaseSpan span); } diff --git a/dd-trace/src/main/java/com/datadoghq/trace/writer/DDAgentWriter.java b/dd-trace/src/main/java/com/datadoghq/trace/writer/DDAgentWriter.java index 6cd53fc93ce..92687b9e1ad 100644 --- a/dd-trace/src/main/java/com/datadoghq/trace/writer/DDAgentWriter.java +++ b/dd-trace/src/main/java/com/datadoghq/trace/writer/DDAgentWriter.java @@ -1,15 +1,20 @@ package com.datadoghq.trace.writer; -import io.opentracing.Span; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Semaphore; +import java.util.concurrent.TimeUnit; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import com.datadoghq.trace.DDBaseSpan; import com.google.auto.service.AutoService; -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.*; - /** * This writer write provided traces to the a DD agent which is most of time located on the same host. *

@@ -45,7 +50,7 @@ public class DDAgentWriter implements Writer { /** * In memory collection of traces waiting for departure */ - private final BlockingQueue> traces; + private final BlockingQueue>> traces; /** * Async worker that posts the spans to the DD agent @@ -66,13 +71,13 @@ public DDAgentWriter(DDApi api) { this.api = api; tokens = new Semaphore(DEFAULT_MAX_SPANS); - traces = new ArrayBlockingQueue>(DEFAULT_MAX_SPANS); + traces = new ArrayBlockingQueue>>(DEFAULT_MAX_SPANS); } /* (non-Javadoc) * @see com.datadoghq.trace.Writer#write(java.util.List) */ - public void write(List trace) { + public void write(List> trace) { //Try to add a new span in the queue boolean proceed = tokens.tryAcquire(trace.size()); @@ -111,10 +116,10 @@ protected class SpansSendingTask implements Runnable { public void run() { while (true) { try { - List> payload = new ArrayList>(); + List>> payload = new ArrayList>>(); //WAIT until a new span comes - List l = DDAgentWriter.this.traces.take(); + List> l = DDAgentWriter.this.traces.take(); payload.add(l); //Drain all spans up to a certain batch suze @@ -126,7 +131,7 @@ public void run() { //Compute the number of spans sent int spansCount = 0; - for (List trace : payload) { + for (List> trace : payload) { spansCount += trace.size(); } logger.debug("Async writer just sent {} spans through {} traces", spansCount, payload.size()); diff --git a/dd-trace/src/main/java/com/datadoghq/trace/writer/DDApi.java b/dd-trace/src/main/java/com/datadoghq/trace/writer/DDApi.java index 1c10f950ed1..21df592c8fb 100644 --- a/dd-trace/src/main/java/com/datadoghq/trace/writer/DDApi.java +++ b/dd-trace/src/main/java/com/datadoghq/trace/writer/DDApi.java @@ -8,12 +8,11 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import com.datadoghq.trace.DDBaseSpan; import com.fasterxml.jackson.core.JsonFactory; import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.databind.ObjectMapper; -import io.opentracing.Span; - /** * The API pointing to a DD agent */ @@ -41,7 +40,7 @@ public DDApi(String host, int port) { * @param traces the traces to be sent * @return the staus code returned */ - public boolean sendTraces(List> traces) { + public boolean sendTraces(List>> traces) { int status = callPUT(tracesEndpoint, traces); if (status == 200) { logger.debug("Succesfully sent {} traces to the DD agent.", traces.size()); diff --git a/dd-trace/src/main/java/com/datadoghq/trace/writer/ListWriter.java b/dd-trace/src/main/java/com/datadoghq/trace/writer/ListWriter.java new file mode 100644 index 00000000000..e04c529bc3a --- /dev/null +++ b/dd-trace/src/main/java/com/datadoghq/trace/writer/ListWriter.java @@ -0,0 +1,38 @@ +package com.datadoghq.trace.writer; + +import java.util.ArrayList; +import java.util.List; + +import com.datadoghq.trace.DDBaseSpan; + +/** + * List writer used by tests mostly + */ +public class ListWriter implements Writer { + + protected List>> list = new ArrayList>>(); + + public List>> getList() { + return list; + } + + public List> firstTrace() { + return list.get(0); + } + + @Override + public void write(List> trace) { + list.add(trace); + } + + @Override + public void start() { + list.clear(); + } + + @Override + public void close() { + list.clear(); + } + +} diff --git a/dd-trace/src/main/java/com/datadoghq/trace/writer/LoggingWriter.java b/dd-trace/src/main/java/com/datadoghq/trace/writer/LoggingWriter.java index 86110280275..929008f7755 100644 --- a/dd-trace/src/main/java/com/datadoghq/trace/writer/LoggingWriter.java +++ b/dd-trace/src/main/java/com/datadoghq/trace/writer/LoggingWriter.java @@ -5,17 +5,16 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import com.datadoghq.trace.DDBaseSpan; import com.google.auto.service.AutoService; -import io.opentracing.Span; - @AutoService(Writer.class) public class LoggingWriter implements Writer{ private static final Logger logger = LoggerFactory.getLogger(LoggingWriter.class.getName()); @Override - public void write(List trace) { + public void write(List> trace) { logger.info("write(trace): {}", trace); } diff --git a/dd-trace/src/main/java/com/datadoghq/trace/writer/Writer.java b/dd-trace/src/main/java/com/datadoghq/trace/writer/Writer.java index 969954f8b13..2fd8ae7af8c 100644 --- a/dd-trace/src/main/java/com/datadoghq/trace/writer/Writer.java +++ b/dd-trace/src/main/java/com/datadoghq/trace/writer/Writer.java @@ -2,7 +2,7 @@ import java.util.List; -import io.opentracing.Span; +import com.datadoghq.trace.DDBaseSpan; /** * A writer is responsible to send collected spans to some place @@ -14,7 +14,7 @@ public interface Writer { * * @param trace the list of spans to write */ - void write(List trace); + void write(List> trace); /** * Start the writer diff --git a/dd-trace/src/test/java/com/datadoghq/trace/DDActiveSpanTest.java b/dd-trace/src/test/java/com/datadoghq/trace/DDActiveSpanTest.java new file mode 100644 index 00000000000..4ca4aac46b0 --- /dev/null +++ b/dd-trace/src/test/java/com/datadoghq/trace/DDActiveSpanTest.java @@ -0,0 +1,129 @@ +package com.datadoghq.trace; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.Before; +import org.junit.Test; + +import com.datadoghq.trace.writer.ListWriter; + +import io.opentracing.ActiveSpan.Continuation; + +public class DDActiveSpanTest { + + private ListWriter listWriter = new ListWriter(); + private DDTracer ddTracer = new DDTracer(listWriter); + + @Before + public void setUp(){ + listWriter.start(); + } + + @Test + public void testThreadContextPropagation() { + + DDActiveSpan span1 = ddTracer.buildSpan("op1").startActive(); + + assertThat(span1.getOperationName()).isEqualTo("op1"); + assertThat(ddTracer.activeSpan()).isEqualTo(span1); + + DDActiveSpan span2 = ddTracer.buildSpan("op2").startActive(); + assertThat(span2.getOperationName()).isEqualTo("op2"); + assertThat(span2.getParent()).isEqualTo(span1); + assertThat(span2.context().getParentId()).isEqualTo(span1.getSpanId()); + assertThat(span2.context().getTraceId()).isEqualTo(span1.getTraceId()); + assertThat(ddTracer.activeSpan()).isEqualTo(span2); + + span2.deactivate(); + assertThat(ddTracer.activeSpan()).isEqualTo(span1); + + assertThat(listWriter.getList().size()).isEqualTo(0); + span1.deactivate(); + assertThat(ddTracer.activeSpan()).isNull(); + + assertThat(listWriter.getList().size()).isEqualTo(1); + assertThat(listWriter.getList().get(0).size()).isEqualTo(2); + assertThat(listWriter.getList().get(0).get(0)).isEqualTo(span1); + assertThat(listWriter.getList().get(0).get(1)).isEqualTo(span2); + } + + @Test + public void testParentDeactivationFirst() { + + DDActiveSpan span1 = ddTracer.buildSpan("op1").startActive(); + + assertThat(span1.getOperationName()).isEqualTo("op1"); + + DDActiveSpan span2 = ddTracer.buildSpan("op2").startActive(); + + assertThat(ddTracer.activeSpan()).isEqualTo(span2); + + span1.deactivate(); + + //If parent span deactivated first => Span 2 remains the active span + assertThat(ddTracer.activeSpan()).isEqualTo(span2); + + span2.deactivate(); + + //If span2 comes to be deactivated + assertThat(ddTracer.activeSpan()).isNull(); + + assertThat(listWriter.getList().size()).isEqualTo(1); + assertThat(listWriter.getList().get(0).size()).isEqualTo(2); + assertThat(listWriter.getList().get(0).get(0)).isEqualTo(span1); + assertThat(listWriter.getList().get(0).get(1)).isEqualTo(span2); + } + + @Test + public void testContinuation() throws Exception{ + final DDActiveSpan span1 = ddTracer.buildSpan("op1").startActive(); + + final Continuation continuation = span1.capture(); + + Thread t = new Thread(new Runnable() { + @Override + public void run() { + assertThat(ddTracer.activeSpan()).isNull(); + continuation.activate(); + assertThat(ddTracer.activeSpan()).isEqualTo(span1); + DDActiveSpan span2 = ddTracer.buildSpan("op2").startActive(); + assertThat(ddTracer.activeSpan()).isEqualTo(span2); + span2.deactivate(); + assertThat(ddTracer.activeSpan()).isEqualTo(span1); + } + }); + + t.start(); + t.join(); + + span1.deactivate(); + assertThat(ddTracer.activeSpan()).isNull(); + + assertThat(listWriter.getList().size()).isEqualTo(1); + assertThat(listWriter.getList().get(0).size()).isEqualTo(2); + assertThat(listWriter.getList().get(0).get(0)).isEqualTo(span1); + } + + @Test + public void testMakeSpanActive() { + final DDSpan manualSpan = ddTracer.buildSpan("op1").startManual(); + + DDActiveSpan span1 = ddTracer.makeActive(manualSpan); + + assertThat(span1.getOperationName()).isEqualTo("op1"); + assertThat(ddTracer.activeSpan()).isEqualTo(span1); + assertThat(manualSpan.context()).isEqualTo(span1.context()); + assertThat(manualSpan.startTimeNano).isEqualTo(span1.startTimeNano); + assertThat(manualSpan.startTimeMicro).isEqualTo(span1.startTimeMicro); + } + + @Test + public void testCrossContextPropagation() { + final DDSpan manualSpan = ddTracer.buildSpan("op1").startManual(); + + DDActiveSpan activeSpan = ddTracer.buildSpan("op2").asChildOf(manualSpan.context()).startActive(); + + assertThat(activeSpan.getParentId()).isEqualTo(manualSpan.getSpanId()); + assertThat(activeSpan.getTraceId()).isEqualTo(manualSpan.getTraceId()); + } +} diff --git a/dd-trace/src/test/java/com/datadoghq/trace/DDSpanBuilderTest.java b/dd-trace/src/test/java/com/datadoghq/trace/DDSpanBuilderTest.java index 75355be2406..06ea01a704e 100644 --- a/dd-trace/src/test/java/com/datadoghq/trace/DDSpanBuilderTest.java +++ b/dd-trace/src/test/java/com/datadoghq/trace/DDSpanBuilderTest.java @@ -131,9 +131,7 @@ public void shouldLinkToParentSpan() { final long expectedParentId = spanId; DDSpanContext mockedContext = mock(DDSpanContext.class); - DDSpan mockedSpan = mock(DDSpan.class); - - when(mockedSpan.context()).thenReturn(mockedContext); + when(mockedContext.getSpanId()).thenReturn(spanId); when(mockedContext.getServiceName()).thenReturn("foo"); @@ -142,13 +140,12 @@ public void shouldLinkToParentSpan() { DDSpan span = tracer .buildSpan(expectedName) .withServiceName("foo") - .asChildOf(mockedSpan) + .asChildOf(mockedContext) .start(); DDSpanContext actualContext = span.context(); assertThat(actualContext.getParentId()).isEqualTo(expectedParentId); - } diff --git a/dd-trace/src/test/java/com/datadoghq/trace/DDSpanSerializerTest.java b/dd-trace/src/test/java/com/datadoghq/trace/DDSpanSerializationTest.java similarity index 78% rename from dd-trace/src/test/java/com/datadoghq/trace/DDSpanSerializerTest.java rename to dd-trace/src/test/java/com/datadoghq/trace/DDSpanSerializationTest.java index 434711eb0ea..ff7cbc5dc0f 100644 --- a/dd-trace/src/test/java/com/datadoghq/trace/DDSpanSerializerTest.java +++ b/dd-trace/src/test/java/com/datadoghq/trace/DDSpanSerializationTest.java @@ -10,11 +10,12 @@ import com.fasterxml.jackson.databind.ObjectMapper; -public class DDSpanSerializerTest { +public class DDSpanSerializationTest { ObjectMapper serializer; DDSpan span; + DDActiveSpan activeSpan; @Before public void setUp() throws Exception { @@ -42,8 +43,10 @@ public void setUp() throws Exception { span = new DDSpan( 100L, context); - span.finish(133L); + + activeSpan = new DDActiveSpan(null,100L,context); + activeSpan.deactivate(); serializer = new ObjectMapper(); } @@ -55,9 +58,16 @@ public void test() throws Exception { // FIXME At the moment, just compare the string sizes try { assertThat(serializer.writeValueAsString(span).length()).isEqualTo(expected.length()); + } catch (AssertionError e) { assertThat(serializer.writeValueAsString(span)).isEqualTo(expected); } + +// try { +// assertThat(serializer.writeValueAsString(activeSpan).length()).isEqualTo(expected.length()); +// } catch (AssertionError e) { +// assertThat(serializer.writeValueAsString(activeSpan)).isEqualTo(expected); +// } } } diff --git a/dd-trace/src/test/java/com/datadoghq/trace/DDTracerTest.java b/dd-trace/src/test/java/com/datadoghq/trace/DDTracerTest.java index 691cd5e4fb8..866eddcd733 100644 --- a/dd-trace/src/test/java/com/datadoghq/trace/DDTracerTest.java +++ b/dd-trace/src/test/java/com/datadoghq/trace/DDTracerTest.java @@ -16,6 +16,7 @@ import com.datadoghq.trace.sampling.RateSampler; import com.datadoghq.trace.writer.Writer; +import io.opentracing.BaseSpan; import io.opentracing.Span; @@ -34,7 +35,7 @@ public void write() throws Exception { .thenReturn(true) .thenReturn(false); - List spans = new ArrayList(); + List> spans = new ArrayList>(); spans.add(span); spans.add(span); spans.add(span); diff --git a/dd-trace/src/test/java/com/datadoghq/trace/writer/impl/DDAgentWriterTest.java b/dd-trace/src/test/java/com/datadoghq/trace/writer/impl/DDAgentWriterTest.java index f5da256de7c..80edb066381 100644 --- a/dd-trace/src/test/java/com/datadoghq/trace/writer/impl/DDAgentWriterTest.java +++ b/dd-trace/src/test/java/com/datadoghq/trace/writer/impl/DDAgentWriterTest.java @@ -11,6 +11,7 @@ import org.junit.Before; import org.junit.Test; +import com.datadoghq.trace.DDBaseSpan; import com.datadoghq.trace.DDSpan; import com.datadoghq.trace.DDTracer; import com.datadoghq.trace.writer.DDAgentWriter; @@ -22,7 +23,7 @@ public class DDAgentWriterTest { DDSpan parent = null; DDApi mockedAPI = null; - List> traces = new ArrayList>(); + List>> traces = new ArrayList>>(); DDAgentWriter ddAgentWriter = null; @Before diff --git a/dd-trace/src/test/resources/logback.xml b/dd-trace/src/test/resources/logback.xml index 607d3e615d8..c331c42dfdb 100644 --- a/dd-trace/src/test/resources/logback.xml +++ b/dd-trace/src/test/resources/logback.xml @@ -9,7 +9,7 @@ - + diff --git a/pom.xml b/pom.xml index 24b11f37afb..2441ecdd2bd 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ com.datadoghq dd-trace-java - 0.0.7-SNAPSHOT + 0.0.8-SNAPSHOT pom @@ -44,7 +44,7 @@ - 0.22.0 + 0.30.0 1.7