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/examples/powertools-examples-core-utilities/cdk/app/pom.xml b/examples/powertools-examples-core-utilities/cdk/app/pom.xml index 6895f4117..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 - 1.16.1 + 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 988da2a73..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 @@ -44,7 +44,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) @@ -57,11 +57,11 @@ public APIGatewayProxyResponseEvent handleRequest(final APIGatewayProxyRequestEv metricsLogger().putMetric("CustomMetric1", 1, Unit.COUNT); - withSingleMetric("CustomMetrics2", 1, Unit.COUNT, "Another", (metric) -> - { - metric.setDimensions(DimensionSet.of("AnotherService", "CustomService")); - metric.setDimensions(DimensionSet.of("AnotherService1", "CustomService1")); - }); + withSingleMetric("CustomMetrics2", 1, Unit.COUNT, "Another", metric -> + { + metric.setDimensions(DimensionSet.of("AnotherService", "CustomService")); + metric.setDimensions(DimensionSet.of("AnotherService1", "CustomService1")); + }); LoggingUtils.appendKey("test", "willBeLogged"); @@ -74,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 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"); diff --git a/pom.xml b/pom.xml index 17fb1a712..1c6df58bf 100644 --- a/pom.xml +++ b/pom.xml @@ -90,7 +90,7 @@ 3.3.0 3.1.0 5.10.0 - 1.0.6 + 4.1.1 0.5.1 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"; } 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..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 @@ -14,11 +14,15 @@ 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; +import software.amazon.lambda.powertools.metrics.exception.InvalidMetricDimensionException; public final class MetricsLoggerHelper { + private MetricsLoggerHelper() { } @@ -27,7 +31,11 @@ public static boolean hasNoMetrics() { } public static long dimensionsCount() { - return metricsContext().getDimensions().size(); + try { + return metricsContext().getDimensions().size(); + } catch (DimensionSetExceededException e) { + throw new InvalidMetricDimensionException(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..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 @@ -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,11 +24,14 @@ 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; 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 @@ -63,23 +65,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 +80,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 InvalidMetricNamespaceException(e); + } catch (InvalidMetricException e) { + throw new software.amazon.lambda.powertools.metrics.exception.InvalidMetricException(e); + } finally { + metricsLogger.flush(); + } } /** @@ -118,12 +112,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 InvalidMetricNamespaceException(e); + } catch (InvalidMetricException e) { + throw new software.amazon.lambda.powertools.metrics.exception.InvalidMetricException(e); + } finally { + metricsLogger.flush(); + } } /** @@ -141,25 +143,13 @@ public static void withMetricsLogger(final Consumer logger) { metricsLogger.setNamespace(defaultNameSpace()); captureRequestAndTraceId(metricsLogger); logger.accept(metricsLogger); + } catch (InvalidNamespaceException e) { + throw new InvalidMetricNamespaceException(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/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 56a35f67f..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 @@ -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; @@ -38,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 { @@ -57,13 +64,17 @@ 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 e) { + throw new InvalidMetricNamespaceException(e); + } catch (DimensionSetExceededException e) { + throw new InvalidMetricDimensionException(e); } } @@ -115,12 +126,26 @@ 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 InvalidMetricNamespaceException(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 e) { + throw new InvalidMetricNamespaceException(e); + } catch (DimensionSetExceededException e) { + throw new InvalidMetricDimensionException(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..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; @@ -32,6 +31,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 +62,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 +101,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 +134,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,23 +162,6 @@ void singleMetricsCaptureUtilityWithDefaultNameSpace() { } } - @Test - void metricsLoggerCaptureUtilityWithDefaultNameSpace() { - testLogger(MetricsUtils::withMetricsLogger); - } - - @Test - void deprecatedMetricLoggerCaptureUtilityWithDefaultNameSpace() { - testLogger(MetricsUtils::withMetricLogger); - } - - @Test - void shouldThrowExceptionWhenDefaultDimensionIsNull() { - assertThatNullPointerException() - .isThrownBy(() -> MetricsUtils.defaultDimensionSet(null)) - .withMessage("Null dimension set not allowed"); - } - private void testLogger(Consumer> methodToTest) { try (MockedStatic mocked = mockStatic(SystemWrapper.class); MockedStatic internalWrapper = mockStatic( @@ -176,8 +173,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 + + + +