# Powertools for AWS Lambda (Java) Preview
> Powertools for AWS Lambda (Java) Preview
Powertools for AWS Lambda (Java) is a developer toolkit to implement Serverless best practices and increase developer velocity. It provides a suite of utilities for AWS Lambda Functions that makes tracing with AWS X-Ray, structured logging and creating custom metrics asynchronously easier.
# Project Overview
Warning
You are browsing the documentation for Powertools for AWS Lambda (Java) - v2. This is a snapshot release and not stable! Check out our stable [v1](https://docs.powertools.aws.dev/lambda/java/) documentation if this is not what you wanted.\
The v2 maven snapshot repository can be found [here](https://aws.oss.sonatype.org/content/repositories/snapshots/software/amazon/lambda/) .
Powertools for AWS Lambda (Java) is a suite of utilities for AWS Lambda Functions that makes tracing with AWS X-Ray, structured logging and creating custom metrics asynchronously easier.
Tip
Powertools for AWS Lambda is also available for [Python](https://docs.powertools.aws.dev/lambda/python/latest/), [TypeScript](https://docs.powertools.aws.dev/lambda/typescript/latest/), and [.NET](https://docs.powertools.aws.dev/lambda/dotnet/)
Looking for a quick run through of the core utilities?
Check out [this detailed blog post](https://aws.amazon.com/blogs/opensource/simplifying-serverless-best-practices-with-aws-lambda-powertools-java/) with a practical example. To dive deeper, the [Powertools for AWS Lambda (Java) workshop](https://catalog.us-east-1.prod.workshops.aws/workshops/a7011c82-e4af-4a52-80fa-fcd61f1dacd9/en-US/introduction) is a great next step.
## Tenets
This project separates core utilities that will be available in other runtimes vs general utilities that might not be available across all runtimes.
- **AWS Lambda only** – We optimise for AWS Lambda function environments and supported runtimes only. Utilities might work with web frameworks and non-Lambda environments, though they are not officially supported.
- **Eases the adoption of best practices** – The main priority of the utilities is to facilitate best practices adoption, as defined in the AWS Well-Architected Serverless Lens; all other functionality is optional.
- **Keep it lean** – Additional dependencies are carefully considered for security and ease of maintenance, and prevent negatively impacting startup time.
- **We strive for backwards compatibility** – New features and changes should keep backwards compatibility. If a breaking change cannot be avoided, the deprecation and migration process should be clearly defined.
- **We work backwards from the community** – We aim to strike a balance of what would work best for 80% of customers. Emerging practices are considered and discussed via Requests for Comment (RFCs)
- **Progressive** - Utilities are designed to be incrementally adoptable for customers at any stage of their Serverless journey. They follow language idioms and their community’s common practices.
## Install
**Quick hello world example using SAM CLI**
You can use [SAM](https://aws.amazon.com/serverless/sam/) to quickly setup a serverless project including Powertools for AWS Lambda (Java).
```
sam init
Which template source would you like to use?
1 - AWS Quick Start Templates
2 - Custom Template Location
Choice: 1
Choose an AWS Quick Start application template
1 - Hello World Example
2 - Data processing
3 - Hello World Example with Powertools for AWS Lambda
4 - Multi-step workflow
5 - Scheduled task
6 - Standalone function
7 - Serverless API
8 - Infrastructure event management
9 - Lambda Response Streaming
10 - Serverless Connector Hello World Example
11 - Multi-step workflow with Connectors
12 - Full Stack
13 - Lambda EFS example
14 - DynamoDB Example
15 - Machine Learning
Template: 3
Which runtime would you like to use?
1 - dotnet6
2 - java17
3 - java11
4 - java8.al2
5 - java8
6 - nodejs18.x
7 - nodejs16.x
8 - nodejs14.x
9 - python3.9
10 - python3.8
11 - python3.7
12 - python3.10
Runtime: 2, 3, 4 or 5
```
**Manual installation** Powertools for AWS Lambda (Java) dependencies are available in Maven Central. You can use your favourite dependency management tool to install it
- [Maven](https://maven.apache.org/)
- [Gradle](https://gradle.org)
```
...
software.amazon.lambdapowertools-tracing2.0.0-SNAPSHOTsoftware.amazon.lambdapowertools-logging2.0.0-SNAPSHOTsoftware.amazon.lambdapowertools-metrics2.0.0-SNAPSHOTorg.aspectjaspectjrt1.9.22
...
...
...
dev.aspectjaspectj-maven-plugin1.14111111software.amazon.lambdapowertools-tracingsoftware.amazon.lambdapowertools-loggingsoftware.amazon.lambdapowertools-metricsorg.aspectjaspectjtools1.9.22compile
...
```
```
plugins {
id 'java'
id 'io.freefair.aspectj.post-compile-weaving' version '8.2.2'
}
// the freefair aspect plugins targets gradle 8.2.1
// https://docs.freefair.io/gradle-plugins/8.2.2/reference/
wrapper {
gradleVersion = "8.2.1"
}
repositories {
mavenCentral()
}
dependencies {
aspect 'software.amazon.lambda:powertools-logging:2.0.0-SNAPSHOT'
aspect 'software.amazon.lambda:powertools-tracing:2.0.0-SNAPSHOT'
aspect 'software.amazon.lambda:powertools-metrics:2.0.0-SNAPSHOT'
}
sourceCompatibility = 11
targetCompatibility = 11
```
Why a different configuration?
Powertools for AWS Lambda (Java) is using [AspectJ](https://eclipse.dev/aspectj/doc/released/progguide/starting.html) internally to handle annotations. Recently, in order to support Java 17 we had to move to `dev.aspectj:aspectj-maven-plugin` because\
`org.codehaus.mojo:aspectj-maven-plugin` does not support Java 17. Under the hood, `org.codehaus.mojo:aspectj-maven-plugin` is based on AspectJ 1.9.7, while `dev.aspectj:aspectj-maven-plugin` is based on AspectJ 1.9.8, compiled for Java 11+.
### Java Compatibility
Powertools for AWS Lambda (Java) supports all Java version from 11 up to 21 as well as the [corresponding Lambda runtimes](https://docs.aws.amazon.com/lambda/latest/dg/lambda-runtimes.html).
For the following modules, Powertools for AWS Lambda (Java) leverages the **aspectj** library to provide annotations:
- Logging
- Metrics
- Tracing
- Parameters
- Idempotency
- Validation
- Large messages
You may need to add the good version of `aspectjrt` to your dependencies based on the jdk used for building your function:
```
org.aspectjaspectjrt1.9.??
```
Use the following [dependency matrix](https://github.com/eclipse-aspectj/aspectj/blob/master/docs/dist/doc/JavaVersionCompatibility.md) between this library and the JDK:
| JDK version | aspectj version | | --- | --- | | `11-17` | `1.9.20.1` (or higher) | | `21` | `1.9.21` (or higher) |
## Environment variables
Info
**Explicit parameters take precedence over environment variables.**
| Environment variable | Description | Utility | | --- | --- | --- | | **POWERTOOLS_SERVICE_NAME** | Sets service name used for tracing namespace, metrics dimension and structured logging | All | | **POWERTOOLS_METRICS_NAMESPACE** | Sets namespace used for metrics | [Metrics](./core/metrics) | | **POWERTOOLS_LOGGER_SAMPLE_RATE** | Debug log sampling | [Logging](./core/logging) | | **POWERTOOLS_LOG_LEVEL** | Sets logging level | [Logging](./core/logging) | | **POWERTOOLS_LOGGER_LOG_EVENT** | Enables/Disables whether to log the incoming event when using the aspect | [Logging](./core/logging) | | **POWERTOOLS_TRACER_CAPTURE_RESPONSE** | Enables/Disables tracing mode to capture method response | [Tracing](./core/tracing) | | **POWERTOOLS_TRACER_CAPTURE_ERROR** | Enables/Disables tracing mode to capture method error | [Tracing](./core/tracing) |
## 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.
To enable in-place weaving feature you need to use following `aspectj-maven-plugin` configuration:
```
true${project.build.directory}/classes
...
software.amazon.lambdapowertools-logging
```
## 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.
To enable `forceAjcCompile` you need to use following `aspectj-maven-plugin` configuration:
```
true
...
software.amazon.lambdapowertools-logging
```
## 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.
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.
```
software.amazon.lambdapowertools-parameters2.0.0software.amazon.awssdkurl-connection-client
```
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.
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.
```
software.amazon.awssdkaws-crt-client2.23.21software.amazon.awssdk.crtaws-crtsoftware.amazon.awssdk.crtaws-crt0.29.9linux-x86_64
```
### 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.
```
import static software.amazon.lambda.powertools.parameters.transform.Transformer.base64;
import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;
import software.amazon.awssdk.services.ssm.SsmClient;
import software.amazon.awssdk.http.crt.AwsCrtHttpClient;
import software.amazon.lambda.powertools.parameters.ssm.SSMProvider;
public class RequestHandlerWithParams implements RequestHandler {
// Get an instance of the SSMProvider with a custom HTTP client (aws crt).
SSMProvider ssmProvider = SSMProvider
.builder()
.withClient(
SsmClient.builder()
.httpClient(AwsCrtHttpClient.builder().build())
.build()
)
.build();
public String handleRequest(String input, Context context) {
// Retrieve a single param
String value = ssmProvider
.get("/my/secret");
// We might instead want to retrieve multiple parameters at once, returning a Map of key/value pairs
// .getMultiple("/my/secret/path");
// Return the result
return value;
}
}
```
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), 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/), [metrics](../core/metrics/) and [tracing](../core/tracing/), 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:
### Set the environment to use GraalVM
```
export JAVA_HOME=
```
### 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:
```
org.apache.logging.log4jlog4j-api${log4j.version}org.apache.logging.log4jlog4j-core${log4j.version}org.apache.logging.log4jlog4j-slf4j2-impl${log4j.version}org.apache.logging.log4jlog4j-layout-template-json${log4j.version}
```
### Add the AWS Lambda Java Runtime Interface Client dependency
The Runtime Interface Client allows your function to receive invocation events from Lambda, send the response back to Lambda, and report errors to the Lambda service. Add the below dependency to your Maven project:
```
com.amazonawsaws-lambda-java-runtime-interface-client2.1.1
```
Also include the AWS Lambda GRM files by copying the `com.amazonaws` [directory](../examples/powertools-examples-core-utilities/sam-graalvm/src/main/resources/META-INF/native-image/) in your project's `META-INF/native-image` directory
### Build the native image
Use the `native-maven-plugin` to build the native image. You can do this by adding the plugin to your `pom.xml` and creating a build profile called `native-image` that can build the native image of your Lambda function:
```
native-imageorg.graalvm.buildtoolsnative-maven-plugin0.10.1truebuild-nativebuildpackageyour-project-namecom.amazonaws.services.lambda.runtime.api.client.AWSLambda--enable-url-protocols=http--add-opens java.base/java.util=ALL-UNNAMED
```
Create a Docker image using a `Dockerfile` like [this](../examples/powertools-examples-core-utilities/sam-graalvm/Dockerfile) to create an x86 based build image.
```
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.
```
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.
# Changelog
All notable changes to this project will be documented in this file.
This project follows [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) format for changes and adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased]
## [1.20.1] - 2025-04-08
- docs: fix 2 typos (#1739) by @ntestor
- docs: Correct XML formatting for Maven configuration in Large Messages utility docs (#1796) by @jreijn
- fix: Load version.properties file as resource stream to fix loading when packaged as jar (#1813) by @phipag
## [1.20.0] - 2025-03-25
- feat(cfn-custom-resource): Add optional 'reason' field for detailed failure reporting (#1758) by @moizsh
## [1.19.0] - 2025-03-07
- chore(deps): Update deps for jackson ([#1793](https://github.com/aws-powertools/powertools-lambda-java/pull/1793)) by [@sthulb](https://github.com/sthulb)
- build(deps): bump log4j.version from 2.22.1 to 2.24.3 ([#1777](https://github.com/aws-powertools/powertools-lambda-java/pull/1777)) by [@dependabot](https://github.com/dependabot)
- chore(deps): update JSII to 1.108 ([#1791](https://github.com/aws-powertools/powertools-lambda-java/pull/1791)) by [@sthulb](https://github.com/sthulb)
- build(deps): bump jinja2 from 3.1.5 to 3.1.6 in /docs ([#1789](https://github.com/aws-powertools/powertools-lambda-java/pull/1789)) by [@dependabot](https://github.com/dependabot)
- chore: Update netty version ([#1768](https://github.com/aws-powertools/powertools-lambda-java/pull/1768)) by [@sthulb](https://github.com/sthulb)
- chore: Set versions of transitive dependencies ([#1767](https://github.com/aws-powertools/powertools-lambda-java/pull/1767)) by [@sthulb](https://github.com/sthulb)
- chore: update Jackson in examples ([#1766](https://github.com/aws-powertools/powertools-lambda-java/pull/1766)) by [@sthulb](https://github.com/sthulb)
- build(deps): bump org.apache.maven.plugins:maven-jar-plugin from 3.4.1 to 3.4.2 ([#1731](https://github.com/aws-powertools/powertools-lambda-java/pull/1731)) by [@dependabot](https://github.com/dependabot)
- build(deps): bump aws.xray.recorder.version from 2.15.3 to 2.18.1 ([#1726](https://github.com/aws-powertools/powertools-lambda-java/pull/1726)) by [@dependabot](https://github.com/dependabot)
- build(deps): bump aws.sdk.version from 2.26.29 to 2.27.12 ([#1724](https://github.com/aws-powertools/powertools-lambda-java/pull/1724)) by [@dependabot](https://github.com/dependabot)
- fix: Allow empty responses as well as null response in AppConfig ([#1673](https://github.com/aws-powertools/powertools-lambda-java/pull/1673)) by [@chrisclayson](https://github.com/chrisclayson)
- build(deps): bump aws.sdk.version from 2.27.2 to 2.27.7 ([#1715](https://github.com/aws-powertools/powertools-lambda-java/pull/1715)) by [@dependabot](https://github.com/dependabot)
- build(deps): bump aws.sdk.version from 2.26.29 to 2.27.2 ([#1714](https://github.com/aws-powertools/powertools-lambda-java/pull/1714)) by [@dependabot](https://github.com/dependabot)
- build(deps): bump aws.sdk.version from 2.25.26 to 2.26.29 ([#1713](https://github.com/aws-powertools/powertools-lambda-java/pull/1713)) by [@dependabot](https://github.com/dependabot)
- build(deps): bump aws.sdk.version from 2.26.25 to 2.26.29 ([#1712](https://github.com/aws-powertools/powertools-lambda-java/pull/1712)) by [@dependabot](https://github.com/dependabot)
- chore: deprecate java1.8 al1 ([#1706](https://github.com/aws-powertools/powertools-lambda-java/pull/1706)) by [@jeromevdl](https://github.com/jeromevdl)
- chore: java 1.8 AL1 is deprecated, fix E2E tests ([#1692](https://github.com/aws-powertools/powertools-lambda-java/pull/1692)) by [@jeromevdl](https://github.com/jeromevdl)
- build(deps): bump aws.sdk.version from 2.26.21 to 2.26.25 ([#1703](https://github.com/aws-powertools/powertools-lambda-java/pull/1703)) by [@dependabot](https://github.com/dependabot)
- build(deps): bump aws.sdk.version from 2.26.3 to 2.26.21 ([#1697](https://github.com/aws-powertools/powertools-lambda-java/pull/1697)) by [@dependabot](https://github.com/dependabot)
- build(deps): bump jackson.version from 2.17.0 to 2.17.2 ([#1696](https://github.com/aws-powertools/powertools-lambda-java/pull/1696)) by [@dependabot](https://github.com/dependabot)
- build(deps): bump org.apache.commons:commons-lang3 from 3.13.0 to 3.14.0 ([#1694](https://github.com/aws-powertools/powertools-lambda-java/pull/1694)) by [@dependabot](https://github.com/dependabot)
- build(deps): bump commons-io:commons-io from 2.15.1 to 2.16.1 ([#1691](https://github.com/aws-powertools/powertools-lambda-java/pull/1691)) by [@dependabot](https://github.com/dependabot)
- docs: improve tracing doc for sdk instrumentation ([#1687](https://github.com/aws-powertools/powertools-lambda-java/pull/1687)) by [@jeromevdl](https://github.com/jeromevdl)
- docs: fix tracing links for xray ([#1686](https://github.com/aws-powertools/powertools-lambda-java/pull/1686)) by [@jeromevdl](https://github.com/jeromevdl)
- build(deps): bump org.apache.maven.plugins:maven-failsafe-plugin from 3.2.5 to 3.3.0 ([#1679](https://github.com/aws-powertools/powertools-lambda-java/pull/1679)) by [@dependabot](https://github.com/dependabot)
- build(deps): bump aws.sdk.version from 2.25.69 to 2.26.3 ([#1658](https://github.com/aws-powertools/powertools-lambda-java/pull/1658)) by [@dependabot](https://github.com/dependabot)
- build(deps): bump com.github.spotbugs:spotbugs-maven-plugin from 4.7.3.6 to 4.8.5.0 ([#1657](https://github.com/aws-powertools/powertools-lambda-java/pull/1657)) by [@dependabot](https://github.com/dependabot)
- build(deps): bump org.apache.maven.plugins:maven-checkstyle-plugin from 3.3.0 to 3.4.0 ([#1653](https://github.com/aws-powertools/powertools-lambda-java/pull/1653)) by [@dependabot](https://github.com/dependabot)
- build(deps): bump aws.sdk.version from 2.25.50 to 2.25.69 ([#1652](https://github.com/aws-powertools/powertools-lambda-java/pull/1652)) by [@dependabot](https://github.com/dependabot)
- build(deps): bump org.apache.maven.plugins:maven-source-plugin from 3.3.0 to 3.3.1 ([#1646](https://github.com/aws-powertools/powertools-lambda-java/pull/1646)) by [@dependabot](https://github.com/dependabot)
- build(deps): bump org.assertj:assertj-core from 3.25.3 to 3.26.0 ([#1644](https://github.com/aws-powertools/powertools-lambda-java/pull/1644)) by [@dependabot](https://github.com/dependabot)
- build(deps): bump aws.xray.recorder.version from 2.15.1 to 2.15.3 ([#1643](https://github.com/aws-powertools/powertools-lambda-java/pull/1643)) by [@dependabot](https://github.com/dependabot)
- build(deps): bump aws.sdk.version from 2.25.35 to 2.25.50 ([#1642](https://github.com/aws-powertools/powertools-lambda-java/pull/1642)) by [@dependabot](https://github.com/dependabot)
- build(deps): bump com.amazonaws:aws-lambda-java-events from 3.11.2 to 3.11.4 ([#1597](https://github.com/aws-powertools/powertools-lambda-java/pull/1597)) by [@dependabot](https://github.com/dependabot)
- build(deps): bump aws.sdk.version from 2.24.10 to 2.25.6 ([#1603](https://github.com/aws-powertools/powertools-lambda-java/pull/1603)) by [@dependabot](https://github.com/dependabot)
- build(deps): bump org.apache.maven.plugins:maven-surefire-plugin from 3.1.2 to 3.2.5 ([#1596](https://github.com/aws-powertools/powertools-lambda-java/pull/1596)) by [@dependabot](https://github.com/dependabot)
- build(deps): bump org.codehaus.mojo:exec-maven-plugin from 3.1.0 to 3.2.0 ([#1585](https://github.com/aws-powertools/powertools-lambda-java/pull/1585)) by [@dependabot](https://github.com/dependabot)
- build(deps-dev): bump software.amazon.awscdk:aws-cdk-lib from 2.100.0 to 2.130.0 ([#1586](https://github.com/aws-powertools/powertools-lambda-java/pull/1586)) by [@dependabot](https://github.com/dependabot)
- build(deps): bump io.burt:jmespath-jackson from 0.5.1 to 0.6.0 ([#1587](https://github.com/aws-powertools/powertools-lambda-java/pull/1587)) by [@dependabot](https://github.com/dependabot)
- build(deps): bump aws.sdk.version from 2.21.0 to 2.24.10 ([#1581](https://github.com/aws-powertools/powertools-lambda-java/pull/1581)) by [@dependabot](https://github.com/dependabot)
- build(deps): bump commons-io:commons-io from 2.13.0 to 2.15.1 ([#1584](https://github.com/aws-powertools/powertools-lambda-java/pull/1584)) by [@dependabot](https://github.com/dependabot)
- build(deps): bump aws.xray.recorder.version from 2.14.0 to 2.15.1 ([#1583](https://github.com/aws-powertools/powertools-lambda-java/pull/1583)) by [@dependabot](https://github.com/dependabot)
- build(deps): bump org.apache.maven.plugins:maven-shade-plugin from 3.5.0 to 3.5.2 ([#1582](https://github.com/aws-powertools/powertools-lambda-java/pull/1582)) by [@dependabot](https://github.com/dependabot)
- build(deps-dev): bump org.yaml:snakeyaml from 2.1 to 2.2 ([#1400](https://github.com/aws-powertools/powertools-lambda-java/pull/1400)) by [@dependabot](https://github.com/dependabot)
- build(deps): bump log4j.version from 2.20.0 to 2.22.1 ([#1547](https://github.com/aws-powertools/powertools-lambda-java/pull/1547)) by [@dependabot](https://github.com/dependabot)
- build(deps): bump org.apache.maven.plugins:maven-artifact-plugin from 3.4.1 to 3.5.0 ([#1485](https://github.com/aws-powertools/powertools-lambda-java/pull/1485)) by [@dependabot](https://github.com/dependabot)
- build(deps): bump com.amazonaws:aws-lambda-java-serialization from 1.1.2 to 1.1.5 ([#1573](https://github.com/aws-powertools/powertools-lambda-java/pull/1573)) by [@dependabot](https://github.com/dependabot)
- build(deps): bump org.jacoco:jacoco-maven-plugin from 0.8.10 to 0.8.11 ([#1509](https://github.com/aws-powertools/powertools-lambda-java/pull/1509)) by [@dependabot](https://github.com/dependabot)
- build(deps): bump aspectj to 1.9.21 for jdk21 ([#1536](https://github.com/aws-powertools/powertools-lambda-java/pull/1536)) by [@jeromevdl](https://github.com/jeromevdl)
- docs: HelloWorldStreamFunction in examples fails with sam ([#1532](https://github.com/aws-powertools/powertools-lambda-java/pull/1532)) by [@jasoniharris](https://github.com/jasoniharris)
- chore: Testing java21 aspectj pre-release ([#1519](https://github.com/aws-powertools/powertools-lambda-java/pull/1519)) by [@scottgerring](https://github.com/scottgerring)
- fix: LargeMessageIdempotentE2ET Flaky ([#1518](https://github.com/aws-powertools/powertools-lambda-java/pull/1518)) by [@scottgerring](https://github.com/scottgerring)
- build(deps): bump software.amazon.payloadoffloading:payloadoffloading-common from 2.1.3 to 2.2.0 ([#1639](https://github.com/aws-powertools/powertools-lambda-java/pull/1639)) by [@dependabot](https://github.com/dependabot)
- build(deps): bump org.apache.maven.plugins:maven-jar-plugin from 3.3.0 to 3.4.1 ([#1638](https://github.com/aws-powertools/powertools-lambda-java/pull/1638)) by [@dependabot](https://github.com/dependabot)
- build(deps): bump jackson.version from 2.15.3 to 2.17.0 ([#1637](https://github.com/aws-powertools/powertools-lambda-java/pull/1637)) by [@dependabot](https://github.com/dependabot)
- build(deps): bump aws.sdk.version from 2.25.31 to 2.25.35 ([#1629](https://github.com/aws-powertools/powertools-lambda-java/pull/1629)) by [@dependabot](https://github.com/dependabot)
- build(deps): bump aws.sdk.version from 2.25.16 to 2.25.31 ([#1625](https://github.com/aws-powertools/powertools-lambda-java/pull/1625)) by [@dependabot](https://github.com/dependabot)
- build(deps): bump aws.sdk.version from 2.21.1 to 2.25.26 ([#1622](https://github.com/aws-powertools/powertools-lambda-java/pull/1622)) by [@dependabot](https://github.com/dependabot)
- build(deps): bump org.apache.maven.plugins:maven-failsafe-plugin from 3.1.2 to 3.2.5 ([#1619](https://github.com/aws-powertools/powertools-lambda-java/pull/1619)) by [@dependabot](https://github.com/dependabot)
- build(deps): bump com.fasterxml.jackson.datatype:jackson-datatype-joda from 2.15.2 to 2.17.0 ([#1616](https://github.com/aws-powertools/powertools-lambda-java/pull/1616)) by [@dependabot](https://github.com/dependabot)
- build(deps): bump aws.sdk.version from 2.25.6 to 2.25.16 ([#1613](https://github.com/aws-powertools/powertools-lambda-java/pull/1613)) by [@dependabot](https://github.com/dependabot)
- build(deps): bump org.apache.maven.plugins:maven-gpg-plugin from 3.1.0 to 3.2.1 ([#1610](https://github.com/aws-powertools/powertools-lambda-java/pull/1610)) by [@dependabot](https://github.com/dependabot)
- build(deps): bump org.assertj:assertj-core from 3.24.2 to 3.25.3 ([#1609](https://github.com/aws-powertools/powertools-lambda-java/pull/1609)) by [@dependabot](https://github.com/dependabot)
## [1.18.0] - 2023-11-16
### Added
- feat: add support for [Lambda Advanced Logging Controls (ALC)](https://docs.aws.amazon.com/lambda/latest/dg/monitoring-cloudwatchlogs.html#monitoring-cloudwatchlogs-advanced) (#1514) by @jeromevdl
- feat: Add support for POWERTOOLS_LOGGER_LOG_EVENT (#1510) by @AlexeySoshin
### Maintenance
- fix: json schema 403 error (#1457) by @jeromevdl
- fix: array jmespath fail in idempotency module (#1420) by @jeromevdl
- chore: java21 support in our build (#1488) by @jeromevdl
- chore: Addition of Warn Message If Invalid Annotation Key While Tracing #1511 (#1512) by @jdoherty
- fix: null namespace should fallback to default namespace (#1506) by @jeromevdl
- fix: get trace id from system property when env var is not set (#1503) by @mriccia
- chore: artifacts size on good branches (#1493) by @jeromevdl
- fix: enforce jackson databind version (#1472) by @jeromevdl
- chore: add missing projects and improve workflow (#1487) by @jeromevdl
- chore: Reporting size of the jars in GitHub comments (#1196) by @jeromevdl
- Deps: Bump third party dependencies to the latest versions.
### Documentation
- docs(customer-reference): add Vertex Pharmaceuticals as a customer reference (#1486) by @scottgerring
- docs: Adding Kotlin example. (#1454) by @jasoniharris
- docs: Terraform example (#1478) by @skal111
- docs: Add Serveless Framework example (#1363) by @AlexeySoshin
- docs: Fix link to SQS large message migration guide (#1422) by @scottgerring
- docs(logging): correct log example keys (#1411) by @walmsles
- docs: Update gradle configuration readme (#1359) by @scottgerring
## [1.17.0] - 2023-08-21
### Added
- Feat: Add Batch Processor module in (#1317) by @scottgerring
- Feat: Add SNS+SQS large messages module (#1310) by @jeromevdl
### Maintenance
- fix: use default credentials provider for all provided SDK clients in (#1303) by @roamingthings
- Chore: Make request for Logger explicitly for current class in (#1307) by @jreijn
- Chore: checkstyle formater & linter in (#1316) by @jeromevdl
- Chore: Add powertools specific user-agent-suffix to the AWS SDK v2 clients by @eldimi in (#1306)
- Chore: Add 'v2' branch to build workflows to prepare for v2 work in (#1341) by @scottgerring
- Deps: Bump third party dependencies to the latest versions.
### Documentation
- Docs: Add maintainers guide in (#1326) by @scottgerring
- Docs: improve contributing guide in (#1334) by @jeromevdl
- Docs: Improve example documentation in (#1291) by @scottgerring
- Docs: Add discord + sec disclosure links to readme in (#1311) by @scottgerring
- Docs: Add external examples from AWS SAM CLI App Templates in (#1318) by @AlexeySoshin
- Docs: Add CDK example in (#1321) by @AlexeySoshin
## [1.16.1] - 2023-07-19
- Fix: idempotency timeout bug (#1285) by @scottgerring
- Fix: ParamManager cannot provide default SSM & Secrets providers (#1282) by @jeromevdl
- Fix: Handle batch failures in FIFO queues correctly (#1183) by @scottgerring
- Deps: Bump third party dependencies to the latest versions.
## [1.16.0] - 2023-06-29
### Added
- Feature: Add AppConfig provider to parameters module (#1104) by @scottgerring
### Maintenance
- Fix: missing idempotency key should not persist any data (#1201) by @jeromevdl
- Fix:Removing env var credentials provider as default. (#1161) by @msailes
- Chore: Swap implementation of `aspectj-maven-plugin` to support Java 17 (#1172) by @mriccia
- Test: end-to-end tests for core modules and idempotency (#970) by @jeromevdl
- Chore: cleanup spotbugs maven profiles (#1236) by @jeromevdl
- Chore: removing logback from all components (#1227) by @jeromevdl
- Chore: Roll SLF4J log4j bindings to v2 (#1190) by @scottgerring
- Deps: Bump third party dependencies to the latest versions.
## [1.15.0] - 2023-03-20
### Added
- Feature: Add DynamoDB provider to parameters module (#1091) by @scottgerring
- Feature: Update to powertools-cloudformation to deprecate `Response.success()` and `Response.failed()` methods. New helper methods are added to make it easier to follow best practices `Response.success(String physicalResourceId)` and `Response.failed(String physicalResourceId)`. For a detailed explanation please read the [powertools-cloudformation documentation page](https://docs.powertools.aws.dev/lambda-java/utilities/custom_resources/). (#1082) by @msailes
- Update how a Lambda request handler method is identified (#1058) by @humanzz
### Maintenance
- Deps: Bump third party dependencies to the latest versions.
- Examples: Import examples from aws-samples/aws-lambda-powertools-examples (#1051) by @scottgerring
- Deprecate withMetricLogger in favor of withMetricsLogger (#1060) by @humanzz
- Update issue templates (#1062) by @machafer
- Send code coverage report (jacoco) to codecov (#1094) by @jeromevdl
### Documentation
- Improve `powertools-cloudformation` docs (#1090) by @mriccia
- Add link to Powertools for AWS Lambda (Java) workshop (#1095) by @scottgerring
- Fix mdocs and git revision plugin integration (#1066) by @machafer
## [1.14.0] - 2023-02-17
### Added
- Feature: Introduce `MetricsUtils.withMetricsLogger()` utility method (#1000) by @humanzz
#### Maintenance
- Update logic for recording documentation pages views to use correct runtime name (#1047) by @kozub
- Deps: Bump third party dependencies to the latest versions.
### Documentation
- Docs: Update Powertools for AWS Lambda (Java) definition by @heitorlessa
- Docs: Add information about other supported langauges to README and docs (#1033) by @kozub
## [1.13.0] - 2022-12-14
### Added
- Feature: Idempotency - Handle Lambda timeout scenarios for INPROGRESS records (#933) by @jeromevdl
### Bug Fixes
- Fix: Envelope is not taken into account with built-in types (#960) by @jeromevdl
- Fix: Code suggestion from CodeGuru (#984) by @kozub
- Fix: Compilation warning with SqsLargeMessageAspect on gradle (#998) by @jeromevdl
- Fix: Log message processing exceptions as occur (#1011) by @nem0-97
### Documentation
- Docs: Add missing grammar article (#976) by @fsmiamoto
## [1.12.3] - 2022-07-12
#### Maintenance
- Fixes to resolve vulnerable transitive dependencies ([919](https://github.com/aws-powertools/powertools-lambda-java/issues/919))
## [1.12.2] - 2022-04-29
### Bug Fixes
- **SQS Large message processing**: Classpath conflict on `PayloadS3Pointer` when consumer application depends on `payloadoffloading-common`, introduced in [v1.8.0](https://github.com/aws-powertools/powertools-lambda-java/releases/tag/v1.8.0). ([#851](https://github.com/aws-powertools/powertools-lambda-java/pull/851))
## [1.12.1] - 2022-04-21
### Bug Fixes
- **Idempotency**: thread-safety issue of MessageDigest ([#817](https://github.com/aws-powertools/powertools-lambda-java/pull/817))
- **Idempotency**: disable dynamodb client creation in persistent store when disabling idempotency ([#796](https://github.com/aws-powertools/powertools-lambda-java/pull/796))
### Maintenance
- **deps**: Bump third party dependencies to the latest versions.
## [1.12.0] - 2022-03-01
### Added
- **Easy Event Deserialization**: Extraction and deserialization of the main content of events (body, messages, ...) [#757](https://github.com/aws-powertools/powertools-lambda-java/pull/757)
### Bug Fixes
- Different behavior while using SSMProvider with or without trailing slash in parameter names [#758](https://github.com/aws-powertools/powertools-lambda-java/issues/758)
## [1.11.0] - 2022-02-16
### Added
- Powertools for AWS Lambda (Java) Idempotency module: New module to get your Lambda function [Idempotent](https://aws.amazon.com/builders-library/making-retries-safe-with-idempotent-APIs/) (#717)
- Powertools for AWS Lambda (Java) Serialization module: New module to handle JSON (de)serialization (Jackson ObjectMapper, JMESPath functions)
## [1.10.3] - 2022-02-01
### Bug Fixes
- **SQS Batch processing**: Prevent message to be marked as success if failed sending to DLQ for non retryable exceptions. [#731](https://github.com/aws-powertools/powertools-lambda-java/pull/731)
### Documentation
- **SQS Batch processing**: Improve [documentation](https://docs.powertools.aws.dev/lambda-java/utilities/batch/#iam-permissions) on IAM premissions required by function when using utility with an encrypted SQS queue with customer managed KMS keys.
## [1.10.2] - 2022-01-07
- **Tracing**: Ability to override object mapper used for serializing method response as trace metadata when enabled. This provides users ability to customize how and what you want to capture as metadata from method response object. [#698](https://github.com/aws-powertools/powertools-lambda-java/pull/698)
## [1.10.1] - 2022-01-06
- **Logging**: Upgrade Log4j to version 2.17.1 for [CVE-2021-44832](https://nvd.nist.gov/vuln/detail/CVE-2021-44832)
## [1.10.0] - 2021-12-27
- **Logging**: Modern log4j configuration to customise structured logging. Refer [docs](https://docs.powertools.aws.dev/lambda-java/core/logging/#upgrade-to-jsontemplatelayout-from-deprecated-lambdajsonlayout-configuration-in-log4j2xml) to start using new config. [#670](https://github.com/aws-powertools/powertools-lambda-java/pull/670)
- **SQS Batch**: Support batch size greater than 10. [#667](https://github.com/aws-powertools/powertools-lambda-java/pull/667)
## [1.9.0] - 2021-12-21
- **Logging**: Upgrade Log4j to version 2.17.0 for [CVE-2021-45105](https://nvd.nist.gov/vuln/detail/CVE-2021-45105)
- **Tracing**: add `Service` annotation. [#654](https://github.com/aws-powertools/powertools-lambda-java/issues/654)
## [1.8.2] - 2021-12-15
## Security
- Upgrading Log4j to version 2.16.0 for [CVE-2021-45046](https://nvd.nist.gov/vuln/detail/CVE-2021-45046)
## [1.8.1] - 2021-12-10
## Security
- Upgrading Log4j to version 2.15.0 for [CVE-2021-44228](https://nvd.nist.gov/vuln/detail/CVE-2021-44228)
## [1.8.0] - 2021-11-05
### Added
- **Powertools for AWS Lambda (Java) Cloudformation module (NEW)**: New module simplifying [AWS Lambda-backed custom resources](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/template-custom-resources-lambda.html) written in Java. [#560](https://github.com/aws-powertools/powertools-lambda-java/pull/560)
- **SQS Large message processing**: Ability to override the default `S3Client` use to fetch payload from S3. [#602](https://github.com/aws-powertools/powertools-lambda-java/pull/602)
### Regression
- **Logging**: `@Logging` annotation now works with `@Tracing` annotation on `RequestStreamHandler` when used in `logEvent` mode. [#567](https://github.com/aws-powertools/powertools-lambda-java/pull/567)
### Maintenance
- **deps**: Bump third party dependencies to the latest versions.
## [1.7.3] - 2021-09-14
- **SQS Batch processing**: Ability to move non retryable message to configured dead letter queue(DLQ). [#500](https://github.com/aws-powertools/powertools-lambda-java/pull/500)
## [1.7.2] - 2021-08-03
- **Powertools for AWS Lambda (Java) All Modules**: Upgrade to the latest(1.14.0) aspectj-maven-plugin which also supports Java 9 and newer versions. Users no longer need to depend on [com.nickwongdev](https://mvnrepository.com/artifact/com.nickwongdev/aspectj-maven-plugin/1.12.6) as a workaround. [#489](https://github.com/aws-powertools/powertools-lambda-java/pull/489)
- **Logging**: Performance optimisation to improve cold start. [#484](https://github.com/aws-powertools/powertools-lambda-java/pull/484)
- **SQS Batch processing/Large message**: Module now lazy loads default SQS client. [#484](https://github.com/aws-powertools/powertools-lambda-java/pull/484)
## [1.7.1] - 2021-07-06
- **Powertools for AWS Lambda (Java) All Modules**: Fix static code analysis violations done via [spotbugs](https://github.com/spotbugs/spotbugs) ([#458](https://github.com/aws-powertools/powertools-lambda-java/pull/458)).
## [1.7.0] - 2021-07-05
### Added
- **Logging**: Support for extracting Correlation id using `@Logging` annotation via `correlationIdPath` attribute and `setCorrelationId()` method in `LoggingUtils`([#448](https://github.com/aws-powertools/powertools-lambda-java/pull/448)).
- **Logging**: New `clearState` attribute on `@Logging` annotation to clear previously added custom keys upon invocation([#453](https://github.com/aws-powertools/powertools-lambda-java/pull/453)).
### Maintenance
- **deps**: Bump third party dependencies to the latest versions.
## [1.6.0] - 2021-06-21
### Added
- **Tracing**: Support for Boolean and Number type as value in `TracingUtils.putAnnotation()`([#423](https://github.com/aws-powertools/powertools-lambda-java/pull/432)).
- **Logging**: API to remove any additional custom key from logger entry using `LoggingUtils.removeKeys()`([#395](https://github.com/aws-powertools/powertools-lambda-java/pull/395)).
### Maintenance
- **deps**: Bump third party dependencies to the latest versions.
## [1.5.0] - 2021-03-30
- **Metrics**: Ability to set multiple dimensions as default dimensions via `MetricsUtils.defaultDimensions()`. Introduced in [v1.4.0](https://github.com/aws-powertools/powertools-lambda-java/releases/tag/v1.4.0) `MetricsUtils.defaultDimensionSet()` is deprecated now for better user experience.
## [1.4.0] - 2021-03-11
- **Metrics**: Ability to set default dimension for metrics via `MetricsUtils.defaultDimensionSet()`.
**Note**: If your monitoring depends on [default dimensions](https://github.com/awslabs/aws-embedded-metrics-java/blob/main/src/main/java/software/amazon/cloudwatchlogs/emf/logger/MetricsLogger.java#L173) captured before via [aws-embedded-metrics-java](https://github.com/awslabs/aws-embedded-metrics-java), those either need to be updated or has to be explicitly captured via `MetricsUtils.defaultDimensionSet()`.
- **Metrics**: Remove validation of having minimum one dimension. EMF now support [Dimension set being empty](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Embedded_Metric_Format_Specification.html) as well.
## [1.3.0] - 2021-03-05
- **Powertools**: It now works out of the box with [code guru profile handler implementation](https://docs.aws.amazon.com/codeguru/latest/profiler-ug/lambda-custom.html).
- **Logging**: Ability to override object mapper used for logging event. This provides customers ability to customize how and what they want to log from event.
- **Metrics**: Module now by default captures AWS Request id as property if used together with Metrics annotation. It will also capture Xray Trace ID as property if tracing is enabled. This ensures good observability and tracing.
- **Metrics**:`withSingleMetric` from \`MetricsUtils can now pick the default namespace specified either on Metrics annotation or via POWERTOOLS_METRICS_NAMESPACE env var, without need to specify explicitly for each call.
- **Metrics**:`Metrics` annotation captures metrics even in case of unhandled exception from Lambda function.
- **Docs**: Migrated from Gatsby to MKdocs documentation system
## Overview
Our public roadmap outlines the high level direction we are working towards. We update this document when our priorities change: security and stability are our top priority.
### Key areas
Security and operational excellence take precedence above all else. This means bug fixing, stability, customer's support, and internal compliance may delay one or more key areas below.
We may choose to re-prioritize or defer items based on customer feedback, security, and operational impacts, and business value.
#### Release Security (p0)
Our top priority is to establish the processes and infrastructure needed for a fully automated and secure end-to-end release process of new versions to Maven Central.
- Implement GitHub workflows and create infrastructure to release to Maven Central
- [Implement end-to-end tests](https://github.com/aws-powertools/powertools-lambda-java/issues/1815)
- Implement [OpenSSF Scorecard](https://openssf.org/projects/scorecard/)
#### `v2` Release: Consistency and Ecosystem (p1)
As part of a new major version `v2` release, we prioritize the Java project's consistency of core utilities (Logging, Metrics, Tracing) with the other runtimes (Python, TypeScript, .NET). Additionally, we will focus on integrating the library with popular technologies and frameworks from the Java and AWS ecosystem. Particularly, we aim at leveraging new techniques to allow customers to reduce Lambda cold-start time. The `v2` release will also drop support for Java 8 moving to Java 11 as the baseline.
##### Core Utilities
- [Review public interfaces and reduce public API surface area](https://github.com/aws-powertools/powertools-lambda-java/issues/1283)
- [Release Logging `v2` module](https://github.com/aws-powertools/powertools-lambda-java/issues/965) allowing customers to choose the logging framework and adding support for logging deeply nested objects as JSON
- [Support high resolution metrics](https://github.com/aws-powertools/powertools-lambda-java/issues/1041)
##### Ecosystem
- [Add GraalVM support for core utilities](https://github.com/aws-powertools/powertools-lambda-java/issues/764)
- [Implement priming using CRaC to improve AWS Snapstart support](https://github.com/aws-powertools/powertools-lambda-java/issues/1588)
- [Evaluate integration with popular Java frameworks such as Micronaut, Spring Cloud Function, or Quarkus](https://github.com/aws-powertools/powertools-lambda-java/issues/1701)
##### Other
- [Validation module integration with HTTP requests](https://github.com/aws-powertools/powertools-lambda-java/issues/1298)
- [Support validation module from within the batch module](https://github.com/aws-powertools/powertools-lambda-java/issues/1496)
- [Add support for parallel processing in Batch Processing utility](https://github.com/aws-powertools/powertools-lambda-java/issues/1540)
- [Documentation: Review and improve documentation to be consistent with other runtimes](https://github.com/aws-powertools/powertools-lambda-java/issues/1352)
#### Feature Parity (p2)
If priorities `p0` and `p1` are addressed, we will also focus on feature parity of non-core utilities. This allows customers to achieve better standardization of their development processes across different Powertools runtimes.
- [Re-evaluate if there is a need for adding a lightweight customer Powertools event handler](https://github.com/aws-powertools/powertools-lambda-java/issues/1103)
- Add comprehensive GraalVM support for all utilities
- [Add Feature Flags module](https://github.com/aws-powertools/powertools-lambda-java/issues/1086)
- [Add S3 Streaming module](https://github.com/aws-powertools/powertools-lambda-java/issues/1085)
- Add support for Data Masking during JSON serialization
### Missing something?
You can help us prioritize by [upvoting existing feature requests](https://github.com/aws-powertools/powertools-lambda-java/issues?q=is%3Aissue%20state%3Aopen%20label%3Aenhancement), leaving a comment on what use cases it could unblock for you, and by joining our discussions on Discord.
### Roadmap status definition
```
graph LR
Ideas --> Backlog --> Work["Working on it"] --> Merged["Coming soon"] --> Shipped
```
*Visual representation*
Within our [public board](https://github.com/orgs/aws-powertools/projects/4/), you'll see the following values in the `Status` column:
- **Ideas**. Incoming and existing feature requests that are not being actively considered yet. These will be reviewed when bandwidth permits.
- **Backlog**. Accepted feature requests or enhancements that we want to work on.
- **Working on it**. Features or enhancements we're currently either researching or implementing it.
- **Coming soon**. Any feature, enhancement, or bug fixes that have been merged and are coming in the next release.
- **Shipped**. Features or enhancements that are now available in the most recent release.
> Tasks or issues with empty `Status` will be categorized in upcoming review cycles.
### Process
```
graph LR
PFR[Feature request] --> Triage{Need RFC?}
Triage --> |Complex/major change or new utility?| RFC[Ask or write RFC] --> Approval{Approved?}
Triage --> |Minor feature or enhancement?| NoRFC[No RFC required] --> Approval
Approval --> |Yes| Backlog
Approval --> |No | Reject["Inform next steps"]
Backlog --> |Prioritized| Implementation
Backlog --> |Defer| WelcomeContributions["help-wanted label"]
```
*Visual representation*
Our end-to-end mechanism follows four major steps:
- **Feature Request**. Ideas start with a [feature request](https://github.com/aws-powertools/powertools-lambda-java/issues/new?template=feature_request.md) to outline their use case at a high level. For complex use cases, maintainers might ask for/write a RFC.
- Maintainers review requests based on [project tenets](../#tenets), customers reaction (👍), and use cases.
- **Request-for-comments (RFC)**. Design proposals use our [RFC template](https://github.com/aws-powertools/powertools-lambda-java/issues/new?q=is%3Aissue+state%3Aopen+label%3Aenhancement&template=rfc.md) to describe its implementation, challenges, developer experience, dependencies, and alternative solutions.
- This helps refine the initial idea with community feedback before a decision is made.
- **Decision**. After carefully reviewing and discussing them, maintainers make a final decision on whether to start implementation, defer or reject it, and update everyone with the next steps.
- **Implementation**. For approved features, maintainers give priority to the original authors for implementation unless it is a sensitive task that is best handled by maintainers.
See [Maintainers](../processes/maintainers/) document to understand how we triage issues and pull requests, labels and governance.
### Disclaimer
The Powertools for AWS Lambda (Java) team values feedback and guidance from its community of users, although final decisions on inclusion into the project will be made by AWS.
We determine the high-level direction for our open roadmap based on customer feedback and popularity (👍🏽 and comments), security and operational impacts, and business value. Where features don’t meet our goals and longer-term strategy, we will communicate that clearly and openly as quickly as possible with an explanation of why the decision was made.
### FAQs
**Q: Why did you build this?**
A: We know that our customers are making decisions and plans based on what we are developing, and we want to provide our customers the insights they need to plan.
**Q: Why are there no dates on your roadmap?**
A: Because job zero is security and operational stability, we can't provide specific target dates for features. The roadmap is subject to change at any time, and roadmap issues in this repository do not guarantee a feature will be launched as proposed.
**Q: How can I provide feedback or ask for more information?**
A: For existing features, you can directly comment on issues. For anything else, please open an issue.
# Core Utilities
Logging provides an opinionated logger with output structured as JSON.
## Key features
- Leverages standard logging libraries: [*SLF4J*](https://www.slf4j.org/) as the API, and [*log4j2*](https://logging.apache.org/log4j/2.x/) or [*logback*](https://logback.qos.ch/) for the implementation
- Captures key fields from Lambda context, cold start and structures logging output as JSON
- Optionally logs Lambda request
- 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
## Getting started
Tip
You can find complete examples in the [project repository](https://github.com/aws-powertools/powertools-lambda-java/tree/v2/examples/powertools-examples-core-utilities).
### Installation
Depending on preference, you must choose to use either *log4j2* or *logback* as your log provider. In both cases you need to configure *aspectj* to weave the code and make sure the annotation is processed.
#### Maven
```
...
software.amazon.lambdapowertools-logging-log4j2.0.0-SNAPSHOT
...
...
...
dev.aspectjaspectj-maven-plugin1.14111111software.amazon.lambdapowertools-loggingorg.aspectjaspectjtools1.9.22compile
...
```
```
...
software.amazon.lambdapowertools-logging-logback2.0.0-SNAPSHOT
...
...
...
dev.aspectjaspectj-maven-plugin1.14111111software.amazon.lambdapowertools-loggingorg.aspectjaspectjtools1.9.22compile
...
```
#### Gradle
```
plugins {
id 'java'
id 'io.freefair.aspectj.post-compile-weaving' version '8.1.0'
}
repositories {
mavenCentral()
}
dependencies {
aspect 'software.amazon.lambda:powertools-logging-log4j:2.0.0-SNAPSHOT'
}
sourceCompatibility = 11
targetCompatibility = 11
```
```
plugins {
id 'java'
id 'io.freefair.aspectj.post-compile-weaving' version '8.1.0'
}
repositories {
mavenCentral()
}
dependencies {
aspect 'software.amazon.lambda:powertools-logging-logback:2.0.0-SNAPSHOT'
}
sourceCompatibility = 11
targetCompatibility = 11
```
### Configuration
#### Main environment variables
The logging module requires two settings:
| Environment variable | Setting | Description | | --- | --- | --- | | `POWERTOOLS_LOG_LEVEL` | **Logging level** | Sets how verbose Logger should be. If not set, will use the [Logging configuration](#logging-configuration) | | `POWERTOOLS_SERVICE_NAME` | **Service** | Sets service key that will be included in all log statements (Default is `service_undefined`) |
Here is an example using AWS Serverless Application Model (SAM):
```
Resources:
PaymentFunction:
Type: AWS::Serverless::Function
Properties:
MemorySize: 512
Timeout: 20
Runtime: java17
Environment:
Variables:
POWERTOOLS_LOG_LEVEL: WARN
POWERTOOLS_SERVICE_NAME: payment
```
There are some other environment variables which can be set to modify Logging's settings at a global scope:
| Environment variable | Type | Description | | --- | --- | --- | | `POWERTOOLS_LOGGER_SAMPLE_RATE` | float | Configure the sampling rate at which `DEBUG` logs should be included. See [sampling rate](#sampling-debug-logs) | | `POWERTOOLS_LOG_EVENT` | boolean | Specify if the incoming Lambda event should be logged. See [Logging event](#logging-incoming-event) | | `POWERTOOLS_LOG_RESPONSE` | boolean | Specify if the Lambda response should be logged. See [logging response](#logging-handler-response) | | `POWERTOOLS_LOG_ERROR` | boolean | Specify if a Lambda uncaught exception should be logged. See [logging exception](#logging-handler-uncaught-exception) |
#### Logging configuration
Powertools for AWS Lambda (Java) simply extends the functionality of the underlying library you choose (*log4j2* or *logback*). You can leverage the standard configuration files (*log4j2.xml* or *logback.xml*):
With log4j2, we leverage the [`JsonTemplateLayout`](https://logging.apache.org/log4j/2.x/manual/json-template-layout.html) 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)):
```
```
With logback, we leverage a custom [Encoder](https://logback.qos.ch/manual/encoders.html) to provide structured logging:
```
```
## Log level
Log level is generally configured in the `log4j2.xml` or `logback.xml`. But this level is static and needs a redeployment of the function to be changed. Powertools for AWS Lambda permits to change this level dynamically thanks to an environment variable `POWERTOOLS_LOG_LEVEL`.
We support the following log levels (SLF4J levels): `TRACE`, `DEBUG`, `INFO`, `WARN`, `ERROR`. If the level is set to `CRITICAL` (supported in log4j but not logback), we revert it back to `ERROR`. If the level is set to any other value, we set it to the default value (`INFO`).
### AWS Lambda Advanced Logging Controls (ALC)
When is it useful?
When you want to set a logging policy to drop informational or verbose logs for one or all AWS Lambda functions, regardless of runtime and logger used.
With [AWS Lambda Advanced Logging Controls (ALC)](https://docs.aws.amazon.com/lambda/latest/dg/monitoring-cloudwatchlogs.html#monitoring-cloudwatchlogs-advanced), 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.
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`.
```
sequenceDiagram
participant Lambda service
participant Lambda function
participant Application Logger
Note over Lambda service: AWS_LAMBDA_LOG_LEVEL="WARN"
Note over Application Logger: POWERTOOLS_LOG_LEVEL="DEBUG"
Lambda service->>Lambda function: Invoke (event)
Lambda function->>Lambda function: Calls handler
Lambda function->>Application Logger: logger.error("Something happened")
Lambda function-->>Application Logger: logger.debug("Something happened")
Lambda function-->>Application Logger: logger.info("Something happened")
Lambda service--xLambda service: DROP INFO and DEBUG logs
Lambda service->>CloudWatch Logs: Ingest error logs
```
### Priority of log level settings in Powertools for AWS Lambda
We prioritise log level settings in this order:
1. `AWS_LAMBDA_LOG_LEVEL` environment variable
1. `POWERTOOLS_LOG_LEVEL` environment variable
1. 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.
> **NOTE**
>
> With ALC enabled, we are unable to increase the minimum log level below the `AWS_LAMBDA_LOG_LEVEL` environment variable value, see [AWS Lambda service documentation](https://docs.aws.amazon.com/lambda/latest/dg/monitoring-cloudwatchlogs.html#monitoring-cloudwatchlogs-log-level) for more details.
## Basic Usage
To use Lambda Powertools for AWS Lambda Logging, use the `@Logging` annotation in your code and the standard *SLF4J* logger:
```
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import software.amazon.lambda.powertools.logging.Logging;
// ... other imports
public class PaymentFunction implements RequestHandler {
private static final Logger LOGGER = LoggerFactory.getLogger(PaymentFunction.class);
@Logging
public APIGatewayProxyResponseEvent handleRequest(final APIGatewayProxyRequestEvent input, final Context context) {
LOGGER.info("Collecting payment");
// ...
LOGGER.debug("order={}, amount={}", order.getId(), order.getAmount());
// ...
}
}
```
## Standard structured keys
Your logs will always include the following keys in your structured logging:
| Key | Type | Example | Description | | --- | --- | --- | --- | | **timestamp** | String | "2023-12-01T14:49:19.293Z" | Timestamp of actual log statement, by default uses default AWS Lambda timezone (UTC) | | **level** | String | "INFO" | Logging level (any level supported by *SLF4J* (i.e. `TRACE`, `DEBUG`, `INFO`, `WARN`, `ERROR`) | | **service** | String | "payment" | Service name defined, by default `service_undefined` | | **sampling_rate** | float | 0.1 | Debug logging sampling rate in percentage e.g. 10% in this case (logged if not 0) | | **message** | String | "Collecting payment" | Log statement value. Unserializable JSON values will be casted to string | | **xray_trace_id** | String | "1-5759e988-bd862e3fe1be46a994272793" | X-Ray Trace ID when [Tracing is enabled](https://docs.aws.amazon.com/lambda/latest/dg/services-xray.html) | | **error** | Map | `{ "name": "InvalidAmountException", "message": "Amount must be superior to 0", "stack": "at..." }` | Eventual exception (e.g. when doing `logger.error("Error", new InvalidAmountException("Amount must be superior to 0"));`) |
## Additional structured keys
### Logging Lambda context information
The following keys will also be added to all your structured logs (unless [configured otherwise](#more-customization_1)):
| Key | Type | Example | Description | | --- | --- | --- | --- | | **cold_start** | Boolean | false | ColdStart value | | **function_name** | String | "example-PaymentFunction-1P1Z6B39FLU73" | Name of the function | | **function_version** | String | "12" | Version of the function | | **function_memory_size** | String | "512" | Memory configure for the function | | **function_arn** | String | "arn:aws:lambda:eu-west-1:012345678910:function:example-PaymentFunction-1P1Z6B39FLU73" | ARN of the function | | **function_request_id** | String | "899856cb-83d1-40d7-8611-9e78f15f32f4"" | AWS Request ID from lambda context |
### Logging additional keys
#### Logging a correlation ID
You can set a correlation ID using the `correlationIdPath` attribute of the `@Logging`annotation, by passing a [JMESPath expression](https://jmespath.org/tutorial.html), including our custom [JMESPath Functions](../../utilities/serialization/#built-in-functions).
```
public class AppCorrelationIdPath implements RequestHandler {
private static final Logger LOGGER = LoggerFactory.getLogger(AppCorrelationIdPath.class);
@Logging(correlationIdPath = "headers.my_request_id_header")
public APIGatewayProxyResponseEvent handleRequest(final APIGatewayProxyRequestEvent input, final Context context) {
// ...
LOGGER.info("Collecting payment")
// ...
}
}
```
```
{
"headers": {
"my_request_id_header": "correlation_id_value"
}
}
```
```
{
"level": "INFO",
"message": "Collecting payment",
"timestamp": "2023-12-01T14:49:19.293Z",
"service": "payment",
"correlation_id": "correlation_id_value"
}
```
**Known correlation IDs**
To ease routine tasks like extracting correlation ID from popular event sources, we provide [built-in JMESPath expressions](#built-in-correlation-id-expressions).
```
import software.amazon.lambda.powertools.logging.CorrelationIdPaths;
public class AppCorrelationId implements RequestHandler {
private static final Logger LOGGER = LoggerFactory.getLogger(AppCorrelationId.class);
@Logging(correlationIdPath = CorrelationIdPaths.API_GATEWAY_REST)
public APIGatewayProxyResponseEvent handleRequest(final APIGatewayProxyRequestEvent input, final Context context) {
// ...
LOGGER.info("Collecting payment")
// ...
}
}
```
```
{
"requestContext": {
"requestId": "correlation_id_value"
}
}
```
```
{
"level": "INFO",
"message": "Collecting payment",
"timestamp": "2023-12-01T14:49:19.293Z",
"service": "payment",
"correlation_id": "correlation_id_value"
}
```
#### Custom keys
**Using StructuredArguments**
To append additional keys in your logs, you can use the `StructuredArguments` class:
```
import static software.amazon.lambda.powertools.logging.argument.StructuredArguments.entry;
import static software.amazon.lambda.powertools.logging.argument.StructuredArguments.entries;
public class PaymentFunction implements RequestHandler {
private static final Logger LOGGER = LoggerFactory.getLogger(AppLogResponse.class);
@Logging
public APIGatewayProxyResponseEvent handleRequest(final APIGatewayProxyRequestEvent input, final Context context) {
// ...
LOGGER.info("Collecting payment", entry("orderId", order.getId()));
// ...
Map customKeys = new HashMap<>();
customKeys.put("paymentId", payment.getId());
customKeys.put("amount", payment.getAmount);
LOGGER.info("Payment successful", entries(customKeys));
}
}
```
```
{
"level": "INFO",
"message": "Collecting payment",
"service": "payment",
"timestamp": "2023-12-01T14:49:19.293Z",
"xray_trace_id": "1-6569f266-4b0c7f97280dcd8428d3c9b5",
"orderId": "41376"
}
...
{
"level": "INFO",
"message": "Payment successful",
"service": "payment",
"timestamp": "2023-12-01T14:49:20.118Z",
"xray_trace_id": "1-6569f266-4b0c7f97280dcd8428d3c9b5",
"orderId": "41376",
"paymentId": "3245",
"amount": 345.99
}
```
`StructuredArguments` provides several options:
- `entry` to add one key and value into the log structure. Note that value can be any object type.
- `entries` to add multiple keys and values (from a Map) into the log structure. Note that values can be any object type.
- `json` to add a key and raw json (string) as value into the log structure.
- `array` to add one key and multiple values into the log structure. Note that values can be any object type.
```
import static software.amazon.lambda.powertools.logging.argument.StructuredArguments.entry;
import static software.amazon.lambda.powertools.logging.argument.StructuredArguments.array;
public class OrderFunction implements RequestHandler {
private static final Logger LOGGER = LoggerFactory.getLogger(AppLogResponse.class);
@Logging
public APIGatewayProxyResponseEvent handleRequest(final APIGatewayProxyRequestEvent input, final Context context) {
// ...
LOGGER.info("Processing order", entry("order", order), array("products", productList));
// ...
}
}
```
```
{
"level": "INFO",
"message": "Processing order",
"service": "payment",
"timestamp": "2023-12-01T14:49:19.293Z",
"xray_trace_id": "1-6569f266-4b0c7f97280dcd8428d3c9b5",
"order": {
"orderId": 23542,
"amount": 459.99,
"date": "2023-12-01T14:49:19.018Z",
"customerId": 328496
},
"products": [
{
"productId": 764330,
"name": "product1",
"quantity": 1,
"price": 300
},
{
"productId": 798034,
"name": "product42",
"quantity": 1,
"price": 159.99
}
]
}
```
Use arguments without log placeholders
As shown in the example above, you can use arguments (with `StructuredArguments`) without placeholders (`{}`) in the message. If you add the placeholders, the arguments will be logged both as an additional field and also as a string in the log message, using the `toString()` method.
```
LOGGER.info("Processing {}", entry("order", order));
```
```
public class Order {
// ...
@Override
public String toString() {
return "Order{" +
"orderId=" + id +
", amount=" + amount +
", date='" + date + '\'' +
", customerId=" + customerId +
'}';
}
}
```
```
{
"level": "INFO",
"message": "Processing order=Order{orderId=23542, amount=459.99, date='2023-12-01T14:49:19.018Z', customerId=328496}",
"service": "payment",
"timestamp": "2023-12-01T14:49:19.293Z",
"xray_trace_id": "1-6569f266-4b0c7f97280dcd8428d3c9b5",
"order": {
"orderId": 23542,
"amount": 459.99,
"date": "2023-12-01T14:49:19.018Z",
"customerId": 328496
}
}
```
You can also combine structured arguments with non structured ones. For example:
```
LOGGER.info("Processing order {}", order.getOrderId(), entry("order", order));
```
```
{
"level": "INFO",
"message": "Processing order 23542",
"service": "payment",
"timestamp": "2023-12-01T14:49:19.293Z",
"xray_trace_id": "1-6569f266-4b0c7f97280dcd8428d3c9b5",
"order": {
"orderId": 23542,
"amount": 459.99,
"date": "2023-12-01T14:49:19.018Z",
"customerId": 328496
}
}
```
**Using MDC**
Mapped Diagnostic Context (MDC) is essentially a Key-Value store. It is supported by the [SLF4J API](https://www.slf4j.org/manual.html#mdc), [logback](https://logback.qos.ch/manual/mdc.html) and log4j (known as [ThreadContext](https://logging.apache.org/log4j/2.x/manual/thread-context.html)). You can use the following standard:
`MDC.put("key", "value");`
Custom keys stored in the MDC are persisted across warm invocations
Always set additional keys as part of your handler method to ensure they have the latest value, or explicitly clear them with [`clearState=true`](#clearing-state).
### Removing additional keys
You can remove additional keys added with the MDC using `MDC.remove("key")`.
#### Clearing state
Logger is commonly initialized in the global scope. Due to [Lambda Execution Context reuse](https://docs.aws.amazon.com/lambda/latest/dg/runtimes-context.html), this means that custom keys, added with the MDC can be persisted across invocations. If you want all custom keys to be deleted, you can use `clearState=true` attribute on the `@Logging` annotation.
```
public class CreditCardFunction implements RequestHandler {
private static final Logger LOGGER = LoggerFactory.getLogger(CreditCardFunction.class);
@Logging(clearState = true)
public APIGatewayProxyResponseEvent handleRequest(final APIGatewayProxyRequestEvent input, final Context context) {
// ...
MDC.put("cardNumber", card.getId());
LOGGER.info("Updating card information");
// ...
}
}
```
```
{
"level": "INFO",
"message": "Updating card information",
"service": "card",
"timestamp": "2023-12-01T14:49:19.293Z",
"xray_trace_id": "1-6569f266-4b0c7f97280dcd8428d3c9b5",
"cardNumber": "6818 8419 9395 5322"
}
```
```
{
"level": "INFO",
"message": "Updating card information",
"service": "card",
"timestamp": "2023-12-01T14:49:20.213Z",
"xray_trace_id": "2-7a518f43-5e9d2b1f6cfd5e8b3a4e1f9c",
"cardNumber": "7201 6897 6685 3285"
}
```
`clearState` is based on `MDC.clear()`. State clearing is automatically done at the end of the execution of the handler if set to `true`.
## Logging incoming event
When debugging in non-production environments, you can instruct the `@Logging` annotation to log the incoming event with `logEvent` param or via `POWERTOOLS_LOGGER_LOG_EVENT` env var.
Warning
This is disabled by default to prevent sensitive info being logged
```
public class AppLogEvent implements RequestHandler {
private static final Logger LOGGER = LoggerFactory.getLogger(AppLogEvent.class);
@Logging(logEvent = true)
public APIGatewayProxyResponseEvent handleRequest(final APIGatewayProxyRequestEvent input, final Context context) {
// ...
}
}
```
Note
If you use this on a RequestStreamHandler, Powertools must duplicate input streams in order to log them.
## Logging handler response
When debugging in non-production environments, you can instruct the `@Logging` annotation to log the response with `logResponse` param or via `POWERTOOLS_LOGGER_LOG_RESPONSE` env var.
Warning
This is disabled by default to prevent sensitive info being logged
```
public class AppLogResponse implements RequestHandler {
private static final Logger LOGGER = LoggerFactory.getLogger(AppLogResponse.class);
@Logging(logResponse = true)
public APIGatewayProxyResponseEvent handleRequest(final APIGatewayProxyRequestEvent input, final Context context) {
// ...
}
}
```
Note
If you use this on a RequestStreamHandler, Powertools must duplicate output streams in order to log them.
## Logging handler uncaught exception
By default, AWS Lambda logs any uncaught exception that might happen in the handler. However, this log is not structured and does not contain any additional context. You can instruct the `@Logging` annotation to log this kind of exception with `logError` param or via `POWERTOOLS_LOGGER_LOG_ERROR` env var.
Warning
This is disabled by default to prevent double logging
```
public class AppLogError implements RequestHandler {
private static final Logger LOGGER = LoggerFactory.getLogger(AppLogError.class);
@Logging(logError = true)
public APIGatewayProxyResponseEvent handleRequest(final APIGatewayProxyRequestEvent input, final Context context) {
// ...
}
}
```
# Advanced
## Sampling debug logs
You can dynamically set a percentage of your logs to`DEBUG` level to be included in the logger output, regardless of configured log leve, using the`POWERTOOLS_LOGGER_SAMPLE_RATE` environment variable or via `samplingRate` attribute on the `@Logging` annotation.
Info
Configuration on environment variable is given precedence over sampling rate configuration on annotation, provided it's in valid value range.
```
public class App implements RequestHandler {
private static final Logger LOGGER = LoggerFactory.getLogger(App.class);
@Logging(samplingRate = 0.5)
public APIGatewayProxyResponseEvent handleRequest(final APIGatewayProxyRequestEvent input, final Context context) {
// will eventually be logged based on the sampling rate
LOGGER.debug("Handle payment");
}
}
```
```
Resources:
PaymentFunction:
Type: AWS::Serverless::Function
Properties:
...
Environment:
Variables:
POWERTOOLS_LOGGER_SAMPLE_RATE: 0.5
```
## Built-in Correlation ID expressions
You can use any of the following built-in JMESPath expressions as part of `@Logging(correlationIdPath = ...)`:
Note: Any object key named with `-` must be escaped
For example, **`request.headers."x-amzn-trace-id"`**.
| Name | Expression | Description | | --- | --- | --- | | **API_GATEWAY_REST** | `"requestContext.requestId"` | API Gateway REST API request ID | | **API_GATEWAY_HTTP** | `"requestContext.requestId"` | API Gateway HTTP API request ID | | **APPSYNC_RESOLVER** | `request.headers."x-amzn-trace-id"` | AppSync X-Ray Trace ID | | **APPLICATION_LOAD_BALANCER** | `headers."x-amzn-trace-id"` | ALB X-Ray Trace ID | | **EVENT_BRIDGE** | `"id"` | EventBridge Event ID |
## Customising fields in logs
Powertools for AWS Lambda comes with default json structure ([standard fields](#standard-structured-keys) & [lambda context fields](#logging-lambda-context-information)).
You can go further and customize which fields you want to keep in your logs or not. The configuration varies according to the underlying logging library.
### Log4j2 configuration
Log4j2 configuration is done in *log4j2.xml* and leverages `JsonTemplateLayout`:
```
```
The `JsonTemplateLayout` is automatically configured with the provided template:
LambdaJsonLayout.json
```
{
"level": {
"$resolver": "level",
"field": "name"
},
"message": {
"$resolver": "powertools",
"field": "message"
},
"error": {
"message": {
"$resolver": "exception",
"field": "message"
},
"name": {
"$resolver": "exception",
"field": "className"
},
"stack": {
"$resolver": "exception",
"field": "stackTrace",
"stackTrace": {
"stringified": true
}
}
},
"cold_start": {
"$resolver": "powertools",
"field": "cold_start"
},
"function_arn": {
"$resolver": "powertools",
"field": "function_arn"
},
"function_memory_size": {
"$resolver": "powertools",
"field": "function_memory_size"
},
"function_name": {
"$resolver": "powertools",
"field": "function_name"
},
"function_request_id": {
"$resolver": "powertools",
"field": "function_request_id"
},
"function_version": {
"$resolver": "powertools",
"field": "function_version"
},
"sampling_rate": {
"$resolver": "powertools",
"field": "sampling_rate"
},
"service": {
"$resolver": "powertools",
"field": "service"
},
"timestamp": {
"$resolver": "timestamp",
"pattern": {
"format": "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"
}
},
"xray_trace_id": {
"$resolver": "powertools",
"field": "xray_trace_id"
},
"": {
"$resolver": "powertools"
}
}
```
You can create your own template and leverage the [PowertoolsResolver](https://github.com/aws-powertools/powertools-lambda-java/tree/v2/powertools-logging/powertools-logging-log4j/src/main/java/org/apache/logging/log4j/layout/template/json/resolver/PowertoolsResolver.java) and any other resolver to log the desired fields with the desired format. Some examples of customization are given below:
#### Customising date format
Utility by default emits `timestamp` field in the logs in format `yyyy-MM-dd'T'HH:mm:ss.SSS'Z'` and in system default timezone. If you need to customize format and timezone, you can update your template.json or by configuring `log4j2.component.properties` as shown in examples below:
```
{
"timestamp": {
"$resolver": "timestamp",
"pattern": {
"format": "yyyy-MM-dd HH:mm:ss",
"timeZone": "Europe/Paris",
}
},
}
```
```
log4j.layout.jsonTemplate.timestampFormatPattern=yyyy-MM-dd'T'HH:mm:ss.SSSZz
log4j.layout.jsonTemplate.timeZone=Europe/Oslo
```
See [`TimestampResolver` documentation](https://logging.apache.org/log4j/2.x/manual/json-template-layout.html#event-template-resolver-timestamp) for more details.
Lambda Advanced Logging Controls date format
When using the Lambda ALC, you must have a date format compatible with the [RFC3339](https://www.rfc-editor.org/rfc/rfc3339)
#### More customization
You can also customize how [exceptions are logged](https://logging.apache.org/log4j/2.x/manual/json-template-layout.html#event-template-resolver-exception), and much more. See the [JSON Layout template documentation](https://logging.apache.org/log4j/2.x/manual/json-template-layout.html) for more details.
### Logback configuration
Logback configuration is done in *logback.xml* and the Powertools `LambdaJsonEncoder`:
```
```
The `LambdaJsonEncoder` can be customized in different ways:
#### Customising date format
Utility by default emits `timestamp` field in the logs in format `yyyy-MM-dd'T'HH:mm:ss.SSS'Z'` and in system default timezone. If you need to customize format and timezone, you can change use the following:
```
yyyy-MM-dd HH:mm:ssEurope/Paris
```
#### More customization
- You can use a standard `ThrowableHandlingConverter` to customize the exception format (default is no converter). Example:
```
30204820sun\.reflect\..*\.invoke.*net\.sf\.cglib\.proxy\.MethodProxy\.invoketruetrue
```
- You can choose to add information about threads (default is `false`):
```
true
```
- You can even choose to remove Powertools information from the logs like function name, arn:
```
false
```
## Elastic Common Schema (ECS) Support
Utility also supports [Elastic Common Schema(ECS)](https://www.elastic.co/guide/en/ecs/current/ecs-reference.html) format. The field emitted in logs will follow specs from [ECS](https://www.elastic.co/guide/en/ecs/current/ecs-reference.html) together with field captured by utility as mentioned [above](#standard-structured-keys).
### Log4j2 configuration
Use `LambdaEcsLayout.json` as `eventTemplateUri` when configuring `JsonTemplateLayout`.
```
```
### Logback configuration
Use the `LambdaEcsEncoder` rather than the `LambdaJsonEncoder` when configuring the appender:
```
```
Metrics creates custom metrics asynchronously by logging metrics to standard output following Amazon CloudWatch Embedded Metric Format (EMF).
These metrics can be visualized through [Amazon CloudWatch Console](https://console.aws.amazon.com/cloudwatch/).
**Key features**
- Aggregate up to 100 metrics using a single CloudWatch EMF object (large JSON blob).
- Validate against common metric definitions mistakes (metric unit, values, max dimensions, max metrics, etc).
- Metrics are created asynchronously by the CloudWatch service, no custom stacks needed.
- Context manager to create a one off metric with a different dimension.
## Terminologies
If you're new to Amazon CloudWatch, there are two terminologies you must be aware of before using this utility:
- **Namespace**. It's the highest level container that will group multiple metrics from multiple services for a given application, for example `ServerlessEcommerce`.
- **Dimensions**. Metrics metadata in key-value format. They help you slice and dice metrics visualization, for example `ColdStart` metric by Payment `service`.
Metric terminology, visually explained
## Install
```
...
software.amazon.lambdapowertools-metrics2.0.0-SNAPSHOT
...
...
...
dev.aspectjaspectj-maven-plugin1.14111111software.amazon.lambdapowertools-metricsorg.aspectjaspectjtools1.9.22compile
...
```
```
plugins {
id 'java'
id 'io.freefair.aspectj.post-compile-weaving' version '8.1.0'
}
repositories {
mavenCentral()
}
dependencies {
aspect 'software.amazon.lambda:powertools-metrics:2.0.0-SNAPSHOT'
}
sourceCompatibility = 11
targetCompatibility = 11
```
## Getting started
Metric has two global settings that will be used across all metrics emitted:
| Setting | Description | Environment variable | Constructor parameter | | --- | --- | --- | --- | | **Metric namespace** | Logical container where all metrics will be placed e.g. `ServerlessAirline` | `POWERTOOLS_METRICS_NAMESPACE` | `namespace` | | **Service** | Optionally, sets **service** metric dimension across all metrics e.g. `payment` | `POWERTOOLS_SERVICE_NAME` | `service` |
Use your application or main service as the metric namespace to easily group all metrics
```
Resources:
HelloWorldFunction:
Type: AWS::Serverless::Function
Properties:
...
Runtime: java8
Environment:
Variables:
POWERTOOLS_SERVICE_NAME: payment
POWERTOOLS_METRICS_NAMESPACE: ServerlessAirline
```
```
import software.amazon.lambda.powertools.metrics.Metrics;
public class MetricsEnabledHandler implements RequestHandler