From 181d594b53522dbb4f0a01f543bd0f0421ce2e9a Mon Sep 17 00:00:00 2001 From: Ranjan Bhandari Date: Fri, 25 Sep 2020 11:12:29 -0400 Subject: [PATCH 1/2] Integration with CloudWatch ServiceLens #88 --- docs/content/core/logging.mdx | 2 +- powertools-logging/pom.xml | 5 +++++ .../logging/internal/LambdaLoggingAspect.java | 10 +++++++++ .../logging/internal/SystemWrapper.java | 10 +++++++++ .../internal/LambdaLoggingAspectTest.java | 21 +++++++++++++++++-- 5 files changed, 45 insertions(+), 3 deletions(-) create mode 100644 powertools-logging/src/main/java/software/amazon/lambda/powertools/logging/internal/SystemWrapper.java 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..73eb8cedb 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; @@ -83,6 +84,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 +181,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 = SystemWrapper.getenv("_X_AMZN_TRACE_ID"); + if(X_AMZN_TRACE_ID != null) { + return Optional.ofNullable(X_AMZN_TRACE_ID.split(";")[0].replace("Root=", "")); + } + return Optional.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..dbcaf6d7f --- /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; + +public class SystemWrapper { + public 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..5e9924255 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; @@ -39,7 +41,7 @@ import static org.apache.commons.lang3.reflect.FieldUtils.writeStaticField; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.when; -import static org.mockito.MockitoAnnotations.initMocks; +import static org.mockito.MockitoAnnotations.openMocks; class LambdaLoggingAspectTest { @@ -52,7 +54,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 +174,21 @@ void shouldLogServiceNameWhenEnvVarSet() throws IllegalAccessException { .containsEntry("service", "testService"); } + @Test + void shouldLogxRayTraceIdEnvVarSet() { + String xRayTraceId = "1-5759e988-bd862e3fe1be46a994272793"; + + try (MockedStatic mocked = Mockito.mockStatic(SystemWrapper.class)) { + mocked.when(() -> SystemWrapper.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"); From c4f32b4afccadc956f6ba289cfec0b980ed8875e Mon Sep 17 00:00:00 2001 From: Ranjan Bhandari Date: Fri, 25 Sep 2020 13:41:37 -0400 Subject: [PATCH 2/2] feat: integration with CloudWatch ServiceLens #88 cleanup on last pr #111 --- .../powertools/logging/internal/LambdaLoggingAspect.java | 9 ++++++--- .../powertools/logging/internal/SystemWrapper.java | 4 ++-- .../logging/internal/LambdaLoggingAspectTest.java | 6 ++++-- 3 files changed, 12 insertions(+), 7 deletions(-) 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 73eb8cedb..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 @@ -36,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; @@ -45,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 { @@ -183,10 +186,10 @@ private Logger logger(final ProceedingJoinPoint pjp) { } private static Optional getXrayTraceId() { - final String X_AMZN_TRACE_ID = SystemWrapper.getenv("_X_AMZN_TRACE_ID"); + final String X_AMZN_TRACE_ID = getenv("_X_AMZN_TRACE_ID"); if(X_AMZN_TRACE_ID != null) { - return Optional.ofNullable(X_AMZN_TRACE_ID.split(";")[0].replace("Root=", "")); + return ofNullable(X_AMZN_TRACE_ID.split(";")[0].replace("Root=", "")); } - return Optional.empty(); + 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 index dbcaf6d7f..c521fe77f 100644 --- 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 @@ -1,7 +1,7 @@ package software.amazon.lambda.powertools.logging.internal; -public class SystemWrapper { - public SystemWrapper() { +class SystemWrapper { + private SystemWrapper() { } public static String getenv(String 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 5e9924255..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 @@ -40,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.openMocks; +import static software.amazon.lambda.powertools.logging.internal.SystemWrapper.getenv; class LambdaLoggingAspectTest { @@ -178,8 +180,8 @@ void shouldLogServiceNameWhenEnvVarSet() throws IllegalAccessException { void shouldLogxRayTraceIdEnvVarSet() { String xRayTraceId = "1-5759e988-bd862e3fe1be46a994272793"; - try (MockedStatic mocked = Mockito.mockStatic(SystemWrapper.class)) { - mocked.when(() -> SystemWrapper.getenv("_X_AMZN_TRACE_ID")).thenReturn("Root=1-5759e988-bd862e3fe1be46a994272793;Parent=53995c3f42cd8ad8;Sampled=1\""); + 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);