Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
59011e5
Log buffer PoC with log4j2 appender implementation.
phipag Aug 29, 2025
6dde0a5
Add buffer cleaning to avoid memory leak and flushBufferOnUncaughtErr…
phipag Aug 29, 2025
4ff36d9
Call appenders with logevent directly from BufferingAppender.
phipag Aug 29, 2025
966e576
Extract buffer management logic into KeyBuffer class and keep log4j a…
phipag Aug 29, 2025
dd8473d
Unit tests for BufferingAppender
phipag Aug 29, 2025
fb3dcc0
Rename to Log4jConstants.
phipag Sep 1, 2025
ee08593
Make Appender detection independent of plugin name.
phipag Sep 1, 2025
447633f
Add assertions in unit test to test multiple appenders.
phipag Sep 1, 2025
e158b76
Make assertion stronger to assert that each message appears twice bec…
phipag Sep 1, 2025
0ff03b2
Add logback implementation. Decouple KeyBuffer and BufferingAppender …
phipag Sep 1, 2025
eb2502e
Log error in AppStream example.
phipag Sep 1, 2025
d9fe1e1
Update Logging E2E test to use log buffering.
phipag Sep 1, 2025
2dbae69
Prepare Logging E2E test to support paramaterized versions by logging…
phipag Sep 1, 2025
f3cfd5d
Add Logging E2E tests for both logback and log4j2.
phipag Sep 1, 2025
cc863c4
Debug not found appender on Linux.
phipag Sep 1, 2025
c6478be
Isolate log4j context loading in unit tests.
phipag Sep 1, 2025
5ed645d
Avoid logging config leakage in log4j unit test.
phipag Sep 1, 2025
44ebc64
Avoid config leaking in logback unit tests.
phipag Sep 1, 2025
47f403b
Update Graal metadata for powertools-logging.
phipag Sep 1, 2025
6f4e4c3
Update Graal metadata for powertools-logging-log4j.
phipag Sep 1, 2025
6933e1d
Update Graal metadata for powertools-logging-logback.
phipag Sep 1, 2025
30c1644
Merge branch 'main' into phipag/issue2095
phipag Sep 1, 2025
15efff4
Address Sonar findings.
phipag Sep 1, 2025
95a11b1
Address pmd findings.
phipag Sep 2, 2025
82e0d17
Set allowCommentedBlocks=true in pmd rules.
phipag Sep 2, 2025
3bfbbe8
Fix thread-safety issue in double-checked singleton instance creation.
phipag Sep 2, 2025
7652b93
Increase scope of thread-safety tests in KeyBuffer.
phipag Sep 2, 2025
d6d514d
Try to satisfy pmd executor service closing.
phipag Sep 2, 2025
496a2b1
Try to satisfy pmd executor service closing.
phipag Sep 2, 2025
54acdc2
Add PMD suppressions with reason where appropriate.
phipag Sep 2, 2025
3a3ccff
Add PMD suppressions with reason where appropriate.
phipag Sep 2, 2025
4d6d22e
Restore original example.
phipag Sep 2, 2025
01c6bce
Enable log sampling again.
phipag Sep 2, 2025
10c51c7
Restore formatting in pmd ruleset.
phipag Sep 2, 2025
8a87ea5
Update Javadoc of BufferingAppenders.
phipag Sep 2, 2025
88a26a0
Remove unncessary cleanup.
phipag Sep 2, 2025
76b1ab5
Remove duplicated infrastructure clearnup in LoggingE2E.
phipag Sep 2, 2025
a44c0ac
Make javadoc for Keybuffer more concise.
phipag Sep 2, 2025
7b9d8d2
Add comment for large event rejection.
phipag Sep 2, 2025
61231f4
Fix grammer in error message.
phipag Sep 2, 2025
c6d55d6
Remove redundant tests in PowertoolsLoggingTest.
phipag Sep 2, 2025
d439ba4
Add developer documentation.
phipag Sep 2, 2025
2d20f75
Fix sonar finding.
phipag Sep 2, 2025
c147b01
Clarify log buffering log level configuration with upper and lower bo…
phipag Sep 3, 2025
1640f6f
Update docs/core/logging.md
phipag Sep 3, 2025
e60edcb
Update docs/core/logging.md
phipag Sep 3, 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
5 changes: 4 additions & 1 deletion .github/pmd-ruleset.xml
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,9 @@
</rule>
<rule ref="category/java/errorprone.xml/EmptyCatchBlock">
<priority>1</priority>
<properties>
<property name="allowCommentedBlocks" value="true" />
</properties>
</rule>
<!-- <rule ref="category/java/errorprone.xml/EmptyFinalizer" /> -->
<!-- <rule ref="category/java/errorprone.xml/EmptyFinallyBlock" /> -->
Expand Down Expand Up @@ -641,4 +644,4 @@
</property>
</properties>
</rule>
</ruleset>
</ruleset>
378 changes: 374 additions & 4 deletions docs/core/logging.md

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -97,11 +97,6 @@ public APIGatewayProxyResponseEvent handleRequest(final APIGatewayProxyRequestEv
}
}

@Tracing
private void log() {
log.info("inside threaded logging for function");
}

@Tracing(namespace = "getPageContents", captureMode = CaptureMode.DISABLED)
private String getPageContents(String address) throws IOException {
URL url = new URL(address);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,46 +14,49 @@

package helloworld;

import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestStreamHandler;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.nio.charset.StandardCharsets;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestStreamHandler;
import com.fasterxml.jackson.databind.ObjectMapper;

import software.amazon.lambda.powertools.logging.Logging;
import software.amazon.lambda.powertools.metrics.FlushMetrics;

import java.io.InputStreamReader;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;

public class AppStream implements RequestStreamHandler {
private static final ObjectMapper mapper = new ObjectMapper();
private final static Logger log = LogManager.getLogger(AppStream.class);
private static final Logger log = LoggerFactory.getLogger(AppStream.class);

@Override
@Logging(logEvent = true)
@FlushMetrics(namespace = "ServerlessAirline", service = "payment", captureColdStart = true)
// RequestStreamHandler can be used instead of RequestHandler for cases when you'd like to deserialize request body or serialize response body yourself, instead of allowing that to happen automatically
// Note that you still need to return a proper JSON for API Gateway to handle
// See Lambda Response format for examples: https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-develop-integrations-lambda.html
// RequestStreamHandler can be used instead of RequestHandler for cases when you'd like to deserialize request body
// or serialize response body yourself, instead of allowing that to happen automatically
// Note that you still need to return a proper JSON for API Gateway to handle
// See Lambda Response format for examples:
// https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-develop-integrations-lambda.html
public void handleRequest(InputStream input, OutputStream output, Context context) {
try (BufferedReader reader = new BufferedReader(new InputStreamReader(input, StandardCharsets.UTF_8));
PrintWriter writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(output, StandardCharsets.UTF_8)))) {
PrintWriter writer = new PrintWriter(
new BufferedWriter(new OutputStreamWriter(output, StandardCharsets.UTF_8)))) {

log.info("Received: " + mapper.writerWithDefaultPrettyPrinter().writeValueAsString(mapper.readTree(reader)));
log.info(
"Received: " + mapper.writerWithDefaultPrettyPrinter().writeValueAsString(mapper.readTree(reader)));

writer.write("{\"body\": \"" + System.currentTimeMillis() + "\"} ");
} catch (IOException e) {
log.error("Something has gone wrong: ", e);
}
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@
<Console name="JsonAppender" target="SYSTEM_OUT">
<JsonTemplateLayout eventTemplateUri="classpath:LambdaJsonLayout.json" />
</Console>
<BufferingAppender name="BufferedAppender" bufferAtVerbosity="DEBUG">
<AppenderRef ref="JsonAppender" />
</BufferingAppender>
</Appenders>
<Loggers>
<Logger name="JsonLogger" level="INFO" additivity="false">
<AppenderRef ref="JsonAppender"/>
</Logger>
<Root level="info">
<AppenderRef ref="JsonAppender"/>
<Root level="debug">
<AppenderRef ref="BufferedAppender" />
</Root>
</Loggers>
</Configuration>
</Configuration>
4 changes: 2 additions & 2 deletions examples/powertools-examples-core-utilities/sam/template.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
AWSTemplateFormatVersion: '2010-09-09'
AWSTemplateFormatVersion: "2010-09-09"
Transform: AWS::Serverless-2016-10-31
Description: >
CoreUtilities
Expand All @@ -13,7 +13,7 @@ Globals:
Environment:
Variables:
# Powertools for AWS Lambda (Java) env vars: https://docs.powertools.aws.dev/lambda/java/#environment-variables
POWERTOOLS_LOG_LEVEL: INFO
POWERTOOLS_LOG_LEVEL: DEBUG # We use log buffering to buffer DEBUG logs (see log4j2.xml)
POWERTOOLS_LOGGER_SAMPLE_RATE: 0.1
POWERTOOLS_LOGGER_LOG_EVENT: true
POWERTOOLS_METRICS_NAMESPACE: Coreutilities
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,15 @@
<version>2.3.0</version>
</parent>

<artifactId>e2e-test-handler-logging</artifactId>
<artifactId>e2e-test-handler-logging-log4j</artifactId>
<packaging>jar</packaging>
<name>E2E test handler – Logging</name>
<name>E2E test handler – Logging Log4j</name>

<dependencies>
<dependency>
<groupId>software.amazon.lambda</groupId>
<artifactId>powertools-logging-log4j</artifactId>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-layout-template-json</artifactId>
<version>2.25.1</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,15 @@

package software.amazon.lambda.powertools.e2e;

import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;

import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;

import software.amazon.lambda.powertools.logging.Logging;
import software.amazon.lambda.powertools.logging.PowertoolsLogging;

public class Function implements RequestHandler<Input, String> {
private static final Logger LOG = LoggerFactory.getLogger(Function.class);
Expand All @@ -29,6 +32,9 @@ public String handleRequest(Input input, Context context) {
input.getKeys().forEach(MDC::put);
LOG.info(input.getMessage());

// Flush buffer manually since we buffer at INFO level to test log buffering
PowertoolsLogging.flushBuffer();

return "OK";
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,6 @@ public class Input {
private String message;
private Map<String, String> keys;

public Input() {
}

public String getMessage() {
return message;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,14 @@
<Console name="JsonAppender" target="SYSTEM_OUT">
<JsonTemplateLayout eventTemplateUri="classpath:LambdaJsonLayout.json" />
</Console>
<!-- We buffer everything to implicitly test buffer flushing -->
<BufferingAppender name="BufferedAppender" bufferAtVerbosity="INFO">
<AppenderRef ref="JsonAppender" />
</BufferingAppender>
</Appenders>
<Loggers>
<Root level="INFO">
<AppenderRef ref="JsonAppender"/>
<AppenderRef ref="BufferedAppender" />
</Root>
<Logger name="JsonLogger" level="INFO" additivity="false">
<AppenderRef ref="JsonAppender"/>
</Logger>
</Loggers>
</Configuration>
</Configuration>
82 changes: 82 additions & 0 deletions powertools-e2e-tests/handlers/logging-logback/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>software.amazon.lambda</groupId>
<artifactId>e2e-test-handlers-parent</artifactId>
<version>2.3.0</version>
</parent>

<artifactId>e2e-test-handler-logging-logback</artifactId>
<packaging>jar</packaging>
<name>E2E test handler – Logging Logback</name>

<dependencies>
<dependency>
<groupId>software.amazon.lambda</groupId>
<artifactId>powertools-logging-logback</artifactId>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
</dependency>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-lambda-java-events</artifactId>
</dependency>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-lambda-java-runtime-interface-client</artifactId>
</dependency>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-lambda-java-core</artifactId>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>dev.aspectj</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<configuration>
<source>${maven.compiler.source}</source>
<target>${maven.compiler.target}</target>
<complianceLevel>${maven.compiler.target}</complianceLevel>
<aspectLibraries>
<aspectLibrary>
<groupId>software.amazon.lambda</groupId>
<artifactId>powertools-logging</artifactId>
</aspectLibrary>
</aspectLibraries>
</configuration>
<executions>
<execution>
<goals>
<goal>compile</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
</plugin>
</plugins>
</build>

<profiles>
<profile>
<id>native-image</id>
<build>
<plugins>
<plugin>
<groupId>org.graalvm.buildtools</groupId>
<artifactId>native-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* Copyright 2023 Amazon.com, Inc. or its affiliates.
* Licensed under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/

package software.amazon.lambda.powertools.e2e;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;

import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;

import software.amazon.lambda.powertools.logging.Logging;
import software.amazon.lambda.powertools.logging.PowertoolsLogging;

public class Function implements RequestHandler<Input, String> {
private static final Logger LOG = LoggerFactory.getLogger(Function.class);

@Logging
public String handleRequest(Input input, Context context) {
input.getKeys().forEach(MDC::put);
LOG.info(input.getMessage());

// Flush buffer manually since we buffer at INFO level to test log buffering
PowertoolsLogging.flushBuffer();

return "OK";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
* Copyright 2023 Amazon.com, Inc. or its affiliates.
* Licensed under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/

package software.amazon.lambda.powertools.e2e;

import java.util.Map;

public class Input {
private String message;
private Map<String, String> keys;

public String getMessage() {
return message;
}

public void setMessage(String message) {
this.message = message;
}

public Map<String, String> getKeys() {
return keys;
}

public void setKeys(Map<String, String> keys) {
this.keys = keys;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[
{
"name":"com.amazonaws.services.lambda.runtime.LambdaRuntime",
"methods":[{"name":"<init>","parameterTypes":[] }],
"fields":[{"name":"logger"}],
"allPublicMethods":true
},
{
"name":"com.amazonaws.services.lambda.runtime.LambdaRuntimeInternal",
"methods":[{"name":"<init>","parameterTypes":[] }],
"allPublicMethods":true
}
]
Loading
Loading