diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 99764e5e0..b8affdda3 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -11,6 +11,7 @@ on: - 'powertools-tracing/**' - 'powertools-validation/**' - 'powertools-parameters/**' + - 'powertools-metrics/**' - 'pom.xml' - '.github/workflows/**' push: @@ -21,8 +22,11 @@ on: - 'powertools-logging/**' - 'powertools-sqs/**' - 'powertools-tracing/**' + - 'powertools-validation/**' + - 'powertools-parameters/**' + - 'powertools-metrics/**' - 'pom.xml' - + - '.github/workflows/**' jobs: build: runs-on: ubuntu-latest diff --git a/powertools-metrics/src/main/java/software/amazon/lambda/powertools/metrics/internal/LambdaMetricsAspect.java b/powertools-metrics/src/main/java/software/amazon/lambda/powertools/metrics/internal/LambdaMetricsAspect.java index 8e1443d54..b42f141b1 100644 --- a/powertools-metrics/src/main/java/software/amazon/lambda/powertools/metrics/internal/LambdaMetricsAspect.java +++ b/powertools-metrics/src/main/java/software/amazon/lambda/powertools/metrics/internal/LambdaMetricsAspect.java @@ -53,16 +53,12 @@ public Object around(ProceedingJoinPoint pjp, coldStartSingleMetricIfApplicable(pjp, metrics); try { - Object proceed = pjp.proceed(proceedArgs); + return pjp.proceed(proceedArgs); + } finally { coldStartDone(); - - validateBeforeFlushingMetrics(metrics); - + validateMetricsAndRefreshOnFailure(metrics); logger.flush(); - return proceed; - - } finally { refreshMetricsContext(); } } @@ -105,6 +101,16 @@ private String service(Metrics metrics) { return !"".equals(metrics.service()) ? metrics.service() : serviceName(); } + private void validateMetricsAndRefreshOnFailure(Metrics metrics) { + try { + + validateBeforeFlushingMetrics(metrics); + } catch (ValidationException e){ + refreshMetricsContext(); + throw e; + } + } + // This can be simplified after this issues https://github.com/awslabs/aws-embedded-metrics-java/issues/35 is fixed private static void refreshMetricsContext() { try { diff --git a/powertools-metrics/src/test/java/software/amazon/lambda/powertools/metrics/handlers/PowertoolsMetricsWithExceptionInHandler.java b/powertools-metrics/src/test/java/software/amazon/lambda/powertools/metrics/handlers/PowertoolsMetricsWithExceptionInHandler.java new file mode 100644 index 000000000..db75d9f95 --- /dev/null +++ b/powertools-metrics/src/test/java/software/amazon/lambda/powertools/metrics/handlers/PowertoolsMetricsWithExceptionInHandler.java @@ -0,0 +1,19 @@ +package software.amazon.lambda.powertools.metrics.handlers; + +import com.amazonaws.services.lambda.runtime.Context; +import com.amazonaws.services.lambda.runtime.RequestHandler; +import software.amazon.cloudwatchlogs.emf.logger.MetricsLogger; +import software.amazon.lambda.powertools.metrics.Metrics; + +import static software.amazon.lambda.powertools.metrics.MetricsUtils.metricsLogger; + +public class PowertoolsMetricsWithExceptionInHandler implements RequestHandler { + + @Override + @Metrics(namespace = "ExampleApplication", service = "booking") + public Object handleRequest(Object input, Context context) { + MetricsLogger metricsLogger = metricsLogger(); + metricsLogger.putMetric("CoolMetric", 1); + throw new IllegalStateException("Whoops, unexpected exception"); + } +} diff --git a/powertools-metrics/src/test/java/software/amazon/lambda/powertools/metrics/internal/LambdaMetricsAspectTest.java b/powertools-metrics/src/test/java/software/amazon/lambda/powertools/metrics/internal/LambdaMetricsAspectTest.java index c39f08eed..08faa445f 100644 --- a/powertools-metrics/src/test/java/software/amazon/lambda/powertools/metrics/internal/LambdaMetricsAspectTest.java +++ b/powertools-metrics/src/test/java/software/amazon/lambda/powertools/metrics/internal/LambdaMetricsAspectTest.java @@ -27,6 +27,7 @@ import software.amazon.lambda.powertools.metrics.handlers.PowertoolsMetricsNoDimensionsHandler; import software.amazon.lambda.powertools.metrics.handlers.PowertoolsMetricsNoExceptionWhenNoMetricsHandler; import software.amazon.lambda.powertools.metrics.handlers.PowertoolsMetricsTooManyDimensionsHandler; +import software.amazon.lambda.powertools.metrics.handlers.PowertoolsMetricsWithExceptionInHandler; import static java.util.Collections.emptyMap; import static org.apache.commons.lang3.reflect.FieldUtils.writeStaticField; @@ -233,6 +234,26 @@ public void exceptionWhenTooManyDimensionsSet() { } } + @Test + public void metricsPublishedEvenHandlerThrowsException() { + requestHandler = new PowertoolsMetricsWithExceptionInHandler(); + try (MockedStatic mocked = mockStatic(SystemWrapper.class)) { + mocked.when(() -> SystemWrapper.getenv("AWS_EMF_ENVIRONMENT")).thenReturn("Lambda"); + assertThatExceptionOfType(IllegalStateException.class) + .isThrownBy(() -> requestHandler.handleRequest("input", context)) + .withMessage("Whoops, unexpected exception"); + + assertThat(out.toString()) + .satisfies(s -> { + Map logAsJson = readAsJson(s); + assertThat(logAsJson) + .containsEntry("CoolMetric", 1.0) + .containsEntry("Service", "booking") + .containsKey("_aws"); + }); + } + } + private void setupContext() { when(context.getFunctionName()).thenReturn("testFunction"); when(context.getInvokedFunctionArn()).thenReturn("testArn");