Skip to content

Commit 5cfbfb1

Browse files
committed
Add support for lambda traces for concurrent environments
1 parent d8ed0bb commit 5cfbfb1

File tree

3 files changed

+98
-1
lines changed

3 files changed

+98
-1
lines changed

core/aws-core/src/main/java/software/amazon/awssdk/awscore/interceptor/TraceIdExecutionInterceptor.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
package software.amazon.awssdk.awscore.interceptor;
1717

1818
import java.util.Optional;
19+
import org.slf4j.MDC;
1920
import software.amazon.awssdk.annotations.SdkProtectedApi;
2021
import software.amazon.awssdk.awscore.internal.interceptor.TracingSystemSetting;
2122
import software.amazon.awssdk.core.interceptor.Context;
@@ -32,6 +33,7 @@
3233
public class TraceIdExecutionInterceptor implements ExecutionInterceptor {
3334
private static final String TRACE_ID_HEADER = "X-Amzn-Trace-Id";
3435
private static final String LAMBDA_FUNCTION_NAME_ENVIRONMENT_VARIABLE = "AWS_LAMBDA_FUNCTION_NAME";
36+
private static final String CONCURRENT_TRACE_ID_KEY = "AWS_LAMBDA_X_TraceId";
3537

3638
@Override
3739
public SdkHttpRequest modifyHttpRequest(Context.ModifyHttpRequest context, ExecutionAttributes executionAttributes) {
@@ -53,6 +55,9 @@ private Optional<String> traceIdHeader(Context.ModifyHttpRequest context) {
5355
}
5456

5557
private Optional<String> traceId() {
58+
if (TracingSystemSetting.AWS_LAMBDA_MAX_CONCURRENCY.getStringValue().isPresent()) {
59+
return Optional.ofNullable(MDC.get(CONCURRENT_TRACE_ID_KEY));
60+
}
5661
return TracingSystemSetting._X_AMZN_TRACE_ID.getStringValue();
5762
}
5863

core/aws-core/src/main/java/software/amazon/awssdk/awscore/internal/interceptor/TracingSystemSetting.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,9 @@
2424
@SdkInternalApi
2525
public enum TracingSystemSetting implements SystemSetting {
2626
// See: https://github.com/aws/aws-xray-sdk-java/issues/251
27-
_X_AMZN_TRACE_ID("com.amazonaws.xray.traceHeader", null);
27+
_X_AMZN_TRACE_ID("com.amazonaws.xray.traceHeader", null),
28+
// Environment variable to detect Lambda multi concurrency mode ("elevator"). This value is set by the Lambda runtime.
29+
AWS_LAMBDA_MAX_CONCURRENCY("aws.lambda.maxConcurrency", null);
2830

2931
private final String systemProperty;
3032
private final String defaultValue;

core/aws-core/src/test/java/software/amazon/awssdk/awscore/interceptor/TraceIdExecutionInterceptorTest.java

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import java.util.Properties;
2222
import org.junit.jupiter.api.Test;
2323
import org.mockito.Mockito;
24+
import org.slf4j.MDC;
2425
import software.amazon.awssdk.core.SdkRequest;
2526
import software.amazon.awssdk.core.interceptor.Context;
2627
import software.amazon.awssdk.core.interceptor.ExecutionAttributes;
@@ -111,6 +112,94 @@ public void headerNotAddedIfNoTraceIdEnvVar() {
111112
});
112113
}
113114

115+
@Test
116+
public void modifyHttpRequest_whenMultiConcurrencyModeWithMdc_shouldAddTraceIdHeader() {
117+
EnvironmentVariableHelper.run(env -> {
118+
resetRelevantEnvVars(env);
119+
env.set("AWS_LAMBDA_FUNCTION_NAME", "foo");
120+
env.set("AWS_LAMBDA_MAX_CONCURRENCY", "10");
121+
122+
MDC.put("AWS_LAMBDA_X_TraceId", "mdc-trace-123");
123+
124+
try {
125+
Context.ModifyHttpRequest context = context();
126+
assertThat(modifyHttpRequest(context).firstMatchingHeader("X-Amzn-Trace-Id")).hasValue("mdc-trace-123");
127+
} finally {
128+
MDC.remove("AWS_LAMBDA_X_TraceId");
129+
}
130+
});
131+
}
132+
133+
@Test
134+
public void modifyHttpRequest_whenMultiConcurrencyModeWithBothMdcAndSystemProperty_shouldUseMdcValue() {
135+
EnvironmentVariableHelper.run(env -> {
136+
resetRelevantEnvVars(env);
137+
env.set("AWS_LAMBDA_FUNCTION_NAME", "foo");
138+
env.set("AWS_LAMBDA_MAX_CONCURRENCY", "10");
139+
140+
MDC.put("AWS_LAMBDA_X_TraceId", "mdc-trace-123");
141+
Properties props = System.getProperties();
142+
props.setProperty("com.amazonaws.xray.traceHeader", "sys-prop-345");
143+
144+
try {
145+
Context.ModifyHttpRequest context = context();
146+
assertThat(modifyHttpRequest(context).firstMatchingHeader("X-Amzn-Trace-Id")).hasValue("mdc-trace-123");
147+
} finally {
148+
MDC.remove("AWS_LAMBDA_X_TraceId");
149+
props.remove("com.amazonaws.xray.traceHeader");
150+
}
151+
});
152+
}
153+
154+
@Test
155+
public void modifyHttpRequest_whenMultiConcurrencyModeWithEmptyMdc_shouldNotAddHeader() {
156+
EnvironmentVariableHelper.run(env -> {
157+
resetRelevantEnvVars(env);
158+
env.set("AWS_LAMBDA_FUNCTION_NAME", "foo");
159+
env.set("AWS_LAMBDA_MAX_CONCURRENCY", "10");
160+
161+
MDC.clear();
162+
163+
Context.ModifyHttpRequest context = context();
164+
assertThat(modifyHttpRequest(context)).isSameAs(context.httpRequest());
165+
});
166+
}
167+
168+
@Test
169+
public void modifyHttpRequest_whenNotInLambdaEnvironmentWithMdc_shouldNotAddHeader() {
170+
EnvironmentVariableHelper.run(env -> {
171+
resetRelevantEnvVars(env);
172+
env.set("AWS_LAMBDA_MAX_CONCURRENCY", "10");
173+
174+
MDC.put("AWS_LAMBDA_X_TraceId", "should-be-ignored");
175+
176+
try {
177+
Context.ModifyHttpRequest context = context();
178+
assertThat(modifyHttpRequest(context)).isSameAs(context.httpRequest());
179+
} finally {
180+
MDC.remove("AWS_LAMBDA_X_TraceId");
181+
}
182+
});
183+
}
184+
185+
@Test
186+
public void modifyHttpRequest_whenConcurrencyModeIsEmptyString_shouldUseMdcValue() {
187+
EnvironmentVariableHelper.run(env -> {
188+
resetRelevantEnvVars(env);
189+
env.set("AWS_LAMBDA_FUNCTION_NAME", "foo");
190+
env.set("AWS_LAMBDA_MAX_CONCURRENCY", "");
191+
192+
MDC.put("AWS_LAMBDA_X_TraceId", "empty-string-test");
193+
194+
try {
195+
Context.ModifyHttpRequest context = context();
196+
assertThat(modifyHttpRequest(context).firstMatchingHeader("X-Amzn-Trace-Id")).hasValue("empty-string-test");
197+
} finally {
198+
MDC.remove("AWS_LAMBDA_X_TraceId");
199+
}
200+
});
201+
}
202+
114203
private Context.ModifyHttpRequest context() {
115204
return context(SdkHttpRequest.builder()
116205
.uri(URI.create("https://localhost"))
@@ -133,5 +222,6 @@ private SdkHttpRequest modifyHttpRequest(Context.ModifyHttpRequest context) {
133222
private void resetRelevantEnvVars(EnvironmentVariableHelper env) {
134223
env.remove("AWS_LAMBDA_FUNCTION_NAME");
135224
env.remove("_X_AMZN_TRACE_ID");
225+
env.remove("AWS_LAMBDA_MAX_CONCURRENCY");
136226
}
137227
}

0 commit comments

Comments
 (0)