Skip to content

feat(metrics): New metrics module implementation with support for Metrics providers and usage without annotations #1863

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 36 commits into from
Jun 6, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
2a79c02
Rewrite metrics module with interface abstraction and provider patter…
phipag Jun 2, 2025
4249766
Update default dimension and namespace logic to have the precedence: …
phipag Jun 3, 2025
9961072
Small cosmetic changes.
phipag Jun 3, 2025
f1e9acb
Add unit tests.
phipag Jun 4, 2025
6b81805
Update metrics documentation with new interface.
phipag Jun 4, 2025
86cb3ce
Make unit tests compatible with GraalVM. It is not supported to mock …
phipag Jun 4, 2025
483766c
Add GraalVM support bullet points to docs pages.
phipag Jun 4, 2025
a14c43c
Update GraalVM metadata files after re-implementing metrics module.
phipag Jun 4, 2025
17c865d
Fix spotbugs issue. This is expected for this factory class for Metri…
phipag Jun 4, 2025
4085b0d
Fix SonarCube findings.
phipag Jun 4, 2025
ead827b
Rename back namespace to ServerlessAirline example.
phipag Jun 4, 2025
ac56a5b
Fix DimensionSet validation to be inline with most recent specification.
phipag Jun 4, 2025
feeefdc
Overload void addDimension(DimensionSet dimensionSet) to be able to a…
phipag Jun 4, 2025
a178128
Update setDefaultDimensions to take a DimensionSet instead of a Map.
phipag Jun 4, 2025
4515ee4
Add warning if not emitting metrics and raiseOnEmptyMetrics is false.
phipag Jun 4, 2025
cc74f3f
Remove unused imports.
phipag Jun 4, 2025
37de57d
Add namespace validation. Refacator into own Validator class. Require…
phipag Jun 5, 2025
36dd713
Update docs with DimensionSet.of instead of Map.of. Fix naming consis…
phipag Jun 5, 2025
e0df19b
Add example for overwriting dimension of cold start metric.
phipag Jun 5, 2025
0a79cec
Add note that metadata needs to be added before flushing.
phipag Jun 5, 2025
7ef4e69
Remove test classes from GRM reflect-config.json.
phipag Jun 5, 2025
b05634d
Rename pushSingleMetric to flushSingleMetric.
phipag Jun 5, 2025
ba09a50
Add example for high cardinality dimensions using DimensionSet.
phipag Jun 5, 2025
05fe15e
Add support for POWERTOOLS_METRICS_DISABLED environment variable.
phipag Jun 5, 2025
eb167f1
Only add service name dimension if the service is actually defined.
phipag Jun 5, 2025
4637fef
Add support for POWERTOOLS_METRICS_FUNCTION_NAME.
phipag Jun 5, 2025
c7c9ed5
Add Testing your code section to docs.
phipag Jun 5, 2025
e4a3464
Rename @Metrics to @FlushMetrics.
phipag Jun 5, 2025
a635610
Rename MetricsLogger to Metrics, rename MetricsLoggerBuilder to Metri…
phipag Jun 5, 2025
ef3347a
Add support for setTimestamp.
phipag Jun 5, 2025
6b82ea5
Update regex for namespace validation.
phipag Jun 5, 2025
120b8d0
Fix namespace regex and fix metrics e2e tests.
phipag Jun 5, 2025
26a4b1d
Add comment in empty callAt method to satisfy pmd_analyse.
phipag Jun 6, 2025
0017e8b
Replace usages of standalone Powertools wording with alternative word…
phipag Jun 6, 2025
3d02853
Reduce cognitive complexity of around() method in LambdaMetricsAspect.
phipag Jun 6, 2025
53d054d
Re-generate GRM files after applying MetricsLogger renaming.
phipag Jun 6, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 23 additions & 20 deletions docs/FAQs.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,15 @@ title: FAQs
description: Frequently Asked Questions
---


## How can I use Powertools for AWS Lambda (Java) with Lombok?

Powertools uses `aspectj-maven-plugin` to compile-time weave (CTW) aspects into the project. In case you want to use `Lombok` or other compile-time preprocessor for your project, it is required to change `aspectj-maven-plugin` configuration to enable in-place weaving feature. Otherwise the plugin will ignore changes introduced by `Lombok` and will use `.java` files as a source.
Many utilities in this library use `aspectj-maven-plugin` to compile-time weave (CTW) aspects into the project. In case you want to use `Lombok` or other compile-time preprocessor for your project, it is required to change `aspectj-maven-plugin` configuration to enable in-place weaving feature. Otherwise the plugin will ignore changes introduced by `Lombok` and will use `.java` files as a source.

To enable in-place weaving feature you need to use following `aspectj-maven-plugin` configuration:

```xml hl_lines="2-6"
<configuration>
<forceAjcCompile>true</forceAjcCompile>
<forceAjcCompile>true</forceAjcCompile>
<sources/>
<weaveDirectories>
<weaveDirectory>${project.build.directory}/classes</weaveDirectory>
Expand All @@ -29,14 +28,14 @@ To enable in-place weaving feature you need to use following `aspectj-maven-plug

## How can I use Powertools for AWS Lambda (Java) with Kotlin projects?

Powertools uses `aspectj-maven-plugin` to compile-time weave (CTW) aspects into the project. When using it with Kotlin projects, it is required to `forceAjcCompile`.
No explicit configuration should be required for gradle projects.
Many utilities use `aspectj-maven-plugin` to compile-time weave (CTW) aspects into the project. When using it with Kotlin projects, it is required to `forceAjcCompile`.
No explicit configuration should be required for gradle projects.

To enable `forceAjcCompile` you need to use following `aspectj-maven-plugin` configuration:

```xml hl_lines="2"
<configuration>
<forceAjcCompile>true</forceAjcCompile>
<forceAjcCompile>true</forceAjcCompile>
...
<aspectLibraries>
<aspectLibrary>
Expand All @@ -49,17 +48,17 @@ To enable `forceAjcCompile` you need to use following `aspectj-maven-plugin` con

## How can I use Powertools for AWS Lambda (Java) with the AWS CRT HTTP Client?

Powertools uses the `url-connection-client` as the default HTTP client. The `url-connection-client` is a lightweight HTTP client, which keeps the impact on Lambda cold starts to a minimum.
With the [announcement](https://aws.amazon.com/blogs/developer/announcing-availability-of-the-aws-crt-http-client-in-the-aws-sdk-for-java-2-x/) of the `aws-crt-client` a new HTTP client has been released, which offers faster SDK startup time and smaller memory footprint.
Utilities relying on AWS SDK clients use the `url-connection-client` as the default HTTP client. The `url-connection-client` is a lightweight HTTP client, which keeps the impact on Lambda cold starts to a minimum.
With the [announcement](https://aws.amazon.com/blogs/developer/announcing-availability-of-the-aws-crt-http-client-in-the-aws-sdk-for-java-2-x/) of the `aws-crt-client` a new HTTP client has been released, which offers faster SDK startup time and smaller memory footprint.

Unfortunately, replacing the `url-connection-client` dependency with the `aws-crt-client` will not immediately improve the lambda cold start performance and memory footprint,
as the default version of the dependency contains native system libraries for all supported runtimes and architectures (Linux, MacOS, Windows, AMD64, ARM64, etc). This makes the CRT client portable, without the user having to consider _where_ their code will run, but comes at the cost of JAR size.
Unfortunately, replacing the `url-connection-client` dependency with the `aws-crt-client` will not immediately improve the lambda cold start performance and memory footprint,
as the default version of the dependency contains native system libraries for all supported runtimes and architectures (Linux, MacOS, Windows, AMD64, ARM64, etc). This makes the CRT client portable, without the user having to consider _where_ their code will run, but comes at the cost of JAR size.

### Configuring dependencies

Using the `aws-crt-client` in your project requires the exclusion of the `url-connection-client` transitive dependency from the powertools dependency.
Using the `aws-crt-client` in your project requires the exclusion of the `url-connection-client` transitive dependency from the `powertools-*` dependency.

```xml
```xml
<dependency>
<groupId>software.amazon.lambda</groupId>
<artifactId>powertools-parameters</artifactId>
Expand All @@ -72,8 +71,9 @@ Using the `aws-crt-client` in your project requires the exclusion of the `url-co
</exclusions>
</dependency>
```
Next, add the `aws-crt-client` and exclude the "generic" `aws-crt` dependency (contains all runtime libraries).
Instead, set a specific classifier of the `aws-crt` to use the one for your target runtime: either `linux-x86_64` for a Lambda configured for x86 or `linux-aarch_64` for Lambda using arm64.

Next, add the `aws-crt-client` and exclude the "generic" `aws-crt` dependency (contains all runtime libraries).
Instead, set a specific classifier of the `aws-crt` to use the one for your target runtime: either `linux-x86_64` for a Lambda configured for x86 or `linux-aarch_64` for Lambda using arm64.

!!! note "You will need to add a separate maven profile to build and debug locally when your development environment does not share the target architecture you are using in Lambda."
By specifying the specific target runtime, we prevent other target runtimes from being included in the jar file, resulting in a smaller Lambda package and improved cold start times.
Expand Down Expand Up @@ -102,10 +102,11 @@ By specifying the specific target runtime, we prevent other target runtimes from
```

### Explicitly set the AWS CRT HTTP Client
After configuring the dependencies, it's required to explicitly specify the AWS SDK HTTP client.
Depending on the Powertools module, there is a different way to configure the SDK client.

The following example shows how to use the Lambda Powertools Parameters module while leveraging the AWS CRT Client.
After configuring the dependencies, it's required to explicitly specify the AWS SDK HTTP client.
Depending on the utility you are using, there is a different way to configure the SDK client.

The following example shows how to use the Parameters module while leveraging the AWS CRT Client.

```java hl_lines="16 23-24"
import static software.amazon.lambda.powertools.parameters.transform.Transformer.base64;
Expand Down Expand Up @@ -141,12 +142,12 @@ public class RequestHandlerWithParams implements RequestHandler<String, String>
}
```

The `aws-crt-client` was considered for adoption as the default HTTP client in Lambda Powertools for Java as mentioned in [Move SDK http client to CRT](https://github.com/aws-powertools/powertools-lambda-java/issues/1092),
The `aws-crt-client` was considered for adoption as the default HTTP client in Powertools for AWS Lambda (Java) as mentioned in [Move SDK http client to CRT](https://github.com/aws-powertools/powertools-lambda-java/issues/1092),
but due to the impact on the developer experience it was decided to stick with the `url-connection-client`.

## How can I use Powertools for AWS Lambda (Java) with GraalVM?

Powertools core utilities, i.e. [logging](./core/logging.md), [metrics](./core/metrics.md) and [tracing](./core/tracing.md), include the [GraalVM Reachability Metadata (GRM)](https://www.graalvm.org/latest/reference-manual/native-image/metadata/) in the `META-INF` directories of the respective JARs. You can find a working example of Serverless Application Model (SAM) based application in the [examples](../examples/powertools-examples-core-utilities/sam-graalvm/README.md) directory.
Core utilities, i.e. [logging](./core/logging.md), [metrics](./core/metrics.md) and [tracing](./core/tracing.md), include the [GraalVM Reachability Metadata (GRM)](https://www.graalvm.org/latest/reference-manual/native-image/metadata/) in the `META-INF` directories of the respective JARs. You can find a working example of Serverless Application Model (SAM) based application in the [examples](../examples/powertools-examples-core-utilities/sam-graalvm/README.md) directory.

Below, you find typical steps you need to follow in a Maven based Java project:

Expand All @@ -157,6 +158,7 @@ export JAVA_HOME=<path to GraalVM>
```

### Use log4j `>2.24.0`

Log4j version `2.24.0` adds [support for GraalVM](https://github.com/apache/logging-log4j2/issues/1539#issuecomment-2106766878). Depending on your project's dependency hierarchy, older version of log4j might be included in the final dependency graph. Make sure version `>2.24.0` of these dependencies are used by your Maven project:

```xml
Expand Down Expand Up @@ -245,10 +247,11 @@ Create a Docker image using a `Dockerfile` like [this](../examples/powertools-ex
docker build --platform linux/amd64 . -t your-org/your-app-graalvm-builder
```

Create the native image of you Lambda function using the Docker command below.
Create the native image of you Lambda function using the Docker command below.

```shell
docker run --platform linux/amd64 -it -v `pwd`:`pwd` -w `pwd` -v ~/.m2:/root/.m2 your-org/your-app-graalvm-builder mvn clean -Pnative-image package

```

The native image is created in the `target/` directory.
11 changes: 6 additions & 5 deletions docs/core/logging.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ Logging provides an opinionated logger with output structured as JSON.
* Optionally logs Lambda response
* Optionally supports log sampling by including a configurable percentage of DEBUG logs in logging output
* Allows additional keys to be appended to the structured log at any point in time
* GraalVM support


## Getting started
Expand Down Expand Up @@ -219,7 +220,7 @@ You can leverage the standard configuration files (_log4j2.xml_ or _logback.xml_
=== "log4j2.xml"

With log4j2, we leverage the [`JsonTemplateLayout`](https://logging.apache.org/log4j/2.x/manual/json-template-layout.html){target="_blank"}
to provide structured logging. A default template is provided in powertools ([_LambdaJsonLayout.json_](https://github.com/aws-powertools/powertools-lambda-java/tree/v2/powertools-logging/powertools-logging-log4j/src/main/resources/LambdaJsonLayout.json){target="_blank"}):
to provide structured logging. A default template is provided in powertools ([_LambdaJsonLayout.json_](https://github.com/aws-powertools/powertools-lambda-java/blob/4444b4bce8eb1cc19880d1c1ef07188d97de9126/powertools-logging/powertools-logging-log4j/src/main/resources/LambdaJsonLayout.json){target="_blank"}):

```xml hl_lines="5"
<?xml version="1.0" encoding="UTF-8"?>
Expand Down Expand Up @@ -277,7 +278,7 @@ If the level is set to any other value, we set it to the default value (`INFO`).
<!-- markdownlint-disable MD013 -->
With [AWS Lambda Advanced Logging Controls (ALC)](https://docs.aws.amazon.com/lambda/latest/dg/monitoring-cloudwatchlogs.html#monitoring-cloudwatchlogs-advanced){target="_blank"}, you can enforce a minimum log level that Lambda will accept from your application code.

When enabled, you should keep Powertools and ALC log level in sync to avoid data loss.
When enabled, you should keep your own log level and ALC log level in sync to avoid data loss.

Here's a sequence diagram to demonstrate how ALC will drop both `INFO` and `DEBUG` logs emitted from `Logger`, when ALC log level is stricter than `Logger`.
<!-- markdownlint-enable MD013 -->
Expand Down Expand Up @@ -308,7 +309,7 @@ We prioritise log level settings in this order:
2. `POWERTOOLS_LOG_LEVEL` environment variable
3. level defined in the `log4j2.xml` or `logback.xml` files

If you set Powertools level lower than ALC, we will emit a warning informing you that your messages will be discarded by Lambda.
If you set `POWERTOOLS_LOG_LEVEL` lower than ALC, we will emit a warning informing you that your messages will be discarded by Lambda.

> **NOTE**
>
Expand Down Expand Up @@ -738,7 +739,7 @@ When debugging in non-production environments, you can instruct the `@Logging` a
```

???+ note
If you use this on a RequestStreamHandler, Powertools must duplicate input streams in order to log them.
If you use this on a RequestStreamHandler, the SDK must duplicate input streams in order to log them.

## Logging handler response

Expand Down Expand Up @@ -973,7 +974,7 @@ You can also customize how [exceptions are logged](https://logging.apache.org/lo
See the [JSON Layout template documentation](https://logging.apache.org/log4j/2.x/manual/json-template-layout.html){target="_blank"} for more details.

### Logback configuration
Logback configuration is done in _logback.xml_ and the Powertools [`LambdaJsonEncoder`]():
Logback configuration is done in _logback.xml_ and the `LambdaJsonEncoder`:

```xml
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
Expand Down
Loading
Loading