Skip to content

Metrics are not flushed when lambda handler throws an exception #285

@qtdzz

Description

@qtdzz

What were you trying to accomplish?
I am trying to publish metrics even when the lambda handler fails. Apparently, metrics won't be flushed if the handler throws exception: https://github.com/awslabs/aws-lambda-powertools-java/blob/master/powertools-metrics/src/main/java/software/amazon/lambda/powertools/metrics/internal/LambdaMetricsAspect.java#L62

Expected Behavior

Metrics are flushed regardless of the handler execution status

Current Behavior

Metrics are flushed only when the handler finishes successfully

Possible Solution

Some thing likes the following snippet in the around method

public Object around(ProceedingJoinPoint pjp,
                         Metrics metrics) throws Throwable {

...[omitted code]...

            try {
                Object proceed;
                try {
                     proceed = pjp.proceed(proceedArgs);
                } finally {
                    coldStartDone();
                    validateBeforeFlushingMetrics(metrics);
                    logger.flush();
                }
                return proceed;

            } finally {
                refreshMetricsContext();
            }
}

Steps to Reproduce (for bugs)

  1. Add the following class to src/test/java/software/amazon/lambda/powertools/metrics/handlers
public class PowertoolsMetricsWithExceptionInHandler implements RequestHandler<Object, Object> {

    @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");
    }
}
  1. Add the following test to software.amazon.lambda.powertools.metrics.internal.LambdaMetricsAspectTest
    @Test
    public void metricsPublishedEvenHandlerThrowsException() {
        requestHandler = new PowertoolsMetricsWithExceptionInHandler();
        try (MockedStatic<SystemWrapper> 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<String, Object> logAsJson = readAsJson(s);
                    assertThat(logAsJson)
                        .containsEntry("CoolMetric", 1.0)
                        .containsEntry("Service", "booking")
                        .containsKey("_aws");
                });
        }
    }
  1. Run unit tests
  2. The unit test would fail

Environment

  • Powertools version used: master branch
  • Packaging format (Layers, Maven/Gradle): Maven
  • AWS Lambda function runtime: Java 8
  • Debugging logs

How to enable debug mode**

# paste logs here

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions