Skip to content

init #9141

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from
Draft

init #9141

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import datadog.trace.bootstrap.instrumentation.api.AgentSpanContext;
import datadog.trace.bootstrap.instrumentation.api.AgentTracer;
import datadog.trace.bootstrap.instrumentation.api.ErrorPriorities;
import datadog.trace.bootstrap.instrumentation.api.InferredProxyContext;
import datadog.trace.bootstrap.instrumentation.api.InternalSpanTypes;
import datadog.trace.bootstrap.instrumentation.api.ResourceNamePriorities;
import datadog.trace.bootstrap.instrumentation.api.TagContext;
Expand Down Expand Up @@ -128,6 +129,7 @@ public Context extract(REQUEST_CARRIER carrier) {

public AgentSpan startSpan(
String instrumentationName, REQUEST_CARRIER carrier, AgentSpanContext.Extracted context) {

AgentSpan span =
tracer()
.startSpan(instrumentationName, spanName(), callIGCallbackStart(context))
Expand All @@ -144,6 +146,12 @@ public AgentSpan startSpan(
}

public AgentSpan startSpan(REQUEST_CARRIER carrier, Context context) {
if (Config.get().isTraceInferredProxyServicesEnabled()){
InferredProxyContext inferredContext = InferredProxyContext.fromContext(context);
if (Context.root() != inferredContext){
return startInferredProxySpan("http-server", carrier, inferredContext, context);
}
}
return startSpan("http-server", carrier, getExtractedSpanContext(context));
}

Expand All @@ -152,6 +160,11 @@ public AgentSpanContext.Extracted getExtractedSpanContext(Context context) {
return extractedSpan == null ? null : (AgentSpanContext.Extracted) extractedSpan.context();
}

public AgentSpan startInferredProxySpan(String instrumentationName, REQUEST_CARRIER carrier, InferredProxyContext inferredContext, Context context){
// AgentSpan span = tracer().startSpan(instrumentationName, )
return null;
}

public AgentSpan onRequest(
final AgentSpan span,
final CONNECTION connection,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ public final class ConfigDefaults {
new LinkedHashSet<>(asList(PropagationStyle.DATADOG));
static final int DEFAULT_TRACE_BAGGAGE_MAX_ITEMS = 64;
static final int DEFAULT_TRACE_BAGGAGE_MAX_BYTES = 8192;
static final boolean DEFAULT_TRACE_INFERRED_PROXY_SERVICES_ENABLED = false;
static final boolean DEFAULT_JMX_FETCH_ENABLED = true;
static final boolean DEFAULT_TRACE_AGENT_V05_ENABLED = false;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,9 @@ public final class TracerConfig {
public static final String TRACE_BAGGAGE_MAX_ITEMS = "trace.baggage.max.items";
public static final String TRACE_BAGGAGE_MAX_BYTES = "trace.baggage.max.bytes";

public static final String TRACE_INFERRED_PROXY_SERVICES_ENABLED =
"trace.inferred.proxy.services.enabled";

public static final String ENABLE_TRACE_AGENT_V05 = "trace.agent.v0.5.enabled";

public static final String CLIENT_IP_ENABLED = "trace.client-ip.enabled";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import static datadog.trace.api.TracePropagationBehaviorExtract.IGNORE;
import static datadog.trace.bootstrap.instrumentation.api.AgentPropagation.BAGGAGE_CONCERN;
import static datadog.trace.bootstrap.instrumentation.api.AgentPropagation.DSM_CONCERN;
import static datadog.trace.bootstrap.instrumentation.api.AgentPropagation.INFERRED_PROXY_CONCERN;
import static datadog.trace.bootstrap.instrumentation.api.AgentPropagation.TRACING_CONCERN;
import static datadog.trace.bootstrap.instrumentation.api.AgentPropagation.XRAY_TRACING_CONCERN;
import static datadog.trace.common.metrics.MetricsAggregatorFactory.createMetricsAggregator;
Expand Down Expand Up @@ -77,6 +78,7 @@
import datadog.trace.common.writer.WriterFactory;
import datadog.trace.common.writer.ddintake.DDIntakeTraceInterceptor;
import datadog.trace.context.TraceScope;
import datadog.trace.core.apigw.InferredProxyPropagator;
import datadog.trace.core.baggage.BaggagePropagator;
import datadog.trace.core.datastreams.DataStreamsMonitoring;
import datadog.trace.core.datastreams.DefaultDataStreamsMonitoring;
Expand Down Expand Up @@ -720,6 +722,9 @@ private CoreTracer(
&& config.getTracePropagationBehaviorExtract() != IGNORE) {
Propagators.register(BAGGAGE_CONCERN, new BaggagePropagator(config));
}
if (config.isTraceInferredProxyServicesEnabled()) {
Propagators.register(INFERRED_PROXY_CONCERN, new InferredProxyPropagator());
}

this.tagInterceptor =
null == tagInterceptor ? new TagInterceptor(new RuleFlags(config)) : tagInterceptor;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
package datadog.trace.core.apigw;

import datadog.context.Context;
import datadog.context.propagation.CarrierSetter;
import datadog.context.propagation.CarrierVisitor;
import datadog.context.propagation.Propagator;
import datadog.trace.bootstrap.instrumentation.api.InferredProxyContext;
import datadog.trace.core.CoreTracer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.function.BiConsumer;

public class InferredProxyPropagator implements Propagator {
private static final Logger log = LoggerFactory.getLogger(InferredProxyPropagator.class);
static final String INFERRED_PROXY_KEY = "x-dd-proxy";
static final String REQUEST_TIME_KEY = "x-dd-proxy-request-time-ms";
static final String DOMAIN_NAME_KEY = "x-dd-proxy-domain-name";
static final String HTTP_METHOD_KEY = "x-dd-proxy-httpmethod";
static final String PATH_KEY = "x-dd-proxy-path";
static final String STAGE_KEY = "x-dd-proxy-stage";

/**
* METHOD STUB: InferredProxy is currently not meant to be injected to downstream services
*
* @param context the context containing the values to be injected.
* @param carrier the instance that will receive the key/value pairs to propagate.
* @param setter the callback to set key/value pairs into the carrier.
*/
@Override
public <C> void inject(Context context, C carrier, CarrierSetter<C> setter) {}

/**
* Extracts an InferredProxyContext from un upstream service and stores it as part of the Context object
*
* @param context the base context to store the extracted values on top, use {@link
* Context#root()} for a default base context.
* @param carrier the instance to fetch the propagated key/value pairs from.
* @param visitor the callback to walk over the carrier and extract its key/value pais.
* @return A context with the extracted values on top of the given base context.
*/
@Override
public <C> Context extract(Context context, C carrier, CarrierVisitor<C> visitor) {
if (context == null || carrier == null || visitor == null) {
return context;
}
InferredProxyContextExtractor extractor = new InferredProxyContextExtractor();
visitor.forEachKeyValue(carrier, extractor);

InferredProxyContext extractedContext = extractor.extractedContext;
// Mandatory headers for APIGW
if (extractedContext == null || !extractedContext.validContext()) {
return context;
}
return context.with(extractedContext);
}

public static class InferredProxyContextExtractor implements BiConsumer<String, String> {
private InferredProxyContext extractedContext;

InferredProxyContextExtractor() {}

/**
* Performs this operation on the given arguments.
*
* @param key the first input argument from an http header
* @param value the second input argument from an http header
*/
@Override
public void accept(String key, String value) {
if (key == null || key.isEmpty() || !key.startsWith(INFERRED_PROXY_KEY)) {
return;
}

if (extractedContext == null) {
extractedContext = new InferredProxyContext();
}

switch (key) {
case INFERRED_PROXY_KEY:
if (value.equals("aws.apigateway")){
extractedContext.setProxyName(value);
}
break;
case REQUEST_TIME_KEY:
extractedContext.setStartTime(value);
break;
case DOMAIN_NAME_KEY:
extractedContext.setDomainName(value);
break;
case HTTP_METHOD_KEY:
extractedContext.setHttpMethod(value);
break;
case PATH_KEY:
extractedContext.setPath(value);
break;
case STAGE_KEY:
extractedContext.setStage(value);
break;
default:
log.info("Extracting Inferred Proxy header that doesn't match accepted Inferred Proxy keys");
}
}
}
}
11 changes: 11 additions & 0 deletions internal-api/src/main/java/datadog/trace/api/Config.java
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@
import static datadog.trace.api.ConfigDefaults.DEFAULT_TRACE_CLOUD_PAYLOAD_TAGGING_SERVICES;
import static datadog.trace.api.ConfigDefaults.DEFAULT_TRACE_EXPERIMENTAL_FEATURES_ENABLED;
import static datadog.trace.api.ConfigDefaults.DEFAULT_TRACE_HTTP_RESOURCE_REMOVE_TRAILING_SLASH;
import static datadog.trace.api.ConfigDefaults.DEFAULT_TRACE_INFERRED_PROXY_SERVICES_ENABLED;
import static datadog.trace.api.ConfigDefaults.DEFAULT_TRACE_KEEP_LATENCY_THRESHOLD_MS;
import static datadog.trace.api.ConfigDefaults.DEFAULT_TRACE_LONG_RUNNING_ENABLED;
import static datadog.trace.api.ConfigDefaults.DEFAULT_TRACE_LONG_RUNNING_FLUSH_INTERVAL;
Expand Down Expand Up @@ -597,6 +598,7 @@
import static datadog.trace.api.config.TracerConfig.TRACE_HTTP_RESOURCE_REMOVE_TRAILING_SLASH;
import static datadog.trace.api.config.TracerConfig.TRACE_HTTP_SERVER_ERROR_STATUSES;
import static datadog.trace.api.config.TracerConfig.TRACE_HTTP_SERVER_PATH_RESOURCE_NAME_MAPPING;
import static datadog.trace.api.config.TracerConfig.TRACE_INFERRED_PROXY_SERVICES_ENABLED;
import static datadog.trace.api.config.TracerConfig.TRACE_KEEP_LATENCY_THRESHOLD_MS;
import static datadog.trace.api.config.TracerConfig.TRACE_LONG_RUNNING_ENABLED;
import static datadog.trace.api.config.TracerConfig.TRACE_LONG_RUNNING_FLUSH_INTERVAL;
Expand Down Expand Up @@ -823,6 +825,7 @@ public static String getHostName() {
private final boolean tracePropagationExtractFirst;
private final int traceBaggageMaxItems;
private final int traceBaggageMaxBytes;
private final boolean traceInferredProxyServicesEnabled;
private final int clockSyncPeriod;
private final boolean logsInjectionEnabled;

Expand Down Expand Up @@ -1717,6 +1720,8 @@ private Config(final ConfigProvider configProvider, final InstrumenterConfig ins
configProvider.getBoolean(
TRACE_PROPAGATION_EXTRACT_FIRST, DEFAULT_TRACE_PROPAGATION_EXTRACT_FIRST);

traceInferredProxyServicesEnabled = configProvider.getBoolean(TRACE_INFERRED_PROXY_SERVICES_ENABLED, DEFAULT_TRACE_INFERRED_PROXY_SERVICES_ENABLED);

clockSyncPeriod = configProvider.getInteger(CLOCK_SYNC_PERIOD, DEFAULT_CLOCK_SYNC_PERIOD);

if (experimentalFeaturesEnabled.contains(
Expand Down Expand Up @@ -3115,6 +3120,10 @@ public int getTraceBaggageMaxBytes() {
return traceBaggageMaxBytes;
}

public boolean isTraceInferredProxyServicesEnabled() {
return traceInferredProxyServicesEnabled;
}

public int getClockSyncPeriod() {
return clockSyncPeriod;
}
Expand Down Expand Up @@ -5373,6 +5382,8 @@ public String toString() {
+ tracePropagationBehaviorExtract
+ ", tracePropagationExtractFirst="
+ tracePropagationExtractFirst
+ ", traceInferredProxyServicesEnabled="
+ traceInferredProxyServicesEnabled
+ ", clockSyncPeriod="
+ clockSyncPeriod
+ ", jmxFetchEnabled="
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
public final class AgentPropagation {
public static final Concern TRACING_CONCERN = named("tracing");
public static final Concern BAGGAGE_CONCERN = named("baggage");
public static final Concern INFERRED_PROXY_CONCERN = named("inferred_proxy");
public static final Concern XRAY_TRACING_CONCERN = named("tracing-xray");

// TODO DSM propagator should run after the other propagators as it stores the pathway context
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
package datadog.trace.bootstrap.instrumentation.api;

import datadog.context.Context;
import datadog.context.ContextKey;
import datadog.context.ImplicitContextKeyed;

import java.util.Objects;
import java.util.stream.Stream;

public class InferredProxyContext implements ImplicitContextKeyed {
public static final ContextKey<InferredProxyContext> CONTEXT_KEY =
ContextKey.named("inferred-proxy-key");
private String proxyName;
private String startTime;
private String domainName;
private String httpMethod;
private String path;
private String stage;

public static InferredProxyContext fromContext(Context context) {
return context.get(CONTEXT_KEY);
}

public InferredProxyContext() {}

public void setProxyName(String name){
this.proxyName = name;
}

public String getProxyName(){
return this.proxyName;
}

public void setStartTime(String time){
this.startTime = time;
}

public String getStartTime(){
return this.startTime;
}

public void setDomainName(String name){
this.domainName = name;
}

public String getDomainName(){
return this.domainName;
}

public void setHttpMethod(String httpMethod){
this.httpMethod = httpMethod;
}

public String getHttpMethod(){
return this.httpMethod;
}

public void setPath(String path){
this.path = path;
}

public String getPath(){
return this.path;
}

public void setStage(String stage){
this.stage = stage;
}

public String getStage(){
return this.stage;
}

public boolean validContext(){
return Stream.of(proxyName, startTime, domainName, httpMethod, path, stage)
.allMatch(Objects::nonNull);
}

/**
* Creates a new context with this value under its chosen key.
*
* @param context the context to copy the original values from.
* @return the new context with the implicitly keyed value.
* @see Context#with(ImplicitContextKeyed)
*/
@Override
public Context storeInto(Context context) {
return context.with(CONTEXT_KEY, this);
}
}
Loading