Merge pull request #975 from DataDog/tyler/split-by-tag

Add new setting to allow renaming service by tag
This commit is contained in:
Tyler Benson 2019-09-05 14:24:20 -07:00 committed by GitHub
commit df017e044a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 150 additions and 50 deletions

View File

@ -33,6 +33,7 @@ public abstract class DatabaseClientDecorator<CONNECTION> extends ClientDecorato
Tags.DB_USER.set(span, dbUser(connection));
final String instanceName = dbInstance(connection);
Tags.DB_INSTANCE.set(span, instanceName);
if (instanceName != null && Config.get().isDbClientSplitByInstance()) {
span.setTag(DDTags.SERVICE_NAME, instanceName);
}

View File

@ -8,6 +8,7 @@ import java.io.IOException;
import java.io.InputStreamReader;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
@ -71,6 +72,7 @@ public class Config {
public static final String HTTP_CLIENT_TAG_QUERY_STRING = "http.client.tag.query-string";
public static final String HTTP_CLIENT_HOST_SPLIT_BY_DOMAIN = "trace.http.client.split-by-domain";
public static final String DB_CLIENT_HOST_SPLIT_BY_INSTANCE = "trace.db.client.split-by-instance";
public static final String SPLIT_BY_TAGS = "trace.split-by-tags";
public static final String PARTIAL_FLUSH_MIN_SPANS = "trace.partial.flush.min.spans";
public static final String RUNTIME_CONTEXT_FIELD_INJECTION =
"trace.runtime.context.field.injection";
@ -116,6 +118,7 @@ public class Config {
private static final boolean DEFAULT_HTTP_CLIENT_TAG_QUERY_STRING = false;
private static final boolean DEFAULT_HTTP_CLIENT_SPLIT_BY_DOMAIN = false;
private static final boolean DEFAULT_DB_CLIENT_HOST_SPLIT_BY_INSTANCE = false;
private static final String DEFAULT_SPLIT_BY_TAGS = "";
private static final int DEFAULT_PARTIAL_FLUSH_MIN_SPANS = 1000;
private static final String DEFAULT_PROPAGATION_STYLE_EXTRACT = PropagationStyle.DATADOG.name();
private static final String DEFAULT_PROPAGATION_STYLE_INJECT = PropagationStyle.DATADOG.name();
@ -171,6 +174,7 @@ public class Config {
@Getter private final boolean httpClientTagQueryString;
@Getter private final boolean httpClientSplitByDomain;
@Getter private final boolean dbClientSplitByInstance;
@Getter private final Set<String> splitByTags;
@Getter private final Integer partialFlushMinSpans;
@Getter private final boolean runtimeContextFieldInjection;
@Getter private final Set<PropagationStyle> propagationStylesToExtract;
@ -258,6 +262,11 @@ public class Config {
getBooleanSettingFromEnvironment(
DB_CLIENT_HOST_SPLIT_BY_INSTANCE, DEFAULT_DB_CLIENT_HOST_SPLIT_BY_INSTANCE);
splitByTags =
Collections.unmodifiableSet(
new LinkedHashSet<>(
getListSettingFromEnvironment(SPLIT_BY_TAGS, DEFAULT_SPLIT_BY_TAGS)));
partialFlushMinSpans =
getIntegerSettingFromEnvironment(PARTIAL_FLUSH_MIN_SPANS, DEFAULT_PARTIAL_FLUSH_MIN_SPANS);
@ -366,6 +375,12 @@ public class Config {
getPropertyBooleanValue(
properties, DB_CLIENT_HOST_SPLIT_BY_INSTANCE, parent.dbClientSplitByInstance);
splitByTags =
Collections.unmodifiableSet(
new LinkedHashSet<>(
getPropertyListValue(
properties, SPLIT_BY_TAGS, new ArrayList<>(parent.splitByTags))));
partialFlushMinSpans =
getPropertyIntegerValue(properties, PARTIAL_FLUSH_MIN_SPANS, parent.partialFlushMinSpans);
@ -850,6 +865,10 @@ public class Config {
}
final String[] tokens = str.split(",", -1);
// Remove whitespace from each item.
for (int i = 0; i < tokens.length; i++) {
tokens[i] = tokens[i].trim();
}
return Collections.unmodifiableList(Arrays.asList(tokens));
}

View File

@ -34,6 +34,7 @@ import static datadog.trace.api.Config.SERVICE
import static datadog.trace.api.Config.SERVICE_MAPPING
import static datadog.trace.api.Config.SERVICE_NAME
import static datadog.trace.api.Config.SPAN_TAGS
import static datadog.trace.api.Config.SPLIT_BY_TAGS
import static datadog.trace.api.Config.TRACE_AGENT_PORT
import static datadog.trace.api.Config.TRACE_ENABLED
import static datadog.trace.api.Config.TRACE_REPORT_HOSTNAME
@ -80,6 +81,7 @@ class ConfigTest extends Specification {
config.httpClientErrorStatuses == (400..499).toSet()
config.httpClientSplitByDomain == false
config.dbClientSplitByInstance == false
config.splitByTags == [].toSet()
config.partialFlushMinSpans == 1000
config.reportHostName == false
config.runtimeContextFieldInjection == true
@ -122,6 +124,7 @@ class ConfigTest extends Specification {
prop.setProperty(HTTP_CLIENT_ERROR_STATUSES, "111")
prop.setProperty(HTTP_CLIENT_HOST_SPLIT_BY_DOMAIN, "true")
prop.setProperty(DB_CLIENT_HOST_SPLIT_BY_INSTANCE, "true")
prop.setProperty(SPLIT_BY_TAGS, "some.tag1,some.tag2,some.tag1")
prop.setProperty(PARTIAL_FLUSH_MIN_SPANS, "15")
prop.setProperty(TRACE_REPORT_HOSTNAME, "true")
prop.setProperty(RUNTIME_CONTEXT_FIELD_INJECTION, "false")
@ -154,6 +157,7 @@ class ConfigTest extends Specification {
config.httpClientErrorStatuses == (111..111).toSet()
config.httpClientSplitByDomain == true
config.dbClientSplitByInstance == true
config.splitByTags == ["some.tag1", "some.tag2"].toSet()
config.partialFlushMinSpans == 15
config.reportHostName == true
config.runtimeContextFieldInjection == false
@ -187,6 +191,7 @@ class ConfigTest extends Specification {
System.setProperty(PREFIX + HTTP_CLIENT_ERROR_STATUSES, "111")
System.setProperty(PREFIX + HTTP_CLIENT_HOST_SPLIT_BY_DOMAIN, "true")
System.setProperty(PREFIX + DB_CLIENT_HOST_SPLIT_BY_INSTANCE, "true")
System.setProperty(PREFIX + SPLIT_BY_TAGS, "some.tag3, some.tag2, some.tag1")
System.setProperty(PREFIX + PARTIAL_FLUSH_MIN_SPANS, "25")
System.setProperty(PREFIX + TRACE_REPORT_HOSTNAME, "true")
System.setProperty(PREFIX + RUNTIME_CONTEXT_FIELD_INJECTION, "false")
@ -219,6 +224,7 @@ class ConfigTest extends Specification {
config.httpClientErrorStatuses == (111..111).toSet()
config.httpClientSplitByDomain == true
config.dbClientSplitByInstance == true
config.splitByTags == ["some.tag3", "some.tag2", "some.tag1"].toSet()
config.partialFlushMinSpans == 25
config.reportHostName == true
config.runtimeContextFieldInjection == false
@ -314,6 +320,7 @@ class ConfigTest extends Specification {
config.httpClientErrorStatuses == (400..499).toSet()
config.httpClientSplitByDomain == false
config.dbClientSplitByInstance == false
config.splitByTags == [].toSet()
config.propagationStylesToExtract.toList() == [Config.PropagationStyle.DATADOG]
config.propagationStylesToInject.toList() == [Config.PropagationStyle.DATADOG]
}
@ -409,6 +416,7 @@ class ConfigTest extends Specification {
config.httpClientErrorStatuses == (111..111).toSet()
config.httpClientSplitByDomain == true
config.dbClientSplitByInstance == true
config.splitByTags == [].toSet()
config.partialFlushMinSpans == 15
config.propagationStylesToExtract.toList() == [Config.PropagationStyle.B3, Config.PropagationStyle.DATADOG]
config.propagationStylesToInject.toList() == [Config.PropagationStyle.DATADOG, Config.PropagationStyle.B3]

View File

@ -1,5 +1,7 @@
package datadog.opentracing.decorators;
import datadog.trace.api.Config;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@ -7,7 +9,9 @@ import java.util.List;
public class DDDecoratorsFactory {
public static List<AbstractDecorator> createBuiltinDecorators() {
return Arrays.asList(
final List<AbstractDecorator> decorators =
new ArrayList<>(
Arrays.asList(
new AnalyticsSampleRateDecorator(),
new DBStatementAsResourceName(),
new DBTypeDecorator(),
@ -17,12 +21,18 @@ public class DDDecoratorsFactory {
new OperationDecorator(),
new PeerServiceDecorator(),
new ResourceNameDecorator(),
new ServiceDecorator(),
new ServiceNameDecorator(),
new ServiceNameDecorator("service", false),
new ServletContextDecorator(),
new SpanTypeDecorator(),
new Status404Decorator(),
new Status5XXDecorator(),
new URLAsResourceName());
new URLAsResourceName()));
for (final String splitByTag : Config.get().getSplitByTags()) {
decorators.add(new ServiceNameDecorator(splitByTag, true));
}
return decorators;
}
}

View File

@ -1,17 +0,0 @@
package datadog.opentracing.decorators;
import datadog.opentracing.DDSpanContext;
public class ServiceDecorator extends AbstractDecorator {
public ServiceDecorator() {
super();
this.setMatchingTag("service"); // will be added to a future OT version.
}
@Override
public boolean shouldSetTag(final DDSpanContext context, final String tag, final Object value) {
context.setServiceName(String.valueOf(value));
return false;
}
}

View File

@ -5,14 +5,21 @@ import datadog.trace.api.DDTags;
public class ServiceNameDecorator extends AbstractDecorator {
private final boolean setTag;
public ServiceNameDecorator() {
this(DDTags.SERVICE_NAME, false);
}
public ServiceNameDecorator(final String splitByTag, final boolean setTag) {
super();
this.setMatchingTag(DDTags.SERVICE_NAME);
this.setTag = setTag;
setMatchingTag(splitByTag);
}
@Override
public boolean shouldSetTag(final DDSpanContext context, final String tag, final Object value) {
context.setServiceName(String.valueOf(value));
return false;
return setTag;
}
}

View File

@ -2,6 +2,7 @@ package datadog.opentracing
import datadog.opentracing.propagation.ExtractedContext
import datadog.opentracing.propagation.TagContext
import datadog.trace.agent.test.utils.ConfigUtils
import datadog.trace.api.Config
import datadog.trace.api.DDTags
import datadog.trace.api.sampling.PrioritySampling
@ -16,6 +17,10 @@ import static org.mockito.Mockito.mock
import static org.mockito.Mockito.when
class DDSpanBuilderTest extends Specification {
static {
ConfigUtils.makeConfigInstanceModifiable()
}
def writer = new ListWriter()
def config = Config.get()
def tracer = new DDTracer(writer)

View File

@ -3,6 +3,7 @@ package datadog.opentracing
import com.fasterxml.jackson.databind.ObjectMapper
import com.google.common.collect.Maps
import datadog.trace.agent.test.utils.ConfigUtils
import datadog.trace.api.DDTags
import datadog.trace.api.sampling.PrioritySampling
import datadog.trace.common.writer.ListWriter
@ -13,6 +14,9 @@ import org.msgpack.value.ValueType
import spock.lang.Specification
class DDSpanSerializationTest extends Specification {
static {
ConfigUtils.makeConfigInstanceModifiable()
}
def "serialize spans with sampling #samplingPriority"() throws Exception {
setup:

View File

@ -2,6 +2,7 @@ package datadog.opentracing
import datadog.opentracing.propagation.ExtractedContext
import datadog.opentracing.propagation.TagContext
import datadog.trace.agent.test.utils.ConfigUtils
import datadog.trace.api.sampling.PrioritySampling
import datadog.trace.common.sampling.RateByServiceSampler
import datadog.trace.common.writer.ListWriter
@ -14,6 +15,10 @@ import java.util.concurrent.TimeUnit
import static datadog.trace.api.Config.DEFAULT_SERVICE_NAME
class DDSpanTest extends Specification {
static {
ConfigUtils.makeConfigInstanceModifiable()
}
def writer = new ListWriter()
def tracer = new DDTracer(DEFAULT_SERVICE_NAME, writer, new RateByServiceSampler(), [:])

View File

@ -1,5 +1,6 @@
package datadog.opentracing
import datadog.trace.agent.test.utils.ConfigUtils
import datadog.trace.api.Config
import datadog.trace.common.writer.ListWriter
import datadog.trace.util.gc.GCUtils
@ -14,6 +15,10 @@ import java.util.concurrent.atomic.AtomicInteger
import static datadog.trace.api.Config.PARTIAL_FLUSH_MIN_SPANS
class PendingTraceTest extends Specification {
static {
ConfigUtils.makeConfigInstanceModifiable()
}
def traceCount = new AtomicInteger()
def writer = new ListWriter() {
@Override

View File

@ -1,9 +1,14 @@
package datadog.opentracing
import datadog.trace.agent.test.utils.ConfigUtils
import datadog.trace.api.sampling.PrioritySampling
import datadog.trace.common.writer.ListWriter
class SpanFactory {
static {
ConfigUtils.makeConfigInstanceModifiable()
}
static newSpanOf(long timestampMicro, String threadName = Thread.currentThread().name) {
def writer = new ListWriter()
def tracer = new DDTracer(writer)

View File

@ -1,10 +1,14 @@
package datadog.opentracing
import datadog.trace.agent.test.utils.ConfigUtils
import datadog.trace.common.writer.ListWriter
import spock.lang.Shared
import spock.lang.Specification
class TraceCorrelationTest extends Specification {
static {
ConfigUtils.makeConfigInstanceModifiable()
}
static final WRITER = new ListWriter()

View File

@ -1,5 +1,6 @@
package datadog.opentracing
import datadog.trace.agent.test.utils.ConfigUtils
import datadog.trace.api.GlobalTracer
import datadog.trace.api.interceptor.MutableSpan
import datadog.trace.api.interceptor.TraceInterceptor
@ -9,6 +10,10 @@ import spock.lang.Specification
import java.util.concurrent.atomic.AtomicBoolean
class TraceInterceptorTest extends Specification {
static {
ConfigUtils.makeConfigInstanceModifiable()
}
def writer = new ListWriter()
def tracer = new DDTracer(writer)

View File

@ -3,6 +3,8 @@ package datadog.opentracing.decorators
import datadog.opentracing.DDSpanContext
import datadog.opentracing.DDTracer
import datadog.opentracing.SpanFactory
import datadog.trace.agent.test.utils.ConfigUtils
import datadog.trace.api.Config
import datadog.trace.api.DDSpanTypes
import datadog.trace.api.DDTags
import datadog.trace.common.sampling.AllSampler
@ -16,14 +18,23 @@ import static datadog.trace.api.DDTags.EVENT_SAMPLE_RATE
import static java.util.Collections.emptyMap
class SpanDecoratorTest extends Specification {
static {
ConfigUtils.updateConfig {
System.setProperty("dd.$Config.SPLIT_BY_TAGS", "sn.tag1,sn.tag2")
}
}
def cleanupSpec() {
ConfigUtils.updateConfig {
System.clearProperty("dd.$Config.SPLIT_BY_TAGS")
}
}
def tracer = new DDTracer(new LoggingWriter())
def span = SpanFactory.newSpanOf(tracer)
def "adding span personalisation using Decorators"() {
setup:
def decorator = new AbstractDecorator() {
@Override
boolean shouldSetTag(DDSpanContext context, String tag, Object value) {
return super.shouldSetTag(context, tag, value)
}
@ -69,6 +80,10 @@ class SpanDecoratorTest extends Specification {
"service" | "other-service" | "other-service"
Tags.PEER_SERVICE.key | "some-service" | "new-service"
Tags.PEER_SERVICE.key | "other-service" | "other-service"
"sn.tag1" | "some-service" | "new-service"
"sn.tag1" | "other-service" | "other-service"
"sn.tag2" | "some-service" | "new-service"
"sn.tag2" | "other-service" | "other-service"
mapping = ["some-service": "new-service"]
}
@ -310,7 +325,13 @@ class SpanDecoratorTest extends Specification {
def "decorators apply to builder too"() {
when:
def span = tracer.buildSpan("decorator.test").withTag("servlet.context", "/my-servlet").start()
def span = tracer.buildSpan("decorator.test").withTag("sn.tag1", "some val").start()
then:
span.serviceName == "some val"
when:
span = tracer.buildSpan("decorator.test").withTag("servlet.context", "/my-servlet").start()
then:
span.serviceName == "my-servlet"

View File

@ -3,6 +3,7 @@ package datadog.opentracing.decorators
import datadog.opentracing.DDSpanContext
import datadog.opentracing.DDTracer
import datadog.opentracing.PendingTrace
import datadog.trace.agent.test.utils.ConfigUtils
import datadog.trace.api.sampling.PrioritySampling
import datadog.trace.common.writer.ListWriter
import io.opentracing.tag.Tags
@ -10,6 +11,10 @@ import spock.lang.Specification
import spock.lang.Subject
class URLAsResourceNameTest extends Specification {
static {
ConfigUtils.makeConfigInstanceModifiable()
}
def writer = new ListWriter()
def tracer = new DDTracer(writer)

View File

@ -1,11 +1,15 @@
package datadog.opentracing.resolver
import datadog.opentracing.DDTracer
import datadog.trace.agent.test.utils.ConfigUtils
import datadog.trace.api.Config
import io.opentracing.contrib.tracerresolver.TracerResolver
import spock.lang.Specification
class DDTracerResolverTest extends Specification {
static {
ConfigUtils.makeConfigInstanceModifiable()
}
def resolver = new DDTracerResolver()

View File

@ -3,6 +3,7 @@ package datadog.opentracing.scopemanager
import datadog.opentracing.DDSpan
import datadog.opentracing.DDSpanContext
import datadog.opentracing.DDTracer
import datadog.trace.agent.test.utils.ConfigUtils
import datadog.trace.common.writer.ListWriter
import datadog.trace.context.ScopeListener
import datadog.trace.util.gc.GCUtils
@ -22,6 +23,9 @@ import java.util.concurrent.atomic.AtomicReference
import static java.util.concurrent.TimeUnit.SECONDS
class ScopeManagerTest extends Specification {
static {
ConfigUtils.makeConfigInstanceModifiable()
}
def latch
def writer
def tracer

View File

@ -2,6 +2,7 @@ package datadog.trace
import datadog.opentracing.DDTracer
import datadog.opentracing.propagation.HttpCodec
import datadog.trace.agent.test.utils.ConfigUtils
import datadog.trace.api.Config
import datadog.trace.common.sampling.AllSampler
import datadog.trace.common.sampling.RateByServiceSampler
@ -22,6 +23,10 @@ import static datadog.trace.api.Config.SPAN_TAGS
import static datadog.trace.api.Config.WRITER_TYPE
class DDTracerTest extends Specification {
static {
ConfigUtils.makeConfigInstanceModifiable()
}
@Rule
public final RestoreSystemProperties restoreSystemProperties = new RestoreSystemProperties()
@Rule