diff --git a/docs/content/core/logging.mdx b/docs/content/core/logging.mdx
index 865b73432..a5e33c352 100644
--- a/docs/content/core/logging.mdx
+++ b/docs/content/core/logging.mdx
@@ -69,7 +69,7 @@ Key | Type | Example | Description
**functionVersion**| String | "12"
**functionMemorySize**| String | "128"
**functionArn**| String | "arn:aws:lambda:eu-west-1:012345678910:function:example-powertools-HelloWorldFunction-1P1Z6B39FLU73"
-
+**xray_trace_id**| String | "1-5759e988-bd862e3fe1be46a994272793" | X-Ray Trace ID when Lambda function has enabled Tracing
## Capturing context Lambda info
diff --git a/powertools-logging/pom.xml b/powertools-logging/pom.xml
index 4e521cc9a..038f6a31d 100644
--- a/powertools-logging/pom.xml
+++ b/powertools-logging/pom.xml
@@ -88,6 +88,11 @@
mockito-core
test
+
+ org.mockito
+ mockito-inline
+ test
+
org.aspectj
aspectjweaver
diff --git a/powertools-logging/src/main/java/software/amazon/lambda/powertools/logging/internal/LambdaLoggingAspect.java b/powertools-logging/src/main/java/software/amazon/lambda/powertools/logging/internal/LambdaLoggingAspect.java
index 7c9b1a3e1..ec3f64165 100644
--- a/powertools-logging/src/main/java/software/amazon/lambda/powertools/logging/internal/LambdaLoggingAspect.java
+++ b/powertools-logging/src/main/java/software/amazon/lambda/powertools/logging/internal/LambdaLoggingAspect.java
@@ -20,6 +20,7 @@
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.Map;
+import java.util.Optional;
import java.util.Random;
import com.fasterxml.jackson.databind.ObjectMapper;
@@ -35,6 +36,8 @@
import org.aspectj.lang.annotation.Pointcut;
import software.amazon.lambda.powertools.logging.PowertoolsLogging;
+import static java.util.Optional.empty;
+import static java.util.Optional.ofNullable;
import static software.amazon.lambda.powertools.core.internal.LambdaHandlerProcessor.coldStartDone;
import static software.amazon.lambda.powertools.core.internal.LambdaHandlerProcessor.extractContext;
import static software.amazon.lambda.powertools.core.internal.LambdaHandlerProcessor.isColdStart;
@@ -44,6 +47,7 @@
import static software.amazon.lambda.powertools.core.internal.LambdaHandlerProcessor.serviceName;
import static software.amazon.lambda.powertools.logging.PowertoolsLogger.appendKey;
import static software.amazon.lambda.powertools.logging.PowertoolsLogger.appendKeys;
+import static software.amazon.lambda.powertools.logging.internal.SystemWrapper.getenv;
@Aspect
public final class LambdaLoggingAspect {
@@ -83,6 +87,7 @@ public Object around(ProceedingJoinPoint pjp,
appendKey("service", serviceName());
});
+ getXrayTraceId().ifPresent(xRayTraceId -> appendKey("xray_trace_id", xRayTraceId));
if (powertoolsLogging.logEvent()) {
proceedArgs = logEvent(pjp);
@@ -179,4 +184,12 @@ private Object[] logFromInputStream(final ProceedingJoinPoint pjp) {
private Logger logger(final ProceedingJoinPoint pjp) {
return LogManager.getLogger(pjp.getSignature().getDeclaringType());
}
+
+ private static Optional getXrayTraceId() {
+ final String X_AMZN_TRACE_ID = getenv("_X_AMZN_TRACE_ID");
+ if(X_AMZN_TRACE_ID != null) {
+ return ofNullable(X_AMZN_TRACE_ID.split(";")[0].replace("Root=", ""));
+ }
+ return empty();
+ }
}
diff --git a/powertools-logging/src/main/java/software/amazon/lambda/powertools/logging/internal/SystemWrapper.java b/powertools-logging/src/main/java/software/amazon/lambda/powertools/logging/internal/SystemWrapper.java
new file mode 100644
index 000000000..c521fe77f
--- /dev/null
+++ b/powertools-logging/src/main/java/software/amazon/lambda/powertools/logging/internal/SystemWrapper.java
@@ -0,0 +1,10 @@
+package software.amazon.lambda.powertools.logging.internal;
+
+class SystemWrapper {
+ private SystemWrapper() {
+ }
+
+ public static String getenv(String name) {
+ return System.getenv(name);
+ }
+}
diff --git a/powertools-logging/src/test/java/software/amazon/lambda/powertools/logging/internal/LambdaLoggingAspectTest.java b/powertools-logging/src/test/java/software/amazon/lambda/powertools/logging/internal/LambdaLoggingAspectTest.java
index c99fdabe5..91e76a154 100644
--- a/powertools-logging/src/test/java/software/amazon/lambda/powertools/logging/internal/LambdaLoggingAspectTest.java
+++ b/powertools-logging/src/test/java/software/amazon/lambda/powertools/logging/internal/LambdaLoggingAspectTest.java
@@ -28,6 +28,8 @@
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.Mock;
+import org.mockito.MockedStatic;
+import org.mockito.Mockito;
import software.amazon.lambda.powertools.core.internal.LambdaHandlerProcessor;
import software.amazon.lambda.powertools.logging.handlers.PowerLogToolEnabled;
import software.amazon.lambda.powertools.logging.handlers.PowerLogToolEnabledForStream;
@@ -38,8 +40,10 @@
import static org.apache.commons.lang3.reflect.FieldUtils.writeStaticField;
import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mockStatic;
import static org.mockito.Mockito.when;
-import static org.mockito.MockitoAnnotations.initMocks;
+import static org.mockito.MockitoAnnotations.openMocks;
+import static software.amazon.lambda.powertools.logging.internal.SystemWrapper.getenv;
class LambdaLoggingAspectTest {
@@ -52,7 +56,7 @@ class LambdaLoggingAspectTest {
@BeforeEach
void setUp() throws IllegalAccessException {
- initMocks(this);
+ openMocks(this);
ThreadContext.clearAll();
writeStaticField(LambdaHandlerProcessor.class, "IS_COLD_START", null, true);
setupContext();
@@ -172,6 +176,21 @@ void shouldLogServiceNameWhenEnvVarSet() throws IllegalAccessException {
.containsEntry("service", "testService");
}
+ @Test
+ void shouldLogxRayTraceIdEnvVarSet() {
+ String xRayTraceId = "1-5759e988-bd862e3fe1be46a994272793";
+
+ try (MockedStatic mocked = mockStatic(SystemWrapper.class)) {
+ mocked.when(() -> getenv("_X_AMZN_TRACE_ID")).thenReturn("Root=1-5759e988-bd862e3fe1be46a994272793;Parent=53995c3f42cd8ad8;Sampled=1\"");
+
+ requestHandler.handleRequest(new Object(), context);
+
+ assertThat(ThreadContext.getImmutableContext())
+ .hasSize(EXPECTED_CONTEXT_SIZE + 1)
+ .containsEntry("xray_trace_id", xRayTraceId);
+ }
+ }
+
private void setupContext() {
when(context.getFunctionName()).thenReturn("testFunction");
when(context.getInvokedFunctionArn()).thenReturn("testArn");