Skip to content

Commit

Permalink
POC for proposed spec change
Browse files Browse the repository at this point in the history
Because of the following statement added to the spec, the xray and xray-lambda propagators must be combined:

> To avoid potential issues when extracting with an active span context, the xray-lambda propagator SHOULD check if the provided context already has an active span context. If found, the propagator SHOULD return the provided context unmodified.

With this condition, if they are separate the xray-lambda propagator will see the context from xray and avoid modifying the context.
By combining, the propagator is able to consider the context before xray has modified it.
  • Loading branch information
tylerbenson committed Jan 25, 2024
1 parent 16807c9 commit e0785d5
Show file tree
Hide file tree
Showing 7 changed files with 122 additions and 271 deletions.
3 changes: 3 additions & 0 deletions aws-xray-propagator/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,8 @@ otelJava.moduleName.set("io.opentelemetry.contrib.awsxray.propagator")
dependencies {
api("io.opentelemetry:opentelemetry-api")
compileOnly("io.opentelemetry:opentelemetry-sdk-extension-autoconfigure-spi")
testImplementation("io.opentelemetry:opentelemetry-sdk-extension-autoconfigure")
testImplementation("io.opentelemetry:opentelemetry-sdk-trace")
testImplementation("io.opentelemetry:opentelemetry-sdk-testing")
testImplementation("uk.org.webcompere:system-stubs-jupiter:2.0.2")
}

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
import io.opentelemetry.sdk.autoconfigure.spi.ConfigurablePropagatorProvider;

/**
* A {@link ConfigurablePropagatorProvider} which allows enabling the {@link
* AwsXrayLambdaPropagator} with the propagator name {@code aws}.
* A {@link ConfigurablePropagatorProvider} which allows enabling the {@link AwsXrayLambdaPropagator}
* with the propagator name {@code xray-lambda}.
*/
public final class AwsXrayLambdaConfigurablePropagator implements ConfigurablePropagatorProvider {
@Override
Expand All @@ -21,6 +21,6 @@ public TextMapPropagator getPropagator(ConfigProperties config) {

@Override
public String getName() {
return "aws";
return "xray-lambda";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,17 @@

package io.opentelemetry.contrib.awsxray.propagator;

import io.opentelemetry.api.trace.Span;
import io.opentelemetry.context.Context;
import io.opentelemetry.context.propagation.TextMapGetter;
import io.opentelemetry.context.propagation.TextMapPropagator;
import io.opentelemetry.context.propagation.TextMapSetter;
import java.util.List;

import javax.annotation.Nullable;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
* Implementation of the AWS X-Ray Trace Header propagation protocol but with special handling for
Expand All @@ -25,13 +30,15 @@
* ContextPropagators.create(
* TextMapPropagator.composite(
* W3CTraceContextPropagator.getInstance(),
* AwsXrayLambdaPropagator.getInstance())))
* AwsXrayEnvPropagator.getInstance())))
* .build();
* }</pre>
*/
public final class AwsXrayLambdaPropagator implements TextMapPropagator {
private static final AwsXrayPropagator XRAY = AwsXrayPropagator.getInstance();
private static final AwsXrayEnvPropagator XRAY_ENV = AwsXrayEnvPropagator.getInstance();

private static final String AWS_TRACE_HEADER_ENV_KEY = "_X_AMZN_TRACE_ID";
private static final String AWS_TRACE_HEADER_PROP = "com.amazonaws.xray.traceHeader";
private final AwsXrayPropagator xrayPropagator = AwsXrayPropagator.getInstance();
private static final AwsXrayLambdaPropagator INSTANCE = new AwsXrayLambdaPropagator();

private AwsXrayLambdaPropagator() {
Expand All @@ -44,20 +51,51 @@ public static AwsXrayLambdaPropagator getInstance() {

@Override
public List<String> fields() {
return XRAY.fields();
return xrayPropagator.fields();
}

@Override
public <C> void inject(Context context, @Nullable C carrier, TextMapSetter<C> setter) {
XRAY.inject(context, carrier, setter);
// XRAY_ENV.inject is a no-op, so no need to invoke.
xrayPropagator.inject(context, carrier, setter);
}

@Override
public <C> Context extract(Context context, @Nullable C carrier, TextMapGetter<C> getter) {
context = XRAY.extract(context, carrier, getter);
// Currently last one wins, so invoke XRAY_ENV second to allow parent to be overwritten.
context = XRAY_ENV.extract(context, carrier, getter);
return context;
if (Span.fromContext(context).getSpanContext().isValid()) {
return xrayPropagator.extract(context, carrier, getter);
}

context = xrayPropagator.extract(context, carrier, getter);

String traceHeader = System.getProperty(AWS_TRACE_HEADER_PROP);
if (isEmptyOrNull(traceHeader)) {
traceHeader = System.getenv(AWS_TRACE_HEADER_ENV_KEY);
}
if (isEmptyOrNull(traceHeader)) {
return context;
}
return xrayPropagator.extract(
context,
Collections.singletonMap(AwsXrayPropagator.TRACE_HEADER_KEY, traceHeader),
MapGetter.INSTANCE);
}

private static boolean isEmptyOrNull(@Nullable String value) {
return value == null || value.isEmpty();
}

private enum MapGetter implements TextMapGetter<Map<String, String>> {
INSTANCE;

@Override
public Set<String> keys(Map<String, String> map) {
return map.keySet();
}

@Override
@Nullable
public String get(@Nullable Map<String, String> map, String s) {
return map == null ? null : map.get(s);
}
}
}

This file was deleted.

Loading

0 comments on commit e0785d5

Please sign in to comment.