[core] override operation name using decorators
RENAME
dd-trace/src/main/java/com/datadoghq/trace/integration/DBComponent.java
dd-trace/src/main/java/com/datadoghq/trace/integration/DBTypeDecorator.java
@@ -8,9 +8,9 @@ import io.opentracing.tag.Tags;
* This span decorator leverages DB tags. It allows the dev to define a custom service name and
* retrieves some DB meta such as the statement
*/
-public class DBComponent extends DDSpanContextDecorator {
+public class DBTypeDecorator extends AbstractDecorator {
- public DBComponent() {
+ public DBTypeDecorator() {
super();
this.setMatchingTag(Tags.DB_TYPE.getKey());
this.setSetTag(DDTags.SERVICE_NAME);
@@ -22,6 +22,8 @@ public class DBComponent extends DDSpanContextDecorator {
if (super.afterSetTag(context, tag, value)) {
//Assign span type to DB
context.setSpanType("db");
+ // Works for: mongo, cassandra, jdbc
+ context.setOperationName(String.valueOf(value) + ".query");
return true;
}
return false;

DELETE
dd-trace/src/main/java/com/datadoghq/trace/integration/DDSpanContextDecorator.java
-package com.datadoghq.trace.integration;
-
-import com.datadoghq.trace.DDSpanContext;
-import com.datadoghq.trace.DDTags;
-
-/**
- * Span decorators are called when new tags are written and proceed to various remappings and
- * enrichments
- */
-public abstract class DDSpanContextDecorator {
-
- private String matchingTag;
-
- private String matchingValue;
-
- private String setTag;
-
- private String setValue;
-
- public boolean afterSetTag(DDSpanContext context, String tag, Object value) {
- if ((this.getMatchingValue() == null || value.equals(this.getMatchingValue()))) {
- String targetTag = getSetTag() == null ? tag : getSetTag();
- String targetValue = getSetValue() == null ? String.valueOf(value) : getSetValue();
-
- if (targetTag.equals(DDTags.SERVICE_NAME)) {
- context.setServiceName(targetValue);
- } else if (targetTag.equals(DDTags.RESOURCE_NAME)) {
- context.setResourceName(targetValue);
- } else if (targetTag.equals(DDTags.SPAN_TYPE)) {
- context.setSpanType(targetValue);
- } else {
- context.setTag(targetTag, targetValue);
- }
- return true;
- } else {
- return false;
- }
- }
-
- public String getMatchingTag() {
- return matchingTag;
- }
-
- public void setMatchingTag(String tag) {
- this.matchingTag = tag;
- }
-
- public String getMatchingValue() {
- return matchingValue;
- }
-
- public void setMatchingValue(String value) {
- this.matchingValue = value;
- }
-
- public String getSetTag() {
- return setTag;
- }
-
- public void setSetTag(String targetTag) {
- this.setTag = targetTag;
- }
-
- public String getSetValue() {
- return setValue;
- }
-
- public void setSetValue(String targetValue) {
- this.setValue = targetValue;
- }
-}

ADD
dd-trace/src/main/java/com/datadoghq/trace/integration/OperationDecorator.java
+package com.datadoghq.trace.integration;
+
+import com.datadoghq.trace.DDSpanContext;
+import io.opentracing.tag.Tags;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * This span decorator is a simple mapping to override the operation DB tags. The operation name of
+ * DB integration are handled by the DBTypeDecorator
+ */
+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");
+ // Jetty + Tomcat (same integration used)
+ put("java-web-servlet", "servlet.request");
+ // 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
+ }
+ };
+
+ public OperationDecorator() {
+ super();
+ this.setMatchingTag(Tags.COMPONENT.getKey());
+ }
+
+ @Override
+ public boolean afterSetTag(final DDSpanContext context, final String tag, final Object value) {
+
+ if (MAPPINGS.containsKey(String.valueOf(value))) {
+ context.setOperationName(MAPPINGS.get(String.valueOf(value)));
+ return true;
+ }
+ return false;
+ }
+}

MODIFY
dd-trace/src/main/resources/dd-trace-decorators.yaml
dd-trace/src/main/resources/dd-trace-decorators.yaml
@@ -4,9 +4,8 @@ decorators:
- type: HTTPComponent
matchingValue: java-okhttp
setValue: http-client
- - type: DBComponent
+ - type: BDTypeDecorator
- type: HTTPComponent
matchingValue: java-aws-sdk
setValue: aws-client
-# - type: DBStatementAsResourceName
- type: ErrorFlag

MODIFY
dd-trace/src/test/groovy/com/datadoghq/trace/integration/SpanDecoratorTest.groovy
dd-trace/src/test/groovy/com/datadoghq/trace/integration/SpanDecoratorTest.groovy
@@ -4,6 +4,7 @@ import com.datadoghq.trace.DDSpanContext
import com.datadoghq.trace.DDTracer
import com.datadoghq.trace.SpanFactory
import io.opentracing.tag.StringTag
+import io.opentracing.tag.Tags
import spock.lang.Specification
class SpanDecoratorTest extends Specification {
@@ -11,7 +12,7 @@ class SpanDecoratorTest extends Specification {
def "adding span personalisation using Decorators"() {
setup:
def tracer = new DDTracer()
- def decorator = new DDSpanContextDecorator() {
+ def decorator = new AbstractDecorator() {
@Override
boolean afterSetTag(DDSpanContext context, String tag, Object value) {
@@ -32,4 +33,44 @@ class SpanDecoratorTest extends Specification {
span.getTags().containsKey("newFoo")
span.getTags().get("newFoo") == "newBar"
}
+
+ def "override operation with OperationDecorator"() {
+
+ setup:
+ def tracer = new DDTracer()
+ def span = SpanFactory.newSpanOf(tracer)
+ tracer.addDecorator(new OperationDecorator())
+
+ when:
+ Tags.COMPONENT.set(span, component)
+
+ then:
+ span.getOperationName() == operationName
+
+ where:
+ component << OperationDecorator.MAPPINGS.keySet()
+ operationName << OperationDecorator.MAPPINGS.values()
+
+
+ }
+
+ def "override operation with DBTypeDecorator"() {
+
+ setup:
+ def tracer = new DDTracer()
+ def span = SpanFactory.newSpanOf(tracer)
+ tracer.addDecorator(new DBTypeDecorator())
+
+ when:
+ Tags.DB_TYPE.set(span, type)
+
+ then:
+ span.getOperationName() == type + ".query"
+ span.context().getSpanType() == "db"
+
+ where:
+ type = "foo"
+
+
+ }
}

[core] override operation name using decorators