Skip to content
2 changes: 1 addition & 1 deletion .circleci/config.continue.yml.j2
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ instrumentation_modules: &instrumentation_modules "dd-java-agent/instrumentation
debugger_modules: &debugger_modules "dd-java-agent/agent-debugger|dd-java-agent/agent-bootstrap|dd-java-agent/agent-builder|internal-api|communication|dd-trace-core"
profiling_modules: &profiling_modules "dd-java-agent/agent-profiling"

default_system_tests_commit: &default_system_tests_commit 761b9e7a82ffb136c4653a4d1623d120d67b005b
default_system_tests_commit: &default_system_tests_commit 08276e905c5c81055412ea4c318856d879cf15e5

parameters:
nightly:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ public static void onEnter(@Advice.Argument(value = 0, readOnly = false) String[
+ "datadog.trace.api.Platform:rerun,"
+ "datadog.trace.api.Platform$Captured:build_time,"
+ "datadog.trace.api.env.CapturedEnvironment:build_time,"
+ "datadog.trace.api.env.CapturedEnvironment$ProcessInfo:build_time,"
+ "datadog.trace.api.ConfigCollector:rerun,"
+ "datadog.trace.api.ConfigDefaults:build_time,"
+ "datadog.trace.api.ConfigOrigin:build_time,"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import datadog.trace.agent.tooling.Instrumenter;
import datadog.trace.agent.tooling.InstrumenterModule;
import datadog.trace.api.Config;
import datadog.trace.api.ProcessTags;
import datadog.trace.bootstrap.instrumentation.api.AgentTracer;
import net.bytebuddy.asm.Advice;
import org.springframework.core.env.ConfigurableEnvironment;
Expand Down Expand Up @@ -60,6 +61,18 @@ public static void afterEnvironmentPostProcessed(
final String applicationName = environment.getProperty("spring.application.name");
if (applicationName != null && !applicationName.isEmpty()) {
AgentTracer.get().updatePreferredServiceName(applicationName);
ProcessTags.addTag("springboot.application", applicationName);
}
if (Config.get().isExperimentalPropagateProcessTagsEnabled()) {
final String[] profiles = environment.getActiveProfiles();
if (profiles != null && profiles.length > 0) {
ProcessTags.addTag("springboot.profile", profiles[0]);
} else {
final String[] defaultProfiles = environment.getDefaultProfiles();
if (defaultProfiles != null && defaultProfiles.length > 0) {
ProcessTags.addTag("springboot.profile", defaultProfiles[0]);
}
}
}
}
}
Expand All @@ -77,6 +90,18 @@ public static void afterEnvironmentPostProcessed(
final String applicationName = environment.getProperty("spring.application.name");
if (applicationName != null && !applicationName.isEmpty()) {
AgentTracer.get().updatePreferredServiceName(applicationName);
ProcessTags.addTag("springboot.application", applicationName);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should it be extracted into a helper to avoid duplicating this logic in two places?

}
if (Config.get().isExperimentalPropagateProcessTagsEnabled()) {
final String[] profiles = environment.getActiveProfiles();
if (profiles != null && profiles.length > 0) {
ProcessTags.addTag("springboot.profile", profiles[0]);
} else {
final String[] defaultProfiles = environment.getDefaultProfiles();
if (defaultProfiles != null && defaultProfiles.length > 0) {
ProcessTags.addTag("springboot.profile", defaultProfiles[0]);
}
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,20 @@
import datadog.trace.api.ProcessTags

import static datadog.trace.agent.test.utils.TraceUtils.runUnderTrace

import datadog.trace.agent.test.AgentTestRunner
import datadog.trace.api.Config
import org.springframework.beans.factory.InitializingBean
import org.springframework.boot.SpringApplication

import static datadog.trace.api.config.GeneralConfig.EXPERIMENTAL_PROPAGATE_PROCESS_TAGS_ENABLED

class SpringBootApplicationTest extends AgentTestRunner {
@Override
protected void configurePreAgent() {
super.configurePreAgent()
injectSysConfig(EXPERIMENTAL_PROPAGATE_PROCESS_TAGS_ENABLED, "true")
}

static class BeanWhoTraces implements InitializingBean {

@Override
Expand All @@ -32,15 +37,19 @@ class SpringBootApplicationTest extends AgentTestRunner {
}
}
})
and:
def processTags = ProcessTags.getTagsForSerialization()
assert processTags.toString() =~ ".+,springboot.application:$expectedService,springboot.profile:$expectedProfile"
context != null
cleanup:
context?.stop()
where:
expectedService | args
"application-name-from-args" | new String[]{
"--spring.application.name=application-name-from-args"
expectedService | expectedProfile | args
"application-name-from-args" | "prod" | new String[]{
"--spring.application.name=application-name-from-args",
"--spring.profiles.active=prod,common",
}
"application-name-from-properties" | new String[0] // will load from properties
"application-name-from-properties" | "default" | new String[0] // will load from properties
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import datadog.trace.agent.tooling.bytebuddy.matcher.GlobalIgnores
import datadog.trace.api.Config
import datadog.trace.api.DDSpanId
import datadog.trace.api.IdGenerationStrategy
import datadog.trace.api.ProcessTags
import datadog.trace.api.StatsDClient
import datadog.trace.api.TraceConfig
import datadog.trace.api.WellKnownTags
Expand Down Expand Up @@ -509,6 +510,7 @@ abstract class AgentTestRunner extends DDSpecification implements AgentBuilder.L
ActiveSubsystems.APPSEC_ACTIVE = true
}
InstrumentationErrors.resetErrorCount()
ProcessTags.reset()
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,8 @@ public final class ConfigDefaults {
static final int DEFAULT_TELEMETRY_DEPENDENCY_RESOLUTION_QUEUE_SIZE = 100000;

static final Set<String> DEFAULT_TRACE_EXPERIMENTAL_FEATURES_ENABLED =
new HashSet<>(asList("DD_TAGS", "DD_LOGS_INJECTION"));
new HashSet<>(
asList("DD_TAGS", "DD_LOGS_INJECTION", "DD_EXPERIMENTAL_PROPAGATE_PROCESS_TAGS_ENABLED"));

static final boolean DEFAULT_TRACE_128_BIT_TRACEID_GENERATION_ENABLED = true;
static final boolean DEFAULT_TRACE_128_BIT_TRACEID_LOGGING_ENABLED = true;
Expand Down
1 change: 1 addition & 0 deletions dd-trace-api/src/main/java/datadog/trace/api/DDTags.java
Original file line number Diff line number Diff line change
Expand Up @@ -98,4 +98,5 @@ public class DDTags {
public static final String DECISION_MAKER_INHERITED = "_dd.dm.inherited";
public static final String DECISION_MAKER_SERVICE = "_dd.dm.service";
public static final String DECISION_MAKER_RESOURCE = "_dd.dm.resource";
public static final String PROCESS_TAGS = "_dd.tags.process";
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ public final class GeneralConfig {
@Deprecated // Use dd.tags instead
public static final String GLOBAL_TAGS = "trace.global.tags";

public static final String EXPERIMENTAL_PROPAGATE_PROCESS_TAGS_ENABLED =
"experimental.propagate.process.tags.enabled";

public static final String LOG_LEVEL = "log.level";
public static final String TRACE_DEBUG = "trace.debug";
public static final String TRACE_TRIAGE = "trace.triage";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@
import datadog.communication.serialization.GrowableBuffer;
import datadog.communication.serialization.WritableFormatter;
import datadog.communication.serialization.msgpack.MsgPackWriter;
import datadog.trace.api.ProcessTags;
import datadog.trace.api.WellKnownTags;
import datadog.trace.bootstrap.instrumentation.api.UTF8BytesString;

public final class SerializingMetricWriter implements MetricWriter {

Expand All @@ -28,6 +30,7 @@ public final class SerializingMetricWriter implements MetricWriter {
private static final byte[] STATS = "Stats".getBytes(ISO_8859_1);
private static final byte[] OK_SUMMARY = "OkSummary".getBytes(ISO_8859_1);
private static final byte[] ERROR_SUMMARY = "ErrorSummary".getBytes(ISO_8859_1);
private static final byte[] PROCESS_TAGS = "ProcessTags".getBytes(ISO_8859_1);

private final WellKnownTags wellKnownTags;
private final WritableFormatter writer;
Expand All @@ -48,7 +51,9 @@ public SerializingMetricWriter(WellKnownTags wellKnownTags, Sink sink, int initi

@Override
public void startBucket(int metricCount, long start, long duration) {
writer.startMap(6);
final UTF8BytesString processTags = ProcessTags.getTagsForSerialization();
final boolean writeProcessTags = processTags != null;
writer.startMap(6 + (writeProcessTags ? 1 : 0));

writer.writeUTF8(RUNTIME_ID);
writer.writeUTF8(wellKnownTags.getRuntimeId());
Expand All @@ -65,7 +70,13 @@ public void startBucket(int metricCount, long start, long duration) {
writer.writeUTF8(VERSION);
writer.writeUTF8(wellKnownTags.getVersion());

if (writeProcessTags) {
writer.writeUTF8(PROCESS_TAGS);
writer.writeUTF8(processTags);
}

writer.writeUTF8(STATS);

writer.startArray(1);

writer.startMap(3);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,5 @@ public interface TraceMapper extends RemoteMapper {
UTF8BytesString SAMPLING_PRIORITY_KEY =
UTF8BytesString.create(DDSpanContext.PRIORITY_SAMPLING_KEY);
UTF8BytesString ORIGIN_KEY = UTF8BytesString.create(DDTags.ORIGIN_KEY);
UTF8BytesString PROCESS_TAGS_KEY = UTF8BytesString.create(DDTags.PROCESS_TAGS);
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import datadog.communication.serialization.GrowableBuffer;
import datadog.communication.serialization.Writable;
import datadog.communication.serialization.msgpack.MsgPackWriter;
import datadog.trace.api.ProcessTags;
import datadog.trace.bootstrap.instrumentation.api.InstrumentationTags;
import datadog.trace.bootstrap.instrumentation.api.UTF8BytesString;
import datadog.trace.common.writer.Payload;
Expand Down Expand Up @@ -36,25 +37,35 @@ public TraceMapperV0_4() {
private static final class MetaWriter implements MetadataConsumer {

private Writable writable;
private boolean writeSamplingPriority;
private boolean firstSpanInChunk;
private boolean lastSpanInChunk;

MetaWriter withWritable(Writable writable) {
this.writable = writable;
return this;
}

MetaWriter withWriteSamplingPriority(final boolean writeSamplingPriority) {
this.writeSamplingPriority = writeSamplingPriority;
MetaWriter forFirstSpanInChunk(final boolean firstSpanInChunk) {
this.firstSpanInChunk = firstSpanInChunk;
return this;
}

MetaWriter forLastSpanInChunk(final boolean lastSpanInChunk) {
this.lastSpanInChunk = lastSpanInChunk;
return this;
}

@Override
public void accept(Metadata metadata) {
final boolean writeSamplingPriority = firstSpanInChunk || lastSpanInChunk;
final UTF8BytesString processTags =
firstSpanInChunk ? ProcessTags.getTagsForSerialization() : null;
int metaSize =
metadata.getBaggage().size()
+ metadata.getTags().size()
+ (null == metadata.getHttpStatusCode() ? 0 : 1)
+ (null == metadata.getOrigin() ? 0 : 1)
+ (null == processTags ? 0 : 1)
+ 1;
int metricsSize =
(writeSamplingPriority && metadata.hasSamplingPriority() ? 1 : 0)
Expand Down Expand Up @@ -124,6 +135,10 @@ public void accept(Metadata metadata) {
writable.writeUTF8(ORIGIN_KEY);
writable.writeString(metadata.getOrigin(), null);
}
if (processTags != null) {
writable.writeUTF8(PROCESS_TAGS_KEY);
writable.writeUTF8(processTags);
}
for (Map.Entry<String, Object> entry : metadata.getTags().entrySet()) {
String key = entry.getKey();
Object value = entry.getValue();
Expand Down Expand Up @@ -273,7 +288,8 @@ public void map(List<? extends CoreSpan<?>> trace, final Writable writable) {
span.processTagsAndBaggage(
metaWriter
.withWritable(writable)
.withWriteSamplingPriority(i == 0 || i == trace.size() - 1));
.forFirstSpanInChunk(i == 0)
.forLastSpanInChunk(i == trace.size() - 1));
if (!metaStruct.isEmpty()) {
/* 13 */
metaStructWriter.withWritable(writable).write(metaStruct);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import datadog.communication.serialization.Writable;
import datadog.communication.serialization.WritableFormatter;
import datadog.communication.serialization.msgpack.MsgPackWriter;
import datadog.trace.api.ProcessTags;
import datadog.trace.bootstrap.instrumentation.api.InstrumentationTags;
import datadog.trace.bootstrap.instrumentation.api.UTF8BytesString;
import datadog.trace.common.writer.Payload;
Expand Down Expand Up @@ -78,7 +79,8 @@ public void map(final List<? extends CoreSpan<?>> trace, final Writable writable
span.processTagsAndBaggage(
metaWriter
.withWritable(writable)
.withWriteSamplingPriority(i == 0 || i == trace.size() - 1));
.forFirstSpanInChunk(i == 0)
.forLastSpanInChunk(i == trace.size() - 1));
/* 12 */
writeDictionaryEncoded(writable, span.getType());
}
Expand Down Expand Up @@ -179,25 +181,35 @@ private List<ByteBuffer> toList() {
private final class MetaWriter implements MetadataConsumer {

private Writable writable;
private boolean writeSamplingPriority;
private boolean firstSpanInChunk;
private boolean lastSpanInChunk;

MetaWriter withWritable(final Writable writable) {
this.writable = writable;
return this;
}

MetaWriter withWriteSamplingPriority(final boolean writeSamplingPriority) {
this.writeSamplingPriority = writeSamplingPriority;
MetaWriter forFirstSpanInChunk(final boolean firstSpanInChunk) {
this.firstSpanInChunk = firstSpanInChunk;
return this;
}

MetaWriter forLastSpanInChunk(final boolean lastSpanInChunk) {
this.lastSpanInChunk = lastSpanInChunk;
return this;
}

@Override
public void accept(Metadata metadata) {
final boolean writeSamplingPriority = firstSpanInChunk || lastSpanInChunk;
final UTF8BytesString processTags =
firstSpanInChunk ? ProcessTags.getTagsForSerialization() : null;
int metaSize =
metadata.getBaggage().size()
+ metadata.getTags().size()
+ (null == metadata.getHttpStatusCode() ? 0 : 1)
+ (null == metadata.getOrigin() ? 0 : 1)
+ (null == processTags ? 0 : 1)
+ 1;
int metricsSize =
(writeSamplingPriority && metadata.hasSamplingPriority() ? 1 : 0)
Expand Down Expand Up @@ -234,6 +246,10 @@ public void accept(Metadata metadata) {
writeDictionaryEncoded(writable, ORIGIN_KEY);
writeDictionaryEncoded(writable, metadata.getOrigin());
}
if (null != processTags) {
writeDictionaryEncoded(writable, PROCESS_TAGS_KEY);
writeDictionaryEncoded(writable, processTags);
}
for (Map.Entry<String, Object> entry : metadata.getTags().entrySet()) {
String key = entry.getKey();
Object value = entry.getValue();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import datadog.trace.api.DDTags;
import datadog.trace.api.DDTraceId;
import datadog.trace.api.Functions;
import datadog.trace.api.ProcessTags;
import datadog.trace.api.cache.DDCache;
import datadog.trace.api.cache.DDCaches;
import datadog.trace.api.config.TracerConfig;
Expand Down Expand Up @@ -874,7 +875,8 @@ public void processTagsAndBaggage(
httpStatusCode == 0 ? null : HTTP_STATUSES.get(httpStatusCode),
// Get origin from rootSpan.context
getOrigin(),
longRunningVersion));
longRunningVersion,
ProcessTags.getTagsForSerialization()));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ public final class Metadata {
private final boolean topLevel;
private final CharSequence origin;
private final int longRunningVersion;
private final UTF8BytesString processTags;

public Metadata(
long threadId,
Expand All @@ -28,7 +29,8 @@ public Metadata(
boolean topLevel,
UTF8BytesString httpStatusCode,
CharSequence origin,
int longRunningVersion) {
int longRunningVersion,
UTF8BytesString processTags) {
this.threadId = threadId;
this.threadName = threadName;
this.httpStatusCode = httpStatusCode;
Expand All @@ -39,6 +41,7 @@ public Metadata(
this.topLevel = topLevel;
this.origin = origin;
this.longRunningVersion = longRunningVersion;
this.processTags = processTags;
}

public UTF8BytesString getHttpStatusCode() {
Expand Down Expand Up @@ -84,4 +87,8 @@ public boolean hasSamplingPriority() {
public int samplingPriority() {
return samplingPriority;
}

public UTF8BytesString processTags() {
return processTags;
}
}
Loading
Loading