Skip to content

Commit df017e0

Browse files
authored
Merge pull request DataDog#975 from DataDog/tyler/split-by-tag
Add new setting to allow renaming service by tag
2 parents 2e5766e + 8177b95 commit df017e0

18 files changed

Lines changed: 150 additions & 50 deletions

File tree

dd-java-agent/agent-tooling/src/main/java/datadog/trace/agent/decorator/DatabaseClientDecorator.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ public Span onConnection(final Span span, final CONNECTION connection) {
3333
Tags.DB_USER.set(span, dbUser(connection));
3434
final String instanceName = dbInstance(connection);
3535
Tags.DB_INSTANCE.set(span, instanceName);
36+
3637
if (instanceName != null && Config.get().isDbClientSplitByInstance()) {
3738
span.setTag(DDTags.SERVICE_NAME, instanceName);
3839
}

dd-trace-api/src/main/java/datadog/trace/api/Config.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import java.io.InputStreamReader;
99
import java.net.InetAddress;
1010
import java.net.UnknownHostException;
11+
import java.util.ArrayList;
1112
import java.util.Arrays;
1213
import java.util.Collections;
1314
import java.util.HashMap;
@@ -71,6 +72,7 @@ public class Config {
7172
public static final String HTTP_CLIENT_TAG_QUERY_STRING = "http.client.tag.query-string";
7273
public static final String HTTP_CLIENT_HOST_SPLIT_BY_DOMAIN = "trace.http.client.split-by-domain";
7374
public static final String DB_CLIENT_HOST_SPLIT_BY_INSTANCE = "trace.db.client.split-by-instance";
75+
public static final String SPLIT_BY_TAGS = "trace.split-by-tags";
7476
public static final String PARTIAL_FLUSH_MIN_SPANS = "trace.partial.flush.min.spans";
7577
public static final String RUNTIME_CONTEXT_FIELD_INJECTION =
7678
"trace.runtime.context.field.injection";
@@ -116,6 +118,7 @@ public class Config {
116118
private static final boolean DEFAULT_HTTP_CLIENT_TAG_QUERY_STRING = false;
117119
private static final boolean DEFAULT_HTTP_CLIENT_SPLIT_BY_DOMAIN = false;
118120
private static final boolean DEFAULT_DB_CLIENT_HOST_SPLIT_BY_INSTANCE = false;
121+
private static final String DEFAULT_SPLIT_BY_TAGS = "";
119122
private static final int DEFAULT_PARTIAL_FLUSH_MIN_SPANS = 1000;
120123
private static final String DEFAULT_PROPAGATION_STYLE_EXTRACT = PropagationStyle.DATADOG.name();
121124
private static final String DEFAULT_PROPAGATION_STYLE_INJECT = PropagationStyle.DATADOG.name();
@@ -171,6 +174,7 @@ public enum PropagationStyle {
171174
@Getter private final boolean httpClientTagQueryString;
172175
@Getter private final boolean httpClientSplitByDomain;
173176
@Getter private final boolean dbClientSplitByInstance;
177+
@Getter private final Set<String> splitByTags;
174178
@Getter private final Integer partialFlushMinSpans;
175179
@Getter private final boolean runtimeContextFieldInjection;
176180
@Getter private final Set<PropagationStyle> propagationStylesToExtract;
@@ -258,6 +262,11 @@ public enum PropagationStyle {
258262
getBooleanSettingFromEnvironment(
259263
DB_CLIENT_HOST_SPLIT_BY_INSTANCE, DEFAULT_DB_CLIENT_HOST_SPLIT_BY_INSTANCE);
260264

265+
splitByTags =
266+
Collections.unmodifiableSet(
267+
new LinkedHashSet<>(
268+
getListSettingFromEnvironment(SPLIT_BY_TAGS, DEFAULT_SPLIT_BY_TAGS)));
269+
261270
partialFlushMinSpans =
262271
getIntegerSettingFromEnvironment(PARTIAL_FLUSH_MIN_SPANS, DEFAULT_PARTIAL_FLUSH_MIN_SPANS);
263272

@@ -366,6 +375,12 @@ private Config(final Properties properties, final Config parent) {
366375
getPropertyBooleanValue(
367376
properties, DB_CLIENT_HOST_SPLIT_BY_INSTANCE, parent.dbClientSplitByInstance);
368377

378+
splitByTags =
379+
Collections.unmodifiableSet(
380+
new LinkedHashSet<>(
381+
getPropertyListValue(
382+
properties, SPLIT_BY_TAGS, new ArrayList<>(parent.splitByTags))));
383+
369384
partialFlushMinSpans =
370385
getPropertyIntegerValue(properties, PARTIAL_FLUSH_MIN_SPANS, parent.partialFlushMinSpans);
371386

@@ -850,6 +865,10 @@ private static List<String> parseList(final String str) {
850865
}
851866

852867
final String[] tokens = str.split(",", -1);
868+
// Remove whitespace from each item.
869+
for (int i = 0; i < tokens.length; i++) {
870+
tokens[i] = tokens[i].trim();
871+
}
853872
return Collections.unmodifiableList(Arrays.asList(tokens));
854873
}
855874

dd-trace-api/src/test/groovy/datadog/trace/api/ConfigTest.groovy

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ import static datadog.trace.api.Config.SERVICE
3434
import static datadog.trace.api.Config.SERVICE_MAPPING
3535
import static datadog.trace.api.Config.SERVICE_NAME
3636
import static datadog.trace.api.Config.SPAN_TAGS
37+
import static datadog.trace.api.Config.SPLIT_BY_TAGS
3738
import static datadog.trace.api.Config.TRACE_AGENT_PORT
3839
import static datadog.trace.api.Config.TRACE_ENABLED
3940
import static datadog.trace.api.Config.TRACE_REPORT_HOSTNAME
@@ -80,6 +81,7 @@ class ConfigTest extends Specification {
8081
config.httpClientErrorStatuses == (400..499).toSet()
8182
config.httpClientSplitByDomain == false
8283
config.dbClientSplitByInstance == false
84+
config.splitByTags == [].toSet()
8385
config.partialFlushMinSpans == 1000
8486
config.reportHostName == false
8587
config.runtimeContextFieldInjection == true
@@ -122,6 +124,7 @@ class ConfigTest extends Specification {
122124
prop.setProperty(HTTP_CLIENT_ERROR_STATUSES, "111")
123125
prop.setProperty(HTTP_CLIENT_HOST_SPLIT_BY_DOMAIN, "true")
124126
prop.setProperty(DB_CLIENT_HOST_SPLIT_BY_INSTANCE, "true")
127+
prop.setProperty(SPLIT_BY_TAGS, "some.tag1,some.tag2,some.tag1")
125128
prop.setProperty(PARTIAL_FLUSH_MIN_SPANS, "15")
126129
prop.setProperty(TRACE_REPORT_HOSTNAME, "true")
127130
prop.setProperty(RUNTIME_CONTEXT_FIELD_INJECTION, "false")
@@ -154,6 +157,7 @@ class ConfigTest extends Specification {
154157
config.httpClientErrorStatuses == (111..111).toSet()
155158
config.httpClientSplitByDomain == true
156159
config.dbClientSplitByInstance == true
160+
config.splitByTags == ["some.tag1", "some.tag2"].toSet()
157161
config.partialFlushMinSpans == 15
158162
config.reportHostName == true
159163
config.runtimeContextFieldInjection == false
@@ -187,6 +191,7 @@ class ConfigTest extends Specification {
187191
System.setProperty(PREFIX + HTTP_CLIENT_ERROR_STATUSES, "111")
188192
System.setProperty(PREFIX + HTTP_CLIENT_HOST_SPLIT_BY_DOMAIN, "true")
189193
System.setProperty(PREFIX + DB_CLIENT_HOST_SPLIT_BY_INSTANCE, "true")
194+
System.setProperty(PREFIX + SPLIT_BY_TAGS, "some.tag3, some.tag2, some.tag1")
190195
System.setProperty(PREFIX + PARTIAL_FLUSH_MIN_SPANS, "25")
191196
System.setProperty(PREFIX + TRACE_REPORT_HOSTNAME, "true")
192197
System.setProperty(PREFIX + RUNTIME_CONTEXT_FIELD_INJECTION, "false")
@@ -219,6 +224,7 @@ class ConfigTest extends Specification {
219224
config.httpClientErrorStatuses == (111..111).toSet()
220225
config.httpClientSplitByDomain == true
221226
config.dbClientSplitByInstance == true
227+
config.splitByTags == ["some.tag3", "some.tag2", "some.tag1"].toSet()
222228
config.partialFlushMinSpans == 25
223229
config.reportHostName == true
224230
config.runtimeContextFieldInjection == false
@@ -314,6 +320,7 @@ class ConfigTest extends Specification {
314320
config.httpClientErrorStatuses == (400..499).toSet()
315321
config.httpClientSplitByDomain == false
316322
config.dbClientSplitByInstance == false
323+
config.splitByTags == [].toSet()
317324
config.propagationStylesToExtract.toList() == [Config.PropagationStyle.DATADOG]
318325
config.propagationStylesToInject.toList() == [Config.PropagationStyle.DATADOG]
319326
}
@@ -409,6 +416,7 @@ class ConfigTest extends Specification {
409416
config.httpClientErrorStatuses == (111..111).toSet()
410417
config.httpClientSplitByDomain == true
411418
config.dbClientSplitByInstance == true
419+
config.splitByTags == [].toSet()
412420
config.partialFlushMinSpans == 15
413421
config.propagationStylesToExtract.toList() == [Config.PropagationStyle.B3, Config.PropagationStyle.DATADOG]
414422
config.propagationStylesToInject.toList() == [Config.PropagationStyle.DATADOG, Config.PropagationStyle.B3]
Lines changed: 27 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,38 @@
11
package datadog.opentracing.decorators;
22

3+
import datadog.trace.api.Config;
4+
import java.util.ArrayList;
35
import java.util.Arrays;
46
import java.util.List;
57

68
/** Create DDSpanDecorators */
79
public class DDDecoratorsFactory {
810
public static List<AbstractDecorator> createBuiltinDecorators() {
911

10-
return Arrays.asList(
11-
new AnalyticsSampleRateDecorator(),
12-
new DBStatementAsResourceName(),
13-
new DBTypeDecorator(),
14-
new ErrorFlag(),
15-
new ForceManualDropDecorator(),
16-
new ForceManualKeepDecorator(),
17-
new OperationDecorator(),
18-
new PeerServiceDecorator(),
19-
new ResourceNameDecorator(),
20-
new ServiceDecorator(),
21-
new ServiceNameDecorator(),
22-
new ServletContextDecorator(),
23-
new SpanTypeDecorator(),
24-
new Status404Decorator(),
25-
new Status5XXDecorator(),
26-
new URLAsResourceName());
12+
final List<AbstractDecorator> decorators =
13+
new ArrayList<>(
14+
Arrays.asList(
15+
new AnalyticsSampleRateDecorator(),
16+
new DBStatementAsResourceName(),
17+
new DBTypeDecorator(),
18+
new ErrorFlag(),
19+
new ForceManualDropDecorator(),
20+
new ForceManualKeepDecorator(),
21+
new OperationDecorator(),
22+
new PeerServiceDecorator(),
23+
new ResourceNameDecorator(),
24+
new ServiceNameDecorator(),
25+
new ServiceNameDecorator("service", false),
26+
new ServletContextDecorator(),
27+
new SpanTypeDecorator(),
28+
new Status404Decorator(),
29+
new Status5XXDecorator(),
30+
new URLAsResourceName()));
31+
32+
for (final String splitByTag : Config.get().getSplitByTags()) {
33+
decorators.add(new ServiceNameDecorator(splitByTag, true));
34+
}
35+
36+
return decorators;
2737
}
2838
}

dd-trace-ot/src/main/java/datadog/opentracing/decorators/ServiceDecorator.java

Lines changed: 0 additions & 17 deletions
This file was deleted.

dd-trace-ot/src/main/java/datadog/opentracing/decorators/ServiceNameDecorator.java

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,21 @@
55

66
public class ServiceNameDecorator extends AbstractDecorator {
77

8+
private final boolean setTag;
9+
810
public ServiceNameDecorator() {
11+
this(DDTags.SERVICE_NAME, false);
12+
}
13+
14+
public ServiceNameDecorator(final String splitByTag, final boolean setTag) {
915
super();
10-
this.setMatchingTag(DDTags.SERVICE_NAME);
16+
this.setTag = setTag;
17+
setMatchingTag(splitByTag);
1118
}
1219

1320
@Override
1421
public boolean shouldSetTag(final DDSpanContext context, final String tag, final Object value) {
1522
context.setServiceName(String.valueOf(value));
16-
return false;
23+
return setTag;
1724
}
1825
}

dd-trace-ot/src/test/groovy/datadog/opentracing/DDSpanBuilderTest.groovy

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package datadog.opentracing
22

33
import datadog.opentracing.propagation.ExtractedContext
44
import datadog.opentracing.propagation.TagContext
5+
import datadog.trace.agent.test.utils.ConfigUtils
56
import datadog.trace.api.Config
67
import datadog.trace.api.DDTags
78
import datadog.trace.api.sampling.PrioritySampling
@@ -16,6 +17,10 @@ import static org.mockito.Mockito.mock
1617
import static org.mockito.Mockito.when
1718

1819
class DDSpanBuilderTest extends Specification {
20+
static {
21+
ConfigUtils.makeConfigInstanceModifiable()
22+
}
23+
1924
def writer = new ListWriter()
2025
def config = Config.get()
2126
def tracer = new DDTracer(writer)

dd-trace-ot/src/test/groovy/datadog/opentracing/DDSpanSerializationTest.groovy

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package datadog.opentracing
33

44
import com.fasterxml.jackson.databind.ObjectMapper
55
import com.google.common.collect.Maps
6+
import datadog.trace.agent.test.utils.ConfigUtils
67
import datadog.trace.api.DDTags
78
import datadog.trace.api.sampling.PrioritySampling
89
import datadog.trace.common.writer.ListWriter
@@ -13,6 +14,9 @@ import org.msgpack.value.ValueType
1314
import spock.lang.Specification
1415

1516
class DDSpanSerializationTest extends Specification {
17+
static {
18+
ConfigUtils.makeConfigInstanceModifiable()
19+
}
1620

1721
def "serialize spans with sampling #samplingPriority"() throws Exception {
1822
setup:

dd-trace-ot/src/test/groovy/datadog/opentracing/DDSpanTest.groovy

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package datadog.opentracing
22

33
import datadog.opentracing.propagation.ExtractedContext
44
import datadog.opentracing.propagation.TagContext
5+
import datadog.trace.agent.test.utils.ConfigUtils
56
import datadog.trace.api.sampling.PrioritySampling
67
import datadog.trace.common.sampling.RateByServiceSampler
78
import datadog.trace.common.writer.ListWriter
@@ -14,6 +15,10 @@ import java.util.concurrent.TimeUnit
1415
import static datadog.trace.api.Config.DEFAULT_SERVICE_NAME
1516

1617
class DDSpanTest extends Specification {
18+
static {
19+
ConfigUtils.makeConfigInstanceModifiable()
20+
}
21+
1722
def writer = new ListWriter()
1823
def tracer = new DDTracer(DEFAULT_SERVICE_NAME, writer, new RateByServiceSampler(), [:])
1924

@@ -210,7 +215,7 @@ class DDSpanTest extends Specification {
210215

211216
def "isRootSpan() in and not in the context of distributed tracing"() {
212217
setup:
213-
def root = tracer.buildSpan("root").asChildOf((SpanContext)extractedContext).start()
218+
def root = tracer.buildSpan("root").asChildOf((SpanContext) extractedContext).start()
214219
def child = tracer.buildSpan("child").asChildOf(root).start()
215220

216221
expect:
@@ -222,14 +227,14 @@ class DDSpanTest extends Specification {
222227
root.finish()
223228

224229
where:
225-
extractedContext | isTraceRootSpan
226-
null | true
230+
extractedContext | isTraceRootSpan
231+
null | true
227232
new ExtractedContext("123", "456", 1, "789", [:], [:]) | false
228233
}
229234

230235
def "getApplicationRootSpan() in and not in the context of distributed tracing"() {
231236
setup:
232-
def root = tracer.buildSpan("root").asChildOf((SpanContext)extractedContext).start()
237+
def root = tracer.buildSpan("root").asChildOf((SpanContext) extractedContext).start()
233238
def child = tracer.buildSpan("child").asChildOf(root).start()
234239

235240
expect:
@@ -244,8 +249,8 @@ class DDSpanTest extends Specification {
244249
root.finish()
245250

246251
where:
247-
extractedContext | isTraceRootSpan
248-
null | true
252+
extractedContext | isTraceRootSpan
253+
null | true
249254
new ExtractedContext("123", "456", 1, "789", [:], [:]) | false
250255
}
251256

@@ -264,9 +269,9 @@ class DDSpanTest extends Specification {
264269
span.finish()
265270

266271
where:
267-
tagName | tagValue | expectedPriority
268-
'manual.drop' | true | PrioritySampling.USER_DROP
269-
'manual.keep' | true | PrioritySampling.USER_KEEP
272+
tagName | tagValue | expectedPriority
273+
'manual.drop' | true | PrioritySampling.USER_DROP
274+
'manual.keep' | true | PrioritySampling.USER_KEEP
270275
}
271276

272277
def "not setting forced tracing via tag or setting it wrong value not causing exception"() {
@@ -284,9 +289,9 @@ class DDSpanTest extends Specification {
284289
span.finish()
285290

286291
where:
287-
tagName | tagValue
292+
tagName | tagValue
288293
// When no tag is set default to
289-
null | null
294+
null | null
290295
// Setting to not known value
291296
'manual.drop' | false
292297
'manual.keep' | false

dd-trace-ot/src/test/groovy/datadog/opentracing/PendingTraceTest.groovy

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package datadog.opentracing
22

3+
import datadog.trace.agent.test.utils.ConfigUtils
34
import datadog.trace.api.Config
45
import datadog.trace.common.writer.ListWriter
56
import datadog.trace.util.gc.GCUtils
@@ -14,6 +15,10 @@ import java.util.concurrent.atomic.AtomicInteger
1415
import static datadog.trace.api.Config.PARTIAL_FLUSH_MIN_SPANS
1516

1617
class PendingTraceTest extends Specification {
18+
static {
19+
ConfigUtils.makeConfigInstanceModifiable()
20+
}
21+
1722
def traceCount = new AtomicInteger()
1823
def writer = new ListWriter() {
1924
@Override

0 commit comments

Comments
 (0)