Skip to content

Commit 90b21ff

Browse files
committed
Initial dsm extractors configuration
1 parent 364bb8b commit 90b21ff

File tree

10 files changed

+207
-18
lines changed

10 files changed

+207
-18
lines changed

dd-java-agent/instrumentation-testing/src/main/groovy/datadog/trace/agent/test/InstrumentationSpecification.groovy

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,15 @@
11
package datadog.trace.agent.test
22

3+
import static datadog.communication.http.OkHttpUtils.buildHttpClient
4+
import static datadog.trace.api.ConfigDefaults.DEFAULT_AGENT_HOST
5+
import static datadog.trace.api.ConfigDefaults.DEFAULT_AGENT_TIMEOUT
6+
import static datadog.trace.api.ConfigDefaults.DEFAULT_TRACE_AGENT_PORT
7+
import static datadog.trace.api.config.DebuggerConfig.DYNAMIC_INSTRUMENTATION_SNAPSHOT_URL
8+
import static datadog.trace.api.config.DebuggerConfig.DYNAMIC_INSTRUMENTATION_VERIFY_BYTECODE
9+
import static datadog.trace.api.config.TraceInstrumentationConfig.CODE_ORIGIN_FOR_SPANS_ENABLED
10+
import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.closePrevious
11+
import static datadog.trace.util.AgentThreadFactory.AgentThread.TASK_SCHEDULER
12+
313
import ch.qos.logback.classic.Level
414
import ch.qos.logback.classic.util.ContextInitializer
515
import com.datadog.debugger.agent.ClassesToRetransformFinder
@@ -32,6 +42,7 @@ import datadog.trace.api.TraceConfig
3242
import datadog.trace.api.config.GeneralConfig
3343
import datadog.trace.api.config.TracerConfig
3444
import datadog.trace.api.datastreams.AgentDataStreamsMonitoring
45+
import datadog.trace.api.datastreams.DataStreamsTransactionExtractor
3546
import datadog.trace.api.sampling.SamplingRule
3647
import datadog.trace.api.time.SystemTimeSource
3748
import datadog.trace.bootstrap.ActiveSubsystems
@@ -55,6 +66,13 @@ import de.thetaphi.forbiddenapis.SuppressForbidden
5566
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings
5667
import groovy.transform.stc.ClosureParams
5768
import groovy.transform.stc.SimpleType
69+
import java.lang.instrument.ClassFileTransformer
70+
import java.lang.instrument.Instrumentation
71+
import java.nio.ByteBuffer
72+
import java.util.concurrent.ConcurrentHashMap
73+
import java.util.concurrent.TimeUnit
74+
import java.util.concurrent.TimeoutException
75+
import java.util.concurrent.atomic.AtomicInteger
5876
import net.bytebuddy.agent.ByteBuddyAgent
5977
import net.bytebuddy.agent.builder.AgentBuilder
6078
import net.bytebuddy.description.type.TypeDescription
@@ -68,24 +86,6 @@ import org.slf4j.LoggerFactory
6886
import org.spockframework.mock.MockUtil
6987
import spock.lang.Shared
7088

71-
import java.lang.instrument.ClassFileTransformer
72-
import java.lang.instrument.Instrumentation
73-
import java.nio.ByteBuffer
74-
import java.util.concurrent.ConcurrentHashMap
75-
import java.util.concurrent.TimeUnit
76-
import java.util.concurrent.TimeoutException
77-
import java.util.concurrent.atomic.AtomicInteger
78-
79-
import static datadog.communication.http.OkHttpUtils.buildHttpClient
80-
import static datadog.trace.api.ConfigDefaults.DEFAULT_AGENT_HOST
81-
import static datadog.trace.api.ConfigDefaults.DEFAULT_AGENT_TIMEOUT
82-
import static datadog.trace.api.ConfigDefaults.DEFAULT_TRACE_AGENT_PORT
83-
import static datadog.trace.api.config.DebuggerConfig.DYNAMIC_INSTRUMENTATION_SNAPSHOT_URL
84-
import static datadog.trace.api.config.DebuggerConfig.DYNAMIC_INSTRUMENTATION_VERIFY_BYTECODE
85-
import static datadog.trace.api.config.TraceInstrumentationConfig.CODE_ORIGIN_FOR_SPANS_ENABLED
86-
import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.closePrevious
87-
import static datadog.trace.util.AgentThreadFactory.AgentThread.TASK_SCHEDULER
88-
8989
/**
9090
* A specification that automatically applies instrumentation and exposes a global trace
9191
* writer.
@@ -249,6 +249,10 @@ abstract class InstrumentationSpecification extends DDSpecification implements A
249249
List<? extends SamplingRule.TraceSamplingRule> getTraceSamplingRules() {
250250
return null
251251
}
252+
253+
List<DataStreamsTransactionExtractor> getDataStreamsTransactionExtractors() {
254+
return null
255+
}
252256
}
253257

254258
boolean originalAppSecRuntimeValue

dd-trace-api/src/main/java/datadog/trace/api/config/GeneralConfig.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,8 @@ public final class GeneralConfig {
8888
public static final String DATA_STREAMS_ENABLED = "data.streams.enabled";
8989
public static final String DATA_STREAMS_BUCKET_DURATION_SECONDS =
9090
"data.streams.bucket_duration.seconds";
91+
public static final String DATA_STREAMS_TRANSACTION_EXTRACTORS =
92+
"data.streams.transaction_extractors";
9193

9294
public static final String TELEMETRY_ENABLED = "instrumentation.telemetry.enabled";
9395
public static final String TELEMETRY_HEARTBEAT_INTERVAL = "telemetry.heartbeat.interval";

dd-trace-core/src/main/java/datadog/trace/core/CoreTracer.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@
8686
import datadog.trace.context.TraceScope;
8787
import datadog.trace.core.baggage.BaggagePropagator;
8888
import datadog.trace.core.datastreams.DataStreamsMonitoring;
89+
import datadog.trace.core.datastreams.DataStreamsTransactionExtractors;
8990
import datadog.trace.core.datastreams.DefaultDataStreamsMonitoring;
9091
import datadog.trace.core.histogram.Histograms;
9192
import datadog.trace.core.monitor.HealthMetrics;
@@ -679,6 +680,16 @@ private CoreTracer(
679680
} else {
680681
traceSamplingRules = TraceSamplingRules.deserialize(traceSamplingRulesJson);
681682
}
683+
684+
DataStreamsTransactionExtractors dataStreamsTransactionExtractors;
685+
String dataStreamsTransactionExtractorsJson = config.getDataStreamsTransactionExtractors();
686+
if (dataStreamsTransactionExtractorsJson == null) {
687+
dataStreamsTransactionExtractors = DataStreamsTransactionExtractors.EMPTY;
688+
} else {
689+
dataStreamsTransactionExtractors =
690+
DataStreamsTransactionExtractors.deserialize(dataStreamsTransactionExtractorsJson);
691+
}
692+
682693
// Get initial Span Sampling Rules from config
683694
String spanSamplingRulesJson = config.getSpanSamplingRules();
684695
String spanSamplingRulesFile = config.getSpanSamplingRulesFile();
@@ -708,6 +719,9 @@ private CoreTracer(
708719
.setSpanSamplingRules(spanSamplingRules.getRules())
709720
.setTraceSamplingRules(traceSamplingRules.getRules(), traceSamplingRulesJson)
710721
.setTracingTags(config.getMergedSpanTags())
722+
.setDataStreamsTransactionExtractors(
723+
dataStreamsTransactionExtractors.getExtractors(),
724+
dataStreamsTransactionExtractorsJson)
711725
.apply();
712726

713727
this.logs128bTraceIdEnabled = Config.get().isLogs128bitTraceIdEnabled();
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
package datadog.trace.core.datastreams;
2+
3+
import com.squareup.moshi.FromJson;
4+
import com.squareup.moshi.JsonAdapter;
5+
import com.squareup.moshi.Moshi;
6+
import com.squareup.moshi.ToJson;
7+
import com.squareup.moshi.Types;
8+
import datadog.trace.api.datastreams.DataStreamsTransactionExtractor;
9+
import java.lang.reflect.ParameterizedType;
10+
import java.util.Collections;
11+
import java.util.List;
12+
import org.slf4j.Logger;
13+
import org.slf4j.LoggerFactory;
14+
15+
public class DataStreamsTransactionExtractors {
16+
public static final DataStreamsTransactionExtractors EMPTY =
17+
new DataStreamsTransactionExtractors(Collections.emptyList());
18+
private static final Logger log = LoggerFactory.getLogger(DataStreamsTransactionExtractors.class);
19+
private static final Moshi MOSHI =
20+
new Moshi.Builder()
21+
.add(new DataStreamsTransactionExtractors.DataStreamsTransactionExtractorAdapter())
22+
.build();
23+
private static final ParameterizedType LIST_OF_RULES =
24+
Types.newParameterizedType(List.class, DataStreamsTransactionExtractor.class);
25+
private static final JsonAdapter<List<DataStreamsTransactionExtractor>> LIST_OF_RULES_ADAPTER =
26+
MOSHI.adapter(LIST_OF_RULES);
27+
28+
private final List<DataStreamsTransactionExtractor> extractors;
29+
30+
public DataStreamsTransactionExtractors(List<DataStreamsTransactionExtractor> extractors) {
31+
this.extractors = Collections.unmodifiableList(extractors);
32+
}
33+
34+
public static DataStreamsTransactionExtractors deserialize(String json) {
35+
try {
36+
return new DataStreamsTransactionExtractors(LIST_OF_RULES_ADAPTER.fromJson(json));
37+
} catch (Throwable ex) {
38+
log.error("Couldn't parse Data Streams Extractors from JSON: {}", json, ex);
39+
}
40+
41+
return EMPTY;
42+
}
43+
44+
public List<DataStreamsTransactionExtractor> getExtractors() {
45+
return extractors;
46+
}
47+
48+
private static final class JsonDataStreamsTransactionExtractor {
49+
private static final JsonAdapter<JsonDataStreamsTransactionExtractor> jsonAdapter =
50+
MOSHI.adapter(JsonDataStreamsTransactionExtractor.class);
51+
String name;
52+
String type;
53+
String value;
54+
55+
@Override
56+
public String toString() {
57+
return jsonAdapter.toJson(this);
58+
}
59+
}
60+
61+
private static final class DataStreamsTransactionExtractorAdapter {
62+
private static DataStreamsTransactionExtractor create(
63+
JsonDataStreamsTransactionExtractor jsonExtractor) {
64+
return new DataStreamsTransactionExtractor(
65+
jsonExtractor.name, jsonExtractor.type, jsonExtractor.value);
66+
}
67+
68+
@FromJson
69+
DataStreamsTransactionExtractor fromJson(JsonDataStreamsTransactionExtractor jsonExtractor) {
70+
return create(jsonExtractor);
71+
}
72+
73+
@ToJson
74+
JsonDataStreamsTransactionExtractor toJson(DataStreamsTransactionExtractor extractor) {
75+
throw new UnsupportedOperationException();
76+
}
77+
}
78+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package datadog.trace.core.datastreams
2+
3+
import datadog.trace.core.test.DDCoreSpecification
4+
5+
class DataStreamsTransactionExtractorsTest extends DDCoreSpecification {
6+
def "Deserialize from json"() {
7+
when:
8+
def list = DataStreamsTransactionExtractors.deserialize("""[
9+
{"name": "extractor", "type": "http_request_header", "value": "transaction_id"},
10+
{"name": "second_extractor", "type": "http_response_header", "value": "transaction_id"}
11+
]""")
12+
def extractors = list.getExtractors()
13+
then:
14+
extractors.size() == 2
15+
extractors[0].getName() == "extractor"
16+
extractors[0].getType() == "http_request_header"
17+
extractors[0].getValue() == "transaction_id"
18+
extractors[1].getName() == "second_extractor"
19+
extractors[1].getType() == "http_response_header"
20+
extractors[1].getValue() == "transaction_id"
21+
}
22+
}

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,7 @@
351351
import static datadog.trace.api.config.GeneralConfig.DATA_JOBS_PARSE_SPARK_PLAN_ENABLED;
352352
import static datadog.trace.api.config.GeneralConfig.DATA_STREAMS_BUCKET_DURATION_SECONDS;
353353
import static datadog.trace.api.config.GeneralConfig.DATA_STREAMS_ENABLED;
354+
import static datadog.trace.api.config.GeneralConfig.DATA_STREAMS_TRANSACTION_EXTRACTORS;
354355
import static datadog.trace.api.config.GeneralConfig.DOGSTATSD_ARGS;
355356
import static datadog.trace.api.config.GeneralConfig.DOGSTATSD_HOST;
356357
import static datadog.trace.api.config.GeneralConfig.DOGSTATSD_NAMED_PIPE;
@@ -1200,6 +1201,7 @@ public static String getHostName() {
12001201

12011202
private final boolean dataStreamsEnabled;
12021203
private final float dataStreamsBucketDurationSeconds;
1204+
private final String dataStreamsTransactionExtractors;
12031205

12041206
private final boolean serviceDiscoveryEnabled;
12051207

@@ -2645,6 +2647,8 @@ PROFILING_DATADOG_PROFILER_ENABLED, isDatadogProfilerSafeInCurrentEnvironment())
26452647
dataStreamsBucketDurationSeconds =
26462648
configProvider.getFloat(
26472649
DATA_STREAMS_BUCKET_DURATION_SECONDS, DEFAULT_DATA_STREAMS_BUCKET_DURATION);
2650+
dataStreamsTransactionExtractors =
2651+
configProvider.getString(DATA_STREAMS_TRANSACTION_EXTRACTORS);
26482652

26492653
azureAppServices = configProvider.getBoolean(AZURE_APP_SERVICES, false);
26502654
traceAgentPath = configProvider.getString(TRACE_AGENT_PATH);
@@ -4447,6 +4451,10 @@ public float getDataStreamsBucketDurationSeconds() {
44474451
return dataStreamsBucketDurationSeconds;
44484452
}
44494453

4454+
public String getDataStreamsTransactionExtractors() {
4455+
return dataStreamsTransactionExtractors;
4456+
}
4457+
44504458
public long getDataStreamsBucketDurationNanoseconds() {
44514459
// Rounds to the nearest millisecond before converting to nanos
44524460
int milliseconds = Math.round(dataStreamsBucketDurationSeconds * 1000);

internal-api/src/main/java/datadog/trace/api/DynamicConfig.java

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import static datadog.trace.util.ConfigStrings.normalizedHeaderTag;
1515
import static datadog.trace.util.ConfigStrings.trim;
1616

17+
import datadog.trace.api.datastreams.DataStreamsTransactionExtractor;
1718
import datadog.trace.api.sampling.SamplingRule.SpanSamplingRule;
1819
import datadog.trace.api.sampling.SamplingRule.TraceSamplingRule;
1920
import java.util.Collection;
@@ -111,6 +112,8 @@ public final class Builder {
111112
Double traceSampleRate;
112113

113114
String preferredServiceName;
115+
List<DataStreamsTransactionExtractor> dataStreamsTransactionExtractors;
116+
String dataStreamsTransactionExtractorsJson;
114117

115118
Builder() {}
116119

@@ -134,6 +137,8 @@ public final class Builder {
134137
this.tracingTags = snapshot.tracingTags;
135138

136139
this.preferredServiceName = snapshot.preferredServiceName;
140+
this.dataStreamsTransactionExtractors = snapshot.dataStreamsTransactionExtractors;
141+
this.dataStreamsTransactionExtractorsJson = snapshot.dataStreamsTransactionExtractorsJson;
137142
}
138143

139144
public Builder setRuntimeMetricsEnabled(boolean runtimeMetricsEnabled) {
@@ -151,6 +156,14 @@ public Builder setDataStreamsEnabled(boolean dataStreamsEnabled) {
151156
return this;
152157
}
153158

159+
public Builder setDataStreamsTransactionExtractors(
160+
List<DataStreamsTransactionExtractor> dataStreamsTransactionExtractors,
161+
String dataStreamsTransactionExtractorsJson) {
162+
this.dataStreamsTransactionExtractors = dataStreamsTransactionExtractors;
163+
this.dataStreamsTransactionExtractorsJson = dataStreamsTransactionExtractorsJson;
164+
return this;
165+
}
166+
154167
public Builder setServiceMapping(Map<String, String> serviceMapping) {
155168
return setServiceMapping(serviceMapping.entrySet());
156169
}
@@ -324,6 +337,8 @@ public static class Snapshot implements TraceConfig {
324337
final Map<String, String> tracingTags;
325338

326339
final String preferredServiceName;
340+
final List<DataStreamsTransactionExtractor> dataStreamsTransactionExtractors;
341+
final String dataStreamsTransactionExtractorsJson;
327342

328343
protected Snapshot(DynamicConfig<?>.Builder builder, Snapshot oldSnapshot) {
329344

@@ -345,6 +360,8 @@ protected Snapshot(DynamicConfig<?>.Builder builder, Snapshot oldSnapshot) {
345360
this.tracingTags = nullToEmpty(builder.tracingTags);
346361

347362
this.preferredServiceName = builder.preferredServiceName;
363+
this.dataStreamsTransactionExtractors = builder.dataStreamsTransactionExtractors;
364+
this.dataStreamsTransactionExtractorsJson = builder.dataStreamsTransactionExtractorsJson;
348365
}
349366

350367
private static <K, V> Map<K, V> nullToEmpty(Map<K, V> mapping) {
@@ -415,6 +432,11 @@ public List<? extends TraceSamplingRule> getTraceSamplingRules() {
415432
return traceSamplingRules;
416433
}
417434

435+
@Override
436+
public List<DataStreamsTransactionExtractor> getDataStreamsTransactionExtractors() {
437+
return dataStreamsTransactionExtractors;
438+
}
439+
418440
@Override
419441
public Map<String, String> getTracingTags() {
420442
return tracingTags;

internal-api/src/main/java/datadog/trace/api/TraceConfig.java

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

3+
import datadog.trace.api.datastreams.DataStreamsTransactionExtractor;
34
import datadog.trace.api.sampling.SamplingRule.SpanSamplingRule;
45
import datadog.trace.api.sampling.SamplingRule.TraceSamplingRule;
56
import java.util.List;
@@ -46,4 +47,11 @@ public interface TraceConfig {
4647
* @return The tracer sampler Trace Sampling Rules, or an empty collection if no rule is defined.
4748
*/
4849
List<? extends TraceSamplingRule> getTraceSamplingRules();
50+
51+
/**
52+
* Get DSM transaction extractors.
53+
*
54+
* @return List of Data Streams Transactions extractors.
55+
*/
56+
List<DataStreamsTransactionExtractor> getDataStreamsTransactionExtractors();
4957
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package datadog.trace.api.datastreams;
2+
3+
public final class DataStreamsTransactionExtractor {
4+
private final String name;
5+
private final String type;
6+
private final String value;
7+
8+
public DataStreamsTransactionExtractor(final String name, final String type, final String value) {
9+
this.name = name;
10+
this.type = type;
11+
this.value = value;
12+
}
13+
14+
public String getName() {
15+
return name;
16+
}
17+
18+
public String getType() {
19+
return type;
20+
}
21+
22+
public String getValue() {
23+
return value;
24+
}
25+
}

internal-api/src/main/java/datadog/trace/bootstrap/instrumentation/api/AgentTracer.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import datadog.trace.api.EndpointTracker;
77
import datadog.trace.api.TraceConfig;
88
import datadog.trace.api.datastreams.AgentDataStreamsMonitoring;
9+
import datadog.trace.api.datastreams.DataStreamsTransactionExtractor;
910
import datadog.trace.api.datastreams.NoopDataStreamsMonitoring;
1011
import datadog.trace.api.experimental.DataStreamsCheckpointer;
1112
import datadog.trace.api.gateway.CallbackProvider;
@@ -797,5 +798,10 @@ public List<? extends SamplingRule.SpanSamplingRule> getSpanSamplingRules() {
797798
public List<? extends SamplingRule.TraceSamplingRule> getTraceSamplingRules() {
798799
return Collections.emptyList();
799800
}
801+
802+
@Override
803+
public List<DataStreamsTransactionExtractor> getDataStreamsTransactionExtractors() {
804+
return null;
805+
}
800806
}
801807
}

0 commit comments

Comments
 (0)