Close span when exception exit
MODIFY
dd-java-agent-ittests/src/test/java/com/datadoghq/trace/agent/SayTracedHello.java
dd-java-agent-ittests/src/test/java/com/datadoghq/trace/agent/SayTracedHello.java
@@ -25,4 +25,9 @@ public class SayTracedHello {
new StringTag(DDTags.SERVICE_NAME).set(GlobalTracer.get().activeSpan(), "test2");
return sayHello() + sayHA();
}
+
+ @Trace(operationName = "ERROR")
+ public static String sayERROR() {
+ throw new RuntimeException();
+ }
}

MODIFY
dd-java-agent-ittests/src/test/java/com/datadoghq/trace/agent/TraceAnnotationsManagerTest.java
dd-java-agent-ittests/src/test/java/com/datadoghq/trace/agent/TraceAnnotationsManagerTest.java
@@ -2,32 +2,50 @@ package com.datadoghq.trace.agent;
import static org.assertj.core.api.Assertions.assertThat;
-import com.datadoghq.trace.agent.integration.AAgentIntegration;
+import com.datadoghq.trace.DDTracer;
+import com.datadoghq.trace.integration.ErrorFlag;
+import com.datadoghq.trace.writer.ListWriter;
+import io.opentracing.tag.Tags;
+import io.opentracing.util.GlobalTracer;
+import java.lang.reflect.Field;
import org.junit.Before;
import org.junit.Test;
-public class TraceAnnotationsManagerTest extends AAgentIntegration {
+public class TraceAnnotationsManagerTest {
+
+ private final ListWriter writer = new ListWriter();
+ private final DDTracer tracer = new DDTracer(writer);
@Before
public void beforeTest() throws Exception {
- super.beforeTest();
+ try {
+ GlobalTracer.register(tracer);
+ } catch (final Exception e) {
+ // Force it anyway using reflexion
+ final Field field = GlobalTracer.class.getDeclaredField("tracer");
+ field.setAccessible(true);
+ field.set(null, tracer);
+ }
+ writer.start();
}
@Test
- public void testAnnotations() {
+ public void testSimpleCaseAnnotations() {
//Test single span in new trace
SayTracedHello.sayHello();
assertThat(writer.firstTrace().size()).isEqualTo(1);
assertThat(writer.firstTrace().get(0).getOperationName()).isEqualTo("SAY_HELLO");
assertThat(writer.firstTrace().get(0).getServiceName()).isEqualTo("test");
+ }
- writer.start();
+ @Test
+ public void testComplexCaseAnnotations() {
//Test new trace with 2 children spans
SayTracedHello.sayHELLOsayHA();
assertThat(writer.firstTrace().size()).isEqualTo(3);
- long parentId = writer.firstTrace().get(0).context().getTraceId();
+ final long parentId = writer.firstTrace().get(0).context().getTraceId();
assertThat(writer.firstTrace().get(0).getOperationName()).isEqualTo("NEW_TRACE");
assertThat(writer.firstTrace().get(0).getParentId()).isEqualTo(0); //ROOT / no parent
@@ -41,7 +59,20 @@ public class TraceAnnotationsManagerTest extends AAgentIntegration {
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");
+ }
- writer.start();
+ @Test
+ public void testExceptionExit() {
+
+ tracer.addDecorator(new ErrorFlag());
+
+ try {
+ SayTracedHello.sayERROR();
+ } catch (final Throwable ex) {
+ // DO NOTHING
+ }
+ assertThat(writer.firstTrace().get(0).getOperationName()).isEqualTo("ERROR");
+ assertThat(writer.firstTrace().get(0).getTags().get(Tags.ERROR.getKey())).isEqualTo("true");
+ assertThat(writer.firstTrace().get(0).getError()).isEqualTo(1);
}
}

DELETE
dd-java-agent-ittests/src/test/java/com/datadoghq/trace/agent/integration/AAgentIntegration.java
-package com.datadoghq.trace.agent.integration;
-
-import com.datadoghq.trace.DDTracer;
-import com.datadoghq.trace.writer.ListWriter;
-import io.opentracing.util.GlobalTracer;
-import java.lang.reflect.Field;
-import org.junit.Before;
-
-public class AAgentIntegration {
-
- protected static ListWriter writer = new ListWriter();
- protected static DDTracer tracer = new DDTracer(writer);
-
- @Before
- public void beforeTest() throws Exception {
- try {
- GlobalTracer.register(tracer);
- } catch (Exception e) {
- // Force it anyway using reflexion
- final Field field = GlobalTracer.class.getDeclaredField("tracer");
- field.setAccessible(true);
- field.set(null, tracer);
- }
- writer.start();
- }
-}

MODIFY
dd-java-agent-ittests/src/test/java/com/datadoghq/trace/agent/integration/ApacheHTTPClientTest.java
dd-java-agent-ittests/src/test/java/com/datadoghq/trace/agent/integration/ApacheHTTPClientTest.java
@@ -6,32 +6,12 @@ import io.opentracing.contrib.apache.http.client.TracingHttpClientBuilder;
import org.apache.http.impl.client.HttpClientBuilder;
import org.junit.Test;
-public class ApacheHTTPClientTest extends AAgentIntegration {
+public class ApacheHTTPClientTest {
@Test
public void test() throws Exception {
- HttpClientBuilder builder = HttpClientBuilder.create();
+ final HttpClientBuilder builder = HttpClientBuilder.create();
assertThat(builder).isInstanceOf(TracingHttpClientBuilder.class);
-
- // HttpClient client = builder.build();
- // HttpGet request = new HttpGet("http://apache.org");
- //
- // // add request header
- // HttpResponse response = client.execute(request);
- //
- // System.out.println("Response Code : "
- // + response.getStatusLine().getStatusCode());
- //
- // BufferedReader rd = new BufferedReader(
- // new InputStreamReader(response.getEntity().getContent()));
- //
- // StringBuffer result = new StringBuffer();
- // String line = "";
- // while ((line = rd.readLine()) != null) {
- // result.append(line);
- // }
-
- // assertThat(writer.firstTrace().size()).isEqualTo(2);
}
}

MODIFY
dd-java-agent-ittests/src/test/java/com/datadoghq/trace/agent/integration/ElasticsearchIntegrationTest.java
dd-java-agent-ittests/src/test/java/com/datadoghq/trace/agent/integration/ElasticsearchIntegrationTest.java
@@ -3,7 +3,11 @@ package com.datadoghq.trace.agent.integration;
import static org.assertj.core.api.Assertions.assertThat;
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
+import com.datadoghq.trace.DDTracer;
+import com.datadoghq.trace.writer.ListWriter;
+import io.opentracing.util.GlobalTracer;
import java.io.IOException;
+import java.lang.reflect.Field;
import java.net.Inet4Address;
import java.util.Collection;
import java.util.Collections;
@@ -25,13 +29,15 @@ import org.junit.Ignore;
import org.junit.Test;
@Ignore
-public class ElasticsearchIntegrationTest extends AAgentIntegration {
+public class ElasticsearchIntegrationTest {
private static final int HTTP_PORT = 9205;
private static final String HTTP_TRANSPORT_PORT = "9300";
private static final String ES_WORKING_DIR = "build/es";
private static String clusterName = "elasticsearch";
private static Node node;
+ private final ListWriter writer = new ListWriter();
+ private final DDTracer tracer = new DDTracer(writer);
@AfterClass
public static void stopElasticsearch() throws Exception {
@@ -61,9 +67,16 @@ public class ElasticsearchIntegrationTest extends AAgentIntegration {
}
@Before
- @Override
public void beforeTest() throws Exception {
- super.beforeTest();
+ try {
+ GlobalTracer.register(tracer);
+ } catch (final Exception e) {
+ // Force it anyway using reflexion
+ final Field field = GlobalTracer.class.getDeclaredField("tracer");
+ field.setAccessible(true);
+ field.set(null, tracer);
+ }
+ writer.start();
}
@Test

MODIFY
dd-java-agent/src/main/java/com/datadoghq/trace/agent/TraceAnnotationsManager.java
dd-java-agent/src/main/java/com/datadoghq/trace/agent/TraceAnnotationsManager.java
@@ -11,12 +11,7 @@ import java.lang.reflect.Method;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Enumeration;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
+import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javassist.ClassPool;
@@ -193,6 +188,16 @@ public class TraceAnnotationsManager {
EXIT_RULE);
generatedScripts.append(script).append("\n");
+ // AT EXCEPTION EXIT
+ script =
+ createRuleScript(
+ "Close span in error ",
+ cc,
+ javassistMethod,
+ Location.create(LocationType.EXCEPTION_EXIT, ""),
+ EXCEPTION_EXIT_RULE);
+ generatedScripts.append(script).append("\n");
+
} catch (final Exception e) {
log.warn(
"Could not create rule for method " + method + ". Proceed to next annoted method.", e);
@@ -269,6 +274,13 @@ public class TraceAnnotationsManager {
private static final String EXIT_RULE =
"IF getTracer().activeSpan() != null\n" + "DO\n" + "getTracer().activeSpan().deactivate();\n";
+ private static final String EXCEPTION_EXIT_RULE =
+ "BIND span:io.opentracing.ActiveSpan = getTracer().activeSpan()\n"
+ + "IF span != null\n"
+ + "DO\n"
+ + "span.setTag(io.opentracing.tag.Tags.ERROR.getKey(),\"true\");\n"
+ + "span.deactivate();\n";
+
private static String buildSpan(final CtMethod javassistMethod) {
try {
final Trace trace = (Trace) javassistMethod.getAnnotation(Trace.class);

MODIFY
dd-trace/src/main/java/com/datadoghq/trace/integration/ErrorFlag.java
dd-trace/src/main/java/com/datadoghq/trace/integration/ErrorFlag.java
@@ -4,10 +4,9 @@ import com.datadoghq.trace.DDSpanContext;
import io.opentracing.tag.Tags;
public class ErrorFlag extends DDSpanContextDecorator {
-
public ErrorFlag() {
super();
- this.setMatchingTag(Tags.DB_STATEMENT.getKey());
+ this.setMatchingTag(Tags.ERROR.getKey());
}
@Override

Close span when exception exit (#66)