From a026676bdff6cfe99659781be8570b336f534add Mon Sep 17 00:00:00 2001 From: "J. Koster" Date: Thu, 10 Oct 2024 12:41:50 +0200 Subject: [PATCH] STNG-33 Move to Structured Logging in AWS Lambda (#185) --- cdk/pom.xml | 2 +- lambda/pom.xml | 82 +++++++++++++++++-- .../dcsa/conformance/lambda/ApiLambda.java | 12 +-- .../conformance/lambda/SandboxTaskLambda.java | 20 ++--- .../dcsa/conformance/lambda/WebuiLambda.java | 17 ++-- lambda/src/main/resources/log4j2.xml | 17 ++++ pom.xml | 2 +- .../sandbox/ConformanceWebuiHandler.java | 7 +- 8 files changed, 125 insertions(+), 34 deletions(-) create mode 100644 lambda/src/main/resources/log4j2.xml diff --git a/cdk/pom.xml b/cdk/pom.xml index 4ad0d041..b94a4404 100644 --- a/cdk/pom.xml +++ b/cdk/pom.xml @@ -30,7 +30,7 @@ software.amazon.awscdk aws-cdk-lib - 2.159.1 + 2.161.1 compile diff --git a/lambda/pom.xml b/lambda/pom.xml index 739c4f01..1dc0cf3f 100644 --- a/lambda/pom.xml +++ b/lambda/pom.xml @@ -13,6 +13,10 @@ dcsa-conformance-lambda DCSA Conformance Lambda + + 1.9.21.2 + + @@ -39,18 +43,31 @@ com.amazonaws aws-lambda-java-events - 3.13.0 + 3.14.0 com.amazonaws aws-java-sdk-lambda - 1.12.771 + 1.12.773 + + + software.amazon.lambda + powertools-logging + 1.18.0 + + + software.amazon.lambda + powertools-metrics + 1.18.0 + + - org.slf4j - slf4j-simple - 2.0.16 + org.aspectj + aspectjrt + ${aspectj.version} + runtime @@ -61,6 +78,45 @@ + + dev.aspectj + aspectj-maven-plugin + 1.14 + + ${java.version} + ${java.version} + ${java.version} + true + + + ${project.build.directory}/classes + + + + software.amazon.lambda + powertools-logging + + + software.amazon.lambda + powertools-metrics + + + + + + org.aspectj + aspectjtools + ${aspectj.version} + + + + + + compile + + + + org.apache.maven.plugins maven-shade-plugin @@ -68,6 +124,15 @@ false conformance-lambda + + + + + + META-INF/versions/9/org/apache/logging/log4j/ + org/apache/logging/log4j/ + + @@ -77,6 +142,13 @@ + + + org.apache.logging.log4j + log4j-transform-maven-shade-plugin-extensions + 0.1.0 + + diff --git a/lambda/src/main/java/org/dcsa/conformance/lambda/ApiLambda.java b/lambda/src/main/java/org/dcsa/conformance/lambda/ApiLambda.java index 27315c38..9288b4e3 100644 --- a/lambda/src/main/java/org/dcsa/conformance/lambda/ApiLambda.java +++ b/lambda/src/main/java/org/dcsa/conformance/lambda/ApiLambda.java @@ -11,22 +11,24 @@ import java.util.List; import java.util.Map; import java.util.Objects; -import lombok.extern.slf4j.Slf4j; +import lombok.extern.log4j.Log4j2; import org.dcsa.conformance.sandbox.ConformanceSandbox; import org.dcsa.conformance.sandbox.ConformanceWebRequest; import org.dcsa.conformance.sandbox.ConformanceWebResponse; import org.dcsa.conformance.sandbox.state.ConformancePersistenceProvider; +import software.amazon.lambda.powertools.logging.Logging; -@Slf4j +@Log4j2 public class ApiLambda implements RequestHandler { + @Logging public APIGatewayProxyResponseEvent handleRequest( final APIGatewayProxyRequestEvent event, final Context context) { try { - System.out.println("event = " + event + ", context = " + context); + log.info("event = {}", event); JsonNode jsonEvent = OBJECT_MAPPER.valueToTree(event); - log.info("jsonEvent = " + jsonEvent.toPrettyString()); + log.debug("jsonEvent = {}", jsonEvent); ConformancePersistenceProvider persistenceProvider = LambdaToolkit.createPersistenceProvider(); @@ -51,7 +53,7 @@ public APIGatewayProxyResponseEvent handleRequest( .withStatusCode(conformanceWebResponse.statusCode()) .withBody(conformanceWebResponse.body()); } catch (RuntimeException | Error e) { - log.error("Unhandled exception: " + e, e); + log.error("Unhandled exception: ", e); throw e; } } diff --git a/lambda/src/main/java/org/dcsa/conformance/lambda/SandboxTaskLambda.java b/lambda/src/main/java/org/dcsa/conformance/lambda/SandboxTaskLambda.java index 69068a3f..81d5add1 100644 --- a/lambda/src/main/java/org/dcsa/conformance/lambda/SandboxTaskLambda.java +++ b/lambda/src/main/java/org/dcsa/conformance/lambda/SandboxTaskLambda.java @@ -8,18 +8,20 @@ import com.fasterxml.jackson.databind.node.ObjectNode; import java.io.*; import java.nio.charset.StandardCharsets; -import lombok.extern.slf4j.Slf4j; +import lombok.extern.log4j.Log4j2; import org.dcsa.conformance.core.toolkit.JsonToolkit; import org.dcsa.conformance.sandbox.ConformanceSandbox; import org.dcsa.conformance.sandbox.state.ConformancePersistenceProvider; +import software.amazon.lambda.powertools.logging.Logging; -@Slf4j +@Log4j2 public class SandboxTaskLambda implements RequestStreamHandler { + @Logging public void handleRequest(InputStream inputStream, OutputStream outputStream, Context context) { try { JsonNode jsonInput = JsonToolkit.inputStreamToJsonNode(inputStream); - log.info("jsonInput = " + jsonInput.toPrettyString()); + log.info("jsonInput = {}", jsonInput); try { Thread.sleep(100); // for consistency with the local app @@ -36,17 +38,13 @@ public void handleRequest(InputStream inputStream, OutputStream outputStream, Co jsonInput); ObjectNode jsonOutput = OBJECT_MAPPER.createObjectNode(); - log.info("jsonOutput = " + jsonOutput.toPrettyString()); - try (BufferedWriter writer = - new BufferedWriter(new OutputStreamWriter(outputStream, StandardCharsets.UTF_8))) { - writer.write(jsonOutput.toPrettyString()); - writer.flush(); - } + log.debug("jsonOutput = {}", jsonOutput); + outputStream.write(jsonOutput.toString().getBytes(StandardCharsets.UTF_8)); } catch (RuntimeException | Error e) { - log.error("Unhandled exception: " + e, e); + log.error("Unhandled exception: ", e); throw e; } catch (IOException e) { - log.error("Unhandled exception: " + e, e); + log.error("Unhandled exception: ", e); throw new RuntimeException(e); } } diff --git a/lambda/src/main/java/org/dcsa/conformance/lambda/WebuiLambda.java b/lambda/src/main/java/org/dcsa/conformance/lambda/WebuiLambda.java index 464e3e65..9b51a063 100644 --- a/lambda/src/main/java/org/dcsa/conformance/lambda/WebuiLambda.java +++ b/lambda/src/main/java/org/dcsa/conformance/lambda/WebuiLambda.java @@ -8,24 +8,25 @@ import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyResponseEvent; import com.fasterxml.jackson.databind.JsonNode; import java.util.*; -import lombok.extern.slf4j.Slf4j; +import lombok.extern.log4j.Log4j2; import org.dcsa.conformance.core.toolkit.JsonToolkit; import org.dcsa.conformance.sandbox.ConformanceAccessException; import org.dcsa.conformance.sandbox.ConformanceWebuiHandler; import org.dcsa.conformance.sandbox.state.ConformancePersistenceProvider; +import software.amazon.lambda.powertools.logging.Logging; -@Slf4j +@Log4j2 public class WebuiLambda implements RequestHandler { + @Logging public APIGatewayProxyResponseEvent handleRequest( final APIGatewayProxyRequestEvent event, final Context context) { try { - System.out.println("event = " + event + ", context = " + context); - log.info("event.getPath() = " + event.getPath()); + log.info("event = {}", event); JsonNode jsonEvent = OBJECT_MAPPER.valueToTree(event); - log.info("JSON event = " + jsonEvent.toString()); + log.debug("JSON event = {}", jsonEvent); String cognitoIdAsEnvironmentId = jsonEvent @@ -35,7 +36,7 @@ public APIGatewayProxyResponseEvent handleRequest( .get("claims") .get("cognito:username") .asText(); - log.info("cognitoIdAsEnvironmentId='%s'".formatted(cognitoIdAsEnvironmentId)); + log.debug("cognitoIdAsEnvironmentId='{}'", cognitoIdAsEnvironmentId); ConformancePersistenceProvider persistenceProvider = LambdaToolkit.createPersistenceProvider(); @@ -53,7 +54,7 @@ public APIGatewayProxyResponseEvent handleRequest( webuiHandler .handleRequest( cognitoIdAsEnvironmentId, JsonToolkit.stringToJsonNode(event.getBody())) - .toPrettyString(); + .toString(); } catch (ConformanceAccessException e) { return new APIGatewayProxyResponseEvent() .withMultiValueHeaders(Map.of("Content-Type", List.of(JsonToolkit.JSON_UTF_8))) @@ -66,7 +67,7 @@ public APIGatewayProxyResponseEvent handleRequest( .withStatusCode(200) .withBody(responseBody); } catch (RuntimeException | Error e) { - log.error("Unhandled exception: " + e, e); + log.error("Unhandled exception: ", e); throw e; } } diff --git a/lambda/src/main/resources/log4j2.xml b/lambda/src/main/resources/log4j2.xml new file mode 100644 index 00000000..9d03debd --- /dev/null +++ b/lambda/src/main/resources/log4j2.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/pom.xml b/pom.xml index 7178642f..154cc184 100644 --- a/pom.xml +++ b/pom.xml @@ -16,7 +16,7 @@ 3.3.4 2.20.0 - 5.11.1 + 5.11.2 1.18.34 https://sonarcloud.io diff --git a/sandbox/src/main/java/org/dcsa/conformance/sandbox/ConformanceWebuiHandler.java b/sandbox/src/main/java/org/dcsa/conformance/sandbox/ConformanceWebuiHandler.java index 8c28ea9c..e5c2dc8a 100644 --- a/sandbox/src/main/java/org/dcsa/conformance/sandbox/ConformanceWebuiHandler.java +++ b/sandbox/src/main/java/org/dcsa/conformance/sandbox/ConformanceWebuiHandler.java @@ -59,13 +59,14 @@ public JsonNode handleRequest(String userId, JsonNode requestNode) { node.put("exception", e.getClass().getName()) .put("message", e.getMessage()); } + log.warn("Internal Server Error: {}; Message: {}", e.getClass().getName(), e.getMessage()); return node; } } } public JsonNode _doHandleRequest(String userId, JsonNode requestNode) { - log.info("ConformanceWebuiHandler.handleRequest(%s)".formatted(requestNode.toPrettyString())); + log.info("ConformanceWebuiHandler.handleRequest({})", requestNode.toPrettyString()); String operation = requestNode.get("operation").asText(); JsonNode resultNode = switch (operation) { case "createSandbox" -> _createSandbox(userId, requestNode); @@ -85,7 +86,7 @@ public JsonNode _doHandleRequest(String userId, JsonNode requestNode) { case "completeCurrentAction" -> _completeCurrentAction(userId, requestNode); default -> throw new UnsupportedOperationException(operation); }; - log.debug("ConformanceWebuiHandler.handleRequest() returning: %s".formatted(resultNode.toPrettyString())); + log.debug("ConformanceWebuiHandler.handleRequest() returning: {}", resultNode.toPrettyString()); return resultNode; } @@ -294,7 +295,7 @@ private JsonNode _updateSandboxConfig(String userId, JsonNode requestNode) { ConformanceSandbox.saveSandboxConfiguration(persistenceProvider, userId, sandboxConfiguration); - log.info("Updated sandbox: " + sandboxConfiguration.toJsonNode().toPrettyString()); + log.info("Updated sandbox: {}", sandboxConfiguration.toJsonNode().toPrettyString()); return OBJECT_MAPPER.createObjectNode(); }