From 400551ca86411d10c31ed032e928cde383266eed Mon Sep 17 00:00:00 2001 From: Jerome Van Der Linden Date: Fri, 4 Nov 2022 16:57:43 +0100 Subject: [PATCH 1/7] bump metrics version to 4.0.3 --- docs/core/metrics.md | 30 +++++++-- pom.xml | 2 +- .../emf/model/MetricsLoggerHelper.java | 9 ++- .../powertools/metrics/MetricsUtils.java | 65 ++++++++----------- .../metrics/internal/LambdaMetricsAspect.java | 33 ++++++++-- .../powertools/metrics/MetricsLoggerTest.java | 41 +++++++----- ...ertoolsMetricsColdStartEnabledHandler.java | 7 +- ...MetricsEnabledDefaultDimensionHandler.java | 16 ++++- ...tricsEnabledDefaultNoDimensionHandler.java | 7 +- .../PowertoolsMetricsEnabledHandler.java | 18 ++++- ...PowertoolsMetricsEnabledStreamHandler.java | 7 +- .../PowertoolsMetricsNoDimensionsHandler.java | 7 +- ...rtoolsMetricsTooManyDimensionsHandler.java | 14 +++- ...wertoolsMetricsWithExceptionInHandler.java | 7 +- spotbugs-exclude.xml | 4 ++ 15 files changed, 185 insertions(+), 82 deletions(-) diff --git a/docs/core/metrics.md b/docs/core/metrics.md index e06ab6d10..9d43a0c9a 100644 --- a/docs/core/metrics.md +++ b/docs/core/metrics.md @@ -222,8 +222,12 @@ You can create metrics using `putMetric`, and manually create dimensions for all @Override @Metrics(namespace = "ExampleApplication", service = "booking") public Object handleRequest(Object input, Context context) { - metricsLogger.putDimensions(DimensionSet.of("environment", "prod")); - metricsLogger.putMetric("SuccessfulBooking", 1, Unit.COUNT); + try { + metricsLogger.putDimensions(DimensionSet.of("environment", "prod")); + metricsLogger.putMetric("SuccessfulBooking", 1, Unit.COUNT); + } catch (InvalidDimensionException | InvalidMetricException | DimensionSetExceededException e) { + LOG.error(e); + } ... } } @@ -306,8 +310,12 @@ You can use `putMetadata` for advanced use cases, where you want to metadata as @Override @Metrics(namespace = "ServerlessAirline", service = "payment") public Object handleRequest(Object input, Context context) { - metricsLogger().putMetric("CustomMetric1", 1, Unit.COUNT); - metricsLogger().putMetadata("booking_id", "1234567890"); + try { + metricsLogger().putMetadata("booking_id", "1234567890"); + metricsLogger().putMetric("CustomMetric1", 1, Unit.COUNT); + } catch (InvalidMetricException e) { + throw new RuntimeException(e); + } ... } } @@ -332,7 +340,11 @@ Dimension, it can be done via `#!java MetricsUtils.defaultDimensions()`. MetricsLogger metricsLogger = MetricsUtils.metricsLogger(); static { - MetricsUtils.defaultDimensions(DimensionSet.of("CustomDimension", "booking")); + try { + MetricsUtils.defaultDimensions(DimensionSet.of("CustomDimension", "booking")); + } catch (InvalidDimensionException | DimensionSetExceededException e) { + throw new RuntimeException(e); + } } @Override @@ -361,8 +373,12 @@ CloudWatch EMF uses the same dimensions across all your metrics. Use `withSingle @Override public Object handleRequest(Object input, Context context) { - withSingleMetric("CustomMetrics2", 1, Unit.COUNT, "Another", (metric) -> { - metric.setDimensions(DimensionSet.of("AnotherService", "CustomService")); + withSingleMetric("CustomMetrics2", 1, Unit.COUNT, "Another", (metric) -> { + try { + metric.setDimensions(DimensionSet.of("AnotherService", "CustomService")); + } catch (InvalidDimensionException | DimensionSetExceededException e) { + throw new RuntimeException(e); + } }); } } diff --git a/pom.xml b/pom.xml index 17fb1a712..6f33c863f 100644 --- a/pom.xml +++ b/pom.xml @@ -90,7 +90,7 @@ 3.3.0 3.1.0 5.10.0 - 1.0.6 + 4.0.3 0.5.1 diff --git a/powertools-metrics/src/main/java/software/amazon/cloudwatchlogs/emf/model/MetricsLoggerHelper.java b/powertools-metrics/src/main/java/software/amazon/cloudwatchlogs/emf/model/MetricsLoggerHelper.java index e2d886fe5..c9e1b697f 100644 --- a/powertools-metrics/src/main/java/software/amazon/cloudwatchlogs/emf/model/MetricsLoggerHelper.java +++ b/powertools-metrics/src/main/java/software/amazon/cloudwatchlogs/emf/model/MetricsLoggerHelper.java @@ -14,11 +14,14 @@ package software.amazon.cloudwatchlogs.emf.model; + import static software.amazon.lambda.powertools.metrics.MetricsUtils.metricsLogger; import java.lang.reflect.Field; +import software.amazon.cloudwatchlogs.emf.exception.DimensionSetExceededException; public final class MetricsLoggerHelper { + private MetricsLoggerHelper() { } @@ -27,7 +30,11 @@ public static boolean hasNoMetrics() { } public static long dimensionsCount() { - return metricsContext().getDimensions().size(); + try { + return metricsContext().getDimensions().size(); + } catch (DimensionSetExceededException e) { + throw new RuntimeException("Too many dimensions defined", e); + } } public static MetricsContext metricsContext() { diff --git a/powertools-metrics/src/main/java/software/amazon/lambda/powertools/metrics/MetricsUtils.java b/powertools-metrics/src/main/java/software/amazon/lambda/powertools/metrics/MetricsUtils.java index 8ab2a2f29..dc2824d80 100644 --- a/powertools-metrics/src/main/java/software/amazon/lambda/powertools/metrics/MetricsUtils.java +++ b/powertools-metrics/src/main/java/software/amazon/lambda/powertools/metrics/MetricsUtils.java @@ -14,7 +14,6 @@ package software.amazon.lambda.powertools.metrics; -import static java.util.Objects.requireNonNull; import static java.util.Optional.ofNullable; import static software.amazon.lambda.powertools.common.internal.LambdaHandlerProcessor.getXrayTraceId; import static software.amazon.lambda.powertools.metrics.internal.LambdaMetricsAspect.REQUEST_ID_PROPERTY; @@ -25,6 +24,8 @@ import java.util.function.Consumer; import software.amazon.cloudwatchlogs.emf.config.SystemWrapper; import software.amazon.cloudwatchlogs.emf.environment.EnvironmentProvider; +import software.amazon.cloudwatchlogs.emf.exception.InvalidMetricException; +import software.amazon.cloudwatchlogs.emf.exception.InvalidNamespaceException; import software.amazon.cloudwatchlogs.emf.logger.MetricsLogger; import software.amazon.cloudwatchlogs.emf.model.DimensionSet; import software.amazon.cloudwatchlogs.emf.model.MetricsContext; @@ -63,23 +64,6 @@ public static void defaultDimensions(final DimensionSet... dimensionSets) { MetricsUtils.defaultDimensions = dimensionSets; } - /** - * Configure default dimension to be used by logger. - * By default, @{@link Metrics} annotation captures configured service as a dimension Service - * - * @param dimensionSet Default value of dimension set for logger - * @deprecated use {@link #defaultDimensions(DimensionSet...)} instead - */ - @Deprecated - public static void defaultDimensionSet(final DimensionSet dimensionSet) { - requireNonNull(dimensionSet, "Null dimension set not allowed"); - - if (dimensionSet.getDimensionKeys().size() > 0) { - defaultDimensions(dimensionSet); - } - } - - /** * Add and immediately flush a single metric. It will use the default namespace * specified either on {@link Metrics} annotation or via POWERTOOLS_METRICS_NAMESPACE env var. @@ -95,11 +79,20 @@ public static void withSingleMetric(final String name, final double value, final Unit unit, final Consumer logger) { - withMetricsLogger(metricsLogger -> - { + MetricsLogger metricsLogger = logger(); + + try { + metricsLogger.setNamespace(defaultNameSpace()); metricsLogger.putMetric(name, value, unit); + captureRequestAndTraceId(metricsLogger); logger.accept(metricsLogger); - }); + } catch (InvalidNamespaceException e) { + throw new RuntimeException("A valid namespace is required, either pass it to the @Metrics annotation or set the environment variable POWERTOOLS_METRICS_NAMESPACE", e); + } catch (InvalidMetricException e) { + throw new RuntimeException(e); + } finally { + metricsLogger.flush(); + } } /** @@ -118,12 +111,20 @@ public static void withSingleMetric(final String name, final Unit unit, final String namespace, final Consumer logger) { - withMetricsLogger(metricsLogger -> - { + MetricsLogger metricsLogger = logger(); + + try { metricsLogger.setNamespace(namespace); metricsLogger.putMetric(name, value, unit); + captureRequestAndTraceId(metricsLogger); logger.accept(metricsLogger); - }); + } catch (InvalidNamespaceException e) { + throw new RuntimeException("A valid namespace is required, either pass it to the @Metrics annotation or set the environment variable POWERTOOLS_METRICS_NAMESPACE", e); + } catch (InvalidMetricException e) { + throw new RuntimeException(e); + } finally { + metricsLogger.flush(); + } } /** @@ -141,25 +142,13 @@ public static void withMetricsLogger(final Consumer logger) { metricsLogger.setNamespace(defaultNameSpace()); captureRequestAndTraceId(metricsLogger); logger.accept(metricsLogger); + } catch (InvalidNamespaceException e) { + throw new RuntimeException("A valid namespace is required, either pass it to the @Metrics annotation or set the environment variable POWERTOOLS_METRICS_NAMESPACE", e); } finally { metricsLogger.flush(); } } - /** - * Provide and immediately flush a {@link MetricsLogger}. It uses the default namespace - * specified either on {@link Metrics} annotation or via POWERTOOLS_METRICS_NAMESPACE env var. - * It by default captures function_request_id as property if used together with {@link Metrics} annotation. It will also - * capture xray_trace_id as property if tracing is enabled. - * - * @param logger the MetricsLogger - * @deprecated use {@link MetricsUtils#withMetricsLogger} instead - */ - @Deprecated - public static void withMetricLogger(final Consumer logger) { - withMetricsLogger(logger); - } - public static DimensionSet[] getDefaultDimensions() { return Arrays.copyOf(defaultDimensions, defaultDimensions.length); } 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 56a35f67f..f0a83ef44 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 @@ -24,12 +24,17 @@ import static software.amazon.lambda.powertools.metrics.MetricsUtils.hasDefaultDimension; import static software.amazon.lambda.powertools.metrics.MetricsUtils.metricsLogger; + import com.amazonaws.services.lambda.runtime.Context; import java.lang.reflect.Field; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; +import software.amazon.cloudwatchlogs.emf.exception.DimensionSetExceededException; +import software.amazon.cloudwatchlogs.emf.exception.InvalidDimensionException; +import software.amazon.cloudwatchlogs.emf.exception.InvalidMetricException; +import software.amazon.cloudwatchlogs.emf.exception.InvalidNamespaceException; import software.amazon.cloudwatchlogs.emf.logger.MetricsLogger; import software.amazon.cloudwatchlogs.emf.model.DimensionSet; import software.amazon.cloudwatchlogs.emf.model.MetricsContext; @@ -57,13 +62,15 @@ public static void refreshMetricsContext(Metrics metrics) { MetricsContext context = new MetricsContext(); DimensionSet[] defaultDimensions = hasDefaultDimension() ? MetricsUtils.getDefaultDimensions() - : new DimensionSet[] {DimensionSet.of("Service", service(metrics))}; + : new DimensionSet[]{DimensionSet.of("Service", service(metrics))}; context.setDimensions(defaultDimensions); f.set(metricsLogger(), context); } catch (NoSuchFieldException | IllegalAccessException e) { throw new RuntimeException(e); + } catch (InvalidDimensionException | DimensionSetExceededException e) { + throw new RuntimeException("A valid service is required, either pass it to the @Metrics annotation or set the environment variable POWERTOOLS_SERVICE_NAME", e); } } @@ -115,12 +122,24 @@ private void coldStartSingleMetricIfApplicable(final String awsRequestId, final Metrics metrics) { if (metrics.captureColdStart() && isColdStart()) { - MetricsLogger metricsLogger = new MetricsLogger(); - metricsLogger.setNamespace(namespace(metrics)); - metricsLogger.putMetric("ColdStart", 1, Unit.COUNT); - metricsLogger.setDimensions(DimensionSet.of("Service", service(metrics), "FunctionName", functionName)); - metricsLogger.putProperty(REQUEST_ID_PROPERTY, awsRequestId); - metricsLogger.flush(); + MetricsLogger metricsLogger = new MetricsLogger(); + try { + metricsLogger.setNamespace(namespace(metrics)); + } catch (InvalidNamespaceException e) { + throw new RuntimeException("A valid namespace is required, either pass it to the @Metrics annotation or set the environment variable POWERTOOLS_METRICS_NAMESPACE", e); + } + try { + metricsLogger.putMetric("ColdStart", 1, Unit.COUNT); + } catch (InvalidMetricException e) { + // should not occur + } + try { + metricsLogger.setDimensions(DimensionSet.of("Service", service(metrics), "FunctionName", functionName)); + } catch (InvalidDimensionException | DimensionSetExceededException e) { + throw new RuntimeException("A valid service is required, either pass it to the @Metrics annotation or set the environment variable POWERTOOLS_SERVICE_NAME", e); + } + metricsLogger.putProperty(REQUEST_ID_PROPERTY, awsRequestId); + metricsLogger.flush(); } } diff --git a/powertools-metrics/src/test/java/software/amazon/lambda/powertools/metrics/MetricsLoggerTest.java b/powertools-metrics/src/test/java/software/amazon/lambda/powertools/metrics/MetricsLoggerTest.java index 89cba6bc4..4bf20555a 100644 --- a/powertools-metrics/src/test/java/software/amazon/lambda/powertools/metrics/MetricsLoggerTest.java +++ b/powertools-metrics/src/test/java/software/amazon/lambda/powertools/metrics/MetricsLoggerTest.java @@ -32,6 +32,9 @@ import org.junit.jupiter.api.Test; import org.mockito.MockedStatic; import software.amazon.cloudwatchlogs.emf.config.SystemWrapper; +import software.amazon.cloudwatchlogs.emf.exception.DimensionSetExceededException; +import software.amazon.cloudwatchlogs.emf.exception.InvalidDimensionException; +import software.amazon.cloudwatchlogs.emf.exception.InvalidMetricException; import software.amazon.cloudwatchlogs.emf.logger.MetricsLogger; import software.amazon.cloudwatchlogs.emf.model.DimensionSet; import software.amazon.cloudwatchlogs.emf.model.Unit; @@ -60,7 +63,7 @@ void tearDown() { } @Test - void singleMetricsCaptureUtilityWithDefaultDimension() { + void singleMetricsCaptureUtilityWithDefaultDimension() throws InvalidDimensionException, DimensionSetExceededException { try (MockedStatic mocked = mockStatic(SystemWrapper.class); MockedStatic internalWrapper = mockStatic( software.amazon.lambda.powertools.common.internal.SystemWrapper.class)) { @@ -99,7 +102,13 @@ void singleMetricsCaptureUtility() { .thenReturn("Root=1-5759e988-bd862e3fe1be46a994272793;Parent=53995c3f42cd8ad8;Sampled=1\""); MetricsUtils.withSingleMetric("Metric1", 1, Unit.COUNT, "test", - metricsLogger -> metricsLogger.setDimensions(DimensionSet.of("Dimension1", "Value1"))); + metricsLogger -> { + try { + metricsLogger.setDimensions(DimensionSet.of("Dimension1", "Value1")); + } catch (InvalidDimensionException | DimensionSetExceededException e) { + throw new RuntimeException(e); + } + }); assertThat(out.toString()) .satisfies(s -> @@ -126,7 +135,13 @@ void singleMetricsCaptureUtilityWithDefaultNameSpace() { .thenReturn("Root=1-5759e988-bd862e3fe1be46a994272793;Parent=53995c3f42cd8ad8;Sampled=1\""); MetricsUtils.withSingleMetric("Metric1", 1, Unit.COUNT, - metricsLogger -> metricsLogger.setDimensions(DimensionSet.of("Dimension1", "Value1"))); + metricsLogger -> { + try { + metricsLogger.setDimensions(DimensionSet.of("Dimension1", "Value1")); + } catch (InvalidDimensionException | DimensionSetExceededException e) { + throw new RuntimeException(e); + } + }); assertThat(out.toString()) .satisfies(s -> @@ -148,20 +163,10 @@ void singleMetricsCaptureUtilityWithDefaultNameSpace() { } } - @Test - void metricsLoggerCaptureUtilityWithDefaultNameSpace() { - testLogger(MetricsUtils::withMetricsLogger); - } - - @Test - void deprecatedMetricLoggerCaptureUtilityWithDefaultNameSpace() { - testLogger(MetricsUtils::withMetricLogger); - } - @Test void shouldThrowExceptionWhenDefaultDimensionIsNull() { assertThatNullPointerException() - .isThrownBy(() -> MetricsUtils.defaultDimensionSet(null)) + .isThrownBy(() -> MetricsUtils.defaultDimensions(null)) .withMessage("Null dimension set not allowed"); } @@ -176,8 +181,12 @@ private void testLogger(Consumer> methodToTest) { methodToTest.accept(metricsLogger -> { - metricsLogger.setDimensions(DimensionSet.of("Dimension1", "Value1")); - metricsLogger.putMetric("Metric1", 1, Unit.COUNT); + try { + metricsLogger.setDimensions(DimensionSet.of("Dimension1", "Value1")); + metricsLogger.putMetric("Metric1", 1, Unit.COUNT); + } catch (InvalidDimensionException | DimensionSetExceededException | InvalidMetricException e) { + throw new RuntimeException(e); + } }); assertThat(out.toString()) diff --git a/powertools-metrics/src/test/java/software/amazon/lambda/powertools/metrics/handlers/PowertoolsMetricsColdStartEnabledHandler.java b/powertools-metrics/src/test/java/software/amazon/lambda/powertools/metrics/handlers/PowertoolsMetricsColdStartEnabledHandler.java index e3a0fa22e..bb1f18ef0 100644 --- a/powertools-metrics/src/test/java/software/amazon/lambda/powertools/metrics/handlers/PowertoolsMetricsColdStartEnabledHandler.java +++ b/powertools-metrics/src/test/java/software/amazon/lambda/powertools/metrics/handlers/PowertoolsMetricsColdStartEnabledHandler.java @@ -18,6 +18,7 @@ import com.amazonaws.services.lambda.runtime.Context; import com.amazonaws.services.lambda.runtime.RequestHandler; +import software.amazon.cloudwatchlogs.emf.exception.InvalidMetricException; import software.amazon.cloudwatchlogs.emf.logger.MetricsLogger; import software.amazon.cloudwatchlogs.emf.model.Unit; import software.amazon.lambda.powertools.metrics.Metrics; @@ -28,7 +29,11 @@ public class PowertoolsMetricsColdStartEnabledHandler implements RequestHandler< @Metrics(namespace = "ExampleApplication", service = "booking", captureColdStart = true) public Object handleRequest(Object input, Context context) { MetricsLogger metricsLogger = metricsLogger(); - metricsLogger.putMetric("Metric1", 1, Unit.BYTES); + try { + metricsLogger.putMetric("Metric1", 1, Unit.BYTES); + } catch (InvalidMetricException e) { + throw new RuntimeException(e); + } return null; } diff --git a/powertools-metrics/src/test/java/software/amazon/lambda/powertools/metrics/handlers/PowertoolsMetricsEnabledDefaultDimensionHandler.java b/powertools-metrics/src/test/java/software/amazon/lambda/powertools/metrics/handlers/PowertoolsMetricsEnabledDefaultDimensionHandler.java index 761c20caa..20528506e 100644 --- a/powertools-metrics/src/test/java/software/amazon/lambda/powertools/metrics/handlers/PowertoolsMetricsEnabledDefaultDimensionHandler.java +++ b/powertools-metrics/src/test/java/software/amazon/lambda/powertools/metrics/handlers/PowertoolsMetricsEnabledDefaultDimensionHandler.java @@ -20,6 +20,9 @@ import com.amazonaws.services.lambda.runtime.Context; import com.amazonaws.services.lambda.runtime.RequestHandler; +import software.amazon.cloudwatchlogs.emf.exception.DimensionSetExceededException; +import software.amazon.cloudwatchlogs.emf.exception.InvalidDimensionException; +import software.amazon.cloudwatchlogs.emf.exception.InvalidMetricException; import software.amazon.cloudwatchlogs.emf.logger.MetricsLogger; import software.amazon.cloudwatchlogs.emf.model.DimensionSet; import software.amazon.cloudwatchlogs.emf.model.Unit; @@ -28,14 +31,23 @@ public class PowertoolsMetricsEnabledDefaultDimensionHandler implements RequestHandler { static { - defaultDimensions(DimensionSet.of("CustomDimension", "booking")); + try { + defaultDimensions(DimensionSet.of("CustomDimension", "booking")); + } catch (InvalidDimensionException | DimensionSetExceededException e) { + throw new RuntimeException(e); + } } @Override @Metrics(namespace = "ExampleApplication", service = "booking") public Object handleRequest(Object input, Context context) { MetricsLogger metricsLogger = metricsLogger(); - metricsLogger.putMetric("Metric1", 1, Unit.BYTES); + + try { + metricsLogger.putMetric("Metric1", 1, Unit.BYTES); + } catch (InvalidMetricException e) { + throw new RuntimeException(e); + } withSingleMetric("Metric2", 1, Unit.COUNT, log -> { diff --git a/powertools-metrics/src/test/java/software/amazon/lambda/powertools/metrics/handlers/PowertoolsMetricsEnabledDefaultNoDimensionHandler.java b/powertools-metrics/src/test/java/software/amazon/lambda/powertools/metrics/handlers/PowertoolsMetricsEnabledDefaultNoDimensionHandler.java index d968f94f5..55c1f3cb0 100644 --- a/powertools-metrics/src/test/java/software/amazon/lambda/powertools/metrics/handlers/PowertoolsMetricsEnabledDefaultNoDimensionHandler.java +++ b/powertools-metrics/src/test/java/software/amazon/lambda/powertools/metrics/handlers/PowertoolsMetricsEnabledDefaultNoDimensionHandler.java @@ -19,6 +19,7 @@ import com.amazonaws.services.lambda.runtime.Context; import com.amazonaws.services.lambda.runtime.RequestHandler; +import software.amazon.cloudwatchlogs.emf.exception.InvalidMetricException; import software.amazon.cloudwatchlogs.emf.logger.MetricsLogger; import software.amazon.cloudwatchlogs.emf.model.Unit; import software.amazon.lambda.powertools.metrics.Metrics; @@ -34,7 +35,11 @@ public class PowertoolsMetricsEnabledDefaultNoDimensionHandler implements Reques @Metrics(namespace = "ExampleApplication", service = "booking") public Object handleRequest(Object input, Context context) { MetricsLogger metricsLogger = metricsLogger(); - metricsLogger.putMetric("Metric1", 1, Unit.BYTES); + try { + metricsLogger.putMetric("Metric1", 1, Unit.BYTES); + } catch (InvalidMetricException e) { + throw new RuntimeException(e); + } withSingleMetric("Metric2", 1, Unit.COUNT, log -> { diff --git a/powertools-metrics/src/test/java/software/amazon/lambda/powertools/metrics/handlers/PowertoolsMetricsEnabledHandler.java b/powertools-metrics/src/test/java/software/amazon/lambda/powertools/metrics/handlers/PowertoolsMetricsEnabledHandler.java index 7cfee533d..e0a47b766 100644 --- a/powertools-metrics/src/test/java/software/amazon/lambda/powertools/metrics/handlers/PowertoolsMetricsEnabledHandler.java +++ b/powertools-metrics/src/test/java/software/amazon/lambda/powertools/metrics/handlers/PowertoolsMetricsEnabledHandler.java @@ -19,6 +19,9 @@ import com.amazonaws.services.lambda.runtime.Context; import com.amazonaws.services.lambda.runtime.RequestHandler; +import software.amazon.cloudwatchlogs.emf.exception.DimensionSetExceededException; +import software.amazon.cloudwatchlogs.emf.exception.InvalidDimensionException; +import software.amazon.cloudwatchlogs.emf.exception.InvalidMetricException; import software.amazon.cloudwatchlogs.emf.logger.MetricsLogger; import software.amazon.cloudwatchlogs.emf.model.DimensionSet; import software.amazon.cloudwatchlogs.emf.model.Unit; @@ -30,11 +33,20 @@ public class PowertoolsMetricsEnabledHandler implements RequestHandler log.setDimensions(DimensionSet.of("Dimension1", "Value1"))); + log -> { + try { + log.setDimensions(DimensionSet.of("Dimension1", "Value1")); + } catch (InvalidDimensionException | DimensionSetExceededException e) { + throw new RuntimeException(e); + } + }); return null; } diff --git a/powertools-metrics/src/test/java/software/amazon/lambda/powertools/metrics/handlers/PowertoolsMetricsEnabledStreamHandler.java b/powertools-metrics/src/test/java/software/amazon/lambda/powertools/metrics/handlers/PowertoolsMetricsEnabledStreamHandler.java index 1600f4a64..d1113fdd8 100644 --- a/powertools-metrics/src/test/java/software/amazon/lambda/powertools/metrics/handlers/PowertoolsMetricsEnabledStreamHandler.java +++ b/powertools-metrics/src/test/java/software/amazon/lambda/powertools/metrics/handlers/PowertoolsMetricsEnabledStreamHandler.java @@ -20,6 +20,7 @@ import com.amazonaws.services.lambda.runtime.RequestStreamHandler; import java.io.InputStream; import java.io.OutputStream; +import software.amazon.cloudwatchlogs.emf.exception.InvalidMetricException; import software.amazon.cloudwatchlogs.emf.logger.MetricsLogger; import software.amazon.cloudwatchlogs.emf.model.Unit; import software.amazon.lambda.powertools.metrics.Metrics; @@ -30,6 +31,10 @@ public class PowertoolsMetricsEnabledStreamHandler implements RequestStreamHandl @Metrics(namespace = "ExampleApplication", service = "booking") public void handleRequest(InputStream input, OutputStream output, Context context) { MetricsLogger metricsLogger = metricsLogger(); - metricsLogger.putMetric("Metric1", 1, Unit.BYTES); + try { + metricsLogger.putMetric("Metric1", 1, Unit.BYTES); + } catch (InvalidMetricException e) { + throw new RuntimeException(e); + } } } diff --git a/powertools-metrics/src/test/java/software/amazon/lambda/powertools/metrics/handlers/PowertoolsMetricsNoDimensionsHandler.java b/powertools-metrics/src/test/java/software/amazon/lambda/powertools/metrics/handlers/PowertoolsMetricsNoDimensionsHandler.java index 04b02e166..63b394520 100644 --- a/powertools-metrics/src/test/java/software/amazon/lambda/powertools/metrics/handlers/PowertoolsMetricsNoDimensionsHandler.java +++ b/powertools-metrics/src/test/java/software/amazon/lambda/powertools/metrics/handlers/PowertoolsMetricsNoDimensionsHandler.java @@ -18,6 +18,7 @@ import com.amazonaws.services.lambda.runtime.Context; import com.amazonaws.services.lambda.runtime.RequestHandler; +import software.amazon.cloudwatchlogs.emf.exception.InvalidMetricException; import software.amazon.cloudwatchlogs.emf.logger.MetricsLogger; import software.amazon.cloudwatchlogs.emf.model.DimensionSet; import software.amazon.lambda.powertools.metrics.Metrics; @@ -28,7 +29,11 @@ public class PowertoolsMetricsNoDimensionsHandler implements RequestHandler { @Override - @Metrics + @Metrics(namespace = "ExampleApplication", service = "booking") public Object handleRequest(Object input, Context context) { MetricsLogger metricsLogger = metricsLogger(); + + metricsLogger.setDimensions(IntStream.range(1, 15) - .mapToObj(value -> DimensionSet.of("Dimension" + value, "DimensionValue" + value)) + .mapToObj(value -> { + try { + return DimensionSet.of("Dimension" + value, "DimensionValue" + value); + } catch (InvalidDimensionException | DimensionSetExceededException e) { + throw new RuntimeException(e); + } + }) .toArray(DimensionSet[]::new)); return null; 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 index da9028a70..339eafc2b 100644 --- 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 @@ -18,6 +18,7 @@ import com.amazonaws.services.lambda.runtime.Context; import com.amazonaws.services.lambda.runtime.RequestHandler; +import software.amazon.cloudwatchlogs.emf.exception.InvalidMetricException; import software.amazon.cloudwatchlogs.emf.logger.MetricsLogger; import software.amazon.lambda.powertools.metrics.Metrics; @@ -27,7 +28,11 @@ public class PowertoolsMetricsWithExceptionInHandler implements RequestHandler + + + + From a0e1fcf297a9153fdd2a3875cee697c56b26cfbe Mon Sep 17 00:00:00 2001 From: Jerome Van Der Linden Date: Mon, 21 Aug 2023 13:43:37 +0200 Subject: [PATCH 2/7] fix tests --- .../lambda/powertools/metrics/MetricsLoggerTest.java | 8 -------- 1 file changed, 8 deletions(-) diff --git a/powertools-metrics/src/test/java/software/amazon/lambda/powertools/metrics/MetricsLoggerTest.java b/powertools-metrics/src/test/java/software/amazon/lambda/powertools/metrics/MetricsLoggerTest.java index 4bf20555a..105858880 100644 --- a/powertools-metrics/src/test/java/software/amazon/lambda/powertools/metrics/MetricsLoggerTest.java +++ b/powertools-metrics/src/test/java/software/amazon/lambda/powertools/metrics/MetricsLoggerTest.java @@ -16,7 +16,6 @@ import static java.util.Collections.emptyMap; import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatNullPointerException; import static org.mockito.Mockito.mockStatic; import static software.amazon.lambda.powertools.common.internal.SystemWrapper.getenv; @@ -163,13 +162,6 @@ void singleMetricsCaptureUtilityWithDefaultNameSpace() { } } - @Test - void shouldThrowExceptionWhenDefaultDimensionIsNull() { - assertThatNullPointerException() - .isThrownBy(() -> MetricsUtils.defaultDimensions(null)) - .withMessage("Null dimension set not allowed"); - } - private void testLogger(Consumer> methodToTest) { try (MockedStatic mocked = mockStatic(SystemWrapper.class); MockedStatic internalWrapper = mockStatic( From 67152ec440a16881ff568bb5c1d68c33cf6d599a Mon Sep 17 00:00:00 2001 From: Jerome Van Der Linden Date: Tue, 29 Aug 2023 17:58:55 +0200 Subject: [PATCH 3/7] update example and e2e test --- .../cdk/app/src/main/java/helloworld/App.java | 21 ++++++++++++++----- .../lambda/powertools/e2e/Function.java | 20 +++++++++++++++--- 2 files changed, 33 insertions(+), 8 deletions(-) diff --git a/examples/powertools-examples-core-utilities/cdk/app/src/main/java/helloworld/App.java b/examples/powertools-examples-core-utilities/cdk/app/src/main/java/helloworld/App.java index 988da2a73..e86b80269 100644 --- a/examples/powertools-examples-core-utilities/cdk/app/src/main/java/helloworld/App.java +++ b/examples/powertools-examples-core-utilities/cdk/app/src/main/java/helloworld/App.java @@ -31,6 +31,9 @@ import java.util.stream.Collectors; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import software.amazon.cloudwatchlogs.emf.exception.DimensionSetExceededException; +import software.amazon.cloudwatchlogs.emf.exception.InvalidDimensionException; +import software.amazon.cloudwatchlogs.emf.exception.InvalidMetricException; import software.amazon.cloudwatchlogs.emf.model.DimensionSet; import software.amazon.cloudwatchlogs.emf.model.Unit; import software.amazon.lambda.powertools.logging.Logging; @@ -44,7 +47,7 @@ * Handler for requests to Lambda function. */ public class App implements RequestHandler { - private final static Logger log = LogManager.getLogger(App.class); + private static final Logger log = LogManager.getLogger(App.class); @Logging(logEvent = true, samplingRate = 0.7) @Tracing(captureMode = CaptureMode.RESPONSE_AND_ERROR) @@ -55,12 +58,20 @@ public APIGatewayProxyResponseEvent handleRequest(final APIGatewayProxyRequestEv headers.put("Content-Type", "application/json"); headers.put("X-Custom-Header", "application/json"); - metricsLogger().putMetric("CustomMetric1", 1, Unit.COUNT); + try { + metricsLogger().putMetric("CustomMetric1", 1, Unit.COUNT); + } catch (InvalidMetricException e) { + log.error(e); + } - withSingleMetric("CustomMetrics2", 1, Unit.COUNT, "Another", (metric) -> + withSingleMetric("CustomMetrics2", 1, Unit.COUNT, "Another", metric -> { - metric.setDimensions(DimensionSet.of("AnotherService", "CustomService")); - metric.setDimensions(DimensionSet.of("AnotherService1", "CustomService1")); + try { + metric.setDimensions(DimensionSet.of("AnotherService", "CustomService")); + metric.setDimensions(DimensionSet.of("AnotherService1", "CustomService1")); + } catch (InvalidDimensionException | DimensionSetExceededException e) { + log.error(e); + } }); LoggingUtils.appendKey("test", "willBeLogged"); diff --git a/powertools-e2e-tests/handlers/metrics/src/main/java/software/amazon/lambda/powertools/e2e/Function.java b/powertools-e2e-tests/handlers/metrics/src/main/java/software/amazon/lambda/powertools/e2e/Function.java index d9cf575c3..2f0467ccf 100644 --- a/powertools-e2e-tests/handlers/metrics/src/main/java/software/amazon/lambda/powertools/e2e/Function.java +++ b/powertools-e2e-tests/handlers/metrics/src/main/java/software/amazon/lambda/powertools/e2e/Function.java @@ -16,6 +16,9 @@ import com.amazonaws.services.lambda.runtime.Context; import com.amazonaws.services.lambda.runtime.RequestHandler; +import software.amazon.cloudwatchlogs.emf.exception.DimensionSetExceededException; +import software.amazon.cloudwatchlogs.emf.exception.InvalidDimensionException; +import software.amazon.cloudwatchlogs.emf.exception.InvalidMetricException; import software.amazon.cloudwatchlogs.emf.logger.MetricsLogger; import software.amazon.cloudwatchlogs.emf.model.DimensionSet; import software.amazon.cloudwatchlogs.emf.model.Unit; @@ -30,10 +33,21 @@ public class Function implements RequestHandler { public String handleRequest(Input input, Context context) { DimensionSet dimensionSet = new DimensionSet(); - input.getDimensions().forEach((key, value) -> dimensionSet.addDimension(key, value)); + input.getDimensions().forEach((key, value) -> { + try { + dimensionSet.addDimension(key, value); + } catch (InvalidDimensionException | DimensionSetExceededException e) { + // log or something + } + }); metricsLogger.putDimensions(dimensionSet); - - input.getMetrics().forEach((key, value) -> metricsLogger.putMetric(key, value, Unit.COUNT)); + input.getMetrics().forEach((key, value) -> { + try { + metricsLogger.putMetric(key, value, Unit.COUNT); + } catch (InvalidMetricException e) { + // log or something + } + }); return "OK"; } From e4317db886c371aaa15558ec2854c6f73f859673 Mon Sep 17 00:00:00 2001 From: Jerome Van Der Linden Date: Tue, 29 Aug 2023 18:01:23 +0200 Subject: [PATCH 4/7] upgrade metrics version --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 6f33c863f..1c6df58bf 100644 --- a/pom.xml +++ b/pom.xml @@ -90,7 +90,7 @@ 3.3.0 3.1.0 5.10.0 - 4.0.3 + 4.1.1 0.5.1 From 75c94f0e4d3a89e7bb99b31ee1f3363027f1e678 Mon Sep 17 00:00:00 2001 From: Jerome Van Der Linden Date: Tue, 29 Aug 2023 18:23:08 +0200 Subject: [PATCH 5/7] fix example --- .../cdk/app/pom.xml | 2 +- .../sam/src/main/java/helloworld/App.java | 17 ++++++++++++++--- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/examples/powertools-examples-core-utilities/cdk/app/pom.xml b/examples/powertools-examples-core-utilities/cdk/app/pom.xml index 6895f4117..fb4ba52cc 100644 --- a/examples/powertools-examples-core-utilities/cdk/app/pom.xml +++ b/examples/powertools-examples-core-utilities/cdk/app/pom.xml @@ -3,7 +3,7 @@ 4.0.0 software.amazon.lambda.examples - 1.16.1 + 2.0.0-SNAPSHOT powertools-examples-core-utilities-cdk jar diff --git a/examples/powertools-examples-core-utilities/sam/src/main/java/helloworld/App.java b/examples/powertools-examples-core-utilities/sam/src/main/java/helloworld/App.java index fccc63b9a..38efe6e5d 100644 --- a/examples/powertools-examples-core-utilities/sam/src/main/java/helloworld/App.java +++ b/examples/powertools-examples-core-utilities/sam/src/main/java/helloworld/App.java @@ -31,6 +31,9 @@ import java.util.stream.Collectors; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import software.amazon.cloudwatchlogs.emf.exception.DimensionSetExceededException; +import software.amazon.cloudwatchlogs.emf.exception.InvalidDimensionException; +import software.amazon.cloudwatchlogs.emf.exception.InvalidMetricException; import software.amazon.cloudwatchlogs.emf.model.DimensionSet; import software.amazon.cloudwatchlogs.emf.model.Unit; import software.amazon.lambda.powertools.logging.Logging; @@ -55,12 +58,20 @@ public APIGatewayProxyResponseEvent handleRequest(final APIGatewayProxyRequestEv headers.put("Content-Type", "application/json"); headers.put("X-Custom-Header", "application/json"); - metricsLogger().putMetric("CustomMetric1", 1, Unit.COUNT); + try { + metricsLogger().putMetric("CustomMetric1", 1, Unit.COUNT); + } catch (InvalidMetricException e) { + log.error(e); + } withSingleMetric("CustomMetrics2", 1, Unit.COUNT, "Another", (metric) -> { - metric.setDimensions(DimensionSet.of("AnotherService", "CustomService")); - metric.setDimensions(DimensionSet.of("AnotherService1", "CustomService1")); + try { + metric.setDimensions(DimensionSet.of("AnotherService", "CustomService")); + metric.setDimensions(DimensionSet.of("AnotherService1", "CustomService1")); + } catch (InvalidDimensionException | DimensionSetExceededException e) { + log.error(e); + } }); LoggingUtils.appendKey("test", "willBeLogged"); From 0ec27cf1a37eb3ac157563e8c406e5987a8fe70b Mon Sep 17 00:00:00 2001 From: Jerome Van Der Linden Date: Wed, 30 Aug 2023 10:05:44 +0200 Subject: [PATCH 6/7] fix cdk example --- .../cdk/app/pom.xml | 4 +-- .../cdk/app/src/main/java/helloworld/App.java | 27 ++++++------------- .../cdk/infra/pom.xml | 2 +- 3 files changed, 11 insertions(+), 22 deletions(-) diff --git a/examples/powertools-examples-core-utilities/cdk/app/pom.xml b/examples/powertools-examples-core-utilities/cdk/app/pom.xml index fb4ba52cc..ef272fbc0 100644 --- a/examples/powertools-examples-core-utilities/cdk/app/pom.xml +++ b/examples/powertools-examples-core-utilities/cdk/app/pom.xml @@ -3,11 +3,11 @@ 4.0.0 software.amazon.lambda.examples - 2.0.0-SNAPSHOT + 1.17.0 powertools-examples-core-utilities-cdk jar - Powertools for AWS Lambda (Java) library Examples - Core + Powertools for AWS Lambda (Java) library Examples - Core Utilities (logging, tracing, metrics) with CDK 2.20.0 diff --git a/examples/powertools-examples-core-utilities/cdk/app/src/main/java/helloworld/App.java b/examples/powertools-examples-core-utilities/cdk/app/src/main/java/helloworld/App.java index e86b80269..acb52c5cd 100644 --- a/examples/powertools-examples-core-utilities/cdk/app/src/main/java/helloworld/App.java +++ b/examples/powertools-examples-core-utilities/cdk/app/src/main/java/helloworld/App.java @@ -31,9 +31,6 @@ import java.util.stream.Collectors; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import software.amazon.cloudwatchlogs.emf.exception.DimensionSetExceededException; -import software.amazon.cloudwatchlogs.emf.exception.InvalidDimensionException; -import software.amazon.cloudwatchlogs.emf.exception.InvalidMetricException; import software.amazon.cloudwatchlogs.emf.model.DimensionSet; import software.amazon.cloudwatchlogs.emf.model.Unit; import software.amazon.lambda.powertools.logging.Logging; @@ -58,21 +55,13 @@ public APIGatewayProxyResponseEvent handleRequest(final APIGatewayProxyRequestEv headers.put("Content-Type", "application/json"); headers.put("X-Custom-Header", "application/json"); - try { - metricsLogger().putMetric("CustomMetric1", 1, Unit.COUNT); - } catch (InvalidMetricException e) { - log.error(e); - } + metricsLogger().putMetric("CustomMetric1", 1, Unit.COUNT); withSingleMetric("CustomMetrics2", 1, Unit.COUNT, "Another", metric -> - { - try { + { metric.setDimensions(DimensionSet.of("AnotherService", "CustomService")); metric.setDimensions(DimensionSet.of("AnotherService1", "CustomService1")); - } catch (InvalidDimensionException | DimensionSetExceededException e) { - log.error(e); - } - }); + }); LoggingUtils.appendKey("test", "willBeLogged"); @@ -85,11 +74,11 @@ public APIGatewayProxyResponseEvent handleRequest(final APIGatewayProxyRequestEv String output = String.format("{ \"message\": \"hello world\", \"location\": \"%s\" }", pageContents); TracingUtils.withSubsegment("loggingResponse", subsegment -> - { - String sampled = "log something out"; - log.info(sampled); - log.info(output); - }); + { + String sampled = "log something out"; + log.info(sampled); + log.info(output); + }); log.info("After output"); return response diff --git a/examples/powertools-examples-core-utilities/cdk/infra/pom.xml b/examples/powertools-examples-core-utilities/cdk/infra/pom.xml index d81118cde..993b378ac 100644 --- a/examples/powertools-examples-core-utilities/cdk/infra/pom.xml +++ b/examples/powertools-examples-core-utilities/cdk/infra/pom.xml @@ -4,7 +4,7 @@ 4.0.0 software.amazon.lambda.examples cdk - 1.18.0-SNAPSHOT + 2.0.0-SNAPSHOT UTF-8 2.91.0 From 75b3fb570e3cc9b2fde7a86f049e4e80a7247a1c Mon Sep 17 00:00:00 2001 From: Jerome Van Der Linden Date: Wed, 30 Aug 2023 10:59:41 +0200 Subject: [PATCH 7/7] fix sonar issues --- .../emf/model/MetricsLoggerHelper.java | 3 +- .../powertools/metrics/MetricsUtils.java | 11 +++---- .../InvalidMetricDimensionException.java | 24 +++++++++++++++ .../exception/InvalidMetricException.java | 24 +++++++++++++++ .../InvalidMetricNamespaceException.java | 29 +++++++++++++++++++ .../metrics/internal/LambdaMetricsAspect.java | 16 ++++++---- 6 files changed, 96 insertions(+), 11 deletions(-) create mode 100644 powertools-metrics/src/main/java/software/amazon/lambda/powertools/metrics/exception/InvalidMetricDimensionException.java create mode 100644 powertools-metrics/src/main/java/software/amazon/lambda/powertools/metrics/exception/InvalidMetricException.java create mode 100644 powertools-metrics/src/main/java/software/amazon/lambda/powertools/metrics/exception/InvalidMetricNamespaceException.java diff --git a/powertools-metrics/src/main/java/software/amazon/cloudwatchlogs/emf/model/MetricsLoggerHelper.java b/powertools-metrics/src/main/java/software/amazon/cloudwatchlogs/emf/model/MetricsLoggerHelper.java index c9e1b697f..5effc20a9 100644 --- a/powertools-metrics/src/main/java/software/amazon/cloudwatchlogs/emf/model/MetricsLoggerHelper.java +++ b/powertools-metrics/src/main/java/software/amazon/cloudwatchlogs/emf/model/MetricsLoggerHelper.java @@ -19,6 +19,7 @@ import java.lang.reflect.Field; import software.amazon.cloudwatchlogs.emf.exception.DimensionSetExceededException; +import software.amazon.lambda.powertools.metrics.exception.InvalidMetricDimensionException; public final class MetricsLoggerHelper { @@ -33,7 +34,7 @@ public static long dimensionsCount() { try { return metricsContext().getDimensions().size(); } catch (DimensionSetExceededException e) { - throw new RuntimeException("Too many dimensions defined", e); + throw new InvalidMetricDimensionException(e); } } diff --git a/powertools-metrics/src/main/java/software/amazon/lambda/powertools/metrics/MetricsUtils.java b/powertools-metrics/src/main/java/software/amazon/lambda/powertools/metrics/MetricsUtils.java index dc2824d80..b3fb5a72c 100644 --- a/powertools-metrics/src/main/java/software/amazon/lambda/powertools/metrics/MetricsUtils.java +++ b/powertools-metrics/src/main/java/software/amazon/lambda/powertools/metrics/MetricsUtils.java @@ -31,6 +31,7 @@ import software.amazon.cloudwatchlogs.emf.model.MetricsContext; import software.amazon.cloudwatchlogs.emf.model.MetricsLoggerHelper; import software.amazon.cloudwatchlogs.emf.model.Unit; +import software.amazon.lambda.powertools.metrics.exception.InvalidMetricNamespaceException; /** * A class used to retrieve the instance of the {@code MetricsLogger} used by @@ -87,9 +88,9 @@ public static void withSingleMetric(final String name, captureRequestAndTraceId(metricsLogger); logger.accept(metricsLogger); } catch (InvalidNamespaceException e) { - throw new RuntimeException("A valid namespace is required, either pass it to the @Metrics annotation or set the environment variable POWERTOOLS_METRICS_NAMESPACE", e); + throw new InvalidMetricNamespaceException(e); } catch (InvalidMetricException e) { - throw new RuntimeException(e); + throw new software.amazon.lambda.powertools.metrics.exception.InvalidMetricException(e); } finally { metricsLogger.flush(); } @@ -119,9 +120,9 @@ public static void withSingleMetric(final String name, captureRequestAndTraceId(metricsLogger); logger.accept(metricsLogger); } catch (InvalidNamespaceException e) { - throw new RuntimeException("A valid namespace is required, either pass it to the @Metrics annotation or set the environment variable POWERTOOLS_METRICS_NAMESPACE", e); + throw new InvalidMetricNamespaceException(e); } catch (InvalidMetricException e) { - throw new RuntimeException(e); + throw new software.amazon.lambda.powertools.metrics.exception.InvalidMetricException(e); } finally { metricsLogger.flush(); } @@ -143,7 +144,7 @@ public static void withMetricsLogger(final Consumer logger) { captureRequestAndTraceId(metricsLogger); logger.accept(metricsLogger); } catch (InvalidNamespaceException e) { - throw new RuntimeException("A valid namespace is required, either pass it to the @Metrics annotation or set the environment variable POWERTOOLS_METRICS_NAMESPACE", e); + throw new InvalidMetricNamespaceException(e); } finally { metricsLogger.flush(); } diff --git a/powertools-metrics/src/main/java/software/amazon/lambda/powertools/metrics/exception/InvalidMetricDimensionException.java b/powertools-metrics/src/main/java/software/amazon/lambda/powertools/metrics/exception/InvalidMetricDimensionException.java new file mode 100644 index 000000000..15994a69a --- /dev/null +++ b/powertools-metrics/src/main/java/software/amazon/lambda/powertools/metrics/exception/InvalidMetricDimensionException.java @@ -0,0 +1,24 @@ +/* + * Copyright 2023 Amazon.com, Inc. or its affiliates. + * Licensed under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package software.amazon.lambda.powertools.metrics.exception; + +public class InvalidMetricDimensionException extends RuntimeException { + + private static final long serialVersionUID = -2011349422261364971L; + + public InvalidMetricDimensionException(Throwable e) { + super(e); + } +} diff --git a/powertools-metrics/src/main/java/software/amazon/lambda/powertools/metrics/exception/InvalidMetricException.java b/powertools-metrics/src/main/java/software/amazon/lambda/powertools/metrics/exception/InvalidMetricException.java new file mode 100644 index 000000000..be2b28fbd --- /dev/null +++ b/powertools-metrics/src/main/java/software/amazon/lambda/powertools/metrics/exception/InvalidMetricException.java @@ -0,0 +1,24 @@ +/* + * Copyright 2023 Amazon.com, Inc. or its affiliates. + * Licensed under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package software.amazon.lambda.powertools.metrics.exception; + +public class InvalidMetricException extends RuntimeException { + + private static final long serialVersionUID = 5525178400429974308L; + + public InvalidMetricException(Throwable e) { + super(e); + } +} diff --git a/powertools-metrics/src/main/java/software/amazon/lambda/powertools/metrics/exception/InvalidMetricNamespaceException.java b/powertools-metrics/src/main/java/software/amazon/lambda/powertools/metrics/exception/InvalidMetricNamespaceException.java new file mode 100644 index 000000000..485aa6690 --- /dev/null +++ b/powertools-metrics/src/main/java/software/amazon/lambda/powertools/metrics/exception/InvalidMetricNamespaceException.java @@ -0,0 +1,29 @@ +/* + * Copyright 2023 Amazon.com, Inc. or its affiliates. + * Licensed under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package software.amazon.lambda.powertools.metrics.exception; + +public class InvalidMetricNamespaceException extends RuntimeException { + private static final long serialVersionUID = -8758457068851174063L; + public static final String POWERTOOLS_METRICS_NAMESPACE_REQUIRED = + "A valid namespace is required, either pass it to the @Metrics annotation or set the environment variable POWERTOOLS_METRICS_NAMESPACE"; + + public InvalidMetricNamespaceException() { + super(POWERTOOLS_METRICS_NAMESPACE_REQUIRED); + } + + public InvalidMetricNamespaceException(Throwable e) { + super(POWERTOOLS_METRICS_NAMESPACE_REQUIRED, e); + } +} 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 f0a83ef44..1f575b074 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 @@ -43,6 +43,8 @@ import software.amazon.lambda.powertools.metrics.Metrics; import software.amazon.lambda.powertools.metrics.MetricsUtils; import software.amazon.lambda.powertools.metrics.ValidationException; +import software.amazon.lambda.powertools.metrics.exception.InvalidMetricDimensionException; +import software.amazon.lambda.powertools.metrics.exception.InvalidMetricNamespaceException; @Aspect public class LambdaMetricsAspect { @@ -69,8 +71,10 @@ public static void refreshMetricsContext(Metrics metrics) { f.set(metricsLogger(), context); } catch (NoSuchFieldException | IllegalAccessException e) { throw new RuntimeException(e); - } catch (InvalidDimensionException | DimensionSetExceededException e) { - throw new RuntimeException("A valid service is required, either pass it to the @Metrics annotation or set the environment variable POWERTOOLS_SERVICE_NAME", e); + } catch (InvalidDimensionException e) { + throw new InvalidMetricNamespaceException(e); + } catch (DimensionSetExceededException e) { + throw new InvalidMetricDimensionException(e); } } @@ -126,7 +130,7 @@ && isColdStart()) { try { metricsLogger.setNamespace(namespace(metrics)); } catch (InvalidNamespaceException e) { - throw new RuntimeException("A valid namespace is required, either pass it to the @Metrics annotation or set the environment variable POWERTOOLS_METRICS_NAMESPACE", e); + throw new InvalidMetricNamespaceException(e); } try { metricsLogger.putMetric("ColdStart", 1, Unit.COUNT); @@ -135,8 +139,10 @@ && isColdStart()) { } try { metricsLogger.setDimensions(DimensionSet.of("Service", service(metrics), "FunctionName", functionName)); - } catch (InvalidDimensionException | DimensionSetExceededException e) { - throw new RuntimeException("A valid service is required, either pass it to the @Metrics annotation or set the environment variable POWERTOOLS_SERVICE_NAME", e); + } catch (InvalidDimensionException e) { + throw new InvalidMetricNamespaceException(e); + } catch (DimensionSetExceededException e) { + throw new InvalidMetricDimensionException(e); } metricsLogger.putProperty(REQUEST_ID_PROPERTY, awsRequestId); metricsLogger.flush();