Skip to content

Commit eb834d3

Browse files
committed
init benchmarking
1 parent 032aad2 commit eb834d3

File tree

5 files changed

+173
-82
lines changed

5 files changed

+173
-82
lines changed

dd-java-agent/agent-bootstrap/src/main/java/datadog/trace/bootstrap/instrumentation/decorator/HttpServerDecorator.java

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import static datadog.trace.api.cache.RadixTreeCache.UNSET_STATUS;
55
import static datadog.trace.api.datastreams.DataStreamsContext.forHttpServer;
66
import static datadog.trace.api.gateway.Events.EVENTS;
7+
import static datadog.trace.bootstrap.instrumentation.api.AgentPropagation.extractContextAndGetSpanContext;
78
import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.traceConfig;
89
import static datadog.trace.bootstrap.instrumentation.decorator.http.HttpResourceDecorator.HTTP_RESOURCE_DECORATOR;
910

@@ -12,6 +13,7 @@
1213
import datadog.context.propagation.Propagators;
1314
import datadog.trace.api.Config;
1415
import datadog.trace.api.DDTags;
16+
import datadog.trace.api.TraceConfig;
1517
import datadog.trace.api.function.TriConsumer;
1618
import datadog.trace.api.function.TriFunction;
1719
import datadog.trace.api.gateway.BlockResponseFunction;
@@ -56,7 +58,6 @@ public abstract class HttpServerDecorator<REQUEST, CONNECTION, RESPONSE, REQUEST
5658

5759
public static final String DD_SPAN_ATTRIBUTE = "datadog.span";
5860
public static final String DD_DISPATCH_SPAN_ATTRIBUTE = "datadog.span.dispatch";
59-
public static final String DD_RUM_INJECTED = "datadog.rum.injected";
6061
public static final String DD_FIN_DISP_LIST_SPAN_ATTRIBUTE =
6162
"datadog.span.finish_dispatch_listener";
6263
public static final String DD_RESPONSE_ATTRIBUTE = "datadog.response";
@@ -118,14 +119,32 @@ protected AgentTracer.TracerAPI tracer() {
118119
return AgentTracer.get();
119120
}
120121

121-
public Context extract(REQUEST_CARRIER carrier) {
122+
/** Deprecated. Use {@link #extractContext(REQUEST_CARRIER)} instead. */
123+
public AgentSpanContext.Extracted extract(REQUEST_CARRIER carrier) {
124+
AgentPropagation.ContextVisitor<REQUEST_CARRIER> getter = getter();
125+
if (null == carrier || null == getter) {
126+
return null;
127+
}
128+
return extractContextAndGetSpanContext(carrier, getter);
129+
}
130+
131+
/**
132+
* Will be renamed to #extract(REQUEST_CARRIER) when refactoring of instrumentations is complete
133+
*/
134+
public Context extractContext(REQUEST_CARRIER carrier) {
122135
AgentPropagation.ContextVisitor<REQUEST_CARRIER> getter = getter();
123136
if (null == carrier || null == getter) {
124137
return root();
125138
}
126139
return Propagators.defaultPropagator().extract(root(), carrier, getter);
127140
}
128141

142+
/** Deprecated. Use {@link #startSpan(Object, Context)} instead. */
143+
@Deprecated
144+
public AgentSpan startSpan(REQUEST_CARRIER carrier, AgentSpanContext.Extracted context) {
145+
return startSpan("http-server", carrier, context);
146+
}
147+
129148
public AgentSpan startSpan(
130149
String instrumentationName, REQUEST_CARRIER carrier, AgentSpanContext.Extracted context) {
131150
AgentSpan span =
@@ -361,8 +380,9 @@ public AgentSpan onResponse(final AgentSpan span, final RESPONSE response) {
361380

362381
AgentPropagation.ContextVisitor<RESPONSE> getter = responseGetter();
363382
if (getter != null) {
383+
TraceConfig tc = traceConfig(span);
364384
ResponseHeaderTagClassifier tagger =
365-
ResponseHeaderTagClassifier.create(span, traceConfig(span).getResponseHeaderTags());
385+
ResponseHeaderTagClassifier.create(span, tc.getResponseHeaderTags());
366386
if (tagger != null) {
367387
getter.forEachKey(response, tagger);
368388
}
@@ -629,7 +649,7 @@ static ResponseHeaderTagClassifier create(AgentSpan span, Map<String, String> he
629649
public ResponseHeaderTagClassifier(AgentSpan span, Map<String, String> headerTags) {
630650
this.span = span;
631651
this.headerTags = headerTags;
632-
this.wildcardHeaderPrefix = this.headerTags.get("*");
652+
this.wildcardHeaderPrefix = this.headerTags.getOrDefault("*", null);
633653
}
634654

635655
@Override

dd-java-agent/agent-bootstrap/src/test/groovy/datadog/trace/bootstrap/instrumentation/decorator/HttpServerDecoratorTest.groovy

Lines changed: 72 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import datadog.trace.api.gateway.Flow
77
import datadog.trace.api.gateway.InstrumentationGateway
88
import datadog.trace.api.gateway.RequestContext
99
import datadog.trace.api.gateway.RequestContextSlot
10-
import datadog.trace.api.TraceConfig
10+
import datadog.trace.api.TraceConfig;
1111
import datadog.trace.bootstrap.ActiveSubsystems
1212
import datadog.trace.bootstrap.instrumentation.api.AgentPropagation
1313
import datadog.trace.bootstrap.instrumentation.api.AgentSpan
@@ -35,17 +35,6 @@ class HttpServerDecoratorTest extends ServerDecoratorTest {
3535

3636
def span = Mock(AgentSpan)
3737

38-
static class MapCarrierVisitor
39-
implements AgentPropagation.ContextVisitor<Map> {
40-
@Override
41-
void forEachKey(Map carrier, AgentPropagation.KeyClassifier classifier) {
42-
Map<String, String> headers = carrier.headers
43-
headers?.each {
44-
classifier.accept(it.key, it.value)
45-
}
46-
}
47-
}
48-
4938
boolean origAppSecActive
5039

5140
void setup() {
@@ -364,103 +353,111 @@ class HttpServerDecoratorTest extends ServerDecoratorTest {
364353

365354
def "test response headers with trace.header.tags"() {
366355
setup:
367-
def traceConfig = Mock(TraceConfig)
368-
traceConfig.getResponseHeaderTags() >> headerTags
369-
370-
def tags = [:]
356+
injectSysConfig("trace.header.tags", headerTags)
357+
def traceConfig = Mock(TraceConfig) {
358+
getResponseHeaderTags() >> [(headerTags.split(":")[0].toLowerCase()): headerTags.split(":")[1]]
359+
}
371360

372361
def responseSpan = Mock(AgentSpan)
373362
responseSpan.traceConfig() >> traceConfig
374-
responseSpan.setTag(_, _) >> { String k, String v ->
375-
tags[k] = v
376-
return responseSpan
377-
}
378-
379-
def decorator = newDecorator(null, new MapCarrierVisitor())
363+
364+
def decorator = newDecorator()
380365

381366
when:
367+
println "Groovy mock span class: ${responseSpan.getClass().name}"
368+
println "Direct call: " + responseSpan.traceConfig()
369+
382370
decorator.onResponse(responseSpan, resp)
383371

384372
then:
385-
if (expectedTag){
386-
expectedTag.each {
387-
assert tags[it.key] == it.value
388-
}
373+
for (Map.Entry<String, String> entry : expectedTag.entrySet()) {
374+
assert responseSpan.getTag(entry.getKey()).equals(entry.getValue())
389375
}
390376

391377
where:
392-
headerTags | resp | expectedTag
393-
[:] | [status: 200, headers: ['X-Custom-Header': 'custom-value', 'Content-Type': 'application/json']] | [:]
394-
["x-custom-header": "abc"] | [status: 200, headers: ['X-Custom-Header': 'custom-value', 'Content-Type': 'application/json']] | [abc:"custom-value"]
395-
["*": "datadog.response.headers."] | [status: 200, headers: ['X-Custom-Header': 'custom-value', 'Content-Type': 'application/json']] | ["datadog.response.headers.x-custom-header":"custom-value", "datadog.response.headers.content-type":"application/json"]
378+
headerTags | resp | expectedTag
379+
"X-Custom-Header:abc" | [status: 200, headers: ['X-Custom-Header': 'custom-value', 'Content-Type': 'application/json']] | [abc:"custom-value"]
396380
}
397381

398382
@Override
399383
def newDecorator() {
400-
return newDecorator(null, null)
384+
return newDecorator(null)
401385
}
402386

403-
def newDecorator(TracerAPI tracer, AgentPropagation.ContextVisitor<Map> contextVisitor) {
387+
def newDecorator(TracerAPI tracer) {
404388
if (!tracer) {
405389
tracer = AgentTracer.NOOP_TRACER
406390
}
407391

408392
return new HttpServerDecorator<Map, Map, Map, Map<String, String>>() {
409-
@Override
410-
protected TracerAPI tracer() {
411-
return tracer
412-
}
393+
@Override
394+
protected TracerAPI tracer() {
395+
return tracer
396+
}
413397

414-
@Override
415-
protected String[] instrumentationNames() {
416-
return ["test1", "test2"]
417-
}
398+
@Override
399+
protected String[] instrumentationNames() {
400+
return ["test1", "test2"]
401+
}
418402

419-
@Override
420-
protected CharSequence component() {
421-
return "test-component"
422-
}
403+
@Override
404+
protected CharSequence component() {
405+
return "test-component"
406+
}
423407

424-
@Override
425-
protected AgentPropagation.ContextVisitor<Map<String, String>> getter() {
426-
return ContextVisitors.stringValuesMap()
427-
}
408+
@Override
409+
protected AgentPropagation.ContextVisitor<Map<String, String>> getter() {
410+
return ContextVisitors.stringValuesMap()
411+
}
428412

429-
@Override
430-
protected AgentPropagation.ContextVisitor<Map> responseGetter() {
431-
return contextVisitor
432-
}
413+
@Override
414+
protected AgentPropagation.ContextVisitor<Map> responseGetter() {
415+
return new MapCarrierVisitor()
416+
}
433417

434-
@Override
435-
CharSequence spanName() {
436-
return "http-test-span"
437-
}
418+
@Override
419+
CharSequence spanName() {
420+
return "http-test-span"
421+
}
438422

439-
@Override
440-
protected String method(Map m) {
441-
return m.method
442-
}
423+
@Override
424+
protected String method(Map m) {
425+
return m.method
426+
}
443427

444-
@Override
445-
protected URIDataAdapter url(Map m) {
446-
return m.url == null ? null : new URIDefaultDataAdapter(m.url)
447-
}
428+
@Override
429+
protected URIDataAdapter url(Map m) {
430+
return m.url == null ? null : new URIDefaultDataAdapter(m.url)
431+
}
448432

449-
@Override
450-
protected String peerHostIP(Map m) {
451-
return m.peerIp
452-
}
433+
@Override
434+
protected String peerHostIP(Map m) {
435+
return m.peerIp
436+
}
453437

454-
@Override
455-
protected int peerPort(Map m) {
456-
return m.port == null ? 0 : m.port
457-
}
438+
@Override
439+
protected int peerPort(Map m) {
440+
return m.port == null ? 0 : m.port
441+
}
458442

443+
@Override
444+
protected int status(Map m) {
445+
return m.status == null ? 0 : m.status
446+
}
447+
448+
static class MapCarrierVisitor
449+
implements AgentPropagation.ContextVisitor<Map> {
459450
@Override
460-
protected int status(Map m) {
461-
return m.status == null ? 0 : m.status
451+
void forEachKey(Map carrier, AgentPropagation.KeyClassifier classifier) {
452+
Map<String, String> headers = carrier.headers
453+
if (headers != null) {
454+
for (Map.Entry<String, String> entry : headers.entrySet()) {
455+
classifier.accept(entry.key, entry.value)
456+
}
457+
}
462458
}
463459
}
460+
}
464461
}
465462

466463
def "test startSpan and InstrumentationGateway"() {
@@ -494,7 +491,7 @@ class HttpServerDecoratorTest extends ServerDecoratorTest {
494491
getUniversalCallbackProvider() >> cbpAppSec // no iast callbacks, so this is equivalent
495492
getDataStreamsMonitoring() >> Mock(DataStreamsMonitoring)
496493
}
497-
def decorator = newDecorator(mTracer, null)
494+
def decorator = newDecorator(mTracer)
498495

499496
when:
500497
decorator.startSpan("test", headers, null)

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* <pre>
77
* DDTracer.builder().withProperties(new Properties()).build()
88
* </pre>
9-
*
9+
* <p>
1010
* If using dd-java-agent, these keys represent settings that should be configured via system
1111
* properties, environment variables, or config properties file. See online documentation for
1212
* details.
@@ -111,5 +111,6 @@ public final class GeneralConfig {
111111
public static final String SSI_INJECTION_FORCE = "inject.force";
112112
public static final String INSTRUMENTATION_SOURCE = "instrumentation.source";
113113

114-
private GeneralConfig() {}
114+
private GeneralConfig() {
115+
}
115116
}
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
package datadog.telemetry.configsources;
2+
3+
import static datadog.trace.api.config.GeneralConfig.ENV;
4+
import static datadog.trace.api.config.GeneralConfig.SERVICE_NAME;
5+
import static datadog.trace.api.config.GeneralConfig.VERSION;
6+
import static java.util.concurrent.TimeUnit.MILLISECONDS;
7+
8+
import java.net.URI;
9+
import java.util.ArrayList;
10+
import java.util.List;
11+
import java.util.Properties;
12+
13+
import datadog.communication.ddagent.DDAgentFeaturesDiscovery;
14+
import datadog.communication.monitor.Monitoring;
15+
import datadog.telemetry.TelemetryRunnable;
16+
import datadog.telemetry.TelemetryService;
17+
import datadog.trace.api.Config;
18+
import datadog.trace.core.baggage.BaggagePropagator;
19+
import org.openjdk.jmh.annotations.Benchmark;
20+
import org.openjdk.jmh.annotations.BenchmarkMode;
21+
import org.openjdk.jmh.annotations.Level;
22+
import org.openjdk.jmh.annotations.Measurement;
23+
import org.openjdk.jmh.annotations.Mode;
24+
import org.openjdk.jmh.annotations.OutputTimeUnit;
25+
import org.openjdk.jmh.annotations.Scope;
26+
import org.openjdk.jmh.annotations.Setup;
27+
import org.openjdk.jmh.annotations.State;
28+
import org.openjdk.jmh.annotations.Warmup;
29+
30+
@OutputTimeUnit(MILLISECONDS)
31+
@BenchmarkMode(Mode.Throughput)
32+
@State(Scope.Benchmark)
33+
public class ConfigSourcesBenchmark {
34+
35+
// Simple mock for DDAgentFeaturesDiscovery for benchmarking purposes
36+
private static class MockFeaturesDiscovery extends DDAgentFeaturesDiscovery {
37+
private final boolean supportsDataStreams;
38+
39+
public MockFeaturesDiscovery(boolean supportsDataStreams) {
40+
super(null, Monitoring.DISABLED, null, true, true);
41+
this.supportsDataStreams = supportsDataStreams;
42+
}
43+
44+
@Override
45+
public void discover() {}
46+
47+
@Override
48+
public void discoverIfOutdated() {}
49+
50+
@Override
51+
public boolean supportsDataStreams() {
52+
return supportsDataStreams;
53+
}
54+
}
55+
56+
private Properties props;
57+
TelemetryRunnable telemetryRunnable;
58+
@Setup(Level.Trial)
59+
public void setUp() {
60+
props = new Properties();
61+
props.setProperty(SERVICE_NAME, "benchmark-service");
62+
props.setProperty(ENV, "benchmark-env");
63+
props.setProperty(VERSION, "1");
64+
DDAgentFeaturesDiscovery featuresDiscovery = new MockFeaturesDiscovery(false);
65+
TelemetryService service = TelemetryService.build(featuresDiscovery, null, null, false, false);
66+
telemetryRunnable = new TelemetryRunnable(service, new ArrayList<>());
67+
}
68+
@Benchmark
69+
public void runTelemetry() {
70+
Config c = Config.get(props);
71+
telemetryRunnable.run();
72+
}
73+
}

telemetry/src/main/java/datadog/telemetry/TelemetryRunnable.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ private List<MetricPeriodicAction> findMetricPeriodicActions(
5858
@Override
5959
public void run() {
6060
// Ensure that Config has been initialized, so ConfigCollector can collect all settings first.
61-
Config.get();
61+
// Config.get();
6262

6363
collectConfigChanges();
6464

0 commit comments

Comments
 (0)