diff --git a/dd-trace-api/src/main/java/datadog/trace/api/Config.java b/dd-trace-api/src/main/java/datadog/trace/api/Config.java index 856516cf35..5ad4842782 100644 --- a/dd-trace-api/src/main/java/datadog/trace/api/Config.java +++ b/dd-trace-api/src/main/java/datadog/trace/api/Config.java @@ -596,6 +596,10 @@ public class Config { return jmxFetchIntegrationEnabled(integrationNames, defaultEnabled); } + public boolean isDecoratorEnabled(final String name) { + return getBooleanSettingFromEnvironment("trace." + name.toLowerCase() + ".enabled", true); + } + /** * @deprecated This method should only be used internally. Use the instance getter instead {@link * #isJmxFetchIntegrationEnabled(SortedSet, boolean)}. diff --git a/dd-trace-ot/src/main/java/datadog/opentracing/decorators/DDDecoratorsFactory.java b/dd-trace-ot/src/main/java/datadog/opentracing/decorators/DDDecoratorsFactory.java index b46d355952..e4880cffa5 100644 --- a/dd-trace-ot/src/main/java/datadog/opentracing/decorators/DDDecoratorsFactory.java +++ b/dd-trace-ot/src/main/java/datadog/opentracing/decorators/DDDecoratorsFactory.java @@ -4,31 +4,44 @@ import datadog.trace.api.Config; import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import lombok.extern.slf4j.Slf4j; /** Create DDSpanDecorators */ +@Slf4j public class DDDecoratorsFactory { public static List createBuiltinDecorators() { - final List decorators = - new ArrayList<>( - Arrays.asList( - new AnalyticsSampleRateDecorator(), - new DBStatementAsResourceName(), - new DBTypeDecorator(), - new ErrorFlag(), - new ForceManualDropDecorator(), - new ForceManualKeepDecorator(), - new OperationDecorator(), - new PeerServiceDecorator(), - new ResourceNameDecorator(), - new ServiceNameDecorator(), - new ServiceNameDecorator("service", false), - new ServletContextDecorator(), - new SpanTypeDecorator(), - new Status404Decorator(), - new Status5XXDecorator(), - new URLAsResourceName())); + final List decorators = new ArrayList<>(); + for (final AbstractDecorator decorator : + Arrays.asList( + new AnalyticsSampleRateDecorator(), + new DBStatementAsResourceName(), + new DBTypeDecorator(), + new ErrorFlag(), + new ForceManualDropDecorator(), + new ForceManualKeepDecorator(), + new OperationDecorator(), + new PeerServiceDecorator(), + new ResourceNameDecorator(), + new ServiceNameDecorator(), + new ServiceNameDecorator("service", false), + new ServletContextDecorator(), + new SpanTypeDecorator(), + new Status404Decorator(), + new Status5XXDecorator(), + new URLAsResourceName())) { + + if (Config.get().isDecoratorEnabled(decorator.getClass().getSimpleName())) { + decorators.add(decorator); + } else { + log.debug("{} disabled", decorator.getClass().getSimpleName()); + } + } + + // SplitByTags purposely does not check for ServiceNameDecorator being enabled + // This allows for ServiceNameDecorator to be disabled above while keeping SplitByTags + // SplitByTags can be disable by removing SplitByTags config for (final String splitByTag : Config.get().getSplitByTags()) { decorators.add(new ServiceNameDecorator(splitByTag, true)); } diff --git a/dd-trace-ot/src/test/groovy/datadog/opentracing/decorators/SpanDecoratorTest.groovy b/dd-trace-ot/src/test/groovy/datadog/opentracing/decorators/SpanDecoratorTest.groovy index 64bffaeed7..f1386e4154 100644 --- a/dd-trace-ot/src/test/groovy/datadog/opentracing/decorators/SpanDecoratorTest.groovy +++ b/dd-trace-ot/src/test/groovy/datadog/opentracing/decorators/SpanDecoratorTest.groovy @@ -470,4 +470,72 @@ class SpanDecoratorTest extends DDSpecification { then: span.resourceName == "some-statement" } + + def "disable decorator via config"() { + setup: + ConfigUtils.updateConfig { + System.setProperty("dd.trace." + PeerServiceDecorator.getSimpleName().toLowerCase() + ".enabled", "false") + } + + tracer = new DDTracer( + "some-service", + new LoggingWriter(), + new AllSampler(), + "some-runtime-id", + emptyMap(), + emptyMap(), + emptyMap(), + emptyMap() + ) + + when: + def span = tracer.buildSpan("some span").withTag(Tags.PEER_SERVICE.key, "peer-service").start() + span.finish() + + then: + span.getServiceName() == "some-service" + + cleanup: + ConfigUtils.updateConfig { + System.clearProperty("dd.trace." + PeerServiceDecorator.getSimpleName().toLowerCase() + ".enabled") + } + } + + def "disabling service decorator does not disable split by tags"() { + setup: + ConfigUtils.updateConfig { + System.setProperty("dd.trace." + ServiceNameDecorator.getSimpleName().toLowerCase() + ".enabled", "false") + } + + tracer = new DDTracer( + "some-service", + new LoggingWriter(), + new AllSampler(), + "some-runtime-id", + emptyMap(), + emptyMap(), + emptyMap(), + emptyMap() + ) + + when: + def span = tracer.buildSpan("some span").withTag(tag, name).start() + span.finish() + + then: + span.getServiceName() == expected + + cleanup: + ConfigUtils.updateConfig { + System.clearProperty("dd.trace." + ServiceNameDecorator.getSimpleName().toLowerCase() + ".enabled") + } + + where: + tag | name | expected + DDTags.SERVICE_NAME | "new-service" | "some-service" + "service" | "new-service" | "some-service" + "sn.tag1" | "new-service" | "new-service" + + + } }