wip: Add languages tag to jmx/runtime tags
MODIFY
dd-trace-api/src/main/java/datadog/trace/api/Config.java
dd-trace-api/src/main/java/datadog/trace/api/Config.java
@@ -50,6 +50,8 @@ public class Config {
public static final String JMX_FETCH_STATSD_PORT = "jmxfetch.statsd.port";
public static final String RUNTIME_ID_TAG = "runtime-id";
+ public static final String LANGUAGES_TAG_KEY = "languages";
+ public static final String LANGUAGES_TAG_VALUE = "jvm";
public static final String DEFAULT_SERVICE_NAME = "unnamed-java-app";
public static final String DD_AGENT_WRITER_TYPE = "DDAgentWriter";
@@ -183,11 +185,29 @@ public class Config {
final Map<String, String> result = newHashMap(globalTags.size() + jmxTags.size() + 1);
result.putAll(globalTags);
result.putAll(jmxTags);
- result.put(RUNTIME_ID_TAG, runtimeId);
+ result.putAll(getRuntimeTags());
+ // service name set here instead of getRuntimeTags because apm already manages the service tag
+ // and may chose to override it.
result.put(SERVICE_NAME, serviceName);
return Collections.unmodifiableMap(result);
}
+ /**
+ * Return a map of tags required by the datadog backend to link runtime metrics (i.e. jmx) and
+ * traces.
+ *
+ * <p>These tags must be applied to every runtime metrics and placed on the root span of every
+ * trace.
+ *
+ * @return A map of tag-name -> tag-value
+ */
+ public Map<String, String> getRuntimeTags() {
+ final Map<String, String> result = newHashMap(3);
+ result.put(RUNTIME_ID_TAG, runtimeId);
+ result.put(LANGUAGES_TAG_KEY, LANGUAGES_TAG_VALUE);
+ return Collections.unmodifiableMap(result);
+ }
+
private static String getSettingFromEnvironment(final String name, final String defaultValue) {
final String completeName = PREFIX + name;
final String value =

MODIFY
dd-trace-api/src/test/groovy/datadog/trace/api/ConfigTest.groovy
dd-trace-api/src/test/groovy/datadog/trace/api/ConfigTest.groovy
@@ -35,7 +35,7 @@ class ConfigTest extends Specification {
config.traceResolverEnabled == true
config.serviceMapping == [:]
config.mergedSpanTags == [:]
- config.mergedJmxTags == [(RUNTIME_ID_TAG): config.getRuntimeId(), (SERVICE_NAME): config.serviceName]
+ config.mergedJmxTags == [(RUNTIME_ID_TAG): config.getRuntimeId(), (SERVICE_NAME): config.serviceName, (LANGUAGES_TAG_KEY): LANGUAGES_TAG_VALUE]
config.headerTags == [:]
config.runtimeContextFieldInjection == true
config.jmxFetchEnabled == false
@@ -81,7 +81,7 @@ class ConfigTest extends Specification {
config.traceResolverEnabled == false
config.serviceMapping == [a: "1"]
config.mergedSpanTags == [b: "2", c: "3"]
- config.mergedJmxTags == [b: "2", d: "4", (RUNTIME_ID_TAG): config.getRuntimeId(), (SERVICE_NAME): config.serviceName]
+ config.mergedJmxTags == [b: "2", d: "4", (RUNTIME_ID_TAG): config.getRuntimeId(), (SERVICE_NAME): config.serviceName, (LANGUAGES_TAG_KEY): LANGUAGES_TAG_VALUE]
config.headerTags == [e: "5"]
config.runtimeContextFieldInjection == false
config.jmxFetchEnabled == true
@@ -202,7 +202,7 @@ class ConfigTest extends Specification {
config.traceResolverEnabled == false
config.serviceMapping == [a: "1"]
config.mergedSpanTags == [b: "2", c: "3"]
- config.mergedJmxTags == [b: "2", d: "4", (RUNTIME_ID_TAG): config.getRuntimeId(), (SERVICE_NAME): config.serviceName]
+ config.mergedJmxTags == [b: "2", d: "4", (RUNTIME_ID_TAG): config.getRuntimeId(), (SERVICE_NAME): config.serviceName, (LANGUAGES_TAG_KEY): LANGUAGES_TAG_VALUE]
config.headerTags == [e: "5"]
config.jmxFetchMetricsConfigs == ["/foo.yaml", "/bar.yaml"]
config.jmxFetchCheckPeriod == 100

MODIFY
dd-trace-ot/src/main/java/datadog/opentracing/DDTracer.java
dd-trace-ot/src/main/java/datadog/opentracing/DDTracer.java
@@ -54,8 +54,8 @@ public class DDTracer implements io.opentracing.Tracer, Closeable, datadog.trace
/** Scope manager is in charge of managing the scopes from which spans are created */
final ContextualScopeManager scopeManager = new ContextualScopeManager();
- /** Value for runtime-id tag */
- private final String runtimeId;
+ /** Tags required to link apm trades to runtime metrics */
+ final Map<String, String> runtimeTags;
/** A set of tags that are added to every span */
private final Map<String, String> defaultSpanTags;
/** A configured mapping of service names to update with new values */
@@ -101,7 +101,7 @@ public class DDTracer implements io.opentracing.Tracer, Closeable, datadog.trace
// This constructor is already used in the wild, so we have to keep it inside this API for now.
public DDTracer(final String serviceName, final Writer writer, final Sampler sampler) {
- this(serviceName, writer, sampler, Config.get().getRuntimeId());
+ this(serviceName, writer, sampler, Config.get().getRuntimeTags());
}
private DDTracer(final String serviceName, final Config config) {
@@ -109,7 +109,7 @@ public class DDTracer implements io.opentracing.Tracer, Closeable, datadog.trace
serviceName,
Writer.Builder.forConfig(config),
Sampler.Builder.forConfig(config),
- config.getRuntimeId(),
+ config.getRuntimeTags(),
config.getMergedSpanTags(),
config.getServiceMapping(),
config.getHeaderTags());
@@ -121,12 +121,12 @@ public class DDTracer implements io.opentracing.Tracer, Closeable, datadog.trace
final String serviceName,
final Writer writer,
final Sampler sampler,
- final String runtimeId) {
+ final Map<String, String> runtimeTags) {
this(
serviceName,
writer,
sampler,
- runtimeId,
+ runtimeTags,
Collections.<String, String>emptyMap(),
Collections.<String, String>emptyMap(),
Collections.<String, String>emptyMap());
@@ -141,12 +141,14 @@ public class DDTracer implements io.opentracing.Tracer, Closeable, datadog.trace
config.getServiceName(),
writer,
Sampler.Builder.forConfig(config),
- config.getRuntimeId(),
+ config.getRuntimeTags(),
config.getMergedSpanTags(),
config.getServiceMapping(),
config.getHeaderTags());
}
+ /** @Deprecated. Use {@link #DDTracer(String, Writer, Sampler, Map, Map, Map, Map)} instead. */
+ @Deprecated
public DDTracer(
final String serviceName,
final Writer writer,
@@ -155,7 +157,33 @@ public class DDTracer implements io.opentracing.Tracer, Closeable, datadog.trace
final Map<String, String> defaultSpanTags,
final Map<String, String> serviceNameMappings,
final Map<String, String> taggedHeaders) {
- assert runtimeId != null;
+ this(
+ serviceName,
+ writer,
+ sampler,
+ customRuntimeTags(runtimeId),
+ defaultSpanTags,
+ serviceNameMappings,
+ taggedHeaders);
+ }
+
+ @Deprecated
+ private static Map<String, String> customRuntimeTags(final String runtimeId) {
+ final Map<String, String> runtimeTags = new HashMap<>();
+ runtimeTags.putAll(Config.get().getRuntimeTags());
+ runtimeTags.put(Config.RUNTIME_ID_TAG, runtimeId);
+ return Collections.unmodifiableMap(runtimeTags);
+ }
+
+ public DDTracer(
+ final String serviceName,
+ final Writer writer,
+ final Sampler sampler,
+ final Map<String, String> runtimeTags,
+ final Map<String, String> defaultSpanTags,
+ final Map<String, String> serviceNameMappings,
+ final Map<String, String> taggedHeaders) {
+ assert runtimeTags != null;
assert defaultSpanTags != null;
assert serviceNameMappings != null;
assert taggedHeaders != null;
@@ -165,7 +193,7 @@ public class DDTracer implements io.opentracing.Tracer, Closeable, datadog.trace
this.writer.start();
this.sampler = sampler;
this.defaultSpanTags = defaultSpanTags;
- this.runtimeId = runtimeId;
+ this.runtimeTags = runtimeTags;
this.serviceNameMappings = serviceNameMappings;
shutdownCallback =
@@ -370,8 +398,6 @@ public class DDTracer implements io.opentracing.Tracer, Closeable, datadog.trace
+ writer
+ ", sampler="
+ sampler
- + ", runtimeId="
- + runtimeId
+ ", defaultSpanTags="
+ defaultSpanTags
+ '}';
@@ -596,12 +622,14 @@ public class DDTracer implements io.opentracing.Tracer, Closeable, datadog.trace
samplingPriority = PrioritySampling.UNSET;
baggage = null;
}
-
// Get header tags whether propagating or not.
if (parentContext instanceof TagContext) {
tags.putAll(((TagContext) parentContext).getTags());
}
- tags.put(Config.RUNTIME_ID_TAG, runtimeId);
+ // add runtime tags to the root span
+ for (Map.Entry<String, String> runtimeTag : runtimeTags.entrySet()) {
+ tags.put(runtimeTag.getKey(), runtimeTag.getValue());
+ }
parentTrace = new PendingTrace(DDTracer.this, traceId, serviceNameMappings);
}

MODIFY
dd-trace-ot/src/test/groovy/datadog/opentracing/DDSpanTest.groovy
dd-trace-ot/src/test/groovy/datadog/opentracing/DDSpanTest.groovy
@@ -11,7 +11,7 @@ import static datadog.trace.api.Config.DEFAULT_SERVICE_NAME
class DDSpanTest extends Specification {
def writer = new ListWriter()
- def tracer = new DDTracer(DEFAULT_SERVICE_NAME, writer, new RateByServiceSampler(), "some-runtime-id")
+ def tracer = new DDTracer(DEFAULT_SERVICE_NAME, writer, new RateByServiceSampler(), [:])
def "getters and setters"() {
setup:

MODIFY
dd-trace-ot/src/test/groovy/datadog/trace/DDTracerTest.groovy
dd-trace-ot/src/test/groovy/datadog/trace/DDTracerTest.groovy
@@ -121,7 +121,7 @@ class DDTracerTest extends Specification {
tracer.serviceName == DEFAULT_SERVICE_NAME
tracer.sampler == sampler
tracer.writer == writer
- tracer.runtimeId.length() > 0
+ tracer.runtimeTags.size() > 0
}
def "Shares TraceCount with DDApi with #key = #value"() {

wip: Add languages tag to jmx/runtime tags