From b28327655e9c6be1ecd75f3beb502f50b80a4e55 Mon Sep 17 00:00:00 2001 From: Guillaume Polaert Date: Fri, 28 Jul 2017 11:45:26 +0200 Subject: [PATCH 1/4] [core] renaming decorators to AbstractDecorator --- .../com/datadoghq/trace/DDSpanContext.java | 49 +++++++------ .../java/com/datadoghq/trace/DDTracer.java | 12 ++-- .../trace/integration/AbstractDecorator.java | 71 +++++++++++++++++++ .../DBStatementAsResourceName.java | 2 +- .../trace/integration/ErrorFlag.java | 6 +- .../trace/integration/HTTPComponent.java | 4 +- .../trace/integration/URLAsResourceName.java | 8 +-- .../trace/resolver/DDDecoratorsFactory.java | 18 +++-- .../trace/resolver/DDTracerFactory.java | 6 +- .../trace/resolver/TracerResolverTest.java | 19 +++-- 10 files changed, 131 insertions(+), 64 deletions(-) create mode 100644 dd-trace/src/main/java/com/datadoghq/trace/integration/AbstractDecorator.java 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 1bb63c2b1e..fd5fc16d66 100644 --- a/dd-trace/src/main/java/com/datadoghq/trace/DDSpanContext.java +++ b/dd-trace/src/main/java/com/datadoghq/trace/DDSpanContext.java @@ -1,6 +1,6 @@ package com.datadoghq.trace; -import com.datadoghq.trace.integration.DDSpanContextDecorator; +import com.datadoghq.trace.integration.AbstractDecorator; import com.fasterxml.jackson.annotation.JsonIgnore; import com.google.common.collect.Maps; import io.opentracing.tag.Tags; @@ -28,28 +28,27 @@ public class DDSpanContext implements io.opentracing.SpanContext { private final long parentId; private final String threadName = Thread.currentThread().getName(); private final long threadId = Thread.currentThread().getId(); - private Map baggageItems; + /** The collection of all span related to this one */ + private final Queue> trace; // DD attributes + /** For technical reasons, the ref to the original tracer */ + private final DDTracer tracer; + + private Map baggageItems; /** The service name is required, otherwise the span are dropped by the agent */ private String serviceName; /** The resource associated to the service (server_web, database, etc.) */ private String resourceName; /** True indicates that the span reports an error */ private boolean errorFlag; - /** The type of the span. If null, the Datadog Agent will report as a custom */ private String spanType; - /** The collection of all span related to this one */ - private final Queue> trace; /** Each span have an operation name describing the current span */ private String operationName; - + // Others attributes /** Tags are associated to the current span, they will not propagate to the children span */ private Map tags; - // Others attributes - /** For technical reasons, the ref to the original tracer */ - private final DDTracer tracer; public DDSpanContext( final long traceId, @@ -109,12 +108,20 @@ public class DDSpanContext implements io.opentracing.SpanContext { return serviceName; } + public void setServiceName(final String serviceName) { + this.serviceName = serviceName; + } + public String getResourceName() { return this.resourceName == null || this.resourceName.isEmpty() ? this.operationName : this.resourceName; } + public void setResourceName(final String resourceName) { + this.resourceName = resourceName; + } + public boolean getErrorFlag() { return errorFlag; } @@ -127,6 +134,10 @@ public class DDSpanContext implements io.opentracing.SpanContext { return spanType; } + public void setSpanType(final String spanType) { + this.spanType = spanType; + } + public void setBaggageItem(final String key, final String value) { if (this.baggageItems.isEmpty()) { this.baggageItems = new HashMap(); @@ -184,9 +195,9 @@ public class DDSpanContext implements io.opentracing.SpanContext { this.tags.put(tag, value); //Call decorators - final List decorators = tracer.getSpanContextDecorators(tag); + final List decorators = tracer.getSpanContextDecorators(tag); if (decorators != null) { - for (final DDSpanContextDecorator decorator : decorators) { + for (final AbstractDecorator decorator : decorators) { decorator.afterSetTag(this, tag, value); } } @@ -223,23 +234,11 @@ public class DDSpanContext implements io.opentracing.SpanContext { .toString(); } - public void setOperationName(final String operationName) { - this.operationName = operationName; - } - public String getOperationName() { return operationName; } - public void setServiceName(final String serviceName) { - this.serviceName = serviceName; - } - - public void setResourceName(final String resourceName) { - this.resourceName = resourceName; - } - - public void setSpanType(final String spanType) { - this.spanType = spanType; + public void setOperationName(final String operationName) { + this.operationName = operationName; } } 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 e6d06e41ac..b5c7f528bd 100644 --- a/dd-trace/src/main/java/com/datadoghq/trace/DDTracer.java +++ b/dd-trace/src/main/java/com/datadoghq/trace/DDTracer.java @@ -1,6 +1,6 @@ package com.datadoghq.trace; -import com.datadoghq.trace.integration.DDSpanContextDecorator; +import com.datadoghq.trace.integration.AbstractDecorator; import com.datadoghq.trace.propagation.Codec; import com.datadoghq.trace.propagation.HTTPCodec; import com.datadoghq.trace.sampling.AllSampler; @@ -39,7 +39,7 @@ public class DDTracer extends ThreadLocalActiveSpanSource implements io.opentrac private final String defaultServiceName; /** Span context decorators */ - private final Map> spanContextDecorators = new HashMap<>(); + private final Map> spanContextDecorators = new HashMap<>(); private final CodecRegistry registry; @@ -70,18 +70,18 @@ public class DDTracer extends ThreadLocalActiveSpanSource implements io.opentrac * * @return the list of span context decorators */ - public List getSpanContextDecorators(final String tag) { + public List getSpanContextDecorators(final String tag) { return spanContextDecorators.get(tag); } /** - * Add a new decorator in the list ({@link DDSpanContextDecorator}) + * Add a new decorator in the list ({@link AbstractDecorator}) * * @param decorator The decorator in the list */ - public void addDecorator(final DDSpanContextDecorator decorator) { + public void addDecorator(final AbstractDecorator decorator) { - List list = spanContextDecorators.get(decorator.getMatchingTag()); + List list = spanContextDecorators.get(decorator.getMatchingTag()); if (list == null) { list = new ArrayList<>(); } diff --git a/dd-trace/src/main/java/com/datadoghq/trace/integration/AbstractDecorator.java b/dd-trace/src/main/java/com/datadoghq/trace/integration/AbstractDecorator.java new file mode 100644 index 0000000000..c78eefa474 --- /dev/null +++ b/dd-trace/src/main/java/com/datadoghq/trace/integration/AbstractDecorator.java @@ -0,0 +1,71 @@ +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 AbstractDecorator { + + private String matchingTag; + + private String matchingValue; + + private String setTag; + + private String setValue; + + public boolean afterSetTag(final DDSpanContext context, final String tag, final Object value) { + if ((this.getMatchingValue() == null || value.equals(this.getMatchingValue()))) { + final String targetTag = getSetTag() == null ? tag : getSetTag(); + final 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(final String tag) { + this.matchingTag = tag; + } + + public String getMatchingValue() { + return matchingValue; + } + + public void setMatchingValue(final String value) { + this.matchingValue = value; + } + + public String getSetTag() { + return setTag; + } + + public void setSetTag(final String targetTag) { + this.setTag = targetTag; + } + + public String getSetValue() { + return setValue; + } + + public void setSetValue(final String targetValue) { + this.setValue = targetValue; + } +} diff --git a/dd-trace/src/main/java/com/datadoghq/trace/integration/DBStatementAsResourceName.java b/dd-trace/src/main/java/com/datadoghq/trace/integration/DBStatementAsResourceName.java index 1113d0d635..862fb3cc8d 100644 --- a/dd-trace/src/main/java/com/datadoghq/trace/integration/DBStatementAsResourceName.java +++ b/dd-trace/src/main/java/com/datadoghq/trace/integration/DBStatementAsResourceName.java @@ -3,7 +3,7 @@ package com.datadoghq.trace.integration; import com.datadoghq.trace.DDTags; import io.opentracing.tag.Tags; -public class DBStatementAsResourceName extends DDSpanContextDecorator { +public class DBStatementAsResourceName extends AbstractDecorator { public DBStatementAsResourceName() { super(); diff --git a/dd-trace/src/main/java/com/datadoghq/trace/integration/ErrorFlag.java b/dd-trace/src/main/java/com/datadoghq/trace/integration/ErrorFlag.java index 273bcda43a..56b8c7c5a8 100644 --- a/dd-trace/src/main/java/com/datadoghq/trace/integration/ErrorFlag.java +++ b/dd-trace/src/main/java/com/datadoghq/trace/integration/ErrorFlag.java @@ -3,18 +3,18 @@ package com.datadoghq.trace.integration; import com.datadoghq.trace.DDSpanContext; import io.opentracing.tag.Tags; -public class ErrorFlag extends DDSpanContextDecorator { +public class ErrorFlag extends AbstractDecorator { public ErrorFlag() { super(); this.setMatchingTag(Tags.ERROR.getKey()); } @Override - public boolean afterSetTag(DDSpanContext context, String tag, Object value) { + public boolean afterSetTag(final DDSpanContext context, final String tag, final Object value) { //Assign resource name try { context.setErrorFlag(Boolean.parseBoolean(String.valueOf(value))); - } catch (Throwable t) { + } catch (final Throwable t) { //DO NOTHING } return true; diff --git a/dd-trace/src/main/java/com/datadoghq/trace/integration/HTTPComponent.java b/dd-trace/src/main/java/com/datadoghq/trace/integration/HTTPComponent.java index 797292b787..0524b05619 100644 --- a/dd-trace/src/main/java/com/datadoghq/trace/integration/HTTPComponent.java +++ b/dd-trace/src/main/java/com/datadoghq/trace/integration/HTTPComponent.java @@ -8,7 +8,7 @@ import io.opentracing.tag.Tags; * This span decorator leverages HTTP tags. It allows the dev to define a custom service name and * retrieves some HTTP meta such as the request path */ -public class HTTPComponent extends DDSpanContextDecorator { +public class HTTPComponent extends AbstractDecorator { public HTTPComponent() { super(); @@ -17,7 +17,7 @@ public class HTTPComponent extends DDSpanContextDecorator { } @Override - public boolean afterSetTag(DDSpanContext context, String tag, Object value) { + public boolean afterSetTag(final DDSpanContext context, final String tag, final Object value) { //Assign service name if (super.afterSetTag(context, tag, value)) { //Assign span type to WEB diff --git a/dd-trace/src/main/java/com/datadoghq/trace/integration/URLAsResourceName.java b/dd-trace/src/main/java/com/datadoghq/trace/integration/URLAsResourceName.java index ff0cca0ee3..f6f059f3ad 100644 --- a/dd-trace/src/main/java/com/datadoghq/trace/integration/URLAsResourceName.java +++ b/dd-trace/src/main/java/com/datadoghq/trace/integration/URLAsResourceName.java @@ -5,7 +5,7 @@ import com.datadoghq.trace.DDTags; import io.opentracing.tag.Tags; import java.net.MalformedURLException; -public class URLAsResourceName extends DDSpanContextDecorator { +public class URLAsResourceName extends AbstractDecorator { public URLAsResourceName() { super(); @@ -14,12 +14,12 @@ public class URLAsResourceName extends DDSpanContextDecorator { } @Override - public boolean afterSetTag(DDSpanContext context, String tag, Object value) { + public boolean afterSetTag(final DDSpanContext context, final String tag, final Object value) { //Assign resource name try { - String path = new java.net.URL(String.valueOf(value)).getPath(); + final String path = new java.net.URL(String.valueOf(value)).getPath(); context.setResourceName(path); - } catch (MalformedURLException e) { + } catch (final MalformedURLException e) { context.setResourceName(String.valueOf(value)); } return true; diff --git a/dd-trace/src/main/java/com/datadoghq/trace/resolver/DDDecoratorsFactory.java b/dd-trace/src/main/java/com/datadoghq/trace/resolver/DDDecoratorsFactory.java index 630073e09e..09f80656e7 100644 --- a/dd-trace/src/main/java/com/datadoghq/trace/resolver/DDDecoratorsFactory.java +++ b/dd-trace/src/main/java/com/datadoghq/trace/resolver/DDDecoratorsFactory.java @@ -1,6 +1,6 @@ package com.datadoghq.trace.resolver; -import com.datadoghq.trace.integration.DDSpanContextDecorator; +import com.datadoghq.trace.integration.AbstractDecorator; import java.util.ArrayList; import java.util.List; import lombok.extern.slf4j.Slf4j; @@ -9,9 +9,8 @@ import lombok.extern.slf4j.Slf4j; @Slf4j public class DDDecoratorsFactory { - public static String DECORATORS_PACKAGE = "com.datadoghq.trace.integration."; - public static final String CONFIG_PATH = "dd-trace-decorators"; + public static String DECORATORS_PACKAGE = "com.datadoghq.trace.integration."; /** * Create decorators from configuration @@ -19,9 +18,8 @@ public class DDDecoratorsFactory { * @param decoratorsConfig * @return the list of instanciated and configured decorators */ - public static List create( - final List decoratorsConfig) { - final List decorators = new ArrayList<>(); + public static List create(final List decoratorsConfig) { + final List decorators = new ArrayList<>(); for (final DDSpanDecoratorConfig decoratorConfig : decoratorsConfig) { if (decoratorConfig.getType() == null) { log.warn("Cannot create decorator without type from configuration {}", decoratorConfig); @@ -39,9 +37,9 @@ public class DDDecoratorsFactory { continue; } - DDSpanContextDecorator decorator = null; + AbstractDecorator decorator = null; try { - decorator = (DDSpanContextDecorator) decoratorClass.getConstructor().newInstance(); + decorator = (AbstractDecorator) decoratorClass.getConstructor().newInstance(); } catch (final Exception e) { log.warn( "Cannot create decorator as we could not invoke the default constructor. Provided configuration {}", @@ -68,8 +66,8 @@ public class DDDecoratorsFactory { return decorators; } - public static List createFromResources() { - List result = new ArrayList<>(); + public static List createFromResources() { + List result = new ArrayList<>(); final TracerConfig config = FactoryUtils.loadConfigFromResource(CONFIG_PATH, TracerConfig.class); if (config != null) { diff --git a/dd-trace/src/main/java/com/datadoghq/trace/resolver/DDTracerFactory.java b/dd-trace/src/main/java/com/datadoghq/trace/resolver/DDTracerFactory.java index 9c846e1493..ff117bac9b 100644 --- a/dd-trace/src/main/java/com/datadoghq/trace/resolver/DDTracerFactory.java +++ b/dd-trace/src/main/java/com/datadoghq/trace/resolver/DDTracerFactory.java @@ -1,7 +1,7 @@ package com.datadoghq.trace.resolver; import com.datadoghq.trace.DDTracer; -import com.datadoghq.trace.integration.DDSpanContextDecorator; +import com.datadoghq.trace.integration.AbstractDecorator; import com.datadoghq.trace.sampling.AbstractSampler; import com.datadoghq.trace.sampling.AllSampler; import com.datadoghq.trace.sampling.RateSampler; @@ -102,8 +102,8 @@ public class DDTracerFactory { } //Create decorators from resource files - final List decorators = DDDecoratorsFactory.createFromResources(); - for (final DDSpanContextDecorator decorator : decorators) { + final List decorators = DDDecoratorsFactory.createFromResources(); + for (final AbstractDecorator decorator : decorators) { tracer.addDecorator(decorator); } diff --git a/dd-trace/src/test/java/com/datadoghq/trace/resolver/TracerResolverTest.java b/dd-trace/src/test/java/com/datadoghq/trace/resolver/TracerResolverTest.java index ab9ca863b7..520c6e9422 100644 --- a/dd-trace/src/test/java/com/datadoghq/trace/resolver/TracerResolverTest.java +++ b/dd-trace/src/test/java/com/datadoghq/trace/resolver/TracerResolverTest.java @@ -3,7 +3,7 @@ package com.datadoghq.trace.resolver; import static org.assertj.core.api.Assertions.assertThat; import com.datadoghq.trace.DDTracer; -import com.datadoghq.trace.integration.DDSpanContextDecorator; +import com.datadoghq.trace.integration.AbstractDecorator; import com.datadoghq.trace.integration.HTTPComponent; import com.datadoghq.trace.integration.URLAsResourceName; import io.opentracing.NoopTracerFactory; @@ -19,17 +19,16 @@ public class TracerResolverTest { @Test public void testResolve() { - DDTracerResolver tracerResolver = new DDTracerResolver(); - DDTracer tracer = (DDTracer) tracerResolver.resolve(); + final DDTracerResolver tracerResolver = new DDTracerResolver(); + final DDTracer tracer = (DDTracer) tracerResolver.resolve(); // for HTTP decorators - List decorators = - tracer.getSpanContextDecorators(Tags.COMPONENT.getKey()); + List decorators = tracer.getSpanContextDecorators(Tags.COMPONENT.getKey()); assertThat(decorators.size()).isEqualTo(2); - DDSpanContextDecorator decorator = decorators.get(0); + AbstractDecorator decorator = decorators.get(0); assertThat(decorator.getClass()).isEqualTo(HTTPComponent.class); - HTTPComponent httpServiceDecorator = (HTTPComponent) decorator; + final HTTPComponent httpServiceDecorator = (HTTPComponent) decorator; assertThat(httpServiceDecorator.getMatchingTag()).isEqualTo("component"); assertThat(httpServiceDecorator.getMatchingValue()).isEqualTo("hello"); assertThat(httpServiceDecorator.getSetValue()).isEqualTo("world"); @@ -44,13 +43,13 @@ public class TracerResolverTest { @Test public void testResolveTracer() throws Exception { - Field tracerField = GlobalTracer.class.getDeclaredField("tracer"); + final Field tracerField = GlobalTracer.class.getDeclaredField("tracer"); tracerField.setAccessible(true); tracerField.set(null, NoopTracerFactory.create()); assertThat(GlobalTracer.isRegistered()).isFalse(); - Tracer tracer = TracerResolver.resolveTracer(); + final Tracer tracer = TracerResolver.resolveTracer(); assertThat(GlobalTracer.isRegistered()).isFalse(); assertThat(tracer).isInstanceOf(DDTracer.class); @@ -58,7 +57,7 @@ public class TracerResolverTest { @Test public void testRegisterTracer() throws Exception { - Field tracerField = GlobalTracer.class.getDeclaredField("tracer"); + final Field tracerField = GlobalTracer.class.getDeclaredField("tracer"); tracerField.setAccessible(true); tracerField.set(null, NoopTracerFactory.create()); From 63cca28fe7165d83aa03b6d1fb7413ff27c6a525 Mon Sep 17 00:00:00 2001 From: Guillaume Polaert Date: Fri, 28 Jul 2017 11:46:04 +0200 Subject: [PATCH 2/4] [core] override operation name using decorators --- ...{DBComponent.java => DBTypeDecorator.java} | 6 +- .../integration/DDSpanContextDecorator.java | 71 ------------------- .../trace/integration/OperationDecorator.java | 43 +++++++++++ .../main/resources/dd-trace-decorators.yaml | 3 +- .../integration/SpanDecoratorTest.groovy | 43 ++++++++++- 5 files changed, 90 insertions(+), 76 deletions(-) rename dd-trace/src/main/java/com/datadoghq/trace/integration/{DBComponent.java => DBTypeDecorator.java} (78%) delete mode 100644 dd-trace/src/main/java/com/datadoghq/trace/integration/DDSpanContextDecorator.java create mode 100644 dd-trace/src/main/java/com/datadoghq/trace/integration/OperationDecorator.java diff --git a/dd-trace/src/main/java/com/datadoghq/trace/integration/DBComponent.java b/dd-trace/src/main/java/com/datadoghq/trace/integration/DBTypeDecorator.java similarity index 78% rename from dd-trace/src/main/java/com/datadoghq/trace/integration/DBComponent.java rename to dd-trace/src/main/java/com/datadoghq/trace/integration/DBTypeDecorator.java index a26f7a7f2e..ec6782fd86 100644 --- a/dd-trace/src/main/java/com/datadoghq/trace/integration/DBComponent.java +++ b/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; diff --git a/dd-trace/src/main/java/com/datadoghq/trace/integration/DDSpanContextDecorator.java b/dd-trace/src/main/java/com/datadoghq/trace/integration/DDSpanContextDecorator.java deleted file mode 100644 index f43aded971..0000000000 --- a/dd-trace/src/main/java/com/datadoghq/trace/integration/DDSpanContextDecorator.java +++ /dev/null @@ -1,71 +0,0 @@ -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; - } -} diff --git a/dd-trace/src/main/java/com/datadoghq/trace/integration/OperationDecorator.java b/dd-trace/src/main/java/com/datadoghq/trace/integration/OperationDecorator.java new file mode 100644 index 0000000000..72ff05e703 --- /dev/null +++ b/dd-trace/src/main/java/com/datadoghq/trace/integration/OperationDecorator.java @@ -0,0 +1,43 @@ +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 MAPPINGS = + new HashMap() { + { + // 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; + } +} diff --git a/dd-trace/src/main/resources/dd-trace-decorators.yaml b/dd-trace/src/main/resources/dd-trace-decorators.yaml index a463da61f1..c06b531132 100644 --- a/dd-trace/src/main/resources/dd-trace-decorators.yaml +++ b/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 diff --git a/dd-trace/src/test/groovy/com/datadoghq/trace/integration/SpanDecoratorTest.groovy b/dd-trace/src/test/groovy/com/datadoghq/trace/integration/SpanDecoratorTest.groovy index 8efaf390c7..5e39b5d4d8 100644 --- a/dd-trace/src/test/groovy/com/datadoghq/trace/integration/SpanDecoratorTest.groovy +++ b/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" + + + } } From 2f22b98cd17951e18f338d9418b213f6e8a144f6 Mon Sep 17 00:00:00 2001 From: Guillaume Polaert Date: Fri, 28 Jul 2017 11:54:22 +0200 Subject: [PATCH 3/4] [core] adding the decorator to the agent loading --- .../DBStatementAsResourceName.java | 31 ------------------- .../main/resources/dd-trace-decorators.yaml | 3 +- 2 files changed, 2 insertions(+), 32 deletions(-) diff --git a/dd-trace/src/main/java/com/datadoghq/trace/integration/DBStatementAsResourceName.java b/dd-trace/src/main/java/com/datadoghq/trace/integration/DBStatementAsResourceName.java index 862fb3cc8d..84b10db48b 100644 --- a/dd-trace/src/main/java/com/datadoghq/trace/integration/DBStatementAsResourceName.java +++ b/dd-trace/src/main/java/com/datadoghq/trace/integration/DBStatementAsResourceName.java @@ -10,35 +10,4 @@ public class DBStatementAsResourceName extends AbstractDecorator { this.setMatchingTag(Tags.DB_STATEMENT.getKey()); this.setSetTag(DDTags.RESOURCE_NAME); } - - //{ "insert" : "calls", "ordered" : true, "documents" : [{ "_id" : { "$oid" : "5979bbb0ed6fed5749cc9e7c" }, "name" : "MongoDB", "type" : "database", "identifier" : "10", "versions" : ["v3.2", "v3.0", "v2.6"], "info" : { "x" : 203, "y" : 102 } }] } - private void normalizeFilter(final Object f) {} } - - /* - def normalize_filter(f=None): - if f is None: - return {} - elif isinstance(f, list): - # normalize lists of filters - # e.g. {$or: [ { age: { $lt: 30 } }, { type: 1 } ]} - return [normalize_filter(s) for s in f] - elif isinstance(f, dict): - # normalize dicts of filters - # {$or: [ { age: { $lt: 30 } }, { type: 1 } ]}) - out = {} - for k, v in iteritems(f): - if k == "$in" or k == "$nin": - # special case $in queries so we don't loop over lists. - out[k] = "?" - elif isinstance(v, list) or isinstance(v, dict): - # RECURSION ALERT: needs to move to the agent - out[k] = normalize_filter(v) - else: - # NOTE: this shouldn't happen, but let's have a safeguard. - out[k] = '?' - return out - else: - # FIXME[matt] unexpected type. not sure this should ever happen, but at - # least it won't crash. - return {}*/ diff --git a/dd-trace/src/main/resources/dd-trace-decorators.yaml b/dd-trace/src/main/resources/dd-trace-decorators.yaml index c06b531132..5067f8aafb 100644 --- a/dd-trace/src/main/resources/dd-trace-decorators.yaml +++ b/dd-trace/src/main/resources/dd-trace-decorators.yaml @@ -4,8 +4,9 @@ decorators: - type: HTTPComponent matchingValue: java-okhttp setValue: http-client - - type: BDTypeDecorator - type: HTTPComponent matchingValue: java-aws-sdk setValue: aws-client - type: ErrorFlag + - type: DBTypeDecorator + - type: OperationDecorator From e236f44b122429261628d75206897d287249aaee Mon Sep 17 00:00:00 2001 From: Emanuele Palazzetti Date: Tue, 1 Aug 2017 11:46:50 +0200 Subject: [PATCH 4/4] [mongo] update the db.statement tag to use the quantized query --- .../datadoghq/trace/agent/integration/MongoHelper.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/dd-java-agent/src/main/java/com/datadoghq/trace/agent/integration/MongoHelper.java b/dd-java-agent/src/main/java/com/datadoghq/trace/agent/integration/MongoHelper.java index 1d9bcf21e0..f965823ca6 100644 --- a/dd-java-agent/src/main/java/com/datadoghq/trace/agent/integration/MongoHelper.java +++ b/dd-java-agent/src/main/java/com/datadoghq/trace/agent/integration/MongoHelper.java @@ -5,6 +5,7 @@ import com.mongodb.MongoClientOptions; import com.mongodb.event.CommandStartedEvent; import io.opentracing.Span; import io.opentracing.contrib.mongo.TracingCommandListener; +import io.opentracing.tag.Tags; import java.util.Arrays; import java.util.List; import java.util.Map; @@ -50,8 +51,14 @@ public class MongoHelper extends DDAgentTracingHelper