From 59d6efb7216d7750da5dda6449feb4649eaf75ca Mon Sep 17 00:00:00 2001 From: Pooya Paridel Date: Mon, 19 Oct 2026 09:45:31 -0700 Subject: [PATCH] refactor: rename Workflow Insight to Durable Execution Telemetry Rename the insight-plugin module to telemetry-exporter, the artifactId to aws-durable-execution-sdk-java-plugin-telemetry-exporter and the Java package to software.amazon.lambda.durable.telemetry. Rename the public API, the recordType discriminator and the default resource names to match the JavaScript SDK (aws/aws-durable-execution-sdk-js#1019). Old names are no longer accepted. --- .github/scripts/maven_publish.sh | 2 +- .github/workflows/build.yml | 4 +- .github/workflows/publish_maven.yml | 2 +- RELEASE.md | 6 +- .../insight/WorkflowInsightSamplingTest.java | 41 --------- pom.xml | 2 +- .../README.md | 38 ++++---- .../pom.xml | 6 +- .../lambda/durable/telemetry}/ArnParser.java | 2 +- .../durable/telemetry}/ContentConfig.java | 2 +- .../telemetry/DurableExecutionTelemetry.java | 72 ++++++++------- .../DurableExecutionTelemetryConfig.java | 22 ++--- .../DurableExecutionTelemetryRecord.java | 20 ++--- .../lambda/durable/telemetry}/ErrorInfo.java | 2 +- .../durable/telemetry}/ExportScheduler.java | 51 +++++------ .../lambda/durable/telemetry}/Json.java | 10 +-- .../durable/telemetry}/OperationOverride.java | 2 +- .../durable/telemetry}/OperationRecord.java | 2 +- .../durable/telemetry}/OperationSummary.java | 2 +- .../durable/telemetry}/OperationsIndex.java | 2 +- .../durable/telemetry/TelemetryExporter.java | 12 +-- .../lambda/durable/telemetry}/Truncation.java | 18 ++-- .../telemetry}/exporters/AuroraExporter.java | 18 ++-- .../exporters/CloudWatchLogsExporter.java | 18 ++-- .../exporters/DynamoDBExporter.java | 20 ++--- .../exporters/EventBridgeExporter.java | 18 ++-- .../telemetry}/exporters/FileExporter.java | 18 ++-- .../exporters/FirehoseExporter.java | 18 ++-- .../telemetry}/exporters/HttpExporter.java | 18 ++-- .../exporters/LambdaLogExporter.java | 16 ++-- .../telemetry}/exporters/LazyClient.java | 2 +- .../telemetry}/exporters/OTelExporter.java | 22 ++--- .../exporters/OpenSearchExporter.java | 18 ++-- .../exporters/OperationsFormat.java | 6 +- .../exporters/RedshiftExporter.java | 18 ++-- .../telemetry}/exporters/S3Exporter.java | 20 ++--- .../telemetry}/exporters/SQSExporter.java | 16 ++-- .../telemetry}/exporters/SqlIdentifiers.java | 2 +- .../durable/telemetry}/ArnParserTest.java | 2 +- .../telemetry}/AuroraExporterTest.java | 25 +++--- .../CloudWatchLogsExporterTest.java | 8 +- .../DurableExecutionTelemetryHookTest.java | 84 ++++++++++-------- .../DurableExecutionTelemetryPluginTest.java | 88 ++++++++++--------- ...DurableExecutionTelemetrySamplingTest.java | 42 +++++++++ .../telemetry}/DynamoDBExporterTest.java | 16 ++-- .../telemetry}/ErrorPrivacyGateTest.java | 21 +++-- .../telemetry}/EventBridgeExporterTest.java | 18 ++-- .../telemetry}/ExportSchedulerTest.java | 44 +++++----- .../telemetry}/ExporterIsolationTest.java | 29 +++--- .../durable/telemetry}/FileExporterTest.java | 22 ++--- .../telemetry}/FirehoseExporterTest.java | 20 ++--- .../durable/telemetry}/HttpExporterTest.java | 12 +-- .../durable/telemetry}/InputSnapshotTest.java | 29 +++--- .../durable/telemetry}/JsonJavaTimeTest.java | 17 ++-- .../durable/telemetry}/LocalHttpServer.java | 2 +- .../MutableNumberIsolationTest.java | 23 ++--- .../durable/telemetry}/OTelExporterTest.java | 12 +-- .../telemetry}/OpenSearchExporterTest.java | 12 +-- .../OperationErrorIdentityTest.java | 16 ++-- .../telemetry}/OperationOrderingTest.java | 19 ++-- .../telemetry}/OperationsFormatTest.java | 8 +- .../telemetry}/OperationsIndexTest.java | 2 +- .../PluginThrowableContainmentTest.java | 74 ++++++++-------- .../durable/telemetry}/RecordFactory.java | 6 +- .../telemetry}/RedshiftExporterTest.java | 41 ++++----- .../durable/telemetry}/S3ExporterTest.java | 10 +-- .../durable/telemetry}/SQSExporterTest.java | 18 ++-- .../telemetry}/StateCleanupLifecycleTest.java | 25 +++--- .../telemetry}/TransformContractTest.java | 35 ++++---- .../durable/telemetry}/TruncationTest.java | 21 +++-- .../UnrecoverableErrorUnwrapTest.java | 25 +++--- .../telemetry}/exporters/LazyClientTest.java | 2 +- .../exporters/OptionalArtifactTest.java | 12 +-- 73 files changed, 727 insertions(+), 681 deletions(-) delete mode 100644 insight-plugin/src/test/java/software/amazon/lambda/durable/insight/WorkflowInsightSamplingTest.java rename {insight-plugin => telemetry-exporter}/README.md (85%) rename {insight-plugin => telemetry-exporter}/pom.xml (95%) rename {insight-plugin/src/main/java/software/amazon/lambda/durable/insight => telemetry-exporter/src/main/java/software/amazon/lambda/durable/telemetry}/ArnParser.java (97%) rename {insight-plugin/src/main/java/software/amazon/lambda/durable/insight => telemetry-exporter/src/main/java/software/amazon/lambda/durable/telemetry}/ContentConfig.java (98%) rename insight-plugin/src/main/java/software/amazon/lambda/durable/insight/WorkflowInsight.java => telemetry-exporter/src/main/java/software/amazon/lambda/durable/telemetry/DurableExecutionTelemetry.java (89%) rename insight-plugin/src/main/java/software/amazon/lambda/durable/insight/WorkflowInsightConfig.java => telemetry-exporter/src/main/java/software/amazon/lambda/durable/telemetry/DurableExecutionTelemetryConfig.java (75%) rename insight-plugin/src/main/java/software/amazon/lambda/durable/insight/WorkflowInsightRecord.java => telemetry-exporter/src/main/java/software/amazon/lambda/durable/telemetry/DurableExecutionTelemetryRecord.java (90%) rename {insight-plugin/src/main/java/software/amazon/lambda/durable/insight => telemetry-exporter/src/main/java/software/amazon/lambda/durable/telemetry}/ErrorInfo.java (95%) rename {insight-plugin/src/main/java/software/amazon/lambda/durable/insight => telemetry-exporter/src/main/java/software/amazon/lambda/durable/telemetry}/ExportScheduler.java (76%) rename {insight-plugin/src/main/java/software/amazon/lambda/durable/insight => telemetry-exporter/src/main/java/software/amazon/lambda/durable/telemetry}/Json.java (94%) rename {insight-plugin/src/main/java/software/amazon/lambda/durable/insight => telemetry-exporter/src/main/java/software/amazon/lambda/durable/telemetry}/OperationOverride.java (97%) rename {insight-plugin/src/main/java/software/amazon/lambda/durable/insight => telemetry-exporter/src/main/java/software/amazon/lambda/durable/telemetry}/OperationRecord.java (99%) rename {insight-plugin/src/main/java/software/amazon/lambda/durable/insight => telemetry-exporter/src/main/java/software/amazon/lambda/durable/telemetry}/OperationSummary.java (97%) rename {insight-plugin/src/main/java/software/amazon/lambda/durable/insight => telemetry-exporter/src/main/java/software/amazon/lambda/durable/telemetry}/OperationsIndex.java (98%) rename insight-plugin/src/main/java/software/amazon/lambda/durable/insight/InsightExporter.java => telemetry-exporter/src/main/java/software/amazon/lambda/durable/telemetry/TelemetryExporter.java (70%) rename {insight-plugin/src/main/java/software/amazon/lambda/durable/insight => telemetry-exporter/src/main/java/software/amazon/lambda/durable/telemetry}/Truncation.java (90%) rename {insight-plugin/src/main/java/software/amazon/lambda/durable/insight => telemetry-exporter/src/main/java/software/amazon/lambda/durable/telemetry}/exporters/AuroraExporter.java (92%) rename {insight-plugin/src/main/java/software/amazon/lambda/durable/insight => telemetry-exporter/src/main/java/software/amazon/lambda/durable/telemetry}/exporters/CloudWatchLogsExporter.java (88%) rename {insight-plugin/src/main/java/software/amazon/lambda/durable/insight => telemetry-exporter/src/main/java/software/amazon/lambda/durable/telemetry}/exporters/DynamoDBExporter.java (85%) rename {insight-plugin/src/main/java/software/amazon/lambda/durable/insight => telemetry-exporter/src/main/java/software/amazon/lambda/durable/telemetry}/exporters/EventBridgeExporter.java (88%) rename {insight-plugin/src/main/java/software/amazon/lambda/durable/insight => telemetry-exporter/src/main/java/software/amazon/lambda/durable/telemetry}/exporters/FileExporter.java (88%) rename {insight-plugin/src/main/java/software/amazon/lambda/durable/insight => telemetry-exporter/src/main/java/software/amazon/lambda/durable/telemetry}/exporters/FirehoseExporter.java (81%) rename {insight-plugin/src/main/java/software/amazon/lambda/durable/insight => telemetry-exporter/src/main/java/software/amazon/lambda/durable/telemetry}/exporters/HttpExporter.java (88%) rename {insight-plugin/src/main/java/software/amazon/lambda/durable/insight => telemetry-exporter/src/main/java/software/amazon/lambda/durable/telemetry}/exporters/LambdaLogExporter.java (64%) rename {insight-plugin/src/main/java/software/amazon/lambda/durable/insight => telemetry-exporter/src/main/java/software/amazon/lambda/durable/telemetry}/exporters/LazyClient.java (98%) rename {insight-plugin/src/main/java/software/amazon/lambda/durable/insight => telemetry-exporter/src/main/java/software/amazon/lambda/durable/telemetry}/exporters/OTelExporter.java (91%) rename {insight-plugin/src/main/java/software/amazon/lambda/durable/insight => telemetry-exporter/src/main/java/software/amazon/lambda/durable/telemetry}/exporters/OpenSearchExporter.java (93%) rename {insight-plugin/src/main/java/software/amazon/lambda/durable/insight => telemetry-exporter/src/main/java/software/amazon/lambda/durable/telemetry}/exporters/OperationsFormat.java (88%) rename {insight-plugin/src/main/java/software/amazon/lambda/durable/insight => telemetry-exporter/src/main/java/software/amazon/lambda/durable/telemetry}/exporters/RedshiftExporter.java (94%) rename {insight-plugin/src/main/java/software/amazon/lambda/durable/insight => telemetry-exporter/src/main/java/software/amazon/lambda/durable/telemetry}/exporters/S3Exporter.java (84%) rename {insight-plugin/src/main/java/software/amazon/lambda/durable/insight => telemetry-exporter/src/main/java/software/amazon/lambda/durable/telemetry}/exporters/SQSExporter.java (89%) rename {insight-plugin/src/main/java/software/amazon/lambda/durable/insight => telemetry-exporter/src/main/java/software/amazon/lambda/durable/telemetry}/exporters/SqlIdentifiers.java (93%) rename {insight-plugin/src/test/java/software/amazon/lambda/durable/insight => telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry}/ArnParserTest.java (93%) rename {insight-plugin/src/test/java/software/amazon/lambda/durable/insight => telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry}/AuroraExporterTest.java (86%) rename {insight-plugin/src/test/java/software/amazon/lambda/durable/insight => telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry}/CloudWatchLogsExporterTest.java (96%) rename insight-plugin/src/test/java/software/amazon/lambda/durable/insight/WorkflowInsightHookTest.java => telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry/DurableExecutionTelemetryHookTest.java (79%) rename insight-plugin/src/test/java/software/amazon/lambda/durable/insight/WorkflowInsightPluginTest.java => telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry/DurableExecutionTelemetryPluginTest.java (84%) create mode 100644 telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry/DurableExecutionTelemetrySamplingTest.java rename {insight-plugin/src/test/java/software/amazon/lambda/durable/insight => telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry}/DynamoDBExporterTest.java (90%) rename {insight-plugin/src/test/java/software/amazon/lambda/durable/insight => telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry}/ErrorPrivacyGateTest.java (85%) rename {insight-plugin/src/test/java/software/amazon/lambda/durable/insight => telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry}/EventBridgeExporterTest.java (87%) rename {insight-plugin/src/test/java/software/amazon/lambda/durable/insight => telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry}/ExportSchedulerTest.java (91%) rename {insight-plugin/src/test/java/software/amazon/lambda/durable/insight => telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry}/ExporterIsolationTest.java (80%) rename {insight-plugin/src/test/java/software/amazon/lambda/durable/insight => telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry}/FileExporterTest.java (86%) rename {insight-plugin/src/test/java/software/amazon/lambda/durable/insight => telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry}/FirehoseExporterTest.java (80%) rename {insight-plugin/src/test/java/software/amazon/lambda/durable/insight => telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry}/HttpExporterTest.java (90%) rename {insight-plugin/src/test/java/software/amazon/lambda/durable/insight => telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry}/InputSnapshotTest.java (83%) rename {insight-plugin/src/test/java/software/amazon/lambda/durable/insight => telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry}/JsonJavaTimeTest.java (83%) rename {insight-plugin/src/test/java/software/amazon/lambda/durable/insight => telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry}/LocalHttpServer.java (98%) rename {insight-plugin/src/test/java/software/amazon/lambda/durable/insight => telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry}/MutableNumberIsolationTest.java (88%) rename {insight-plugin/src/test/java/software/amazon/lambda/durable/insight => telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry}/OTelExporterTest.java (94%) rename {insight-plugin/src/test/java/software/amazon/lambda/durable/insight => telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry}/OpenSearchExporterTest.java (92%) rename {insight-plugin/src/test/java/software/amazon/lambda/durable/insight => telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry}/OperationErrorIdentityTest.java (87%) rename {insight-plugin/src/test/java/software/amazon/lambda/durable/insight => telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry}/OperationOrderingTest.java (87%) rename {insight-plugin/src/test/java/software/amazon/lambda/durable/insight => telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry}/OperationsFormatTest.java (90%) rename {insight-plugin/src/test/java/software/amazon/lambda/durable/insight => telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry}/OperationsIndexTest.java (98%) rename {insight-plugin/src/test/java/software/amazon/lambda/durable/insight => telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry}/PluginThrowableContainmentTest.java (71%) rename {insight-plugin/src/test/java/software/amazon/lambda/durable/insight => telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry}/RecordFactory.java (78%) rename {insight-plugin/src/test/java/software/amazon/lambda/durable/insight => telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry}/RedshiftExporterTest.java (84%) rename {insight-plugin/src/test/java/software/amazon/lambda/durable/insight => telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry}/S3ExporterTest.java (88%) rename {insight-plugin/src/test/java/software/amazon/lambda/durable/insight => telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry}/SQSExporterTest.java (89%) rename {insight-plugin/src/test/java/software/amazon/lambda/durable/insight => telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry}/StateCleanupLifecycleTest.java (81%) rename {insight-plugin/src/test/java/software/amazon/lambda/durable/insight => telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry}/TransformContractTest.java (82%) rename {insight-plugin/src/test/java/software/amazon/lambda/durable/insight => telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry}/TruncationTest.java (78%) rename {insight-plugin/src/test/java/software/amazon/lambda/durable/insight => telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry}/UnrecoverableErrorUnwrapTest.java (84%) rename {insight-plugin/src/test/java/software/amazon/lambda/durable/insight => telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry}/exporters/LazyClientTest.java (96%) rename {insight-plugin/src/test/java/software/amazon/lambda/durable/insight => telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry}/exporters/OptionalArtifactTest.java (96%) diff --git a/.github/scripts/maven_publish.sh b/.github/scripts/maven_publish.sh index 75c1948300..df9142159c 100644 --- a/.github/scripts/maven_publish.sh +++ b/.github/scripts/maven_publish.sh @@ -45,6 +45,6 @@ echo "=== Step 3: Upload to Sonatype Central Portal ===" mvn clean deploy -s "${SETTINGS_FILE}" -pl sdk -P publishing -DskipTests --no-transfer-progress mvn clean deploy -s "${SETTINGS_FILE}" -pl sdk-testing -P publishing -DskipTests --no-transfer-progress mvn clean deploy -s "${SETTINGS_FILE}" -pl otel-plugin -P publishing -DskipTests --no-transfer-progress -mvn clean deploy -s "${SETTINGS_FILE}" -pl insight-plugin -P publishing -DskipTests --no-transfer-progress +mvn clean deploy -s "${SETTINGS_FILE}" -pl telemetry-exporter -P publishing -DskipTests --no-transfer-progress echo "=== Release ${RELEASE_VERSION} uploaded successfully; review and publish it in Sonatype Central Portal. ===" diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 1f4bb00483..ea2b107af8 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -28,7 +28,7 @@ on: - 'sdk/**' - 'sdk-testing/**' - 'sdk-integration-tests/**' - - 'insight-plugin/**' + - 'telemetry-exporter/**' - 'otel-plugin/**' - '.github/scripts/verify_otel_api_compatibility.py' - 'examples/**' @@ -43,7 +43,7 @@ on: - 'sdk/**' - 'sdk-testing/**' - 'sdk-integration-tests/**' - - 'insight-plugin/**' + - 'telemetry-exporter/**' - 'otel-plugin/**' - '.github/scripts/verify_otel_api_compatibility.py' - 'examples/**' diff --git a/.github/workflows/publish_maven.yml b/.github/workflows/publish_maven.yml index 3eb4431045..2381a730cb 100644 --- a/.github/workflows/publish_maven.yml +++ b/.github/workflows/publish_maven.yml @@ -92,7 +92,7 @@ jobs: "sdk/target/aws-durable-execution-sdk-java-${RELEASE_VERSION}.jar" \ "sdk-testing/target/aws-durable-execution-sdk-java-testing-${RELEASE_VERSION}.jar" \ "otel-plugin/target/aws-durable-execution-sdk-java-plugin-otel-${RELEASE_VERSION}.jar" \ - "insight-plugin/target/aws-durable-execution-sdk-java-plugin-insight-${RELEASE_VERSION}.jar" \ + "telemetry-exporter/target/aws-durable-execution-sdk-java-plugin-telemetry-exporter-${RELEASE_VERSION}.jar" \ --clobber - name: Checkout default branch diff --git a/RELEASE.md b/RELEASE.md index f7594d2e5e..068a2dc671 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -44,7 +44,7 @@ The publication workflow: 1. Verifies that the tag is a semantic version, points to a commit on the default branch, and matches the Maven version in the tagged POM. 2. Builds, signs, and uploads the SDK, testing library, OpenTelemetry plugin, - and Workflow Insight plugin to Sonatype Central Portal. + and Durable Execution Telemetry Exporter to Sonatype Central Portal. 3. Uploads the four JARs to the existing GitHub release. 4. Opens a pull request for the next development version. A final release increments the patch version, so `2.1.1` produces `2.1.2-SNAPSHOT`. A @@ -56,8 +56,8 @@ After **Publish Maven Release** succeeds: 1. Open [Publishing Deployments](https://central.sonatype.com/publishing/deployments) in Sonatype Central Portal. 2. Find the deployments for the release version and verify that they contain - the expected SDK, testing library, OpenTelemetry plugin, and Workflow Insight - plugin artifacts. + the expected SDK, testing library, OpenTelemetry plugin, and Durable Execution + Telemetry Exporter artifacts. 3. Click **Publish** for each deployment and wait for publication to complete. The workflow uses `autoPublish=false`, so this manual action is required. 4. Confirm that the GitHub release contains the expected JARs and that the diff --git a/insight-plugin/src/test/java/software/amazon/lambda/durable/insight/WorkflowInsightSamplingTest.java b/insight-plugin/src/test/java/software/amazon/lambda/durable/insight/WorkflowInsightSamplingTest.java deleted file mode 100644 index 763f7755af..0000000000 --- a/insight-plugin/src/test/java/software/amazon/lambda/durable/insight/WorkflowInsightSamplingTest.java +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. -// SPDX-License-Identifier: Apache-2.0 -package software.amazon.lambda.durable.insight; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import org.junit.jupiter.api.Test; - -class WorkflowInsightSamplingTest { - - @Test - void rateOneAlwaysSamplesIn() { - assertTrue(WorkflowInsight.shouldSample("any-arn", 1.0)); - } - - @Test - void rateZeroNeverSamplesIn() { - assertFalse(WorkflowInsight.shouldSample("any-arn", 0.0)); - } - - @Test - void fnv1a32IsDeterministic() { - assertEquals(WorkflowInsight.fnv1a32("hello"), WorkflowInsight.fnv1a32("hello")); - } - - @Test - void resolveSamplingRateClampsOutOfRange() { - assertEquals(1.0, WorkflowInsight.resolveSamplingRate(5.0)); - assertEquals(0.0, WorkflowInsight.resolveSamplingRate(-1.0)); - assertEquals(1.0, WorkflowInsight.resolveSamplingRate(null)); - assertEquals(0.25, WorkflowInsight.resolveSamplingRate(0.25)); - } - - @Test - void samplingDecisionIsStableAcrossCalls() { - String arn = "arn:aws:lambda:us-west-2:1:function:f:$LATEST/durable-execution/e/i"; - assertEquals(WorkflowInsight.shouldSample(arn, 0.5), WorkflowInsight.shouldSample(arn, 0.5)); - } -} diff --git a/pom.xml b/pom.xml index d57477e769..f433f25814 100644 --- a/pom.xml +++ b/pom.xml @@ -43,7 +43,7 @@ sdk-testing sdk-integration-tests otel-plugin - insight-plugin + telemetry-exporter examples conformance-tests coverage-report diff --git a/insight-plugin/README.md b/telemetry-exporter/README.md similarity index 85% rename from insight-plugin/README.md rename to telemetry-exporter/README.md index 75d4e51324..69ee265fb3 100644 --- a/insight-plugin/README.md +++ b/telemetry-exporter/README.md @@ -1,8 +1,8 @@ -# Workflow Insight Plugin (preview) +# Durable Execution Telemetry Exporter (preview) Instrumentation plugin for the AWS Lambda Durable Execution Java SDK that emits a curated, -per-execution **Workflow Insight record** to one or more pluggable exporters. It ports the -JavaScript `workflowInsight()` contract (canonical record schema `1.0`) to the Java plugin hook +per-execution **Durable Execution Telemetry record** to one or more pluggable exporters. It ports the +JavaScript `durableExecutionTelemetry()` contract (canonical record schema `1.0`) to the Java plugin hook surface. > **Preview API.** Every public type is annotated @@ -13,10 +13,10 @@ surface. ```java DurableConfig config = DurableConfig.builder() - .withPlugins(WorkflowInsight.workflowInsight(WorkflowInsightConfig.builder() + .withPlugins(DurableExecutionTelemetry.durableExecutionTelemetry(DurableExecutionTelemetryConfig.builder() .samplingRate(1.0) - .emitMode(WorkflowInsightConfig.EmitMode.ON_COMPLETE) // ON_COMPLETE | ON_CHANGE | ON_FAILURE - .operationDetail(WorkflowInsightConfig.OperationDetail.TOP_LEVEL) // TOP_LEVEL | FULL_TREE + .emitMode(DurableExecutionTelemetryConfig.EmitMode.ON_COMPLETE) // ON_COMPLETE | ON_CHANGE | ON_FAILURE + .operationDetail(DurableExecutionTelemetryConfig.OperationDetail.TOP_LEVEL) // TOP_LEVEL | FULL_TREE .content(ContentConfig.builder() .input(true).output(true).includeErrors(true) .addOverride(OperationOverride.withResult("compute", r -> r)) @@ -28,7 +28,7 @@ DurableConfig config = DurableConfig.builder() ## Exporters -Implement `InsightExporter` for custom sinks. Every exporter has a builder with one setter per option and a +Implement `TelemetryExporter` for custom sinks. Every exporter has a builder with one setter per option and a `maxRecordSizeBytes` override; records over the limit are truncated before export. | Exporter | Destination | Operations rendering | Default size limit | Artifact (optional) | @@ -66,8 +66,8 @@ at first export with a message naming the artifact; the plugin logs it and conti Table keyed by `pk` (string), optionally with sort key `sk`. IAM: `dynamodb:PutItem`. ```java -DynamoDBExporter.builder().tableName("workflow-insight").build() // history: pk = ARN, sk = emittedAt -DynamoDBExporter.builder().tableName("workflow-insight").sortKey("").build() // upsert: pk only +DynamoDBExporter.builder().tableName("durable-execution-telemetry").build() // history: pk = ARN, sk = emittedAt +DynamoDBExporter.builder().tableName("durable-execution-telemetry").sortKey("").build() // upsert: pk only ``` ### AuroraExporter @@ -80,7 +80,7 @@ statement casts the values. IAM: `rds-data:ExecuteStatement`, `secretsmanager:Ge ```java AuroraExporter.builder() - .resourceArn(clusterArn).secretArn(secretArn).database("insight") + .resourceArn(clusterArn).secretArn(secretArn).database("telemetry") .engine(AuroraExporter.Engine.POSTGRESQL) // or MYSQL .build() ``` @@ -92,14 +92,14 @@ columns; rows are upserted with `MERGE`. IAM: `redshift-data:ExecuteStatement` p (Serverless) or `secretsmanager:GetSecretValue` / `redshift:GetClusterCredentialsWithIAM` (provisioned). ```java -RedshiftExporter.builder().workgroupName("insight").database("dev").build() +RedshiftExporter.builder().workgroupName("telemetry").database("dev").build() RedshiftExporter.builder().clusterIdentifier("my-cluster").database("dev").secretArn(secretArn).build() ``` ### OpenSearchExporter Domain endpoint; the index is created on first write. The document id is the execution ARN. IAM (SigV4): -`es:ESHttpPut` on `domain//workflow-insight/*`. +`es:ESHttpPut` on `domain//durable-execution-telemetry/*`. ```java OpenSearchExporter.builder().endpoint("https://my-domain.us-east-1.es.amazonaws.com").region("us-east-1").build() @@ -111,7 +111,7 @@ OpenSearchExporter.builder().endpoint(url).auth(OpenSearchExporter.Auth.BASIC).u Delivery stream with any destination. IAM: `firehose:PutRecord`. ```java -FirehoseExporter.builder().deliveryStreamName("workflow-insight").build() +FirehoseExporter.builder().deliveryStreamName("durable-execution-telemetry").build() ``` ### EventBridgeExporter @@ -119,8 +119,8 @@ FirehoseExporter.builder().deliveryStreamName("workflow-insight").build() Default bus or a custom bus. `DetailType` is the record status, so rules can match `FAILED`. IAM: `events:PutEvents`. ```java -EventBridgeExporter.builder().build() // default bus, source software.amazon.lambda.durable.insight -EventBridgeExporter.builder().eventBusName("insight-bus").build() +EventBridgeExporter.builder().build() // default bus, source software.amazon.lambda.durable.telemetry +EventBridgeExporter.builder().eventBusName("telemetry-bus").build() ``` ### SQSExporter @@ -128,7 +128,7 @@ EventBridgeExporter.builder().eventBusName("insight-bus").build() Standard or FIFO queue; FIFO queues receive a group id (execution ARN) and a deduplication id. IAM: `sqs:SendMessage`. ```java -SQSExporter.builder().queueUrl("https://sqs.us-east-1.amazonaws.com/123456789012/insight.fifo").build() +SQSExporter.builder().queueUrl("https://sqs.us-east-1.amazonaws.com/123456789012/telemetry.fifo").build() ``` ### OTelExporter @@ -144,7 +144,7 @@ OTelExporter.builder().endpoint("https://otlp.example.com/v1/logs").headers(Map. Any endpoint accepting JSON. `timeoutMs` defaults to 10000. No IAM. ```java -HttpExporter.builder().url("https://hooks.example.com/insight").method(HttpExporter.Method.PUT).build() +HttpExporter.builder().url("https://hooks.example.com/telemetry").method(HttpExporter.Method.PUT).build() ``` ### FileExporter @@ -153,7 +153,7 @@ A writable directory such as an EFS mount or `/tmp`. `NDJSON` appends `{date}.nd `{executionName}.json`. ```java -FileExporter.builder().directory("/mnt/efs/workflow-insight").mode(FileExporter.Mode.JSON).build() +FileExporter.builder().directory("/mnt/efs/durable-execution-telemetry").mode(FileExporter.Mode.JSON).build() ``` ### S3Exporter and CloudWatchLogsExporter @@ -213,5 +213,5 @@ one event per record to `{logStreamPrefix}YYYY/MM/DD` (IAM: `logs:CreateLogStrea ## Conformance -Validated against the Workflow Insight conformance suite behaviors `insight-1 … insight-18` +Validated against the Durable Execution Telemetry conformance suite behaviors `telemetry-1 … telemetry-18` (PR #73 Java examples). See the module tests for the behavior mapping. diff --git a/insight-plugin/pom.xml b/telemetry-exporter/pom.xml similarity index 95% rename from insight-plugin/pom.xml rename to telemetry-exporter/pom.xml index c2cbe8df5f..7ef0638000 100644 --- a/insight-plugin/pom.xml +++ b/telemetry-exporter/pom.xml @@ -10,9 +10,9 @@ 2.2.2-SNAPSHOT - aws-durable-execution-sdk-java-plugin-insight - AWS Lambda Durable Execution SDK Workflow Insight Plugin - Workflow Insight instrumentation plugin for AWS Lambda Durable Execution SDK + aws-durable-execution-sdk-java-plugin-telemetry-exporter + Durable Execution Telemetry Exporter + Durable Execution Telemetry exporter plugin for AWS Lambda Durable Execution SDK diff --git a/insight-plugin/src/main/java/software/amazon/lambda/durable/insight/ArnParser.java b/telemetry-exporter/src/main/java/software/amazon/lambda/durable/telemetry/ArnParser.java similarity index 97% rename from insight-plugin/src/main/java/software/amazon/lambda/durable/insight/ArnParser.java rename to telemetry-exporter/src/main/java/software/amazon/lambda/durable/telemetry/ArnParser.java index e07d798cd9..3eafe1ee55 100644 --- a/insight-plugin/src/main/java/software/amazon/lambda/durable/insight/ArnParser.java +++ b/telemetry-exporter/src/main/java/software/amazon/lambda/durable/telemetry/ArnParser.java @@ -1,6 +1,6 @@ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 -package software.amazon.lambda.durable.insight; +package software.amazon.lambda.durable.telemetry; import software.amazon.lambda.durable.annotations.Experimental; diff --git a/insight-plugin/src/main/java/software/amazon/lambda/durable/insight/ContentConfig.java b/telemetry-exporter/src/main/java/software/amazon/lambda/durable/telemetry/ContentConfig.java similarity index 98% rename from insight-plugin/src/main/java/software/amazon/lambda/durable/insight/ContentConfig.java rename to telemetry-exporter/src/main/java/software/amazon/lambda/durable/telemetry/ContentConfig.java index 3a8228ec9c..e211894826 100644 --- a/insight-plugin/src/main/java/software/amazon/lambda/durable/insight/ContentConfig.java +++ b/telemetry-exporter/src/main/java/software/amazon/lambda/durable/telemetry/ContentConfig.java @@ -1,6 +1,6 @@ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 -package software.amazon.lambda.durable.insight; +package software.amazon.lambda.durable.telemetry; import java.util.ArrayList; import java.util.List; diff --git a/insight-plugin/src/main/java/software/amazon/lambda/durable/insight/WorkflowInsight.java b/telemetry-exporter/src/main/java/software/amazon/lambda/durable/telemetry/DurableExecutionTelemetry.java similarity index 89% rename from insight-plugin/src/main/java/software/amazon/lambda/durable/insight/WorkflowInsight.java rename to telemetry-exporter/src/main/java/software/amazon/lambda/durable/telemetry/DurableExecutionTelemetry.java index 531bbc4758..6ece814fd6 100644 --- a/insight-plugin/src/main/java/software/amazon/lambda/durable/insight/WorkflowInsight.java +++ b/telemetry-exporter/src/main/java/software/amazon/lambda/durable/telemetry/DurableExecutionTelemetry.java @@ -1,6 +1,6 @@ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 -package software.amazon.lambda.durable.insight; +package software.amazon.lambda.durable.telemetry; import java.time.Instant; import java.util.ArrayList; @@ -16,24 +16,25 @@ import software.amazon.lambda.durable.annotations.Experimental; import software.amazon.lambda.durable.exception.DurableOperationException; import software.amazon.lambda.durable.exception.UnrecoverableDurableExecutionException; -import software.amazon.lambda.durable.insight.exporters.LambdaLogExporter; import software.amazon.lambda.durable.plugin.DurableExecutionPlugin; import software.amazon.lambda.durable.plugin.InvocationEndInfo; import software.amazon.lambda.durable.plugin.InvocationInfo; import software.amazon.lambda.durable.plugin.InvocationStatus; import software.amazon.lambda.durable.plugin.OperationChangeInfo; import software.amazon.lambda.durable.plugin.OperationChangeItemInfo; +import software.amazon.lambda.durable.telemetry.exporters.LambdaLogExporter; /** - * Workflow Insight instrumentation plugin for the Durable Execution Java SDK. + * Durable Execution Telemetry instrumentation plugin for the Durable Execution Java SDK. * - *

Ports the JS {@code workflowInsight()} emission model to the Java plugin hook surface. Each record is built from - * the current invocation operation snapshot the SDK hands the plugin — {@link InvocationInfo#operations()} at - * invocation start / operation change, and {@link InvocationEndInfo#operations()} at invocation end — rather than from - * per-hook accumulation. Execution input/output flow through {@link InvocationInfo#executionInput()} and - * {@link InvocationEndInfo#executionResult()}, and per-operation results through - * {@link OperationChangeItemInfo#result()}; these are the fields PR #618 surfaced on the hook records, so - * {@code input}, {@code output}, and operation {@code result} are now populated exactly as in the JS plugin. + *

Ports the JS {@code durableExecutionTelemetry()} emission model to the Java plugin hook surface. Each record is + * built from the current invocation operation snapshot the SDK hands the plugin — + * {@link InvocationInfo#operations()} at invocation start / operation change, and + * {@link InvocationEndInfo#operations()} at invocation end — rather than from per-hook accumulation. Execution + * input/output flow through {@link InvocationInfo#executionInput()} and {@link InvocationEndInfo#executionResult()}, + * and per-operation results through {@link OperationChangeItemInfo#result()}; these are the fields PR #618 + * surfaced on the hook records, so {@code input}, {@code output}, and operation {@code result} are now populated + * exactly as in the JS plugin. * *

Per-execution state (keyed by execution ARN) holds only the stable start time, the parsed ARN, the one-time * sampling decision, and a detached snapshot of the execution input. State is removed on every {@code onInvocationEnd} @@ -43,15 +44,18 @@ * the input snapshot from {@link InvocationInfo#executionInput()}. */ @Experimental -public final class WorkflowInsight { +public final class DurableExecutionTelemetry { - private static final Logger logger = LoggerFactory.getLogger(WorkflowInsight.class); + private static final Logger logger = LoggerFactory.getLogger(DurableExecutionTelemetry.class); - private WorkflowInsight() {} + private DurableExecutionTelemetry() {} - /** Creates a Workflow Insight plugin from the given config. Mirrors the JS {@code workflowInsight(config)}. */ - public static DurableExecutionPlugin workflowInsight(WorkflowInsightConfig config) { - return new InsightPlugin(config); + /** + * Creates a Durable Execution Telemetry plugin from the given config. Mirrors the JS + * {@code durableExecutionTelemetry(config)}. + */ + public static DurableExecutionPlugin durableExecutionTelemetry(DurableExecutionTelemetryConfig config) { + return new TelemetryPlugin(config); } /** Per-execution state, keyed by execution ARN, to prevent warm-container bleed and handle resume. */ @@ -75,7 +79,7 @@ private static final class ExecutionState { } /** Schedules the record unless the invocation has already ended; the check and the hand-off are atomic. */ - boolean scheduleIfOpen(ExportScheduler scheduler, WorkflowInsightRecord record) { + boolean scheduleIfOpen(ExportScheduler scheduler, DurableExecutionTelemetryRecord record) { synchronized (this) { if (closed) { return false; @@ -86,7 +90,7 @@ boolean scheduleIfOpen(ExportScheduler scheduler, WorkflowInsightRecord record) } /** Marks the invocation ended and, when given a record, schedules it as the last one for this execution. */ - void closeAndSchedule(ExportScheduler scheduler, WorkflowInsightRecord finalRecord) { + void closeAndSchedule(ExportScheduler scheduler, DurableExecutionTelemetryRecord finalRecord) { synchronized (this) { closed = true; if (finalRecord != null) { @@ -96,14 +100,14 @@ void closeAndSchedule(ExportScheduler scheduler, WorkflowInsightRecord finalReco } } - static final class InsightPlugin implements DurableExecutionPlugin { + static final class TelemetryPlugin implements DurableExecutionPlugin { private final double samplingRate; - private final WorkflowInsightConfig.EmitMode emitMode; + private final DurableExecutionTelemetryConfig.EmitMode emitMode; private final boolean topLevelOnly; private final boolean includeErrors; private final ContentConfig content; private final Map overridesByName = new LinkedHashMap<>(); - private final List exporters; + private final List exporters; private final ExportScheduler scheduler; private final Map byArn = new ConcurrentHashMap<>(); @@ -118,10 +122,12 @@ void drainExports() { scheduler.drain(); } - InsightPlugin(WorkflowInsightConfig config) { + TelemetryPlugin(DurableExecutionTelemetryConfig config) { this.samplingRate = resolveSamplingRate(config.samplingRate()); - this.emitMode = config.emitMode() != null ? config.emitMode() : WorkflowInsightConfig.EmitMode.ON_COMPLETE; - this.topLevelOnly = config.operationDetail() != WorkflowInsightConfig.OperationDetail.FULL_TREE; + this.emitMode = config.emitMode() != null + ? config.emitMode() + : DurableExecutionTelemetryConfig.EmitMode.ON_COMPLETE; + this.topLevelOnly = config.operationDetail() != DurableExecutionTelemetryConfig.OperationDetail.FULL_TREE; this.content = config.content(); this.includeErrors = content == null || content.includeErrors(); if (content != null) { @@ -158,7 +164,7 @@ public void onInvocationStart(InvocationInfo info) { logSafely("failed to snapshot execution input; omitting input", t); state.cachedInput = null; } - if (emitMode == WorkflowInsightConfig.EmitMode.ON_CHANGE) { + if (emitMode == DurableExecutionTelemetryConfig.EmitMode.ON_CHANGE) { scheduler.schedule(buildRecord( state, info.durableExecutionArn(), @@ -177,7 +183,7 @@ public void onInvocationStart(InvocationInfo info) { @Override public void onOperationChange(OperationChangeInfo info) { try { - if (emitMode != WorkflowInsightConfig.EmitMode.ON_CHANGE) { + if (emitMode != DurableExecutionTelemetryConfig.EmitMode.ON_CHANGE) { return; } ExecutionState state = byArn.get(info.durableExecutionArn()); @@ -225,7 +231,7 @@ public void onInvocationEnd(InvocationEndInfo info) { break; } - WorkflowInsightRecord finalRecord = null; + DurableExecutionTelemetryRecord finalRecord = null; if (state.sampledIn && shouldEmit) { finalRecord = buildRecord( state, @@ -282,13 +288,13 @@ private void drainAndFlush() { } /** Shapes and exports one record to one exporter; runs on a scheduler worker, never on an SDK hook thread. */ - private void exportRecord(WorkflowInsightRecord record, InsightExporter exporter) { + private void exportRecord(DurableExecutionTelemetryRecord record, TelemetryExporter exporter) { try { // Give each exporter its own deep copy: truncation returns the original record when it already fits, // so without this a custom exporter that mutates operations or nested content would corrupt every // other exporter's view of the same record. - WorkflowInsightRecord isolated = record.deepCopy(); - WorkflowInsightRecord shaped = + DurableExecutionTelemetryRecord isolated = record.deepCopy(); + DurableExecutionTelemetryRecord shaped = Truncation.truncateRecord(isolated, exporter.maxRecordSizeBytes(), exporter::render); exporter.export(shaped); } catch (Throwable t) { @@ -300,7 +306,7 @@ private void exportRecord(WorkflowInsightRecord record, InsightExporter exporter } } - private WorkflowInsightRecord buildRecord( + private DurableExecutionTelemetryRecord buildRecord( ExecutionState state, String arn, String status, @@ -309,7 +315,7 @@ private WorkflowInsightRecord buildRecord( Object input, Object output, Throwable error) { - WorkflowInsightRecord record = new WorkflowInsightRecord(); + DurableExecutionTelemetryRecord record = new DurableExecutionTelemetryRecord(); ArnParser a = state.arn; record.emittedAt = Instant.now().toString(); record.executionArn = arn; @@ -471,7 +477,7 @@ static Object applyDataContent(String label, Object value, boolean include, Func /** Logs a plugin failure without ever letting the logging itself disrupt durable execution. */ private static void logSafely(String message, Throwable t) { try { - logger.warn("[workflow-insight] {}", message, t); + logger.warn("[durable-execution-telemetry] {}", message, t); } catch (Throwable ignored) { // Never allow a logging failure to propagate into the SDK control flow. } diff --git a/insight-plugin/src/main/java/software/amazon/lambda/durable/insight/WorkflowInsightConfig.java b/telemetry-exporter/src/main/java/software/amazon/lambda/durable/telemetry/DurableExecutionTelemetryConfig.java similarity index 75% rename from insight-plugin/src/main/java/software/amazon/lambda/durable/insight/WorkflowInsightConfig.java rename to telemetry-exporter/src/main/java/software/amazon/lambda/durable/telemetry/DurableExecutionTelemetryConfig.java index d1261e07dd..b9d2fc1933 100644 --- a/insight-plugin/src/main/java/software/amazon/lambda/durable/insight/WorkflowInsightConfig.java +++ b/telemetry-exporter/src/main/java/software/amazon/lambda/durable/telemetry/DurableExecutionTelemetryConfig.java @@ -1,14 +1,14 @@ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 -package software.amazon.lambda.durable.insight; +package software.amazon.lambda.durable.telemetry; import java.util.ArrayList; import java.util.List; import software.amazon.lambda.durable.annotations.Experimental; -/** Configuration for the Workflow Insight plugin. Mirrors the JS {@code WorkflowInsightConfig}. */ +/** Configuration for the Durable Execution Telemetry plugin. Mirrors the JS {@code DurableExecutionTelemetryConfig}. */ @Experimental -public final class WorkflowInsightConfig { +public final class DurableExecutionTelemetryConfig { /** When records are emitted. */ @Experimental @@ -25,13 +25,13 @@ public enum OperationDetail { FULL_TREE } - private final List exporters; + private final List exporters; private final Double samplingRate; private final EmitMode emitMode; private final OperationDetail operationDetail; private final ContentConfig content; - private WorkflowInsightConfig(Builder b) { + private DurableExecutionTelemetryConfig(Builder b) { this.exporters = List.copyOf(b.exporters); this.samplingRate = b.samplingRate; this.emitMode = b.emitMode; @@ -43,7 +43,7 @@ public static Builder builder() { return new Builder(); } - public List exporters() { + public List exporters() { return exporters; } @@ -63,15 +63,15 @@ public ContentConfig content() { return content; } - /** Builder for {@link WorkflowInsightConfig}. */ + /** Builder for {@link DurableExecutionTelemetryConfig}. */ public static final class Builder { - private final List exporters = new ArrayList<>(); + private final List exporters = new ArrayList<>(); private Double samplingRate; private EmitMode emitMode; private OperationDetail operationDetail; private ContentConfig content; - public Builder addExporter(InsightExporter exporter) { + public Builder addExporter(TelemetryExporter exporter) { this.exporters.add(exporter); return this; } @@ -96,8 +96,8 @@ public Builder content(ContentConfig content) { return this; } - public WorkflowInsightConfig build() { - return new WorkflowInsightConfig(this); + public DurableExecutionTelemetryConfig build() { + return new DurableExecutionTelemetryConfig(this); } } } diff --git a/insight-plugin/src/main/java/software/amazon/lambda/durable/insight/WorkflowInsightRecord.java b/telemetry-exporter/src/main/java/software/amazon/lambda/durable/telemetry/DurableExecutionTelemetryRecord.java similarity index 90% rename from insight-plugin/src/main/java/software/amazon/lambda/durable/insight/WorkflowInsightRecord.java rename to telemetry-exporter/src/main/java/software/amazon/lambda/durable/telemetry/DurableExecutionTelemetryRecord.java index f2a1b10603..4fb67a6dda 100644 --- a/insight-plugin/src/main/java/software/amazon/lambda/durable/insight/WorkflowInsightRecord.java +++ b/telemetry-exporter/src/main/java/software/amazon/lambda/durable/telemetry/DurableExecutionTelemetryRecord.java @@ -1,6 +1,6 @@ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 -package software.amazon.lambda.durable.insight; +package software.amazon.lambda.durable.telemetry; import java.util.ArrayList; import java.util.Collections; @@ -12,13 +12,13 @@ /** * The curated execution record emitted to destinations. * - *

Mirrors the JS {@code WorkflowInsightRecord} interface field-for-field so the emitted wire JSON is identical - * (camelCase names, absent fields omitted). Exactly one of {@code operations} (array) or the {@code operationsByName} - * rendering is emitted, depending on the exporter's {@code render}. + *

Mirrors the JS {@code DurableExecutionTelemetryRecord} interface field-for-field so the emitted wire JSON is + * identical (camelCase names, absent fields omitted). Exactly one of {@code operations} (array) or the + * {@code operationsByName} rendering is emitted, depending on the exporter's {@code render}. */ @Experimental -public final class WorkflowInsightRecord { - String recordType = "WorkflowInsight"; +public final class DurableExecutionTelemetryRecord { + String recordType = "DurableExecutionTelemetry"; String schemaVersion = "1.0"; String emittedAt; String executionArn; @@ -70,8 +70,8 @@ public String status() { } /** Shallow copy with a fresh operations list — used by the size limiter so the shared record is never mutated. */ - public WorkflowInsightRecord copy() { - WorkflowInsightRecord c = new WorkflowInsightRecord(); + public DurableExecutionTelemetryRecord copy() { + DurableExecutionTelemetryRecord c = new DurableExecutionTelemetryRecord(); c.recordType = recordType; c.schemaVersion = schemaVersion; c.emittedAt = emittedAt; @@ -103,8 +103,8 @@ public WorkflowInsightRecord copy() { * truncation returns the original record when it already fits, this copy is taken per exporter before shaping. * {@code error} is an immutable {@link ErrorInfo} and is shared safely. */ - public WorkflowInsightRecord deepCopy() { - WorkflowInsightRecord c = copy(); + public DurableExecutionTelemetryRecord deepCopy() { + DurableExecutionTelemetryRecord c = copy(); List deepOps = new ArrayList<>(operations.size()); for (OperationRecord op : operations) { deepOps.add(op.deepCopy()); diff --git a/insight-plugin/src/main/java/software/amazon/lambda/durable/insight/ErrorInfo.java b/telemetry-exporter/src/main/java/software/amazon/lambda/durable/telemetry/ErrorInfo.java similarity index 95% rename from insight-plugin/src/main/java/software/amazon/lambda/durable/insight/ErrorInfo.java rename to telemetry-exporter/src/main/java/software/amazon/lambda/durable/telemetry/ErrorInfo.java index e445864600..b5c323f4cb 100644 --- a/insight-plugin/src/main/java/software/amazon/lambda/durable/insight/ErrorInfo.java +++ b/telemetry-exporter/src/main/java/software/amazon/lambda/durable/telemetry/ErrorInfo.java @@ -1,6 +1,6 @@ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 -package software.amazon.lambda.durable.insight; +package software.amazon.lambda.durable.telemetry; import java.util.LinkedHashMap; import java.util.Map; diff --git a/insight-plugin/src/main/java/software/amazon/lambda/durable/insight/ExportScheduler.java b/telemetry-exporter/src/main/java/software/amazon/lambda/durable/telemetry/ExportScheduler.java similarity index 76% rename from insight-plugin/src/main/java/software/amazon/lambda/durable/insight/ExportScheduler.java rename to telemetry-exporter/src/main/java/software/amazon/lambda/durable/telemetry/ExportScheduler.java index 84e8be3c20..90ab1a2eca 100644 --- a/insight-plugin/src/main/java/software/amazon/lambda/durable/insight/ExportScheduler.java +++ b/telemetry-exporter/src/main/java/software/amazon/lambda/durable/telemetry/ExportScheduler.java @@ -1,6 +1,6 @@ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 -package software.amazon.lambda.durable.insight; +package software.amazon.lambda.durable.telemetry; import java.util.ArrayList; import java.util.Iterator; @@ -17,14 +17,14 @@ /** * Serializes record exports so that, at most, one export runs at a time. * - *

Each {@link WorkflowInsightRecord} is a complete snapshot of its execution, so a newer record for the - * same execution fully supersedes any record of that execution still waiting to be exported. While an export is in - * flight, additional updates are coalesced into a single pending slot per execution — intermediate records are dropped - * because the latest one already contains all of their information. Records of different executions never displace each - * other: one execution's snapshot carries none of another's information, so each execution keeps its own slot and the - * slots are served in the order the executions first became pending. This prevents overlapping {@code export()} calls - * when updates arrive faster than the exporters can keep up, and it keeps exporter I/O off the SDK threads that deliver - * plugin hooks. + *

Each {@link DurableExecutionTelemetryRecord} is a complete snapshot of its execution, so a newer record + * for the same execution fully supersedes any record of that execution still waiting to be exported. While an export is + * in flight, additional updates are coalesced into a single pending slot per execution — intermediate records are + * dropped because the latest one already contains all of their information. Records of different executions never + * displace each other: one execution's snapshot carries none of another's information, so each execution keeps its own + * slot and the slots are served in the order the executions first became pending. This prevents overlapping + * {@code export()} calls when updates arrive faster than the exporters can keep up, and it keeps exporter I/O off the + * SDK threads that deliver plugin hooks. * *

Exports are otherwise fire-and-forget; {@link #drain()} is called before the invocation returns to guarantee the * final record is delivered. @@ -35,13 +35,13 @@ final class ExportScheduler { /** Shared for the process lifetime; idle daemon workers are reclaimed, so nothing keeps the runtime alive. */ private static final ExecutorService WORKERS = Executors.newCachedThreadPool(runnable -> { - var thread = new Thread(runnable, "workflow-insight-export-" + THREAD_NUMBER.incrementAndGet()); + var thread = new Thread(runnable, "durable-execution-telemetry-export-" + THREAD_NUMBER.incrementAndGet()); thread.setDaemon(true); return thread; }); - private final List exporters; - private final BiConsumer exportOne; + private final List exporters; + private final BiConsumer exportOne; private final Consumer failureHandler; private final Executor executor; @@ -52,18 +52,18 @@ final class ExportScheduler { * The latest record of each execution not yet picked up by the pump, keyed by execution ARN and served in the order * the executions first became pending. Guarded by {@code this}. */ - private final LinkedHashMap pending = new LinkedHashMap<>(); + private final LinkedHashMap pending = new LinkedHashMap<>(); ExportScheduler( - List exporters, - BiConsumer exportOne, + List exporters, + BiConsumer exportOne, Consumer failureHandler) { this(exporters, exportOne, failureHandler, WORKERS); } ExportScheduler( - List exporters, - BiConsumer exportOne, + List exporters, + BiConsumer exportOne, Consumer failureHandler, Executor executor) { this.exporters = List.copyOf(exporters); @@ -77,7 +77,7 @@ final class ExportScheduler { * execution's pending slot (replacing any earlier pending record of the same execution) and exported once the * in-flight export completes. */ - void schedule(WorkflowInsightRecord record) { + void schedule(DurableExecutionTelemetryRecord record) { CompletableFuture handle; synchronized (this) { // put() on an existing key keeps its position, so a chatty execution cannot jump ahead of a quieter one. @@ -138,9 +138,10 @@ private void pump(CompletableFuture handle) { // under the lock, so an update scheduled at any point is either exported by this pump or starts the next // one — never lost. while (true) { - WorkflowInsightRecord record; + DurableExecutionTelemetryRecord record; synchronized (this) { - Iterator head = pending.values().iterator(); + Iterator head = + pending.values().iterator(); if (!head.hasNext()) { inFlight = null; return; @@ -160,7 +161,7 @@ record = head.next(); } } - private static String executionKey(WorkflowInsightRecord record) { + private static String executionKey(DurableExecutionTelemetryRecord record) { return record.executionArn() != null ? record.executionArn() : ""; } @@ -169,25 +170,25 @@ private static String executionKey(WorkflowInsightRecord record) { * one exporter never delays or fails the others. */ void flushAll() { - forEachExporterSettled(InsightExporter::flush); + forEachExporterSettled(TelemetryExporter::flush); } /** * Exports one record to every exporter, each on its own worker, and waits for all of them to settle. One failing or * slow exporter never blocks or fails the others, and an export error never propagates into the execution. */ - private void exportToAll(WorkflowInsightRecord record) { + private void exportToAll(DurableExecutionTelemetryRecord record) { forEachExporterSettled(exporter -> exportOne.accept(record, exporter)); } /** Runs the action for every exporter concurrently and returns once all have settled, reporting each failure. */ - private void forEachExporterSettled(Consumer action) { + private void forEachExporterSettled(Consumer action) { if (exporters.size() == 1) { runSafely(() -> action.accept(exporters.get(0))); return; } List> settled = new ArrayList<>(exporters.size()); - for (InsightExporter exporter : exporters) { + for (TelemetryExporter exporter : exporters) { Runnable task = () -> runSafely(() -> action.accept(exporter)); try { settled.add(CompletableFuture.runAsync(task, executor)); diff --git a/insight-plugin/src/main/java/software/amazon/lambda/durable/insight/Json.java b/telemetry-exporter/src/main/java/software/amazon/lambda/durable/telemetry/Json.java similarity index 94% rename from insight-plugin/src/main/java/software/amazon/lambda/durable/insight/Json.java rename to telemetry-exporter/src/main/java/software/amazon/lambda/durable/telemetry/Json.java index dc72a7092a..8a507d4bfc 100644 --- a/insight-plugin/src/main/java/software/amazon/lambda/durable/insight/Json.java +++ b/telemetry-exporter/src/main/java/software/amazon/lambda/durable/telemetry/Json.java @@ -1,6 +1,6 @@ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 -package software.amazon.lambda.durable.insight; +package software.amazon.lambda.durable.telemetry; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.util.DefaultIndenter; @@ -16,7 +16,7 @@ import java.util.Map; import software.amazon.lambda.durable.annotations.Experimental; -/** Minimal JSON helper for emitting insight records and measuring their serialized size. */ +/** Minimal JSON helper for emitting telemetry records and measuring their serialized size. */ @Experimental public final class Json { // Register JavaTimeModule and emit ISO-8601 (not numeric timestamps) so SDK-default payload types such as @@ -40,7 +40,7 @@ public static String stringify(Object value) { try { return MAPPER.writeValueAsString(value); } catch (JsonProcessingException e) { - throw new IllegalStateException("failed to serialize insight record", e); + throw new IllegalStateException("failed to serialize telemetry record", e); } } @@ -51,7 +51,7 @@ public static String prettyStringify(Object value) { try { return MAPPER.writer(PRETTY_PRINTER).writeValueAsString(value); } catch (JsonProcessingException e) { - throw new IllegalStateException("failed to serialize insight record", e); + throw new IllegalStateException("failed to serialize telemetry record", e); } } @@ -107,7 +107,7 @@ static Object deepCopyContent(Object value) { try { return MAPPER.convertValue(value, Object.class); } catch (IllegalArgumentException e) { - throw new IllegalStateException("failed to copy insight record content", e); + throw new IllegalStateException("failed to copy telemetry record content", e); } } } diff --git a/insight-plugin/src/main/java/software/amazon/lambda/durable/insight/OperationOverride.java b/telemetry-exporter/src/main/java/software/amazon/lambda/durable/telemetry/OperationOverride.java similarity index 97% rename from insight-plugin/src/main/java/software/amazon/lambda/durable/insight/OperationOverride.java rename to telemetry-exporter/src/main/java/software/amazon/lambda/durable/telemetry/OperationOverride.java index db5afbc2d1..f42be02b99 100644 --- a/insight-plugin/src/main/java/software/amazon/lambda/durable/insight/OperationOverride.java +++ b/telemetry-exporter/src/main/java/software/amazon/lambda/durable/telemetry/OperationOverride.java @@ -1,6 +1,6 @@ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 -package software.amazon.lambda.durable.insight; +package software.amazon.lambda.durable.telemetry; import java.util.function.Function; import software.amazon.lambda.durable.annotations.Experimental; diff --git a/insight-plugin/src/main/java/software/amazon/lambda/durable/insight/OperationRecord.java b/telemetry-exporter/src/main/java/software/amazon/lambda/durable/telemetry/OperationRecord.java similarity index 99% rename from insight-plugin/src/main/java/software/amazon/lambda/durable/insight/OperationRecord.java rename to telemetry-exporter/src/main/java/software/amazon/lambda/durable/telemetry/OperationRecord.java index 6956d42efc..efde64308d 100644 --- a/insight-plugin/src/main/java/software/amazon/lambda/durable/insight/OperationRecord.java +++ b/telemetry-exporter/src/main/java/software/amazon/lambda/durable/telemetry/OperationRecord.java @@ -1,6 +1,6 @@ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 -package software.amazon.lambda.durable.insight; +package software.amazon.lambda.durable.telemetry; import java.util.LinkedHashMap; import java.util.Map; diff --git a/insight-plugin/src/main/java/software/amazon/lambda/durable/insight/OperationSummary.java b/telemetry-exporter/src/main/java/software/amazon/lambda/durable/telemetry/OperationSummary.java similarity index 97% rename from insight-plugin/src/main/java/software/amazon/lambda/durable/insight/OperationSummary.java rename to telemetry-exporter/src/main/java/software/amazon/lambda/durable/telemetry/OperationSummary.java index 59f8046b8c..130c043a14 100644 --- a/insight-plugin/src/main/java/software/amazon/lambda/durable/insight/OperationSummary.java +++ b/telemetry-exporter/src/main/java/software/amazon/lambda/durable/telemetry/OperationSummary.java @@ -1,6 +1,6 @@ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 -package software.amazon.lambda.durable.insight; +package software.amazon.lambda.durable.telemetry; import java.util.LinkedHashMap; import java.util.Map; diff --git a/insight-plugin/src/main/java/software/amazon/lambda/durable/insight/OperationsIndex.java b/telemetry-exporter/src/main/java/software/amazon/lambda/durable/telemetry/OperationsIndex.java similarity index 98% rename from insight-plugin/src/main/java/software/amazon/lambda/durable/insight/OperationsIndex.java rename to telemetry-exporter/src/main/java/software/amazon/lambda/durable/telemetry/OperationsIndex.java index f7a3663617..98398e36a9 100644 --- a/insight-plugin/src/main/java/software/amazon/lambda/durable/insight/OperationsIndex.java +++ b/telemetry-exporter/src/main/java/software/amazon/lambda/durable/telemetry/OperationsIndex.java @@ -1,6 +1,6 @@ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 -package software.amazon.lambda.durable.insight; +package software.amazon.lambda.durable.telemetry; import java.util.LinkedHashMap; import java.util.List; diff --git a/insight-plugin/src/main/java/software/amazon/lambda/durable/insight/InsightExporter.java b/telemetry-exporter/src/main/java/software/amazon/lambda/durable/telemetry/TelemetryExporter.java similarity index 70% rename from insight-plugin/src/main/java/software/amazon/lambda/durable/insight/InsightExporter.java rename to telemetry-exporter/src/main/java/software/amazon/lambda/durable/telemetry/TelemetryExporter.java index 69ff39739f..e55863a16c 100644 --- a/insight-plugin/src/main/java/software/amazon/lambda/durable/insight/InsightExporter.java +++ b/telemetry-exporter/src/main/java/software/amazon/lambda/durable/telemetry/TelemetryExporter.java @@ -1,22 +1,22 @@ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 -package software.amazon.lambda.durable.insight; +package software.amazon.lambda.durable.telemetry; import software.amazon.lambda.durable.annotations.Experimental; -/** Exports workflow insight records to a destination. */ +/** Exports workflow telemetry records to a destination. */ @Experimental -public interface InsightExporter { +public interface TelemetryExporter { /** Emits one record to the destination. */ - void export(WorkflowInsightRecord record); + void export(DurableExecutionTelemetryRecord record); /** Flushes any buffered records; no-op by default. */ default void flush() {} /** * Maximum serialized record size, in bytes, this exporter will emit; {@code null} disables truncation. Measured - * against {@link #render(WorkflowInsightRecord)}. + * against {@link #render(DurableExecutionTelemetryRecord)}. */ default Integer maxRecordSizeBytes() { return null; @@ -26,7 +26,7 @@ default Integer maxRecordSizeBytes() { * Maps a record to the exact value this exporter serializes/sends (defaults to the canonical {@code operations} * array wire map). Overriding exporters (CloudWatch/Lambda log) return the {@code operationsByName} rendering. */ - default Object render(WorkflowInsightRecord record) { + default Object render(DurableExecutionTelemetryRecord record) { return record.toWireMap(); } } diff --git a/insight-plugin/src/main/java/software/amazon/lambda/durable/insight/Truncation.java b/telemetry-exporter/src/main/java/software/amazon/lambda/durable/telemetry/Truncation.java similarity index 90% rename from insight-plugin/src/main/java/software/amazon/lambda/durable/insight/Truncation.java rename to telemetry-exporter/src/main/java/software/amazon/lambda/durable/telemetry/Truncation.java index 214151a40c..52bb446516 100644 --- a/insight-plugin/src/main/java/software/amazon/lambda/durable/insight/Truncation.java +++ b/telemetry-exporter/src/main/java/software/amazon/lambda/durable/telemetry/Truncation.java @@ -1,6 +1,6 @@ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 -package software.amazon.lambda.durable.insight; +package software.amazon.lambda.durable.telemetry; import java.util.ArrayList; import java.util.Comparator; @@ -28,8 +28,10 @@ public final class Truncation { private Truncation() {} - public static WorkflowInsightRecord truncateRecord( - WorkflowInsightRecord record, Integer maxBytes, Function render) { + public static DurableExecutionTelemetryRecord truncateRecord( + DurableExecutionTelemetryRecord record, + Integer maxBytes, + Function render) { if (maxBytes == null || maxBytes <= 0) { return record; } @@ -90,27 +92,27 @@ public static WorkflowInsightRecord truncateRecord( } private static boolean fits( - WorkflowInsightRecord record, + DurableExecutionTelemetryRecord record, List ops, boolean[] kept, int droppedOperations, boolean droppedInput, boolean droppedOutput, - Function render, + Function render, int maxBytes) { Integer size = Json.byteSize( render.apply(candidate(record, ops, kept, droppedOperations, droppedInput, droppedOutput))); return size != null && size <= maxBytes; } - private static WorkflowInsightRecord candidate( - WorkflowInsightRecord record, + private static DurableExecutionTelemetryRecord candidate( + DurableExecutionTelemetryRecord record, List ops, boolean[] kept, int droppedOperations, boolean droppedInput, boolean droppedOutput) { - WorkflowInsightRecord out = record.copy(); + DurableExecutionTelemetryRecord out = record.copy(); List retained = new ArrayList<>(); for (int i = 0; i < ops.size(); i++) { if (kept[i]) { diff --git a/insight-plugin/src/main/java/software/amazon/lambda/durable/insight/exporters/AuroraExporter.java b/telemetry-exporter/src/main/java/software/amazon/lambda/durable/telemetry/exporters/AuroraExporter.java similarity index 92% rename from insight-plugin/src/main/java/software/amazon/lambda/durable/insight/exporters/AuroraExporter.java rename to telemetry-exporter/src/main/java/software/amazon/lambda/durable/telemetry/exporters/AuroraExporter.java index a84008a56e..ae78d75bbf 100644 --- a/insight-plugin/src/main/java/software/amazon/lambda/durable/insight/exporters/AuroraExporter.java +++ b/telemetry-exporter/src/main/java/software/amazon/lambda/durable/telemetry/exporters/AuroraExporter.java @@ -1,6 +1,6 @@ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 -package software.amazon.lambda.durable.insight.exporters; +package software.amazon.lambda.durable.telemetry.exporters; import static java.util.Objects.requireNonNull; @@ -11,17 +11,17 @@ import software.amazon.awssdk.services.rdsdata.model.Field; import software.amazon.awssdk.services.rdsdata.model.SqlParameter; import software.amazon.lambda.durable.annotations.Experimental; -import software.amazon.lambda.durable.insight.InsightExporter; -import software.amazon.lambda.durable.insight.Json; -import software.amazon.lambda.durable.insight.WorkflowInsightRecord; +import software.amazon.lambda.durable.telemetry.DurableExecutionTelemetryRecord; +import software.amazon.lambda.durable.telemetry.Json; +import software.amazon.lambda.durable.telemetry.TelemetryExporter; /** - * Exports workflow insight records to Amazon Aurora (PostgreSQL or MySQL) through the RDS Data API, upserting one row + * Exports workflow telemetry records to Amazon Aurora (PostgreSQL or MySQL) through the RDS Data API, upserting one row * per execution keyed by execution ARN. Requires the Data API enabled on the cluster, {@code rds-data:ExecuteStatement} * and {@code secretsmanager:GetSecretValue}. */ @Experimental -public final class AuroraExporter implements InsightExporter { +public final class AuroraExporter implements TelemetryExporter { /** Database engine; selects the upsert dialect. */ @Experimental @@ -63,7 +63,7 @@ private AuroraExporter(Builder b) { this.resourceArn = requireNonNull(b.resourceArn, "resourceArn"); this.secretArn = requireNonNull(b.secretArn, "secretArn"); this.database = requireNonNull(b.database, "database"); - this.table = SqlIdentifiers.validate(b.table != null ? b.table : "workflow_insight"); + this.table = SqlIdentifiers.validate(b.table != null ? b.table : "durable_execution_telemetry"); this.engine = requireNonNull(b.engine, "engine"); this.maxRecordSizeBytes = b.maxRecordSizeBytes != null ? b.maxRecordSizeBytes : 1_000_000; this.client = LazyClient.forSdkClient( @@ -80,7 +80,7 @@ public Integer maxRecordSizeBytes() { } @Override - public void export(WorkflowInsightRecord record) { + public void export(DurableExecutionTelemetryRecord record) { RdsDataClient rdsData = client.get(); Map wire = record.toWireMap(); String sql = engine == Engine.POSTGRESQL ? buildPostgresUpsert() : buildMysqlUpsert(); @@ -169,7 +169,7 @@ public Builder database(String database) { return this; } - /** Table name; letters, digits, and underscores only. Default {@code workflow_insight}. */ + /** Table name; letters, digits, and underscores only. Default {@code durable_execution_telemetry}. */ public Builder table(String table) { this.table = table; return this; diff --git a/insight-plugin/src/main/java/software/amazon/lambda/durable/insight/exporters/CloudWatchLogsExporter.java b/telemetry-exporter/src/main/java/software/amazon/lambda/durable/telemetry/exporters/CloudWatchLogsExporter.java similarity index 88% rename from insight-plugin/src/main/java/software/amazon/lambda/durable/insight/exporters/CloudWatchLogsExporter.java rename to telemetry-exporter/src/main/java/software/amazon/lambda/durable/telemetry/exporters/CloudWatchLogsExporter.java index 75ef232b4d..0119f677dc 100644 --- a/insight-plugin/src/main/java/software/amazon/lambda/durable/insight/exporters/CloudWatchLogsExporter.java +++ b/telemetry-exporter/src/main/java/software/amazon/lambda/durable/telemetry/exporters/CloudWatchLogsExporter.java @@ -1,6 +1,6 @@ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 -package software.amazon.lambda.durable.insight.exporters; +package software.amazon.lambda.durable.telemetry.exporters; import java.time.Instant; import java.util.List; @@ -12,17 +12,17 @@ import software.amazon.awssdk.services.cloudwatchlogs.model.InputLogEvent; import software.amazon.awssdk.services.cloudwatchlogs.model.PutLogEventsRequest; import software.amazon.lambda.durable.annotations.Experimental; -import software.amazon.lambda.durable.insight.InsightExporter; -import software.amazon.lambda.durable.insight.Json; -import software.amazon.lambda.durable.insight.WorkflowInsightRecord; +import software.amazon.lambda.durable.telemetry.DurableExecutionTelemetryRecord; +import software.amazon.lambda.durable.telemetry.Json; +import software.amazon.lambda.durable.telemetry.TelemetryExporter; /** - * Exports workflow insight records to a specific CloudWatch Logs group via PutLogEvents, emitting the + * Exports workflow telemetry records to a specific CloudWatch Logs group via PutLogEvents, emitting the * {@code operationsByName} map. Mirrors the JS {@code CloudWatchLogsExporter}. Requires {@code logs:CreateLogStream} * and {@code logs:PutLogEvents} on the target log group. */ @Experimental -public final class CloudWatchLogsExporter implements InsightExporter { +public final class CloudWatchLogsExporter implements TelemetryExporter { private final String logGroupName; private final String logStreamPrefix; private final Integer maxRecordSizeBytes; @@ -34,7 +34,7 @@ public final class CloudWatchLogsExporter implements InsightExporter { private CloudWatchLogsExporter(Builder b) { this.logGroupName = b.logGroupName; - this.logStreamPrefix = b.logStreamPrefix != null ? b.logStreamPrefix : "workflow-insight/"; + this.logStreamPrefix = b.logStreamPrefix != null ? b.logStreamPrefix : "durable-execution-telemetry/"; this.maxRecordSizeBytes = b.maxRecordSizeBytes != null ? b.maxRecordSizeBytes : 256_000; this.client = LazyClient.forSdkClient( b.client, @@ -53,12 +53,12 @@ public Integer maxRecordSizeBytes() { } @Override - public Object render(WorkflowInsightRecord record) { + public Object render(DurableExecutionTelemetryRecord record) { return record.toByNameWireMap(); } @Override - public void export(WorkflowInsightRecord record) { + public void export(DurableExecutionTelemetryRecord record) { CloudWatchLogsClient logs = client.get(); String streamName = buildStreamName(); ensureStream(logs, streamName); diff --git a/insight-plugin/src/main/java/software/amazon/lambda/durable/insight/exporters/DynamoDBExporter.java b/telemetry-exporter/src/main/java/software/amazon/lambda/durable/telemetry/exporters/DynamoDBExporter.java similarity index 85% rename from insight-plugin/src/main/java/software/amazon/lambda/durable/insight/exporters/DynamoDBExporter.java rename to telemetry-exporter/src/main/java/software/amazon/lambda/durable/telemetry/exporters/DynamoDBExporter.java index f84e0ee2f1..a1f5a970b6 100644 --- a/insight-plugin/src/main/java/software/amazon/lambda/durable/insight/exporters/DynamoDBExporter.java +++ b/telemetry-exporter/src/main/java/software/amazon/lambda/durable/telemetry/exporters/DynamoDBExporter.java @@ -1,6 +1,6 @@ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 -package software.amazon.lambda.durable.insight.exporters; +package software.amazon.lambda.durable.telemetry.exporters; import static java.util.Objects.requireNonNull; @@ -12,17 +12,17 @@ import software.amazon.awssdk.services.dynamodb.model.AttributeValue; import software.amazon.awssdk.services.dynamodb.model.PutItemRequest; import software.amazon.lambda.durable.annotations.Experimental; -import software.amazon.lambda.durable.insight.InsightExporter; -import software.amazon.lambda.durable.insight.Json; -import software.amazon.lambda.durable.insight.WorkflowInsightRecord; +import software.amazon.lambda.durable.telemetry.DurableExecutionTelemetryRecord; +import software.amazon.lambda.durable.telemetry.Json; +import software.amazon.lambda.durable.telemetry.TelemetryExporter; /** - * Exports workflow insight records to Amazon DynamoDB, one PutItem per record keyed by execution ARN. With the default - * sort key ({@code emittedAt}) every export adds a history item; with the sort key disabled each export overwrites the - * execution's item. Emits the {@code operationsByName} map. Requires {@code dynamodb:PutItem}. + * Exports workflow telemetry records to Amazon DynamoDB, one PutItem per record keyed by execution ARN. With the + * default sort key ({@code emittedAt}) every export adds a history item; with the sort key disabled each export + * overwrites the execution's item. Emits the {@code operationsByName} map. Requires {@code dynamodb:PutItem}. */ @Experimental -public final class DynamoDBExporter implements InsightExporter { +public final class DynamoDBExporter implements TelemetryExporter { private final String tableName; private final String partitionKey; private final String sortKey; @@ -49,12 +49,12 @@ public Integer maxRecordSizeBytes() { } @Override - public Object render(WorkflowInsightRecord record) { + public Object render(DurableExecutionTelemetryRecord record) { return record.toByNameWireMap(); } @Override - public void export(WorkflowInsightRecord record) { + public void export(DurableExecutionTelemetryRecord record) { Map item = record.toByNameWireMap(); item.put(partitionKey, record.executionArn()); if (sortKey != null) { diff --git a/insight-plugin/src/main/java/software/amazon/lambda/durable/insight/exporters/EventBridgeExporter.java b/telemetry-exporter/src/main/java/software/amazon/lambda/durable/telemetry/exporters/EventBridgeExporter.java similarity index 88% rename from insight-plugin/src/main/java/software/amazon/lambda/durable/insight/exporters/EventBridgeExporter.java rename to telemetry-exporter/src/main/java/software/amazon/lambda/durable/telemetry/exporters/EventBridgeExporter.java index e11f2877d9..452d016ea9 100644 --- a/insight-plugin/src/main/java/software/amazon/lambda/durable/insight/exporters/EventBridgeExporter.java +++ b/telemetry-exporter/src/main/java/software/amazon/lambda/durable/telemetry/exporters/EventBridgeExporter.java @@ -1,6 +1,6 @@ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 -package software.amazon.lambda.durable.insight.exporters; +package software.amazon.lambda.durable.telemetry.exporters; import java.time.Instant; import java.util.Map; @@ -10,20 +10,20 @@ import software.amazon.awssdk.services.eventbridge.model.PutEventsResponse; import software.amazon.awssdk.services.eventbridge.model.PutEventsResultEntry; import software.amazon.lambda.durable.annotations.Experimental; -import software.amazon.lambda.durable.insight.InsightExporter; -import software.amazon.lambda.durable.insight.Json; -import software.amazon.lambda.durable.insight.WorkflowInsightRecord; +import software.amazon.lambda.durable.telemetry.DurableExecutionTelemetryRecord; +import software.amazon.lambda.durable.telemetry.Json; +import software.amazon.lambda.durable.telemetry.TelemetryExporter; /** - * Exports workflow insight records to Amazon EventBridge, one PutEvents entry per record with the record status as + * Exports workflow telemetry records to Amazon EventBridge, one PutEvents entry per record with the record status as * {@code DetailType} and the record JSON as {@code Detail}. Requires {@code events:PutEvents}. */ @Experimental -public final class EventBridgeExporter implements InsightExporter { +public final class EventBridgeExporter implements TelemetryExporter { /** * Default event source. The {@code aws.} prefix is reserved for AWS service events and is rejected by PutEvents. */ - public static final String DEFAULT_SOURCE = "software.amazon.lambda.durable.insight"; + public static final String DEFAULT_SOURCE = "software.amazon.lambda.durable.telemetry"; private final String eventBusName; private final String source; @@ -50,12 +50,12 @@ public Integer maxRecordSizeBytes() { } @Override - public Object render(WorkflowInsightRecord record) { + public Object render(DurableExecutionTelemetryRecord record) { return operationsFormat.apply(record); } @Override - public void export(WorkflowInsightRecord record) { + public void export(DurableExecutionTelemetryRecord record) { EventBridgeClient eventBridge = client.get(); Map detail = operationsFormat.apply(record); PutEventsRequestEntry entry = PutEventsRequestEntry.builder() diff --git a/insight-plugin/src/main/java/software/amazon/lambda/durable/insight/exporters/FileExporter.java b/telemetry-exporter/src/main/java/software/amazon/lambda/durable/telemetry/exporters/FileExporter.java similarity index 88% rename from insight-plugin/src/main/java/software/amazon/lambda/durable/insight/exporters/FileExporter.java rename to telemetry-exporter/src/main/java/software/amazon/lambda/durable/telemetry/exporters/FileExporter.java index 6d14f6c061..81901227a0 100644 --- a/insight-plugin/src/main/java/software/amazon/lambda/durable/insight/exporters/FileExporter.java +++ b/telemetry-exporter/src/main/java/software/amazon/lambda/durable/telemetry/exporters/FileExporter.java @@ -1,6 +1,6 @@ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 -package software.amazon.lambda.durable.insight.exporters; +package software.amazon.lambda.durable.telemetry.exporters; import static java.util.Objects.requireNonNull; @@ -12,17 +12,17 @@ import java.nio.file.StandardOpenOption; import java.util.Map; import software.amazon.lambda.durable.annotations.Experimental; -import software.amazon.lambda.durable.insight.InsightExporter; -import software.amazon.lambda.durable.insight.Json; -import software.amazon.lambda.durable.insight.WorkflowInsightRecord; +import software.amazon.lambda.durable.telemetry.DurableExecutionTelemetryRecord; +import software.amazon.lambda.durable.telemetry.Json; +import software.amazon.lambda.durable.telemetry.TelemetryExporter; /** - * Exports workflow insight records to a directory: appended as one JSON line per record to a date-named NDJSON file + * Exports workflow telemetry records to a directory: appended as one JSON line per record to a date-named NDJSON file * (default), or written as one pretty-printed JSON file per execution that later exports overwrite. Suitable for an EFS * mount or {@code /tmp}. No truncation limit by default. */ @Experimental -public final class FileExporter implements InsightExporter { +public final class FileExporter implements TelemetryExporter { /** File layout. */ @Experimental @@ -78,12 +78,12 @@ public Integer maxRecordSizeBytes() { } @Override - public Object render(WorkflowInsightRecord record) { + public Object render(DurableExecutionTelemetryRecord record) { return operationsFormat.apply(record); } @Override - public void export(WorkflowInsightRecord record) { + public void export(DurableExecutionTelemetryRecord record) { Map formatted = operationsFormat.apply(record); try { ensureDirectory(); @@ -128,7 +128,7 @@ public static final class Builder { private OperationsFormat operationsFormat; private Integer maxRecordSizeBytes; - /** Base directory, for example {@code /mnt/efs/workflow-insight} or {@code /tmp/insight}. */ + /** Base directory, for example {@code /mnt/efs/durable-execution-telemetry} or {@code /tmp/telemetry}. */ public Builder directory(String directory) { this.directory = directory; return this; diff --git a/insight-plugin/src/main/java/software/amazon/lambda/durable/insight/exporters/FirehoseExporter.java b/telemetry-exporter/src/main/java/software/amazon/lambda/durable/telemetry/exporters/FirehoseExporter.java similarity index 81% rename from insight-plugin/src/main/java/software/amazon/lambda/durable/insight/exporters/FirehoseExporter.java rename to telemetry-exporter/src/main/java/software/amazon/lambda/durable/telemetry/exporters/FirehoseExporter.java index ecd7c8c94a..16f90f5f76 100644 --- a/insight-plugin/src/main/java/software/amazon/lambda/durable/insight/exporters/FirehoseExporter.java +++ b/telemetry-exporter/src/main/java/software/amazon/lambda/durable/telemetry/exporters/FirehoseExporter.java @@ -1,6 +1,6 @@ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 -package software.amazon.lambda.durable.insight.exporters; +package software.amazon.lambda.durable.telemetry.exporters; import static java.util.Objects.requireNonNull; @@ -9,16 +9,16 @@ import software.amazon.awssdk.services.firehose.model.PutRecordRequest; import software.amazon.awssdk.services.firehose.model.Record; import software.amazon.lambda.durable.annotations.Experimental; -import software.amazon.lambda.durable.insight.InsightExporter; -import software.amazon.lambda.durable.insight.Json; -import software.amazon.lambda.durable.insight.WorkflowInsightRecord; +import software.amazon.lambda.durable.telemetry.DurableExecutionTelemetryRecord; +import software.amazon.lambda.durable.telemetry.Json; +import software.amazon.lambda.durable.telemetry.TelemetryExporter; /** - * Exports workflow insight records to Amazon Data Firehose, one PutRecord per record as a newline-terminated JSON line - * so concatenated deliveries stay parseable as NDJSON. Requires {@code firehose:PutRecord}. + * Exports workflow telemetry records to Amazon Data Firehose, one PutRecord per record as a newline-terminated JSON + * line so concatenated deliveries stay parseable as NDJSON. Requires {@code firehose:PutRecord}. */ @Experimental -public final class FirehoseExporter implements InsightExporter { +public final class FirehoseExporter implements TelemetryExporter { private final String deliveryStreamName; private final OperationsFormat operationsFormat; private final Integer maxRecordSizeBytes; @@ -42,12 +42,12 @@ public Integer maxRecordSizeBytes() { } @Override - public Object render(WorkflowInsightRecord record) { + public Object render(DurableExecutionTelemetryRecord record) { return operationsFormat.apply(record); } @Override - public void export(WorkflowInsightRecord record) { + public void export(DurableExecutionTelemetryRecord record) { String data = Json.stringify(render(record)) + "\n"; client.get() .putRecord(PutRecordRequest.builder() diff --git a/insight-plugin/src/main/java/software/amazon/lambda/durable/insight/exporters/HttpExporter.java b/telemetry-exporter/src/main/java/software/amazon/lambda/durable/telemetry/exporters/HttpExporter.java similarity index 88% rename from insight-plugin/src/main/java/software/amazon/lambda/durable/insight/exporters/HttpExporter.java rename to telemetry-exporter/src/main/java/software/amazon/lambda/durable/telemetry/exporters/HttpExporter.java index a629313e68..6723f46df2 100644 --- a/insight-plugin/src/main/java/software/amazon/lambda/durable/insight/exporters/HttpExporter.java +++ b/telemetry-exporter/src/main/java/software/amazon/lambda/durable/telemetry/exporters/HttpExporter.java @@ -1,6 +1,6 @@ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 -package software.amazon.lambda.durable.insight.exporters; +package software.amazon.lambda.durable.telemetry.exporters; import static java.util.Objects.requireNonNull; @@ -13,16 +13,16 @@ import java.time.Duration; import java.util.Map; import software.amazon.lambda.durable.annotations.Experimental; -import software.amazon.lambda.durable.insight.InsightExporter; -import software.amazon.lambda.durable.insight.Json; -import software.amazon.lambda.durable.insight.WorkflowInsightRecord; +import software.amazon.lambda.durable.telemetry.DurableExecutionTelemetryRecord; +import software.amazon.lambda.durable.telemetry.Json; +import software.amazon.lambda.durable.telemetry.TelemetryExporter; /** - * Exports workflow insight records to an HTTP endpoint as a JSON body, one request per record. A non-2xx response fails - * the export. No truncation limit by default; set one if the endpoint caps request size. + * Exports workflow telemetry records to an HTTP endpoint as a JSON body, one request per record. A non-2xx response + * fails the export. No truncation limit by default; set one if the endpoint caps request size. */ @Experimental -public final class HttpExporter implements InsightExporter { +public final class HttpExporter implements TelemetryExporter { /** Request method. */ @Experimental @@ -71,12 +71,12 @@ public Integer maxRecordSizeBytes() { } @Override - public Object render(WorkflowInsightRecord record) { + public Object render(DurableExecutionTelemetryRecord record) { return operationsFormat.apply(record); } @Override - public void export(WorkflowInsightRecord record) { + public void export(DurableExecutionTelemetryRecord record) { String body = Json.stringify(render(record)); HttpRequest.Builder rb = HttpRequest.newBuilder(url) .method(method.name(), HttpRequest.BodyPublishers.ofString(body, StandardCharsets.UTF_8)) diff --git a/insight-plugin/src/main/java/software/amazon/lambda/durable/insight/exporters/LambdaLogExporter.java b/telemetry-exporter/src/main/java/software/amazon/lambda/durable/telemetry/exporters/LambdaLogExporter.java similarity index 64% rename from insight-plugin/src/main/java/software/amazon/lambda/durable/insight/exporters/LambdaLogExporter.java rename to telemetry-exporter/src/main/java/software/amazon/lambda/durable/telemetry/exporters/LambdaLogExporter.java index e5010f4c6b..b44e84a8ed 100644 --- a/insight-plugin/src/main/java/software/amazon/lambda/durable/insight/exporters/LambdaLogExporter.java +++ b/telemetry-exporter/src/main/java/software/amazon/lambda/durable/telemetry/exporters/LambdaLogExporter.java @@ -1,20 +1,20 @@ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 -package software.amazon.lambda.durable.insight.exporters; +package software.amazon.lambda.durable.telemetry.exporters; import software.amazon.lambda.durable.annotations.Experimental; -import software.amazon.lambda.durable.insight.InsightExporter; -import software.amazon.lambda.durable.insight.Json; -import software.amazon.lambda.durable.insight.WorkflowInsightRecord; +import software.amazon.lambda.durable.telemetry.DurableExecutionTelemetryRecord; +import software.amazon.lambda.durable.telemetry.Json; +import software.amazon.lambda.durable.telemetry.TelemetryExporter; /** - * Exports workflow insight records to CloudWatch Logs via {@code System.out.println} (Lambda captures stdout to the + * Exports workflow telemetry records to CloudWatch Logs via {@code System.out.println} (Lambda captures stdout to the * function's own log group, so this needs no extra IAM). Emits the {@code operationsByName} map as ONE single-line JSON * record, mirroring the JS {@code LambdaLogExporter} (which uses {@code console.log}). The conformance CloudWatch sink * decodes both raw top-level JSON lines and the Lambda structured-logging envelope. */ @Experimental -public final class LambdaLogExporter implements InsightExporter { +public final class LambdaLogExporter implements TelemetryExporter { /** CloudWatch Logs caps a single log event at 256 KB. */ private final Integer maxRecordSizeBytes; @@ -32,12 +32,12 @@ public Integer maxRecordSizeBytes() { } @Override - public Object render(WorkflowInsightRecord record) { + public Object render(DurableExecutionTelemetryRecord record) { return record.toByNameWireMap(); } @Override - public void export(WorkflowInsightRecord record) { + public void export(DurableExecutionTelemetryRecord record) { System.out.println(Json.stringify(render(record))); } } diff --git a/insight-plugin/src/main/java/software/amazon/lambda/durable/insight/exporters/LazyClient.java b/telemetry-exporter/src/main/java/software/amazon/lambda/durable/telemetry/exporters/LazyClient.java similarity index 98% rename from insight-plugin/src/main/java/software/amazon/lambda/durable/insight/exporters/LazyClient.java rename to telemetry-exporter/src/main/java/software/amazon/lambda/durable/telemetry/exporters/LazyClient.java index bfd427288c..1b64a7b846 100644 --- a/insight-plugin/src/main/java/software/amazon/lambda/durable/insight/exporters/LazyClient.java +++ b/telemetry-exporter/src/main/java/software/amazon/lambda/durable/telemetry/exporters/LazyClient.java @@ -1,6 +1,6 @@ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 -package software.amazon.lambda.durable.insight.exporters; +package software.amazon.lambda.durable.telemetry.exporters; import java.lang.reflect.InvocationTargetException; import java.util.function.Supplier; diff --git a/insight-plugin/src/main/java/software/amazon/lambda/durable/insight/exporters/OTelExporter.java b/telemetry-exporter/src/main/java/software/amazon/lambda/durable/telemetry/exporters/OTelExporter.java similarity index 91% rename from insight-plugin/src/main/java/software/amazon/lambda/durable/insight/exporters/OTelExporter.java rename to telemetry-exporter/src/main/java/software/amazon/lambda/durable/telemetry/exporters/OTelExporter.java index 6c01feb898..f8468a3944 100644 --- a/insight-plugin/src/main/java/software/amazon/lambda/durable/insight/exporters/OTelExporter.java +++ b/telemetry-exporter/src/main/java/software/amazon/lambda/durable/telemetry/exporters/OTelExporter.java @@ -1,6 +1,6 @@ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 -package software.amazon.lambda.durable.insight.exporters; +package software.amazon.lambda.durable.telemetry.exporters; import static java.util.Objects.requireNonNull; @@ -15,17 +15,17 @@ import java.util.List; import java.util.Map; import software.amazon.lambda.durable.annotations.Experimental; -import software.amazon.lambda.durable.insight.InsightExporter; -import software.amazon.lambda.durable.insight.Json; -import software.amazon.lambda.durable.insight.WorkflowInsightRecord; +import software.amazon.lambda.durable.telemetry.DurableExecutionTelemetryRecord; +import software.amazon.lambda.durable.telemetry.Json; +import software.amazon.lambda.durable.telemetry.TelemetryExporter; /** - * Exports workflow insight records as OpenTelemetry log records over OTLP/HTTP JSON. Each record becomes one log record - * with identity fields as resource and log attributes and the full record JSON as the body. Compatible with any + * Exports workflow telemetry records as OpenTelemetry log records over OTLP/HTTP JSON. Each record becomes one log + * record with identity fields as resource and log attributes and the full record JSON as the body. Compatible with any * OTLP-capable backend; authentication is via headers. */ @Experimental -public final class OTelExporter implements InsightExporter { +public final class OTelExporter implements TelemetryExporter { /** OTLP transport encoding. */ @Experimental @@ -56,7 +56,7 @@ public static Protocol fromValue(String value) { } } - private static final String SCOPE_NAME = "software.amazon.lambda.durable.insight"; + private static final String SCOPE_NAME = "software.amazon.lambda.durable.telemetry"; private final URI endpoint; private final Map headers; @@ -86,12 +86,12 @@ public Integer maxRecordSizeBytes() { /** The full OTLP request, so size limits cover the record content and the OTLP envelope together. */ @Override - public Object render(WorkflowInsightRecord record) { + public Object render(DurableExecutionTelemetryRecord record) { return buildPayload(record); } @Override - public void export(WorkflowInsightRecord record) { + public void export(DurableExecutionTelemetryRecord record) { String body = Json.stringify(buildPayload(record)); HttpRequest.Builder rb = HttpRequest.newBuilder(endpoint) .POST(HttpRequest.BodyPublishers.ofString(body, StandardCharsets.UTF_8)) @@ -112,7 +112,7 @@ public void export(WorkflowInsightRecord record) { } } - private Map buildPayload(WorkflowInsightRecord record) { + private Map buildPayload(DurableExecutionTelemetryRecord record) { Map wire = record.toWireMap(); String functionName = record.functionName(); Map resource = Map.of( diff --git a/insight-plugin/src/main/java/software/amazon/lambda/durable/insight/exporters/OpenSearchExporter.java b/telemetry-exporter/src/main/java/software/amazon/lambda/durable/telemetry/exporters/OpenSearchExporter.java similarity index 93% rename from insight-plugin/src/main/java/software/amazon/lambda/durable/insight/exporters/OpenSearchExporter.java rename to telemetry-exporter/src/main/java/software/amazon/lambda/durable/telemetry/exporters/OpenSearchExporter.java index 4c724cdc48..69e9771dc8 100644 --- a/insight-plugin/src/main/java/software/amazon/lambda/durable/insight/exporters/OpenSearchExporter.java +++ b/telemetry-exporter/src/main/java/software/amazon/lambda/durable/telemetry/exporters/OpenSearchExporter.java @@ -1,6 +1,6 @@ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 -package software.amazon.lambda.durable.insight.exporters; +package software.amazon.lambda.durable.telemetry.exporters; import static java.util.Objects.requireNonNull; @@ -23,17 +23,17 @@ import software.amazon.awssdk.http.auth.aws.signer.AwsV4HttpSigner; import software.amazon.awssdk.http.auth.spi.signer.SignedRequest; import software.amazon.lambda.durable.annotations.Experimental; -import software.amazon.lambda.durable.insight.InsightExporter; -import software.amazon.lambda.durable.insight.Json; -import software.amazon.lambda.durable.insight.WorkflowInsightRecord; +import software.amazon.lambda.durable.telemetry.DurableExecutionTelemetryRecord; +import software.amazon.lambda.durable.telemetry.Json; +import software.amazon.lambda.durable.telemetry.TelemetryExporter; /** - * Exports workflow insight records to Amazon OpenSearch Service with the index API, using the execution ARN as the + * Exports workflow telemetry records to Amazon OpenSearch Service with the index API, using the execution ARN as the * document id so later exports overwrite the same document. Authenticates with SigV4 (default) or HTTP basic auth. * Requires {@code es:ESHttpPut} on the index for SigV4. */ @Experimental -public final class OpenSearchExporter implements InsightExporter { +public final class OpenSearchExporter implements TelemetryExporter { /** Authentication method. */ @Experimental @@ -80,7 +80,7 @@ public static Auth fromValue(String value) { private OpenSearchExporter(Builder b) { this.endpoint = requireNonNull(b.endpoint, "endpoint").replaceAll("/$", ""); - this.indexName = b.indexName != null ? b.indexName : "workflow-insight"; + this.indexName = b.indexName != null ? b.indexName : "durable-execution-telemetry"; this.region = b.region; this.auth = b.auth != null ? b.auth : Auth.SIGV4; this.username = b.username; @@ -110,7 +110,7 @@ public Integer maxRecordSizeBytes() { } @Override - public void export(WorkflowInsightRecord record) { + public void export(DurableExecutionTelemetryRecord record) { URI url = URI.create(endpoint + "/" + indexName + "/_doc/" + encodeComponent(record.executionArn())); String body = Json.stringify(record.toWireMap()); HttpRequest.Builder rb = HttpRequest.newBuilder(url) @@ -204,7 +204,7 @@ public Builder endpoint(String endpoint) { return this; } - /** Index name. Default {@code workflow-insight}. */ + /** Index name. Default {@code durable-execution-telemetry}. */ public Builder indexName(String indexName) { this.indexName = indexName; return this; diff --git a/insight-plugin/src/main/java/software/amazon/lambda/durable/insight/exporters/OperationsFormat.java b/telemetry-exporter/src/main/java/software/amazon/lambda/durable/telemetry/exporters/OperationsFormat.java similarity index 88% rename from insight-plugin/src/main/java/software/amazon/lambda/durable/insight/exporters/OperationsFormat.java rename to telemetry-exporter/src/main/java/software/amazon/lambda/durable/telemetry/exporters/OperationsFormat.java index 56e63f4c8c..e75ed8f31c 100644 --- a/insight-plugin/src/main/java/software/amazon/lambda/durable/insight/exporters/OperationsFormat.java +++ b/telemetry-exporter/src/main/java/software/amazon/lambda/durable/telemetry/exporters/OperationsFormat.java @@ -1,10 +1,10 @@ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 -package software.amazon.lambda.durable.insight.exporters; +package software.amazon.lambda.durable.telemetry.exporters; import java.util.Map; import software.amazon.lambda.durable.annotations.Experimental; -import software.amazon.lambda.durable.insight.WorkflowInsightRecord; +import software.amazon.lambda.durable.telemetry.DurableExecutionTelemetryRecord; /** How an exporter renders operations in the emitted record. */ @Experimental @@ -39,7 +39,7 @@ public static OperationsFormat fromValue(String value) { } /** Renders the record's wire map in this format. */ - public Map apply(WorkflowInsightRecord record) { + public Map apply(DurableExecutionTelemetryRecord record) { switch (this) { case BY_NAME: return record.toByNameWireMap(); diff --git a/insight-plugin/src/main/java/software/amazon/lambda/durable/insight/exporters/RedshiftExporter.java b/telemetry-exporter/src/main/java/software/amazon/lambda/durable/telemetry/exporters/RedshiftExporter.java similarity index 94% rename from insight-plugin/src/main/java/software/amazon/lambda/durable/insight/exporters/RedshiftExporter.java rename to telemetry-exporter/src/main/java/software/amazon/lambda/durable/telemetry/exporters/RedshiftExporter.java index 3d3a921c73..99a8b6f1b2 100644 --- a/insight-plugin/src/main/java/software/amazon/lambda/durable/insight/exporters/RedshiftExporter.java +++ b/telemetry-exporter/src/main/java/software/amazon/lambda/durable/telemetry/exporters/RedshiftExporter.java @@ -1,6 +1,6 @@ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 -package software.amazon.lambda.durable.insight.exporters; +package software.amazon.lambda.durable.telemetry.exporters; import static java.util.Objects.requireNonNull; @@ -11,19 +11,19 @@ import software.amazon.awssdk.services.redshiftdata.model.ExecuteStatementRequest; import software.amazon.awssdk.services.redshiftdata.model.SqlParameter; import software.amazon.lambda.durable.annotations.Experimental; -import software.amazon.lambda.durable.insight.InsightExporter; -import software.amazon.lambda.durable.insight.Json; -import software.amazon.lambda.durable.insight.WorkflowInsightRecord; +import software.amazon.lambda.durable.telemetry.DurableExecutionTelemetryRecord; +import software.amazon.lambda.durable.telemetry.Json; +import software.amazon.lambda.durable.telemetry.TelemetryExporter; /** - * Exports workflow insight records to Amazon Redshift (provisioned or Serverless) through the Redshift Data API, + * Exports workflow telemetry records to Amazon Redshift (provisioned or Serverless) through the Redshift Data API, * upserting one row per execution with a MERGE keyed by execution ARN. The statement is submitted without waiting for * completion. Requires {@code redshift-data:ExecuteStatement} plus the credential action for the target * ({@code redshift-serverless:GetCredentials}, {@code redshift:GetClusterCredentialsWithIAM}, or * {@code secretsmanager:GetSecretValue}). */ @Experimental -public final class RedshiftExporter implements InsightExporter { +public final class RedshiftExporter implements TelemetryExporter { private final String database; private final String fqTable; private final String workgroupName; @@ -44,7 +44,7 @@ private RedshiftExporter(Builder b) { throw new IllegalArgumentException("RedshiftExporter: dbUser and secretArn are exclusive."); } this.database = requireNonNull(b.database, "database"); - String table = SqlIdentifiers.validate(b.table != null ? b.table : "workflow_insight"); + String table = SqlIdentifiers.validate(b.table != null ? b.table : "durable_execution_telemetry"); String schema = SqlIdentifiers.validate(b.schema != null ? b.schema : "public"); this.fqTable = schema + "." + table; this.workgroupName = b.workgroupName; @@ -66,7 +66,7 @@ public Integer maxRecordSizeBytes() { } @Override - public void export(WorkflowInsightRecord record) { + public void export(DurableExecutionTelemetryRecord record) { RedshiftDataClient redshift = client.get(); Map wire = record.toWireMap(); List parameters = new ArrayList<>(); @@ -190,7 +190,7 @@ public Builder secretArn(String secretArn) { return this; } - /** Table name; letters, digits, and underscores only. Default {@code workflow_insight}. */ + /** Table name; letters, digits, and underscores only. Default {@code durable_execution_telemetry}. */ public Builder table(String table) { this.table = table; return this; diff --git a/insight-plugin/src/main/java/software/amazon/lambda/durable/insight/exporters/S3Exporter.java b/telemetry-exporter/src/main/java/software/amazon/lambda/durable/telemetry/exporters/S3Exporter.java similarity index 84% rename from insight-plugin/src/main/java/software/amazon/lambda/durable/insight/exporters/S3Exporter.java rename to telemetry-exporter/src/main/java/software/amazon/lambda/durable/telemetry/exporters/S3Exporter.java index 47bda0eb3f..3db659e6f9 100644 --- a/insight-plugin/src/main/java/software/amazon/lambda/durable/insight/exporters/S3Exporter.java +++ b/telemetry-exporter/src/main/java/software/amazon/lambda/durable/telemetry/exporters/S3Exporter.java @@ -1,22 +1,22 @@ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 -package software.amazon.lambda.durable.insight.exporters; +package software.amazon.lambda.durable.telemetry.exporters; import software.amazon.awssdk.core.sync.RequestBody; import software.amazon.awssdk.services.s3.S3Client; import software.amazon.awssdk.services.s3.model.PutObjectRequest; import software.amazon.lambda.durable.annotations.Experimental; -import software.amazon.lambda.durable.insight.InsightExporter; -import software.amazon.lambda.durable.insight.Json; -import software.amazon.lambda.durable.insight.WorkflowInsightRecord; +import software.amazon.lambda.durable.telemetry.DurableExecutionTelemetryRecord; +import software.amazon.lambda.durable.telemetry.Json; +import software.amazon.lambda.durable.telemetry.TelemetryExporter; /** - * Exports workflow insight records to Amazon S3, one JSON object per execution (keyed by execution name so updates + * Exports workflow telemetry records to Amazon S3, one JSON object per execution (keyed by execution name so updates * overwrite the same object). Emits the canonical {@code operations}-array wire shape. Mirrors the JS * {@code S3Exporter}. */ @Experimental -public final class S3Exporter implements InsightExporter { +public final class S3Exporter implements TelemetryExporter { /** How to partition objects in S3. */ @Experimental @@ -34,7 +34,7 @@ public enum Partitioning { private S3Exporter(Builder b) { this.bucket = b.bucket; - this.prefix = b.prefix != null ? b.prefix : "workflow-insight/"; + this.prefix = b.prefix != null ? b.prefix : "durable-execution-telemetry/"; this.partitioning = b.partitioning != null ? b.partitioning : Partitioning.DATE; this.maxRecordSizeBytes = b.maxRecordSizeBytes != null ? b.maxRecordSizeBytes : 5_000_000; this.client = LazyClient.forSdkClient(b.client, "s3", "software.amazon.awssdk.services.s3.S3Client", b.region); @@ -50,7 +50,7 @@ public Integer maxRecordSizeBytes() { } @Override - public void export(WorkflowInsightRecord record) { + public void export(DurableExecutionTelemetryRecord record) { String key = buildKey(record); String body = Json.stringify(record.toWireMap()); client.get() @@ -63,13 +63,13 @@ public void export(WorkflowInsightRecord record) { RequestBody.fromString(body)); } - private String buildKey(WorkflowInsightRecord record) { + private String buildKey(DurableExecutionTelemetryRecord record) { String fileName = sanitize(record.executionName() != null ? record.executionName() : record.executionArn()) + ".json"; return prefix + buildPartition(record) + fileName; } - private String buildPartition(WorkflowInsightRecord record) { + private String buildPartition(DurableExecutionTelemetryRecord record) { switch (partitioning) { case DATE: java.time.ZonedDateTime d = diff --git a/insight-plugin/src/main/java/software/amazon/lambda/durable/insight/exporters/SQSExporter.java b/telemetry-exporter/src/main/java/software/amazon/lambda/durable/telemetry/exporters/SQSExporter.java similarity index 89% rename from insight-plugin/src/main/java/software/amazon/lambda/durable/insight/exporters/SQSExporter.java rename to telemetry-exporter/src/main/java/software/amazon/lambda/durable/telemetry/exporters/SQSExporter.java index e7f9ff5cc0..4e727d9d45 100644 --- a/insight-plugin/src/main/java/software/amazon/lambda/durable/insight/exporters/SQSExporter.java +++ b/telemetry-exporter/src/main/java/software/amazon/lambda/durable/telemetry/exporters/SQSExporter.java @@ -1,6 +1,6 @@ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 -package software.amazon.lambda.durable.insight.exporters; +package software.amazon.lambda.durable.telemetry.exporters; import static java.util.Objects.requireNonNull; @@ -14,17 +14,17 @@ import software.amazon.awssdk.services.sqs.model.MessageAttributeValue; import software.amazon.awssdk.services.sqs.model.SendMessageRequest; import software.amazon.lambda.durable.annotations.Experimental; -import software.amazon.lambda.durable.insight.InsightExporter; -import software.amazon.lambda.durable.insight.Json; -import software.amazon.lambda.durable.insight.WorkflowInsightRecord; +import software.amazon.lambda.durable.telemetry.DurableExecutionTelemetryRecord; +import software.amazon.lambda.durable.telemetry.Json; +import software.amazon.lambda.durable.telemetry.TelemetryExporter; /** - * Exports workflow insight records to Amazon SQS, one SendMessage per record with the record JSON as the body and + * Exports workflow telemetry records to Amazon SQS, one SendMessage per record with the record JSON as the body and * {@code status} / {@code functionName} message attributes. On a FIFO queue the group id defaults to the execution ARN * and the deduplication id is the execution ARN plus {@code emittedAt}. Requires {@code sqs:SendMessage}. */ @Experimental -public final class SQSExporter implements InsightExporter { +public final class SQSExporter implements TelemetryExporter { private final String queueUrl; private final String messageGroupId; private final boolean fifo; @@ -52,12 +52,12 @@ public Integer maxRecordSizeBytes() { } @Override - public Object render(WorkflowInsightRecord record) { + public Object render(DurableExecutionTelemetryRecord record) { return operationsFormat.apply(record); } @Override - public void export(WorkflowInsightRecord record) { + public void export(DurableExecutionTelemetryRecord record) { SqsClient sqs = client.get(); Map body = operationsFormat.apply(record); Map attributes = new LinkedHashMap<>(); diff --git a/insight-plugin/src/main/java/software/amazon/lambda/durable/insight/exporters/SqlIdentifiers.java b/telemetry-exporter/src/main/java/software/amazon/lambda/durable/telemetry/exporters/SqlIdentifiers.java similarity index 93% rename from insight-plugin/src/main/java/software/amazon/lambda/durable/insight/exporters/SqlIdentifiers.java rename to telemetry-exporter/src/main/java/software/amazon/lambda/durable/telemetry/exporters/SqlIdentifiers.java index 515137c2af..fdf8c74db1 100644 --- a/insight-plugin/src/main/java/software/amazon/lambda/durable/insight/exporters/SqlIdentifiers.java +++ b/telemetry-exporter/src/main/java/software/amazon/lambda/durable/telemetry/exporters/SqlIdentifiers.java @@ -1,6 +1,6 @@ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 -package software.amazon.lambda.durable.insight.exporters; +package software.amazon.lambda.durable.telemetry.exporters; import java.util.regex.Pattern; diff --git a/insight-plugin/src/test/java/software/amazon/lambda/durable/insight/ArnParserTest.java b/telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry/ArnParserTest.java similarity index 93% rename from insight-plugin/src/test/java/software/amazon/lambda/durable/insight/ArnParserTest.java rename to telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry/ArnParserTest.java index 7bcebca9fa..b9e68c646b 100644 --- a/insight-plugin/src/test/java/software/amazon/lambda/durable/insight/ArnParserTest.java +++ b/telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry/ArnParserTest.java @@ -1,6 +1,6 @@ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 -package software.amazon.lambda.durable.insight; +package software.amazon.lambda.durable.telemetry; import static org.junit.jupiter.api.Assertions.assertEquals; diff --git a/insight-plugin/src/test/java/software/amazon/lambda/durable/insight/AuroraExporterTest.java b/telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry/AuroraExporterTest.java similarity index 86% rename from insight-plugin/src/test/java/software/amazon/lambda/durable/insight/AuroraExporterTest.java rename to telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry/AuroraExporterTest.java index 3e25684396..2217a7031b 100644 --- a/insight-plugin/src/test/java/software/amazon/lambda/durable/insight/AuroraExporterTest.java +++ b/telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry/AuroraExporterTest.java @@ -1,6 +1,6 @@ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 -package software.amazon.lambda.durable.insight; +package software.amazon.lambda.durable.telemetry; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; @@ -20,14 +20,14 @@ import software.amazon.awssdk.services.rdsdata.model.ExecuteStatementResponse; import software.amazon.awssdk.services.rdsdata.model.Field; import software.amazon.awssdk.services.rdsdata.model.SqlParameter; -import software.amazon.lambda.durable.insight.exporters.AuroraExporter; +import software.amazon.lambda.durable.telemetry.exporters.AuroraExporter; class AuroraExporterTest { private static final String ARN = "arn:aws:lambda:us-east-1:123456789012:function:fn:$LATEST"; - private WorkflowInsightRecord sampleRecord() { - WorkflowInsightRecord r = new WorkflowInsightRecord(); + private DurableExecutionTelemetryRecord sampleRecord() { + DurableExecutionTelemetryRecord r = new DurableExecutionTelemetryRecord(); r.emittedAt = "2026-07-15T12:00:00.000Z"; r.executionArn = ARN; r.functionName = "fn"; @@ -38,7 +38,8 @@ private WorkflowInsightRecord sampleRecord() { return r; } - private static ExecuteStatementRequest export(AuroraExporter.Builder builder, WorkflowInsightRecord record) { + private static ExecuteStatementRequest export( + AuroraExporter.Builder builder, DurableExecutionTelemetryRecord record) { RdsDataClient client = mock(RdsDataClient.class); when(client.executeStatement(any(ExecuteStatementRequest.class))) .thenReturn(ExecuteStatementResponse.builder().build()); @@ -60,18 +61,18 @@ private static AuroraExporter.Builder base() { return AuroraExporter.builder() .resourceArn("arn:aws:rds:us-east-1:123456789012:cluster:c") .secretArn("arn:aws:secretsmanager:us-east-1:123456789012:secret:s") - .database("insight"); + .database("telemetry"); } @Test void postgresUpsertBindsEveryColumnWithNullsForAbsentFields() { - WorkflowInsightRecord record = sampleRecord(); + DurableExecutionTelemetryRecord record = sampleRecord(); ExecuteStatementRequest req = export(base().engine(AuroraExporter.Engine.POSTGRESQL), record); assertEquals("arn:aws:rds:us-east-1:123456789012:cluster:c", req.resourceArn()); assertEquals("arn:aws:secretsmanager:us-east-1:123456789012:secret:s", req.secretArn()); - assertEquals("insight", req.database()); - assertTrue(req.sql().startsWith("INSERT INTO workflow_insight")); + assertEquals("telemetry", req.database()); + assertTrue(req.sql().startsWith("INSERT INTO durable_execution_telemetry")); assertTrue(req.sql().contains("ON CONFLICT (execution_arn) DO UPDATE SET")); assertTrue(req.sql().contains(":record_json::jsonb")); @@ -91,15 +92,15 @@ void postgresUpsertBindsEveryColumnWithNullsForAbsentFields() { @Test void mysqlUpsertBindsCompletedFields() { - WorkflowInsightRecord record = sampleRecord(); + DurableExecutionTelemetryRecord record = sampleRecord(); record.executionName = "exec-1"; record.status = "SUCCEEDED"; record.endTime = "2026-07-15T12:00:00.000Z"; record.durationMs = 60_000L; ExecuteStatementRequest req = - export(base().engine(AuroraExporter.Engine.MYSQL).table("insight_rows"), record); + export(base().engine(AuroraExporter.Engine.MYSQL).table("telemetry_rows"), record); - assertTrue(req.sql().startsWith("INSERT INTO insight_rows")); + assertTrue(req.sql().startsWith("INSERT INTO telemetry_rows")); assertTrue(req.sql().contains("ON DUPLICATE KEY UPDATE")); assertFalse(req.sql().contains("::timestamptz")); diff --git a/insight-plugin/src/test/java/software/amazon/lambda/durable/insight/CloudWatchLogsExporterTest.java b/telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry/CloudWatchLogsExporterTest.java similarity index 96% rename from insight-plugin/src/test/java/software/amazon/lambda/durable/insight/CloudWatchLogsExporterTest.java rename to telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry/CloudWatchLogsExporterTest.java index 2a3f2ab240..7f09af0a52 100644 --- a/insight-plugin/src/test/java/software/amazon/lambda/durable/insight/CloudWatchLogsExporterTest.java +++ b/telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry/CloudWatchLogsExporterTest.java @@ -1,6 +1,6 @@ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 -package software.amazon.lambda.durable.insight; +package software.amazon.lambda.durable.telemetry; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; @@ -31,12 +31,12 @@ import software.amazon.awssdk.services.cloudwatchlogs.model.PutLogEventsResponse; import software.amazon.awssdk.services.cloudwatchlogs.model.ResourceAlreadyExistsException; import software.amazon.awssdk.services.cloudwatchlogs.model.ResourceNotFoundException; -import software.amazon.lambda.durable.insight.exporters.CloudWatchLogsExporter; +import software.amazon.lambda.durable.telemetry.exporters.CloudWatchLogsExporter; class CloudWatchLogsExporterTest { - private WorkflowInsightRecord sampleRecord() { - WorkflowInsightRecord r = new WorkflowInsightRecord(); + private DurableExecutionTelemetryRecord sampleRecord() { + DurableExecutionTelemetryRecord r = new DurableExecutionTelemetryRecord(); r.executionArn = "arn:aws:lambda:us-west-2:1:function:f:$LATEST/durable-execution/exec-1/invocation-1"; r.status = "SUCCEEDED"; r.startTime = "2026-08-05T00:00:00Z"; diff --git a/insight-plugin/src/test/java/software/amazon/lambda/durable/insight/WorkflowInsightHookTest.java b/telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry/DurableExecutionTelemetryHookTest.java similarity index 79% rename from insight-plugin/src/test/java/software/amazon/lambda/durable/insight/WorkflowInsightHookTest.java rename to telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry/DurableExecutionTelemetryHookTest.java index acd3a98b95..1158e2d47e 100644 --- a/insight-plugin/src/test/java/software/amazon/lambda/durable/insight/WorkflowInsightHookTest.java +++ b/telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry/DurableExecutionTelemetryHookTest.java @@ -1,6 +1,6 @@ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 -package software.amazon.lambda.durable.insight; +package software.amazon.lambda.durable.telemetry; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; @@ -27,19 +27,19 @@ * (invocation start / operation change / invocation end), cross-invocation state preservation on PENDING/RETRYING, and * exporter isolation + flush. */ -class WorkflowInsightHookTest { +class DurableExecutionTelemetryHookTest { private static final String ARN = "arn:aws:lambda:us-west-2:1:function:f:$LATEST/durable-execution/exec-1/invocation-1"; private static final Instant START = Instant.parse("2026-08-05T00:00:00Z"); - private static class CapturingExporter implements InsightExporter { - final List records = new CopyOnWriteArrayList<>(); + private static class CapturingExporter implements TelemetryExporter { + final List records = new CopyOnWriteArrayList<>(); final List threads = new CopyOnWriteArrayList<>(); volatile int flushes; @Override - public void export(WorkflowInsightRecord record) { + public void export(DurableExecutionTelemetryRecord record) { records.add(record); threads.add(Thread.currentThread()); } @@ -84,7 +84,7 @@ void anotherExecutionsChangeHookDuringTheEndDrainCannotDropTheFinalRecord() thro var release = new CountDownLatch(1); var exporter = new CapturingExporter() { @Override - public void export(WorkflowInsightRecord record) { + public void export(DurableExecutionTelemetryRecord record) { super.export(record); // Block a's first export so a's final record has to wait in the pending slot while b keeps emitting. if (records.size() == 1) { @@ -97,10 +97,11 @@ public void export(WorkflowInsightRecord record) { } } }; - var plugin = (WorkflowInsight.InsightPlugin) WorkflowInsight.workflowInsight(WorkflowInsightConfig.builder() - .emitMode(WorkflowInsightConfig.EmitMode.ON_CHANGE) - .addExporter(exporter) - .build()); + var plugin = (DurableExecutionTelemetry.TelemetryPlugin) + DurableExecutionTelemetry.durableExecutionTelemetry(DurableExecutionTelemetryConfig.builder() + .emitMode(DurableExecutionTelemetryConfig.EmitMode.ON_CHANGE) + .addExporter(exporter) + .build()); plugin.onInvocationStart(start(arnA, true)); assertTrue(exportingA.await(5, TimeUnit.SECONDS)); @@ -120,11 +121,11 @@ public void export(WorkflowInsightRecord record) { var aStatuses = exporter.records.stream() .filter(r -> arnA.equals(r.executionArn())) - .map(WorkflowInsightRecord::status) + .map(DurableExecutionTelemetryRecord::status) .toList(); var bStatuses = exporter.records.stream() .filter(r -> arnB.equals(r.executionArn())) - .map(WorkflowInsightRecord::status) + .map(DurableExecutionTelemetryRecord::status) .toList(); assertEquals(List.of("RUNNING", "SUCCEEDED"), aStatuses, "a's final record is delivered"); assertEquals("SUCCEEDED", bStatuses.get(bStatuses.size() - 1), "b's final record is delivered last"); @@ -134,10 +135,11 @@ public void export(WorkflowInsightRecord record) { @Test void onChangeEmitsAtStartChangeAndEnd() { var exporter = new CapturingExporter(); - var plugin = (WorkflowInsight.InsightPlugin) WorkflowInsight.workflowInsight(WorkflowInsightConfig.builder() - .emitMode(WorkflowInsightConfig.EmitMode.ON_CHANGE) - .addExporter(exporter) - .build()); + var plugin = (DurableExecutionTelemetry.TelemetryPlugin) + DurableExecutionTelemetry.durableExecutionTelemetry(DurableExecutionTelemetryConfig.builder() + .emitMode(DurableExecutionTelemetryConfig.EmitMode.ON_CHANGE) + .addExporter(exporter) + .build()); // Let each scheduled export land before the next hook so all three snapshots are observable; back-to-back // hooks may otherwise coalesce into the latest record (covered separately below). @@ -158,10 +160,11 @@ void onChangeEmitsAtStartChangeAndEnd() { @Test void onChangeExportsOffTheHookThreadAndCoalescesBurstsIntoTheLatestRecord() { var exporter = new CapturingExporter(); - var plugin = (WorkflowInsight.InsightPlugin) WorkflowInsight.workflowInsight(WorkflowInsightConfig.builder() - .emitMode(WorkflowInsightConfig.EmitMode.ON_CHANGE) - .addExporter(exporter) - .build()); + var plugin = (DurableExecutionTelemetry.TelemetryPlugin) + DurableExecutionTelemetry.durableExecutionTelemetry(DurableExecutionTelemetryConfig.builder() + .emitMode(DurableExecutionTelemetryConfig.EmitMode.ON_CHANGE) + .addExporter(exporter) + .build()); plugin.onInvocationStart(start(true)); for (int i = 0; i < 20; i++) { @@ -188,7 +191,7 @@ void changeHookArrivingWhileTheEndRecordDrainsCannotFollowOrReplaceIt() throws E var release = new CountDownLatch(1); var exporter = new CapturingExporter() { @Override - public void export(WorkflowInsightRecord record) { + public void export(DurableExecutionTelemetryRecord record) { super.export(record); if ("SUCCEEDED".equals(record.status())) { exportingFinal.countDown(); @@ -200,10 +203,11 @@ public void export(WorkflowInsightRecord record) { } } }; - var plugin = (WorkflowInsight.InsightPlugin) WorkflowInsight.workflowInsight(WorkflowInsightConfig.builder() - .emitMode(WorkflowInsightConfig.EmitMode.ON_CHANGE) - .addExporter(exporter) - .build()); + var plugin = (DurableExecutionTelemetry.TelemetryPlugin) + DurableExecutionTelemetry.durableExecutionTelemetry(DurableExecutionTelemetryConfig.builder() + .emitMode(DurableExecutionTelemetryConfig.EmitMode.ON_CHANGE) + .addExporter(exporter) + .build()); plugin.onInvocationStart(start(true)); plugin.drainExports(); @@ -228,8 +232,8 @@ public void export(WorkflowInsightRecord record) { @Test void invocationEndFlushesExportersEvenWhenNothingWasEmitted() { var exporter = new CapturingExporter(); - DurableExecutionPlugin plugin = WorkflowInsight.workflowInsight( - WorkflowInsightConfig.builder().addExporter(exporter).build()); + DurableExecutionPlugin plugin = DurableExecutionTelemetry.durableExecutionTelemetry( + DurableExecutionTelemetryConfig.builder().addExporter(exporter).build()); plugin.onInvocationStart(start(true)); plugin.onInvocationEnd(end(InvocationStatus.PENDING, null, null)); @@ -241,8 +245,8 @@ void invocationEndFlushesExportersEvenWhenNothingWasEmitted() { @Test void onCompleteSkipsNonTerminalAndEmitsTerminalOnly() { var exporter = new CapturingExporter(); - DurableExecutionPlugin plugin = WorkflowInsight.workflowInsight( - WorkflowInsightConfig.builder().addExporter(exporter).build()); + DurableExecutionPlugin plugin = DurableExecutionTelemetry.durableExecutionTelemetry( + DurableExecutionTelemetryConfig.builder().addExporter(exporter).build()); plugin.onInvocationStart(start(true)); plugin.onOperationChange(new OperationChangeInfo( @@ -256,10 +260,11 @@ void onCompleteSkipsNonTerminalAndEmitsTerminalOnly() { @Test void suspendResumeKeepsStableStartTimeAndLeavesNoRetainedState() { var exporter = new CapturingExporter(); - var plugin = (WorkflowInsight.InsightPlugin) WorkflowInsight.workflowInsight(WorkflowInsightConfig.builder() - .emitMode(WorkflowInsightConfig.EmitMode.ON_CHANGE) - .addExporter(exporter) - .build()); + var plugin = (DurableExecutionTelemetry.TelemetryPlugin) + DurableExecutionTelemetry.durableExecutionTelemetry(DurableExecutionTelemetryConfig.builder() + .emitMode(DurableExecutionTelemetryConfig.EmitMode.ON_CHANGE) + .addExporter(exporter) + .build()); plugin.onInvocationStart(start(true)); // first invocation plugin.drainExports(); @@ -279,17 +284,18 @@ void suspendResumeKeepsStableStartTimeAndLeavesNoRetainedState() { @Test void exporterFailureIsIsolatedAndOthersStillReceiveAndFlush() { - var throwing = new InsightExporter() { + var throwing = new TelemetryExporter() { @Override - public void export(WorkflowInsightRecord record) { + public void export(DurableExecutionTelemetryRecord record) { throw new RuntimeException("exporter down"); } }; var good = new CapturingExporter(); - DurableExecutionPlugin plugin = WorkflowInsight.workflowInsight(WorkflowInsightConfig.builder() - .addExporter(throwing) - .addExporter(good) - .build()); + DurableExecutionPlugin plugin = + DurableExecutionTelemetry.durableExecutionTelemetry(DurableExecutionTelemetryConfig.builder() + .addExporter(throwing) + .addExporter(good) + .build()); plugin.onInvocationStart(start(true)); plugin.onInvocationEnd(end(InvocationStatus.SUCCEEDED, "out", null)); diff --git a/insight-plugin/src/test/java/software/amazon/lambda/durable/insight/WorkflowInsightPluginTest.java b/telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry/DurableExecutionTelemetryPluginTest.java similarity index 84% rename from insight-plugin/src/test/java/software/amazon/lambda/durable/insight/WorkflowInsightPluginTest.java rename to telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry/DurableExecutionTelemetryPluginTest.java index 8d5cf0fff1..54dfb41dfb 100644 --- a/insight-plugin/src/test/java/software/amazon/lambda/durable/insight/WorkflowInsightPluginTest.java +++ b/telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry/DurableExecutionTelemetryPluginTest.java @@ -1,6 +1,6 @@ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 -package software.amazon.lambda.durable.insight; +package software.amazon.lambda.durable.telemetry; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; @@ -27,15 +27,16 @@ /** * End-to-end behavior tests exercising the plugin via the local durable test runner, which drives the real SDK * coordinator so the plugin consumes the same hook snapshots (operations, execution input/output, per-op result) it - * receives in production. These map to the Workflow Insight conformance behaviors (insight-1 … insight-18). + * receives in production. These map to the Durable Execution Telemetry conformance behaviors (telemetry-1 … + * telemetry-18). */ -class WorkflowInsightPluginTest { +class DurableExecutionTelemetryPluginTest { - private static final class CapturingExporter implements InsightExporter { - final List records = Collections.synchronizedList(new ArrayList<>()); + private static final class CapturingExporter implements TelemetryExporter { + final List records = Collections.synchronizedList(new ArrayList<>()); @Override - public void export(WorkflowInsightRecord record) { + public void export(DurableExecutionTelemetryRecord record) { records.add(record); } } @@ -43,31 +44,32 @@ public void export(WorkflowInsightRecord record) { private static final RetryStrategy RETRY_ONCE = RetryStrategies.exponentialBackoff( 2, Duration.ofSeconds(1), Duration.ofSeconds(1), 2.0, JitterStrategy.NONE); - private DurableConfig configWith(CapturingExporter exporter, WorkflowInsightConfig.Builder cfg) { - var plugin = WorkflowInsight.workflowInsight(cfg.addExporter(exporter).build()); + private DurableConfig configWith(CapturingExporter exporter, DurableExecutionTelemetryConfig.Builder cfg) { + var plugin = DurableExecutionTelemetry.durableExecutionTelemetry( + cfg.addExporter(exporter).build()); return DurableConfig.builder().withPlugins(plugin).build(); } - private OperationRecord op(WorkflowInsightRecord rec, String name) { + private OperationRecord op(DurableExecutionTelemetryRecord rec, String name) { return rec.operations().stream() .filter(o -> name.equals(o.name())) .findFirst() .orElseThrow(); } - // insight-1 + // telemetry-1 @Test void basicSuccessEmitsOneRecordWithNamedStepAndEchoedIo() { var exporter = new CapturingExporter(); var runner = LocalDurableTestRunner.create( String.class, (input, context) -> context.step("greet", String.class, sc -> "Hello, " + input + "!"), - configWith(exporter, WorkflowInsightConfig.builder())); + configWith(exporter, DurableExecutionTelemetryConfig.builder())); var result = runner.runUntilComplete("World"); assertEquals(ExecutionStatus.SUCCEEDED, result.getStatus()); assertEquals(1, exporter.records.size()); var rec = exporter.records.get(0); - assertEquals("WorkflowInsight", rec.recordType); + assertEquals("DurableExecutionTelemetry", rec.recordType); assertEquals("1.0", rec.schemaVersion); assertEquals("SUCCEEDED", rec.status()); assertEquals("World", rec.input); @@ -81,7 +83,7 @@ void basicSuccessEmitsOneRecordWithNamedStepAndEchoedIo() { assertNull(greet.result(), "result omitted without an override"); } - // insight-2 + // telemetry-2 @Test void executionFailureRecordCarriesErrorAndFailedOp() { var exporter = new CapturingExporter(); @@ -96,7 +98,7 @@ void executionFailureRecordCarriesErrorAndFailedOp() { StepConfig.builder() .retryStrategy(RetryStrategies.Presets.NO_RETRY) .build()), - configWith(exporter, WorkflowInsightConfig.builder())); + configWith(exporter, DurableExecutionTelemetryConfig.builder())); var result = runner.run("World"); assertEquals(ExecutionStatus.FAILED, result.getStatus()); assertEquals(1, exporter.records.size()); @@ -107,7 +109,7 @@ void executionFailureRecordCarriesErrorAndFailedOp() { assertEquals("FAILED", op(rec, "failing-step").status()); } - // insight-3 + // telemetry-3 @Test void onFailureModeEmitsNothingForSuccess() { var exporter = new CapturingExporter(); @@ -115,12 +117,14 @@ void onFailureModeEmitsNothingForSuccess() { String.class, (input, context) -> context.step("greet", String.class, sc -> "hi"), configWith( - exporter, WorkflowInsightConfig.builder().emitMode(WorkflowInsightConfig.EmitMode.ON_FAILURE))); + exporter, + DurableExecutionTelemetryConfig.builder() + .emitMode(DurableExecutionTelemetryConfig.EmitMode.ON_FAILURE))); runner.runUntilComplete("World"); assertTrue(exporter.records.isEmpty()); } - // insight-4 + // telemetry-4 @Test void onFailureModeEmitsExactlyOneFailedRecord() { var exporter = new CapturingExporter(); @@ -136,14 +140,16 @@ void onFailureModeEmitsExactlyOneFailedRecord() { .retryStrategy(RetryStrategies.Presets.NO_RETRY) .build()), configWith( - exporter, WorkflowInsightConfig.builder().emitMode(WorkflowInsightConfig.EmitMode.ON_FAILURE))); + exporter, + DurableExecutionTelemetryConfig.builder() + .emitMode(DurableExecutionTelemetryConfig.EmitMode.ON_FAILURE))); var result = runner.run("World"); assertEquals(ExecutionStatus.FAILED, result.getStatus()); assertEquals(1, exporter.records.size()); assertEquals("FAILED", exporter.records.get(0).status()); } - // insight-5 + // telemetry-5 @Test void waitYieldsExactlyOneTerminalRecordNoRunningRecord() { var exporter = new CapturingExporter(); @@ -153,14 +159,14 @@ void waitYieldsExactlyOneTerminalRecordNoRunningRecord() { context.wait("pause", Duration.ofSeconds(1)); return context.step("after-wait", String.class, sc -> "done"); }, - configWith(exporter, WorkflowInsightConfig.builder())); + configWith(exporter, DurableExecutionTelemetryConfig.builder())); var result = runner.runUntilComplete("World"); assertEquals(ExecutionStatus.SUCCEEDED, result.getStatus()); assertEquals(1, exporter.records.size(), "on-complete emits exactly one terminal record across suspend/resume"); assertEquals("SUCCEEDED", exporter.records.get(0).status()); } - // insight-6 + // telemetry-6 @Test void stepRetryReflectsAttemptNumber() { var exporter = new CapturingExporter(); @@ -177,7 +183,7 @@ void stepRetryReflectsAttemptNumber() { return "ok"; }, StepConfig.builder().retryStrategy(RETRY_ONCE).build()), - configWith(exporter, WorkflowInsightConfig.builder())); + configWith(exporter, DurableExecutionTelemetryConfig.builder())); var result = runner.runUntilComplete("World"); assertEquals(ExecutionStatus.SUCCEEDED, result.getStatus()); var retried = op(exporter.records.get(0), "retried-step"); @@ -185,7 +191,7 @@ void stepRetryReflectsAttemptNumber() { assertEquals(Integer.valueOf(2), retried.attempt(), "attempt reflects the retry"); } - // insight-7 + // telemetry-7 @Test void repeatedNameAggregatesToCountThreeInByName() { var exporter = new CapturingExporter(); @@ -197,7 +203,7 @@ void repeatedNameAggregatesToCountThreeInByName() { } return "done"; }, - configWith(exporter, WorkflowInsightConfig.builder())); + configWith(exporter, DurableExecutionTelemetryConfig.builder())); runner.runUntilComplete("World"); assertEquals(1, exporter.records.size()); Map byName = @@ -206,19 +212,19 @@ void repeatedNameAggregatesToCountThreeInByName() { assertNull(byName.get("task").result, "repeated name drops representative result"); } - // insight-8 + // telemetry-8 @Test void samplingRateZeroEmitsNothing() { var exporter = new CapturingExporter(); var runner = LocalDurableTestRunner.create( String.class, (input, context) -> context.step("greet", String.class, sc -> "hi"), - configWith(exporter, WorkflowInsightConfig.builder().samplingRate(0))); + configWith(exporter, DurableExecutionTelemetryConfig.builder().samplingRate(0))); runner.runUntilComplete("World"); assertTrue(exporter.records.isEmpty()); } - // insight-9 + // telemetry-9 @Test void contentOmittedDropsInputAndOutputWithoutTruncationMarkers() { var exporter = new CapturingExporter(); @@ -227,7 +233,7 @@ void contentOmittedDropsInputAndOutputWithoutTruncationMarkers() { (input, context) -> context.step("greet", String.class, sc -> "Hello, " + input + "!"), configWith( exporter, - WorkflowInsightConfig.builder() + DurableExecutionTelemetryConfig.builder() .content(ContentConfig.builder() .input(false) .output(false) @@ -240,7 +246,7 @@ void contentOmittedDropsInputAndOutputWithoutTruncationMarkers() { assertNull(rec.droppedOutput); } - // insight-10 + // telemetry-10 @Test void includeErrorsFalseDropsOperationError() { var exporter = new CapturingExporter(); @@ -257,7 +263,7 @@ void includeErrorsFalseDropsOperationError() { .build()), configWith( exporter, - WorkflowInsightConfig.builder() + DurableExecutionTelemetryConfig.builder() .content(ContentConfig.builder() .includeErrors(false) .build()))); @@ -268,7 +274,7 @@ void includeErrorsFalseDropsOperationError() { assertNull(op(rec, "failing-step").error(), "operation error suppressed by includeErrors:false"); } - // insight-11 + // telemetry-11 @Test void operationResultOptInSurfacesCheckpointedValue() { var exporter = new CapturingExporter(); @@ -277,7 +283,7 @@ void operationResultOptInSurfacesCheckpointedValue() { (input, context) -> context.step("compute", Integer.class, sc -> 42), configWith( exporter, - WorkflowInsightConfig.builder() + DurableExecutionTelemetryConfig.builder() .content(ContentConfig.builder() .addOverride(OperationOverride.withResult("compute", r -> r)) .build()))); @@ -286,7 +292,7 @@ void operationResultOptInSurfacesCheckpointedValue() { assertEquals(42, compute.result(), "identity override surfaces the checkpointed JSON value"); } - // insight-13 + // telemetry-13 @Test void topLevelOnlyDropsNestedChildren() { var exporter = new CapturingExporter(); @@ -302,7 +308,7 @@ void topLevelOnlyDropsNestedChildren() { parallel.get(); return "done"; }, - configWith(exporter, WorkflowInsightConfig.builder())); + configWith(exporter, DurableExecutionTelemetryConfig.builder())); runner.runUntilComplete("World"); var rec = exporter.records.get(0); assertNotNull(op(rec, "parallel-work")); @@ -312,7 +318,7 @@ void topLevelOnlyDropsNestedChildren() { assertTrue(rec.operations().stream().noneMatch(o -> "branch-a-step".equals(o.name()))); } - // insight-14 + // telemetry-14 @Test void fullTreeIncludesChildrenLinkedToParent() { var exporter = new CapturingExporter(); @@ -322,8 +328,8 @@ void fullTreeIncludesChildrenLinkedToParent() { "parent-context", String.class, child -> child.step("child-step", String.class, sc -> "c")), configWith( exporter, - WorkflowInsightConfig.builder() - .operationDetail(WorkflowInsightConfig.OperationDetail.FULL_TREE))); + DurableExecutionTelemetryConfig.builder() + .operationDetail(DurableExecutionTelemetryConfig.OperationDetail.FULL_TREE))); runner.runUntilComplete("World"); var rec = exporter.records.get(0); var parent = op(rec, "parent-context"); @@ -332,7 +338,7 @@ void fullTreeIncludesChildrenLinkedToParent() { assertEquals(parent.id(), child.parentId(), "child parentId links to parent id in full-tree"); } - // insight-17 + // telemetry-17 @Test void unnamedOperationsAreDropped() { var exporter = new CapturingExporter(); @@ -342,14 +348,14 @@ void unnamedOperationsAreDropped() { context.wait(null, Duration.ofSeconds(1)); // unnamed WAIT -> dropped return context.step("named-step", String.class, sc -> "ok"); }, - configWith(exporter, WorkflowInsightConfig.builder())); + configWith(exporter, DurableExecutionTelemetryConfig.builder())); runner.runUntilComplete("World"); var rec = exporter.records.get(0); assertTrue(rec.operations().stream().allMatch(o -> o.name() != null), "no unnamed operation appears"); assertNotNull(op(rec, "named-step")); } - // insight-18 + // telemetry-18 @Test void summaryMaxAttemptReflectsRetry() { var exporter = new CapturingExporter(); @@ -366,7 +372,7 @@ void summaryMaxAttemptReflectsRetry() { return "ok"; }, StepConfig.builder().retryStrategy(RETRY_ONCE).build()), - configWith(exporter, WorkflowInsightConfig.builder())); + configWith(exporter, DurableExecutionTelemetryConfig.builder())); runner.runUntilComplete("World"); Map byName = OperationsIndex.buildOperationsByName(exporter.records.get(0).operations()); diff --git a/telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry/DurableExecutionTelemetrySamplingTest.java b/telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry/DurableExecutionTelemetrySamplingTest.java new file mode 100644 index 0000000000..f99fc215b1 --- /dev/null +++ b/telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry/DurableExecutionTelemetrySamplingTest.java @@ -0,0 +1,42 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 +package software.amazon.lambda.durable.telemetry; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.Test; + +class DurableExecutionTelemetrySamplingTest { + + @Test + void rateOneAlwaysSamplesIn() { + assertTrue(DurableExecutionTelemetry.shouldSample("any-arn", 1.0)); + } + + @Test + void rateZeroNeverSamplesIn() { + assertFalse(DurableExecutionTelemetry.shouldSample("any-arn", 0.0)); + } + + @Test + void fnv1a32IsDeterministic() { + assertEquals(DurableExecutionTelemetry.fnv1a32("hello"), DurableExecutionTelemetry.fnv1a32("hello")); + } + + @Test + void resolveSamplingRateClampsOutOfRange() { + assertEquals(1.0, DurableExecutionTelemetry.resolveSamplingRate(5.0)); + assertEquals(0.0, DurableExecutionTelemetry.resolveSamplingRate(-1.0)); + assertEquals(1.0, DurableExecutionTelemetry.resolveSamplingRate(null)); + assertEquals(0.25, DurableExecutionTelemetry.resolveSamplingRate(0.25)); + } + + @Test + void samplingDecisionIsStableAcrossCalls() { + String arn = "arn:aws:lambda:us-west-2:1:function:f:$LATEST/durable-execution/e/i"; + assertEquals( + DurableExecutionTelemetry.shouldSample(arn, 0.5), DurableExecutionTelemetry.shouldSample(arn, 0.5)); + } +} diff --git a/insight-plugin/src/test/java/software/amazon/lambda/durable/insight/DynamoDBExporterTest.java b/telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry/DynamoDBExporterTest.java similarity index 90% rename from insight-plugin/src/test/java/software/amazon/lambda/durable/insight/DynamoDBExporterTest.java rename to telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry/DynamoDBExporterTest.java index 54e3e47b64..14ef4d98c6 100644 --- a/insight-plugin/src/test/java/software/amazon/lambda/durable/insight/DynamoDBExporterTest.java +++ b/telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry/DynamoDBExporterTest.java @@ -1,6 +1,6 @@ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 -package software.amazon.lambda.durable.insight; +package software.amazon.lambda.durable.telemetry; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; @@ -19,14 +19,14 @@ import software.amazon.awssdk.services.dynamodb.model.AttributeValue; import software.amazon.awssdk.services.dynamodb.model.PutItemRequest; import software.amazon.awssdk.services.dynamodb.model.PutItemResponse; -import software.amazon.lambda.durable.insight.exporters.DynamoDBExporter; +import software.amazon.lambda.durable.telemetry.exporters.DynamoDBExporter; class DynamoDBExporterTest { private static final String ARN = "arn:aws:lambda:us-east-1:123456789012:function:fn:$LATEST"; - private WorkflowInsightRecord sampleRecord() { - WorkflowInsightRecord r = new WorkflowInsightRecord(); + private DurableExecutionTelemetryRecord sampleRecord() { + DurableExecutionTelemetryRecord r = new DurableExecutionTelemetryRecord(); r.emittedAt = "2026-07-15T12:00:00.000Z"; r.executionArn = ARN; r.executionName = "exec-1"; @@ -58,10 +58,10 @@ private static PutItemRequest export(DynamoDBExporter.Builder builder) { @Test void writesHistoryItemKeyedByArnAndEmittedAt() { - PutItemRequest req = export(DynamoDBExporter.builder().tableName("insight")); + PutItemRequest req = export(DynamoDBExporter.builder().tableName("telemetry")); Map item = req.item(); - assertEquals("insight", req.tableName()); + assertEquals("telemetry", req.tableName()); assertEquals(ARN, item.get("pk").s()); assertEquals("2026-07-15T12:00:00.000Z", item.get("sk").s()); assertEquals("SUCCEEDED", item.get("status").s()); @@ -78,7 +78,7 @@ void writesHistoryItemKeyedByArnAndEmittedAt() { @Test void upsertsWithoutSortKeyAndHonorsCustomPartitionKey() { PutItemRequest req = export(DynamoDBExporter.builder() - .tableName("insight") + .tableName("telemetry") .partitionKey("executionArnKey") .sortKey("")); Map item = req.item(); @@ -91,7 +91,7 @@ void upsertsWithoutSortKeyAndHonorsCustomPartitionKey() { @Test void renderIsTheByNameMapAndDefaultLimitIsFourHundredKilobytes() { DynamoDBExporter exporter = DynamoDBExporter.builder() - .tableName("insight") + .tableName("telemetry") .client(mock(DynamoDbClient.class)) .build(); assertEquals(400_000, exporter.maxRecordSizeBytes()); diff --git a/insight-plugin/src/test/java/software/amazon/lambda/durable/insight/ErrorPrivacyGateTest.java b/telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry/ErrorPrivacyGateTest.java similarity index 85% rename from insight-plugin/src/test/java/software/amazon/lambda/durable/insight/ErrorPrivacyGateTest.java rename to telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry/ErrorPrivacyGateTest.java index 0cd5ede12c..841b5cce37 100644 --- a/insight-plugin/src/test/java/software/amazon/lambda/durable/insight/ErrorPrivacyGateTest.java +++ b/telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry/ErrorPrivacyGateTest.java @@ -1,6 +1,6 @@ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 -package software.amazon.lambda.durable.insight; +package software.amazon.lambda.durable.telemetry; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; @@ -34,11 +34,11 @@ class ErrorPrivacyGateTest { private static final String EXEC_SECRET = "exec-secret-ssn-123-45-6789"; private static final String OP_SECRET = "op-secret-token-abcdef"; - private static final class CapturingExporter implements InsightExporter { - final List records = new ArrayList<>(); + private static final class CapturingExporter implements TelemetryExporter { + final List records = new ArrayList<>(); @Override - public void export(WorkflowInsightRecord record) { + public void export(DurableExecutionTelemetryRecord record) { records.add(record); } } @@ -63,11 +63,14 @@ private Map failingOp() { return m; } - private WorkflowInsightRecord runFailedExecution(boolean includeErrors, CapturingExporter exporter) { - DurableExecutionPlugin plugin = WorkflowInsight.workflowInsight(WorkflowInsightConfig.builder() - .content(ContentConfig.builder().includeErrors(includeErrors).build()) - .addExporter(exporter) - .build()); + private DurableExecutionTelemetryRecord runFailedExecution(boolean includeErrors, CapturingExporter exporter) { + DurableExecutionPlugin plugin = + DurableExecutionTelemetry.durableExecutionTelemetry(DurableExecutionTelemetryConfig.builder() + .content(ContentConfig.builder() + .includeErrors(includeErrors) + .build()) + .addExporter(exporter) + .build()); plugin.onInvocationStart(new InvocationInfo("req", ARN, true, START, "in", failingOp(), Map.of())); plugin.onInvocationEnd(new InvocationEndInfo( "req", diff --git a/insight-plugin/src/test/java/software/amazon/lambda/durable/insight/EventBridgeExporterTest.java b/telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry/EventBridgeExporterTest.java similarity index 87% rename from insight-plugin/src/test/java/software/amazon/lambda/durable/insight/EventBridgeExporterTest.java rename to telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry/EventBridgeExporterTest.java index 75d2efa481..d272b9b282 100644 --- a/insight-plugin/src/test/java/software/amazon/lambda/durable/insight/EventBridgeExporterTest.java +++ b/telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry/EventBridgeExporterTest.java @@ -1,6 +1,6 @@ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 -package software.amazon.lambda.durable.insight; +package software.amazon.lambda.durable.telemetry; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; @@ -19,15 +19,15 @@ import software.amazon.awssdk.services.eventbridge.model.PutEventsRequestEntry; import software.amazon.awssdk.services.eventbridge.model.PutEventsResponse; import software.amazon.awssdk.services.eventbridge.model.PutEventsResultEntry; -import software.amazon.lambda.durable.insight.exporters.EventBridgeExporter; -import software.amazon.lambda.durable.insight.exporters.OperationsFormat; +import software.amazon.lambda.durable.telemetry.exporters.EventBridgeExporter; +import software.amazon.lambda.durable.telemetry.exporters.OperationsFormat; class EventBridgeExporterTest { private static final String ARN = "arn:aws:lambda:us-east-1:123456789012:function:fn:$LATEST"; - private WorkflowInsightRecord sampleRecord() { - WorkflowInsightRecord r = new WorkflowInsightRecord(); + private DurableExecutionTelemetryRecord sampleRecord() { + DurableExecutionTelemetryRecord r = new DurableExecutionTelemetryRecord(); r.emittedAt = "2026-07-15T12:00:00.000Z"; r.executionArn = ARN; r.functionName = "fn"; @@ -55,12 +55,12 @@ private static PutEventsRequestEntry capture(EventBridgeClient client) { void publishesOneEventWithStatusDetailTypeAndRecordDetail() { EventBridgeClient client = clientReturning(PutEventsResponse.builder().failedEntryCount(0).build()); - WorkflowInsightRecord record = sampleRecord(); + DurableExecutionTelemetryRecord record = sampleRecord(); EventBridgeExporter.builder().client(client).build().export(record); PutEventsRequestEntry entry = capture(client); assertEquals("default", entry.eventBusName()); - assertEquals("software.amazon.lambda.durable.insight", entry.source()); + assertEquals("software.amazon.lambda.durable.telemetry", entry.source()); assertEquals(EventBridgeExporter.DEFAULT_SOURCE, entry.source()); assertFalse(entry.source().startsWith("aws."), "the aws. source namespace is reserved for AWS services"); assertEquals("SUCCEEDED", entry.detailType()); @@ -73,7 +73,7 @@ void publishesOneEventWithStatusDetailTypeAndRecordDetail() { void honorsCustomBusSourceAndByNameFormat() { EventBridgeClient client = clientReturning(PutEventsResponse.builder().build()); EventBridgeExporter.builder() - .eventBusName("insight-bus") + .eventBusName("telemetry-bus") .source("my.source") .operationsFormat(OperationsFormat.BY_NAME) .client(client) @@ -81,7 +81,7 @@ void honorsCustomBusSourceAndByNameFormat() { .export(sampleRecord()); PutEventsRequestEntry entry = capture(client); - assertEquals("insight-bus", entry.eventBusName()); + assertEquals("telemetry-bus", entry.eventBusName()); assertEquals("my.source", entry.source()); assertTrue(entry.detail().contains("\"operationsByName\"")); assertFalse(entry.detail().contains("\"operations\"")); diff --git a/insight-plugin/src/test/java/software/amazon/lambda/durable/insight/ExportSchedulerTest.java b/telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry/ExportSchedulerTest.java similarity index 91% rename from insight-plugin/src/test/java/software/amazon/lambda/durable/insight/ExportSchedulerTest.java rename to telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry/ExportSchedulerTest.java index 4f2d8af424..f389e3cf4a 100644 --- a/insight-plugin/src/test/java/software/amazon/lambda/durable/insight/ExportSchedulerTest.java +++ b/telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry/ExportSchedulerTest.java @@ -1,6 +1,6 @@ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 -package software.amazon.lambda.durable.insight; +package software.amazon.lambda.durable.telemetry; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; @@ -45,23 +45,23 @@ void runAll() { } } - private static class CapturingExporter implements InsightExporter { - final List records = new CopyOnWriteArrayList<>(); + private static class CapturingExporter implements TelemetryExporter { + final List records = new CopyOnWriteArrayList<>(); final List threads = new CopyOnWriteArrayList<>(); @Override - public void export(WorkflowInsightRecord record) { + public void export(DurableExecutionTelemetryRecord record) { records.add(record); threads.add(Thread.currentThread()); } } - private static WorkflowInsightRecord record(String status) { + private static DurableExecutionTelemetryRecord record(String status) { return record("arn:exec-a", status); } - private static WorkflowInsightRecord record(String executionArn, String status) { - var r = new WorkflowInsightRecord(); + private static DurableExecutionTelemetryRecord record(String executionArn, String status) { + var r = new DurableExecutionTelemetryRecord(); r.executionArn = executionArn; r.status = status; return r; @@ -102,7 +102,7 @@ void anotherExecutionsUpdateWhileAnExportIsInFlightCannotDropAPendingFinalRecord var release = new CountDownLatch(1); var exporter = new CapturingExporter() { @Override - public void export(WorkflowInsightRecord record) { + public void export(DurableExecutionTelemetryRecord record) { super.export(record); if (records.size() == 1) { entered.countDown(); @@ -124,7 +124,7 @@ public void export(WorkflowInsightRecord record) { } private static ExportScheduler scheduler( - Executor executor, List failures, InsightExporter... exporters) { + Executor executor, List failures, TelemetryExporter... exporters) { return new ExportScheduler(List.of(exporters), (rec, exp) -> exp.export(rec), failures::add, executor); } @@ -178,7 +178,7 @@ void updatesArrivingWhileAnExportIsInFlightAreCoalescedAndExportedAfterIt() thro var release = new CountDownLatch(1); var exporter = new CapturingExporter() { @Override - public void export(WorkflowInsightRecord record) { + public void export(DurableExecutionTelemetryRecord record) { super.export(record); if (records.size() == 1) { entered.countDown(); @@ -212,7 +212,7 @@ void drainWaitsForTheInFlightExportAndEveryPendingRecord() throws Exception { var release = new CountDownLatch(1); var exporter = new CapturingExporter() { @Override - public void export(WorkflowInsightRecord record) { + public void export(DurableExecutionTelemetryRecord record) { super.export(record); if (records.size() == 1) { entered.countDown(); @@ -255,7 +255,7 @@ void exportersRunOffTheSchedulingThread() { void aFailingExporterNeverBlocksTheOthersForTheSameRecord() { var failures = new CopyOnWriteArrayList(); var good = new CapturingExporter(); - InsightExporter bad = record -> { + TelemetryExporter bad = record -> { throw new AssertionError("exporter blew up"); }; var scheduler = scheduler(sharedWorkers(), failures, bad, good); @@ -272,7 +272,7 @@ void aFailingExporterNeverBlocksTheOthersForTheSameRecord() { void exportersForOneRecordRunConcurrentlySoASlowExporterDoesNotDelayTheOthers() throws Exception { var release = new CountDownLatch(1); var fast = new CapturingExporter(); - InsightExporter slow = record -> await(release); + TelemetryExporter slow = record -> await(release); var scheduler = scheduler(sharedWorkers(), new ArrayList<>(), slow, fast); scheduler.schedule(record("RUNNING")); @@ -360,18 +360,18 @@ void aDrainThatObservedTheHandleBeforeTheWorkerWasRejectedStillCompletesInline() void flushAllRunsExporterFlushesConcurrentlySoASlowFlushDoesNotDelayTheOthers() throws Exception { var release = new CountDownLatch(1); var fastFlushed = new CountDownLatch(1); - var slow = new InsightExporter() { + var slow = new TelemetryExporter() { @Override - public void export(WorkflowInsightRecord record) {} + public void export(DurableExecutionTelemetryRecord record) {} @Override public void flush() { await(release); } }; - var fast = new InsightExporter() { + var fast = new TelemetryExporter() { @Override - public void export(WorkflowInsightRecord record) {} + public void export(DurableExecutionTelemetryRecord record) {} @Override public void flush() { @@ -397,18 +397,18 @@ public void flush() { void flushAllIsolatesAFailingFlush() { var failures = new CopyOnWriteArrayList(); var flushed = new CountDownLatch(1); - var bad = new InsightExporter() { + var bad = new TelemetryExporter() { @Override - public void export(WorkflowInsightRecord record) {} + public void export(DurableExecutionTelemetryRecord record) {} @Override public void flush() { throw new IllegalStateException("flush failed"); } }; - var good = new InsightExporter() { + var good = new TelemetryExporter() { @Override - public void export(WorkflowInsightRecord record) {} + public void export(DurableExecutionTelemetryRecord record) {} @Override public void flush() { @@ -425,7 +425,7 @@ public void flush() { private static List statuses(CapturingExporter exporter) { List out = new ArrayList<>(); - for (WorkflowInsightRecord r : exporter.records) { + for (DurableExecutionTelemetryRecord r : exporter.records) { out.add(r.status()); } return out; diff --git a/insight-plugin/src/test/java/software/amazon/lambda/durable/insight/ExporterIsolationTest.java b/telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry/ExporterIsolationTest.java similarity index 80% rename from insight-plugin/src/test/java/software/amazon/lambda/durable/insight/ExporterIsolationTest.java rename to telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry/ExporterIsolationTest.java index 61fe8ae689..8b5032d4bb 100644 --- a/insight-plugin/src/test/java/software/amazon/lambda/durable/insight/ExporterIsolationTest.java +++ b/telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry/ExporterIsolationTest.java @@ -1,6 +1,6 @@ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 -package software.amazon.lambda.durable.insight; +package software.amazon.lambda.durable.telemetry; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertInstanceOf; @@ -37,10 +37,10 @@ private static final class MutablePayload { } /** A malicious exporter that mutates operation fields and nested input content. */ - private static final class MutatingExporter implements InsightExporter { + private static final class MutatingExporter implements TelemetryExporter { @Override @SuppressWarnings("unchecked") - public void export(WorkflowInsightRecord record) { + public void export(DurableExecutionTelemetryRecord record) { for (OperationRecord op : record.operations()) { op.name("HACKED").status("HACKED").result("HACKED"); } @@ -56,11 +56,11 @@ public void export(WorkflowInsightRecord record) { } } - private static final class CapturingExporter implements InsightExporter { - final List records = new ArrayList<>(); + private static final class CapturingExporter implements TelemetryExporter { + final List records = new ArrayList<>(); @Override - public void export(WorkflowInsightRecord record) { + public void export(DurableExecutionTelemetryRecord record) { records.add(record); } } @@ -69,14 +69,15 @@ public void export(WorkflowInsightRecord record) { void firstExporterMutationsDoNotLeakIntoLaterExporter() { var mutating = new MutatingExporter(); var good = new CapturingExporter(); - var plugin = (WorkflowInsight.InsightPlugin) WorkflowInsight.workflowInsight(WorkflowInsightConfig.builder() - .emitMode(WorkflowInsightConfig.EmitMode.ON_CHANGE) - .content(ContentConfig.builder() - .addOverride(OperationOverride.withResult("compute", r -> r)) - .build()) - .addExporter(mutating) - .addExporter(good) - .build()); + var plugin = (DurableExecutionTelemetry.TelemetryPlugin) DurableExecutionTelemetry.durableExecutionTelemetry( + DurableExecutionTelemetryConfig.builder() + .emitMode(DurableExecutionTelemetryConfig.EmitMode.ON_CHANGE) + .content(ContentConfig.builder() + .addOverride(OperationOverride.withResult("compute", r -> r)) + .build()) + .addExporter(mutating) + .addExporter(good) + .build()); Map input = new LinkedHashMap<>(); input.put("k", "v"); diff --git a/insight-plugin/src/test/java/software/amazon/lambda/durable/insight/FileExporterTest.java b/telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry/FileExporterTest.java similarity index 86% rename from insight-plugin/src/test/java/software/amazon/lambda/durable/insight/FileExporterTest.java rename to telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry/FileExporterTest.java index e1580b78d1..2c5fecbb79 100644 --- a/insight-plugin/src/test/java/software/amazon/lambda/durable/insight/FileExporterTest.java +++ b/telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry/FileExporterTest.java @@ -1,6 +1,6 @@ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 -package software.amazon.lambda.durable.insight; +package software.amazon.lambda.durable.telemetry; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; @@ -20,8 +20,8 @@ import java.util.concurrent.Future; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.io.TempDir; -import software.amazon.lambda.durable.insight.exporters.FileExporter; -import software.amazon.lambda.durable.insight.exporters.OperationsFormat; +import software.amazon.lambda.durable.telemetry.exporters.FileExporter; +import software.amazon.lambda.durable.telemetry.exporters.OperationsFormat; class FileExporterTest { @@ -31,8 +31,8 @@ class FileExporterTest { @TempDir Path tempDir; - private WorkflowInsightRecord sampleRecord() { - WorkflowInsightRecord r = new WorkflowInsightRecord(); + private DurableExecutionTelemetryRecord sampleRecord() { + DurableExecutionTelemetryRecord r = new DurableExecutionTelemetryRecord(); r.emittedAt = "2026-07-15T12:00:00.000Z"; r.executionArn = ARN; r.functionName = "fn"; @@ -45,10 +45,10 @@ private WorkflowInsightRecord sampleRecord() { @Test void appendsDatePartitionedNdjsonLinesAndCreatesTheDirectory() throws Exception { - Path dir = tempDir.resolve("nested/insight"); + Path dir = tempDir.resolve("nested/telemetry"); FileExporter exporter = FileExporter.builder().directory(dir.toString()).build(); - WorkflowInsightRecord first = sampleRecord(); - WorkflowInsightRecord second = sampleRecord(); + DurableExecutionTelemetryRecord first = sampleRecord(); + DurableExecutionTelemetryRecord second = sampleRecord(); second.status = "FAILED"; exporter.export(first); exporter.export(second); @@ -71,7 +71,7 @@ void jsonModeWritesOnePrettyFilePerExecutionAndOverwrites() throws Exception { .mode(FileExporter.Mode.JSON) .operationsFormat(OperationsFormat.BY_NAME) .build(); - WorkflowInsightRecord record = sampleRecord(); + DurableExecutionTelemetryRecord record = sampleRecord(); record.executionName = "my exec/1"; record.input = Map.of("empty", List.of()); exporter.export(record); @@ -80,7 +80,7 @@ void jsonModeWritesOnePrettyFilePerExecutionAndOverwrites() throws Exception { Path file = tempDir.resolve("my_exec_1.json"); String content = Files.readString(file); - assertTrue(content.startsWith("{\n \"recordType\": \"WorkflowInsight\",\n"), content); + assertTrue(content.startsWith("{\n \"recordType\": \"DurableExecutionTelemetry\",\n"), content); assertTrue(content.contains("\"empty\": []"), content); assertFalse(content.contains(" : "), "no space before the colon"); JsonNode parsed = MAPPER.readTree(content); @@ -105,7 +105,7 @@ void concurrentLargeRecordsAppendWholeLines() throws Exception { futures.add(pool.submit(() -> { go.await(); for (int i = 0; i < perThread; i++) { - WorkflowInsightRecord r = sampleRecord(); + DurableExecutionTelemetryRecord r = sampleRecord(); r.input = Map.of("payload", payload); exporter.export(r); } diff --git a/insight-plugin/src/test/java/software/amazon/lambda/durable/insight/FirehoseExporterTest.java b/telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry/FirehoseExporterTest.java similarity index 80% rename from insight-plugin/src/test/java/software/amazon/lambda/durable/insight/FirehoseExporterTest.java rename to telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry/FirehoseExporterTest.java index 48604fc0b3..8a85f18c04 100644 --- a/insight-plugin/src/test/java/software/amazon/lambda/durable/insight/FirehoseExporterTest.java +++ b/telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry/FirehoseExporterTest.java @@ -1,6 +1,6 @@ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 -package software.amazon.lambda.durable.insight; +package software.amazon.lambda.durable.telemetry; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; @@ -15,13 +15,13 @@ import software.amazon.awssdk.services.firehose.FirehoseClient; import software.amazon.awssdk.services.firehose.model.PutRecordRequest; import software.amazon.awssdk.services.firehose.model.PutRecordResponse; -import software.amazon.lambda.durable.insight.exporters.FirehoseExporter; -import software.amazon.lambda.durable.insight.exporters.OperationsFormat; +import software.amazon.lambda.durable.telemetry.exporters.FirehoseExporter; +import software.amazon.lambda.durable.telemetry.exporters.OperationsFormat; class FirehoseExporterTest { - private WorkflowInsightRecord sampleRecord() { - WorkflowInsightRecord r = new WorkflowInsightRecord(); + private DurableExecutionTelemetryRecord sampleRecord() { + DurableExecutionTelemetryRecord r = new DurableExecutionTelemetryRecord(); r.emittedAt = "2026-07-15T12:00:00.000Z"; r.executionArn = "arn:aws:lambda:us-east-1:123456789012:function:fn:$LATEST"; r.functionName = "fn"; @@ -32,7 +32,7 @@ private WorkflowInsightRecord sampleRecord() { return r; } - private static PutRecordRequest export(FirehoseExporter.Builder builder, WorkflowInsightRecord record) { + private static PutRecordRequest export(FirehoseExporter.Builder builder, DurableExecutionTelemetryRecord record) { FirehoseClient client = mock(FirehoseClient.class); when(client.putRecord(any(PutRecordRequest.class))) .thenReturn(PutRecordResponse.builder().build()); @@ -44,10 +44,10 @@ private static PutRecordRequest export(FirehoseExporter.Builder builder, Workflo @Test void putsOneNewlineTerminatedJsonRecord() { - WorkflowInsightRecord record = sampleRecord(); - PutRecordRequest req = export(FirehoseExporter.builder().deliveryStreamName("insight-stream"), record); + DurableExecutionTelemetryRecord record = sampleRecord(); + PutRecordRequest req = export(FirehoseExporter.builder().deliveryStreamName("telemetry-stream"), record); - assertEquals("insight-stream", req.deliveryStreamName()); + assertEquals("telemetry-stream", req.deliveryStreamName()); String data = req.record().data().asUtf8String(); assertEquals(Json.stringify(record.toWireMap()) + "\n", data); assertTrue(data.contains("\"operations\":[")); @@ -56,7 +56,7 @@ void putsOneNewlineTerminatedJsonRecord() { @Test void honorsByNameFormatAndDefaultLimit() { FirehoseExporter.Builder builder = FirehoseExporter.builder() - .deliveryStreamName("insight-stream") + .deliveryStreamName("telemetry-stream") .operationsFormat(OperationsFormat.BY_NAME); PutRecordRequest req = export(builder, sampleRecord()); String data = req.record().data().asUtf8String(); diff --git a/insight-plugin/src/test/java/software/amazon/lambda/durable/insight/HttpExporterTest.java b/telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry/HttpExporterTest.java similarity index 90% rename from insight-plugin/src/test/java/software/amazon/lambda/durable/insight/HttpExporterTest.java rename to telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry/HttpExporterTest.java index 493d91e44a..70baa13277 100644 --- a/insight-plugin/src/test/java/software/amazon/lambda/durable/insight/HttpExporterTest.java +++ b/telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry/HttpExporterTest.java @@ -1,6 +1,6 @@ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 -package software.amazon.lambda.durable.insight; +package software.amazon.lambda.durable.telemetry; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; @@ -12,13 +12,13 @@ import java.net.http.HttpTimeoutException; import java.util.Map; import org.junit.jupiter.api.Test; -import software.amazon.lambda.durable.insight.exporters.HttpExporter; -import software.amazon.lambda.durable.insight.exporters.OperationsFormat; +import software.amazon.lambda.durable.telemetry.exporters.HttpExporter; +import software.amazon.lambda.durable.telemetry.exporters.OperationsFormat; class HttpExporterTest { - private WorkflowInsightRecord sampleRecord() { - WorkflowInsightRecord r = new WorkflowInsightRecord(); + private DurableExecutionTelemetryRecord sampleRecord() { + DurableExecutionTelemetryRecord r = new DurableExecutionTelemetryRecord(); r.emittedAt = "2026-07-15T12:00:00.000Z"; r.executionArn = "arn:aws:lambda:us-east-1:123456789012:function:fn:$LATEST"; r.functionName = "fn"; @@ -32,7 +32,7 @@ private WorkflowInsightRecord sampleRecord() { @Test void postsJsonWithContentTypeAndCustomHeaders() throws Exception { try (LocalHttpServer server = new LocalHttpServer()) { - WorkflowInsightRecord record = sampleRecord(); + DurableExecutionTelemetryRecord record = sampleRecord(); HttpExporter exporter = HttpExporter.builder() .url(server.url("/hook")) .headers(Map.of("Authorization", "Bearer t0k")) diff --git a/insight-plugin/src/test/java/software/amazon/lambda/durable/insight/InputSnapshotTest.java b/telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry/InputSnapshotTest.java similarity index 83% rename from insight-plugin/src/test/java/software/amazon/lambda/durable/insight/InputSnapshotTest.java rename to telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry/InputSnapshotTest.java index abd5f89f78..a28b2b066e 100644 --- a/insight-plugin/src/test/java/software/amazon/lambda/durable/insight/InputSnapshotTest.java +++ b/telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry/InputSnapshotTest.java @@ -1,6 +1,6 @@ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 -package software.amazon.lambda.durable.insight; +package software.amazon.lambda.durable.telemetry; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertInstanceOf; @@ -32,11 +32,11 @@ class InputSnapshotTest { "arn:aws:lambda:us-west-2:1:function:f:$LATEST/durable-execution/exec-1/invocation-1"; private static final Instant START = Instant.parse("2026-08-05T00:00:00Z"); - private static final class CapturingExporter implements InsightExporter { - final List records = new ArrayList<>(); + private static final class CapturingExporter implements TelemetryExporter { + final List records = new ArrayList<>(); @Override - public void export(WorkflowInsightRecord record) { + public void export(DurableExecutionTelemetryRecord record) { records.add(record); } } @@ -64,8 +64,8 @@ private Map ops() { @Test void handlerMutationAfterStartDoesNotCorruptCachedInputSnapshot() { var exporter = new CapturingExporter(); - DurableExecutionPlugin plugin = WorkflowInsight.workflowInsight( - WorkflowInsightConfig.builder().addExporter(exporter).build()); + DurableExecutionPlugin plugin = DurableExecutionTelemetry.durableExecutionTelemetry( + DurableExecutionTelemetryConfig.builder().addExporter(exporter).build()); // A mutable input whose nested list the handler mutates after the invocation has started. List items = new ArrayList<>(); @@ -99,13 +99,14 @@ void mutatingInputTransformDoesNotAccumulateAcrossEmissions() { return v; }; var exporter = new CapturingExporter(); - var plugin = (WorkflowInsight.InsightPlugin) WorkflowInsight.workflowInsight(WorkflowInsightConfig.builder() - .emitMode(WorkflowInsightConfig.EmitMode.ON_CHANGE) - .content(ContentConfig.builder() - .inputTransform(mutatingTransform) - .build()) - .addExporter(exporter) - .build()); + var plugin = (DurableExecutionTelemetry.TelemetryPlugin) + DurableExecutionTelemetry.durableExecutionTelemetry(DurableExecutionTelemetryConfig.builder() + .emitMode(DurableExecutionTelemetryConfig.EmitMode.ON_CHANGE) + .content(ContentConfig.builder() + .inputTransform(mutatingTransform) + .build()) + .addExporter(exporter) + .build()); List items = new ArrayList<>(); items.add("a"); @@ -121,7 +122,7 @@ void mutatingInputTransformDoesNotAccumulateAcrossEmissions() { assertEquals(3, exporter.records.size()); // Each emission's transform received a fresh copy: original "a" plus exactly one "MARK", never accumulating. - for (WorkflowInsightRecord rec : exporter.records) { + for (DurableExecutionTelemetryRecord rec : exporter.records) { var emitted = assertInstanceOf(Map.class, rec.input); var emittedItems = assertInstanceOf(List.class, emitted.get("items")); assertEquals(2, emittedItems.size(), "transform sees a fresh snapshot copy each emission"); diff --git a/insight-plugin/src/test/java/software/amazon/lambda/durable/insight/JsonJavaTimeTest.java b/telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry/JsonJavaTimeTest.java similarity index 83% rename from insight-plugin/src/test/java/software/amazon/lambda/durable/insight/JsonJavaTimeTest.java rename to telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry/JsonJavaTimeTest.java index e57366bbac..ddb715ab90 100644 --- a/insight-plugin/src/test/java/software/amazon/lambda/durable/insight/JsonJavaTimeTest.java +++ b/telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry/JsonJavaTimeTest.java @@ -1,6 +1,6 @@ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 -package software.amazon.lambda.durable.insight; +package software.amazon.lambda.durable.telemetry; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; @@ -43,11 +43,11 @@ void byteSizeOfPayloadContainingInstantIsNotNull() { assertTrue(size > 0); } - private static final class CapturingExporter implements InsightExporter { - final List records = new ArrayList<>(); + private static final class CapturingExporter implements TelemetryExporter { + final List records = new ArrayList<>(); @Override - public void export(WorkflowInsightRecord record) { + public void export(DurableExecutionTelemetryRecord record) { records.add(record); } } @@ -55,10 +55,11 @@ public void export(WorkflowInsightRecord record) { @Test void pluginOutputWithInstantInInputSerializesInsteadOfDropping() { var exporter = new CapturingExporter(); - var plugin = (WorkflowInsight.InsightPlugin) WorkflowInsight.workflowInsight(WorkflowInsightConfig.builder() - .emitMode(WorkflowInsightConfig.EmitMode.ON_CHANGE) - .addExporter(exporter) - .build()); + var plugin = (DurableExecutionTelemetry.TelemetryPlugin) + DurableExecutionTelemetry.durableExecutionTelemetry(DurableExecutionTelemetryConfig.builder() + .emitMode(DurableExecutionTelemetryConfig.EmitMode.ON_CHANGE) + .addExporter(exporter) + .build()); Map input = new LinkedHashMap<>(); input.put("startedAt", TS); diff --git a/insight-plugin/src/test/java/software/amazon/lambda/durable/insight/LocalHttpServer.java b/telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry/LocalHttpServer.java similarity index 98% rename from insight-plugin/src/test/java/software/amazon/lambda/durable/insight/LocalHttpServer.java rename to telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry/LocalHttpServer.java index 994939c11d..876fc7de1d 100644 --- a/insight-plugin/src/test/java/software/amazon/lambda/durable/insight/LocalHttpServer.java +++ b/telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry/LocalHttpServer.java @@ -1,6 +1,6 @@ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 -package software.amazon.lambda.durable.insight; +package software.amazon.lambda.durable.telemetry; import com.sun.net.httpserver.Headers; import com.sun.net.httpserver.HttpServer; diff --git a/insight-plugin/src/test/java/software/amazon/lambda/durable/insight/MutableNumberIsolationTest.java b/telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry/MutableNumberIsolationTest.java similarity index 88% rename from insight-plugin/src/test/java/software/amazon/lambda/durable/insight/MutableNumberIsolationTest.java rename to telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry/MutableNumberIsolationTest.java index 19f906209e..ac1362188a 100644 --- a/insight-plugin/src/test/java/software/amazon/lambda/durable/insight/MutableNumberIsolationTest.java +++ b/telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry/MutableNumberIsolationTest.java @@ -1,6 +1,6 @@ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 -package software.amazon.lambda.durable.insight; +package software.amazon.lambda.durable.telemetry; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertInstanceOf; @@ -105,19 +105,20 @@ void customSerializableNumberIsDetachedAndStaysNumeric() { @Test void nestedMutableNumbersInMapAndListAreIsolatedButJsonStaysNumeric() { - var mutating = new InsightExporter() { + var mutating = new TelemetryExporter() { @Override - public void export(WorkflowInsightRecord record) { + public void export(DurableExecutionTelemetryRecord record) { // A hostile exporter cannot mutate an isolated immutable numeric leaf, but attempt any nested access. record.operations().forEach(op -> {}); } }; var good = new CapturingExporter(); - var plugin = (WorkflowInsight.InsightPlugin) WorkflowInsight.workflowInsight(WorkflowInsightConfig.builder() - .emitMode(WorkflowInsightConfig.EmitMode.ON_CHANGE) - .addExporter(mutating) - .addExporter(good) - .build()); + var plugin = (DurableExecutionTelemetry.TelemetryPlugin) + DurableExecutionTelemetry.durableExecutionTelemetry(DurableExecutionTelemetryConfig.builder() + .emitMode(DurableExecutionTelemetryConfig.EmitMode.ON_CHANGE) + .addExporter(mutating) + .addExporter(good) + .build()); AtomicInteger topLevel = new AtomicInteger(3); List list = new ArrayList<>(); @@ -145,11 +146,11 @@ public void export(WorkflowInsightRecord record) { assertTrue(json.contains("\"custom\":99"), json); } - private static final class CapturingExporter implements InsightExporter { - final List records = new ArrayList<>(); + private static final class CapturingExporter implements TelemetryExporter { + final List records = new ArrayList<>(); @Override - public void export(WorkflowInsightRecord record) { + public void export(DurableExecutionTelemetryRecord record) { records.add(record); } } diff --git a/insight-plugin/src/test/java/software/amazon/lambda/durable/insight/OTelExporterTest.java b/telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry/OTelExporterTest.java similarity index 94% rename from insight-plugin/src/test/java/software/amazon/lambda/durable/insight/OTelExporterTest.java rename to telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry/OTelExporterTest.java index b4af9c9aa4..20733257d2 100644 --- a/insight-plugin/src/test/java/software/amazon/lambda/durable/insight/OTelExporterTest.java +++ b/telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry/OTelExporterTest.java @@ -1,6 +1,6 @@ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 -package software.amazon.lambda.durable.insight; +package software.amazon.lambda.durable.telemetry; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; @@ -10,16 +10,16 @@ import com.fasterxml.jackson.databind.ObjectMapper; import java.util.Map; import org.junit.jupiter.api.Test; -import software.amazon.lambda.durable.insight.exporters.OTelExporter; -import software.amazon.lambda.durable.insight.exporters.OperationsFormat; +import software.amazon.lambda.durable.telemetry.exporters.OTelExporter; +import software.amazon.lambda.durable.telemetry.exporters.OperationsFormat; class OTelExporterTest { private static final String ARN = "arn:aws:lambda:us-east-1:123456789012:function:fn:$LATEST"; private static final ObjectMapper MAPPER = new ObjectMapper(); - private WorkflowInsightRecord sampleRecord() { - WorkflowInsightRecord r = new WorkflowInsightRecord(); + private DurableExecutionTelemetryRecord sampleRecord() { + DurableExecutionTelemetryRecord r = new DurableExecutionTelemetryRecord(); r.emittedAt = "2026-07-15T12:00:00.000Z"; r.executionArn = ARN; r.executionName = "exec-1"; @@ -97,7 +97,7 @@ void postsOneOtlpLogRecordWithResourceAndLogAttributes() throws Exception { @Test void absentFieldsRenderEmptyValuesAndByNameBody() throws Exception { try (LocalHttpServer server = new LocalHttpServer()) { - WorkflowInsightRecord record = sampleRecord(); + DurableExecutionTelemetryRecord record = sampleRecord(); record.region = null; record.executionName = null; record.durationMs = null; diff --git a/insight-plugin/src/test/java/software/amazon/lambda/durable/insight/OpenSearchExporterTest.java b/telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry/OpenSearchExporterTest.java similarity index 92% rename from insight-plugin/src/test/java/software/amazon/lambda/durable/insight/OpenSearchExporterTest.java rename to telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry/OpenSearchExporterTest.java index 4e35119605..2c7d7a41e1 100644 --- a/insight-plugin/src/test/java/software/amazon/lambda/durable/insight/OpenSearchExporterTest.java +++ b/telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry/OpenSearchExporterTest.java @@ -1,6 +1,6 @@ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 -package software.amazon.lambda.durable.insight; +package software.amazon.lambda.durable.telemetry; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; @@ -12,7 +12,7 @@ import org.junit.jupiter.api.Test; import software.amazon.awssdk.auth.credentials.AwsBasicCredentials; import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider; -import software.amazon.lambda.durable.insight.exporters.OpenSearchExporter; +import software.amazon.lambda.durable.telemetry.exporters.OpenSearchExporter; class OpenSearchExporterTest { @@ -20,8 +20,8 @@ class OpenSearchExporterTest { private static final String ENCODED_ARN = "arn%3Aaws%3Alambda%3Aus-east-1%3A123456789012%3Afunction%3Afn%3A%24LATEST"; - private WorkflowInsightRecord sampleRecord() { - WorkflowInsightRecord r = new WorkflowInsightRecord(); + private DurableExecutionTelemetryRecord sampleRecord() { + DurableExecutionTelemetryRecord r = new DurableExecutionTelemetryRecord(); r.emittedAt = "2026-07-15T12:00:00.000Z"; r.executionArn = ARN; r.functionName = "fn"; @@ -35,7 +35,7 @@ private WorkflowInsightRecord sampleRecord() { @Test void putsSignedDocumentKeyedByEncodedArn() throws Exception { try (LocalHttpServer server = new LocalHttpServer()) { - WorkflowInsightRecord record = sampleRecord(); + DurableExecutionTelemetryRecord record = sampleRecord(); OpenSearchExporter.builder() .endpoint(server.url("/")) .region("us-east-1") @@ -45,7 +45,7 @@ void putsSignedDocumentKeyedByEncodedArn() throws Exception { LocalHttpServer.Captured req = server.only(); assertEquals("PUT", req.method); - assertEquals("/workflow-insight/_doc/" + ENCODED_ARN, req.path); + assertEquals("/durable-execution-telemetry/_doc/" + ENCODED_ARN, req.path); assertEquals("application/json", req.headers.getFirst("Content-Type")); String authorization = req.headers.getFirst("Authorization"); assertNotNull(authorization); diff --git a/insight-plugin/src/test/java/software/amazon/lambda/durable/insight/OperationErrorIdentityTest.java b/telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry/OperationErrorIdentityTest.java similarity index 87% rename from insight-plugin/src/test/java/software/amazon/lambda/durable/insight/OperationErrorIdentityTest.java rename to telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry/OperationErrorIdentityTest.java index 5e67cd554c..95877850a6 100644 --- a/insight-plugin/src/test/java/software/amazon/lambda/durable/insight/OperationErrorIdentityTest.java +++ b/telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry/OperationErrorIdentityTest.java @@ -1,6 +1,6 @@ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 -package software.amazon.lambda.durable.insight; +package software.amazon.lambda.durable.telemetry; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; @@ -40,11 +40,11 @@ private static DurableOperationException wrapped(String errorType, String errorM return new DurableOperationException(Operation.builder().id("op-1").build(), error); } - private static final class CapturingExporter implements InsightExporter { - final List records = new ArrayList<>(); + private static final class CapturingExporter implements TelemetryExporter { + final List records = new ArrayList<>(); @Override - public void export(WorkflowInsightRecord record) { + public void export(DurableExecutionTelemetryRecord record) { records.add(record); } } @@ -72,8 +72,8 @@ private Map failedOps(Throwable opError) { @Test void operationAndExecutionErrorUseCheckpointedErrorObjectIdentity() { var exporter = new CapturingExporter(); - DurableExecutionPlugin plugin = WorkflowInsight.workflowInsight( - WorkflowInsightConfig.builder().addExporter(exporter).build()); + DurableExecutionPlugin plugin = DurableExecutionTelemetry.durableExecutionTelemetry( + DurableExecutionTelemetryConfig.builder().addExporter(exporter).build()); Throwable opError = wrapped("CustomerValidationError", "invalid postal code"); Throwable execError = wrapped("OrchestrationFailure", "workflow aborted"); @@ -98,8 +98,8 @@ void operationAndExecutionErrorUseCheckpointedErrorObjectIdentity() { @Test void fallsBackToThrowableFieldsWhenErrorObjectFieldsMissing() { var exporter = new CapturingExporter(); - DurableExecutionPlugin plugin = WorkflowInsight.workflowInsight( - WorkflowInsightConfig.builder().addExporter(exporter).build()); + DurableExecutionPlugin plugin = DurableExecutionTelemetry.durableExecutionTelemetry( + DurableExecutionTelemetryConfig.builder().addExporter(exporter).build()); // ErrorObject present but errorType null: name falls back to the throwable's simple class name. ErrorObject partial = diff --git a/insight-plugin/src/test/java/software/amazon/lambda/durable/insight/OperationOrderingTest.java b/telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry/OperationOrderingTest.java similarity index 87% rename from insight-plugin/src/test/java/software/amazon/lambda/durable/insight/OperationOrderingTest.java rename to telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry/OperationOrderingTest.java index d1ca11b039..bddee9acd0 100644 --- a/insight-plugin/src/test/java/software/amazon/lambda/durable/insight/OperationOrderingTest.java +++ b/telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry/OperationOrderingTest.java @@ -1,6 +1,6 @@ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 -package software.amazon.lambda.durable.insight; +package software.amazon.lambda.durable.telemetry; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNull; @@ -27,11 +27,11 @@ class OperationOrderingTest { "arn:aws:lambda:us-west-2:1:function:f:$LATEST/durable-execution/exec-1/invocation-1"; private static final Instant START = Instant.parse("2026-08-05T00:00:00Z"); - private static final class CapturingExporter implements InsightExporter { - final List records = new ArrayList<>(); + private static final class CapturingExporter implements TelemetryExporter { + final List records = new ArrayList<>(); @Override - public void export(WorkflowInsightRecord record) { + public void export(DurableExecutionTelemetryRecord record) { records.add(record); } } @@ -42,12 +42,13 @@ private static OperationChangeItemInfo item( return new OperationChangeItemInfo(id, name, type, subType, null, start, end, status, 1, false, null, null); } - private WorkflowInsightRecord emitStart(Map ops) { + private DurableExecutionTelemetryRecord emitStart(Map ops) { var exporter = new CapturingExporter(); - var plugin = (WorkflowInsight.InsightPlugin) WorkflowInsight.workflowInsight(WorkflowInsightConfig.builder() - .emitMode(WorkflowInsightConfig.EmitMode.ON_CHANGE) - .addExporter(exporter) - .build()); + var plugin = (DurableExecutionTelemetry.TelemetryPlugin) + DurableExecutionTelemetry.durableExecutionTelemetry(DurableExecutionTelemetryConfig.builder() + .emitMode(DurableExecutionTelemetryConfig.EmitMode.ON_CHANGE) + .addExporter(exporter) + .build()); plugin.onInvocationStart(new InvocationInfo("req", ARN, true, START, "in", ops, Map.of())); plugin.drainExports(); return exporter.records.get(0); diff --git a/insight-plugin/src/test/java/software/amazon/lambda/durable/insight/OperationsFormatTest.java b/telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry/OperationsFormatTest.java similarity index 90% rename from insight-plugin/src/test/java/software/amazon/lambda/durable/insight/OperationsFormatTest.java rename to telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry/OperationsFormatTest.java index 58ea536313..b61360982a 100644 --- a/insight-plugin/src/test/java/software/amazon/lambda/durable/insight/OperationsFormatTest.java +++ b/telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry/OperationsFormatTest.java @@ -1,6 +1,6 @@ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 -package software.amazon.lambda.durable.insight; +package software.amazon.lambda.durable.telemetry; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; @@ -10,12 +10,12 @@ import java.util.List; import java.util.Map; import org.junit.jupiter.api.Test; -import software.amazon.lambda.durable.insight.exporters.OperationsFormat; +import software.amazon.lambda.durable.telemetry.exporters.OperationsFormat; class OperationsFormatTest { - private WorkflowInsightRecord sampleRecord() { - WorkflowInsightRecord r = new WorkflowInsightRecord(); + private DurableExecutionTelemetryRecord sampleRecord() { + DurableExecutionTelemetryRecord r = new DurableExecutionTelemetryRecord(); r.executionArn = "arn:aws:lambda:us-east-1:123456789012:function:fn:$LATEST"; r.status = "SUCCEEDED"; r.truncated = true; diff --git a/insight-plugin/src/test/java/software/amazon/lambda/durable/insight/OperationsIndexTest.java b/telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry/OperationsIndexTest.java similarity index 98% rename from insight-plugin/src/test/java/software/amazon/lambda/durable/insight/OperationsIndexTest.java rename to telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry/OperationsIndexTest.java index dfd150219c..d7d997051c 100644 --- a/insight-plugin/src/test/java/software/amazon/lambda/durable/insight/OperationsIndexTest.java +++ b/telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry/OperationsIndexTest.java @@ -1,6 +1,6 @@ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 -package software.amazon.lambda.durable.insight; +package software.amazon.lambda.durable.telemetry; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; diff --git a/insight-plugin/src/test/java/software/amazon/lambda/durable/insight/PluginThrowableContainmentTest.java b/telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry/PluginThrowableContainmentTest.java similarity index 71% rename from insight-plugin/src/test/java/software/amazon/lambda/durable/insight/PluginThrowableContainmentTest.java rename to telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry/PluginThrowableContainmentTest.java index 4a13268bee..0f4fb3a0fb 100644 --- a/insight-plugin/src/test/java/software/amazon/lambda/durable/insight/PluginThrowableContainmentTest.java +++ b/telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry/PluginThrowableContainmentTest.java @@ -1,6 +1,6 @@ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 -package software.amazon.lambda.durable.insight; +package software.amazon.lambda.durable.telemetry; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNull; @@ -32,12 +32,12 @@ class PluginThrowableContainmentTest { "arn:aws:lambda:us-west-2:1:function:f:$LATEST/durable-execution/exec-1/invocation-1"; private static final Instant START = Instant.parse("2026-08-05T00:00:00Z"); - private static final class CapturingExporter implements InsightExporter { - final List records = new ArrayList<>(); + private static final class CapturingExporter implements TelemetryExporter { + final List records = new ArrayList<>(); int flushes; @Override - public void export(WorkflowInsightRecord record) { + public void export(DurableExecutionTelemetryRecord record) { records.add(record); } @@ -85,17 +85,18 @@ private InvocationEndInfo end(Object input) { @Test void exporterThrowingErrorIsIsolatedAndLaterExportersStillReceiveAndFlush() { - var throwing = new InsightExporter() { + var throwing = new TelemetryExporter() { @Override - public void export(WorkflowInsightRecord record) { + public void export(DurableExecutionTelemetryRecord record) { throw new AssertionError("exporter blew up with an Error"); } }; var good = new CapturingExporter(); - DurableExecutionPlugin plugin = WorkflowInsight.workflowInsight(WorkflowInsightConfig.builder() - .addExporter(throwing) - .addExporter(good) - .build()); + DurableExecutionPlugin plugin = + DurableExecutionTelemetry.durableExecutionTelemetry(DurableExecutionTelemetryConfig.builder() + .addExporter(throwing) + .addExporter(good) + .build()); plugin.onInvocationStart(start("in")); plugin.onInvocationEnd(end("in")); @@ -107,8 +108,8 @@ public void export(WorkflowInsightRecord record) { @Test void inputSnapshotErrorOmitsInputButDoesNotDisruptExecution() { var exporter = new CapturingExporter(); - DurableExecutionPlugin plugin = WorkflowInsight.workflowInsight( - WorkflowInsightConfig.builder().addExporter(exporter).build()); + DurableExecutionPlugin plugin = DurableExecutionTelemetry.durableExecutionTelemetry( + DurableExecutionTelemetryConfig.builder().addExporter(exporter).build()); // Snapshotting the input fails with an Error; the hook must not propagate it. plugin.onInvocationStart(start(new ExplodingPayload())); @@ -123,14 +124,15 @@ void inputSnapshotErrorOmitsInputButDoesNotDisruptExecution() { @Test void throwingInputTransformOmitsInputWithoutFailure() { var exporter = new CapturingExporter(); - DurableExecutionPlugin plugin = WorkflowInsight.workflowInsight(WorkflowInsightConfig.builder() - .content(ContentConfig.builder() - .inputTransform(v -> { - throw new AssertionError("redactor blew up"); - }) - .build()) - .addExporter(exporter) - .build()); + DurableExecutionPlugin plugin = + DurableExecutionTelemetry.durableExecutionTelemetry(DurableExecutionTelemetryConfig.builder() + .content(ContentConfig.builder() + .inputTransform(v -> { + throw new AssertionError("redactor blew up"); + }) + .build()) + .addExporter(exporter) + .build()); plugin.onInvocationStart(start("in")); plugin.onInvocationEnd(end("in")); @@ -143,14 +145,15 @@ void throwingInputTransformOmitsInputWithoutFailure() { @Test void throwingResultTransformOmitsResultWithoutFailure() { var exporter = new CapturingExporter(); - DurableExecutionPlugin plugin = WorkflowInsight.workflowInsight(WorkflowInsightConfig.builder() - .content(ContentConfig.builder() - .addOverride(OperationOverride.withResult("compute", r -> { - throw new AssertionError("result redactor blew up"); - })) - .build()) - .addExporter(exporter) - .build()); + DurableExecutionPlugin plugin = + DurableExecutionTelemetry.durableExecutionTelemetry(DurableExecutionTelemetryConfig.builder() + .content(ContentConfig.builder() + .addOverride(OperationOverride.withResult("compute", r -> { + throw new AssertionError("result redactor blew up"); + })) + .build()) + .addExporter(exporter) + .build()); plugin.onInvocationStart(start("in")); plugin.onInvocationEnd(end("in")); @@ -167,18 +170,19 @@ void throwingResultTransformOmitsResultWithoutFailure() { @Test void oneFailingExporterInTheMiddleDoesNotBlockTheThird() { var first = new CapturingExporter(); - var throwing = new InsightExporter() { + var throwing = new TelemetryExporter() { @Override - public void export(WorkflowInsightRecord record) { + public void export(DurableExecutionTelemetryRecord record) { throw new Error("hard error in the middle exporter"); } }; var third = new CapturingExporter(); - DurableExecutionPlugin plugin = WorkflowInsight.workflowInsight(WorkflowInsightConfig.builder() - .addExporter(first) - .addExporter(throwing) - .addExporter(third) - .build()); + DurableExecutionPlugin plugin = + DurableExecutionTelemetry.durableExecutionTelemetry(DurableExecutionTelemetryConfig.builder() + .addExporter(first) + .addExporter(throwing) + .addExporter(third) + .build()); plugin.onInvocationStart(start("in")); plugin.onInvocationEnd(end("in")); diff --git a/insight-plugin/src/test/java/software/amazon/lambda/durable/insight/RecordFactory.java b/telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry/RecordFactory.java similarity index 78% rename from insight-plugin/src/test/java/software/amazon/lambda/durable/insight/RecordFactory.java rename to telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry/RecordFactory.java index 4ffb31d31a..fc116c2c6a 100644 --- a/insight-plugin/src/test/java/software/amazon/lambda/durable/insight/RecordFactory.java +++ b/telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry/RecordFactory.java @@ -1,13 +1,13 @@ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 -package software.amazon.lambda.durable.insight; +package software.amazon.lambda.durable.telemetry; /** Builds a minimal, fully populated record for exporter tests outside this package. */ public final class RecordFactory { private RecordFactory() {} - public static WorkflowInsightRecord sample() { - WorkflowInsightRecord r = new WorkflowInsightRecord(); + public static DurableExecutionTelemetryRecord sample() { + DurableExecutionTelemetryRecord r = new DurableExecutionTelemetryRecord(); r.emittedAt = "2026-07-15T12:00:00.000Z"; r.executionArn = "arn:aws:lambda:us-east-1:123456789012:function:fn:$LATEST"; r.executionName = "exec-1"; diff --git a/insight-plugin/src/test/java/software/amazon/lambda/durable/insight/RedshiftExporterTest.java b/telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry/RedshiftExporterTest.java similarity index 84% rename from insight-plugin/src/test/java/software/amazon/lambda/durable/insight/RedshiftExporterTest.java rename to telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry/RedshiftExporterTest.java index cb03f8a15a..4a4df9a409 100644 --- a/insight-plugin/src/test/java/software/amazon/lambda/durable/insight/RedshiftExporterTest.java +++ b/telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry/RedshiftExporterTest.java @@ -1,6 +1,6 @@ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 -package software.amazon.lambda.durable.insight; +package software.amazon.lambda.durable.telemetry; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; @@ -20,14 +20,14 @@ import software.amazon.awssdk.services.redshiftdata.model.ExecuteStatementRequest; import software.amazon.awssdk.services.redshiftdata.model.ExecuteStatementResponse; import software.amazon.awssdk.services.redshiftdata.model.SqlParameter; -import software.amazon.lambda.durable.insight.exporters.RedshiftExporter; +import software.amazon.lambda.durable.telemetry.exporters.RedshiftExporter; class RedshiftExporterTest { private static final String ARN = "arn:aws:lambda:us-east-1:123456789012:function:fn:$LATEST"; - private WorkflowInsightRecord sampleRecord() { - WorkflowInsightRecord r = new WorkflowInsightRecord(); + private DurableExecutionTelemetryRecord sampleRecord() { + DurableExecutionTelemetryRecord r = new DurableExecutionTelemetryRecord(); r.emittedAt = "2026-07-15T12:00:00.000Z"; r.executionArn = ARN; r.functionName = "fn"; @@ -38,7 +38,8 @@ private WorkflowInsightRecord sampleRecord() { return r; } - private static ExecuteStatementRequest export(RedshiftExporter.Builder builder, WorkflowInsightRecord record) { + private static ExecuteStatementRequest export( + RedshiftExporter.Builder builder, DurableExecutionTelemetryRecord record) { RedshiftDataClient client = mock(RedshiftDataClient.class); when(client.executeStatement(any(ExecuteStatementRequest.class))) .thenReturn(ExecuteStatementResponse.builder().build()); @@ -58,21 +59,21 @@ private static Map params(ExecuteStatementRequest req) { @Test void serverlessMergeUsesTypedNullLiteralsForAbsentFields() { - WorkflowInsightRecord record = sampleRecord(); + DurableExecutionTelemetryRecord record = sampleRecord(); ExecuteStatementRequest req = - export(RedshiftExporter.builder().workgroupName("wg").database("insight"), record); + export(RedshiftExporter.builder().workgroupName("wg").database("telemetry"), record); assertEquals("wg", req.workgroupName()); assertNull(req.clusterIdentifier()); - assertEquals("insight", req.database()); + assertEquals("telemetry", req.database()); assertNull(req.dbUser()); assertNull(req.secretArn()); - assertTrue(req.sql().startsWith("MERGE INTO public.workflow_insight USING (")); + assertTrue(req.sql().startsWith("MERGE INTO public.durable_execution_telemetry USING (")); assertTrue(req.sql().contains("NULL::varchar AS execution_name")); assertTrue(req.sql().contains("NULL::timestamptz AS end_time")); assertTrue(req.sql().contains("NULL::bigint AS duration_ms")); assertTrue(req.sql().contains("JSON_PARSE(:record_json) AS record_json")); - assertTrue(req.sql().contains("ON public.workflow_insight.execution_arn = src.execution_arn")); + assertTrue(req.sql().contains("ON public.durable_execution_telemetry.execution_arn = src.execution_arn")); Map p = params(req); assertEquals(6, p.size()); @@ -86,7 +87,7 @@ void serverlessMergeUsesTypedNullLiteralsForAbsentFields() { @Test void provisionedMergeBindsCompletedFieldsAndCustomSchemaTable() { - WorkflowInsightRecord record = sampleRecord(); + DurableExecutionTelemetryRecord record = sampleRecord(); record.executionName = "exec-1"; record.status = "SUCCEEDED"; record.endTime = "2026-07-15T12:00:00.000Z"; @@ -94,7 +95,7 @@ void provisionedMergeBindsCompletedFieldsAndCustomSchemaTable() { ExecuteStatementRequest req = export( RedshiftExporter.builder() .clusterIdentifier("cluster-1") - .database("insight") + .database("telemetry") .secretArn("arn:aws:secretsmanager:us-east-1:123456789012:secret:s") .schema("analytics") .table("wf"), @@ -118,10 +119,10 @@ void provisionedMergeBindsCompletedFieldsAndCustomSchemaTable() { @Test void omitsStartTimeParameterWhenTheRecordHasNone() { - WorkflowInsightRecord record = sampleRecord(); + DurableExecutionTelemetryRecord record = sampleRecord(); record.startTime = null; ExecuteStatementRequest req = - export(RedshiftExporter.builder().workgroupName("wg").database("insight"), record); + export(RedshiftExporter.builder().workgroupName("wg").database("telemetry"), record); assertTrue(req.sql().contains("NULL::timestamptz AS start_time")); assertFalse(req.sql().contains(":start_time")); @@ -133,21 +134,21 @@ void omitsStartTimeParameterWhenTheRecordHasNone() { void validatesTargetAndIdentifiersAtBuildTime() { assertThrows( IllegalArgumentException.class, - () -> RedshiftExporter.builder().database("insight").build(), + () -> RedshiftExporter.builder().database("telemetry").build(), "workgroupName or clusterIdentifier is required"); assertThrows( IllegalArgumentException.class, () -> RedshiftExporter.builder() .workgroupName("wg") .clusterIdentifier("cluster-1") - .database("insight") + .database("telemetry") .build(), "workgroupName and clusterIdentifier are exclusive"); assertThrows( IllegalArgumentException.class, () -> RedshiftExporter.builder() .clusterIdentifier("cluster-1") - .database("insight") + .database("telemetry") .dbUser("admin") .secretArn("arn:aws:secretsmanager:us-east-1:123456789012:secret:s") .build(), @@ -157,7 +158,7 @@ void validatesTargetAndIdentifiersAtBuildTime() { export( RedshiftExporter.builder() .clusterIdentifier("cluster-1") - .database("insight") + .database("telemetry") .dbUser("admin"), sampleRecord()) .dbUser()); @@ -165,14 +166,14 @@ void validatesTargetAndIdentifiersAtBuildTime() { IllegalArgumentException.class, () -> RedshiftExporter.builder() .workgroupName("wg") - .database("insight") + .database("telemetry") .schema("public; DROP") .build()); assertEquals( 1_000_000, RedshiftExporter.builder() .workgroupName("wg") - .database("insight") + .database("telemetry") .build() .maxRecordSizeBytes()); } diff --git a/insight-plugin/src/test/java/software/amazon/lambda/durable/insight/S3ExporterTest.java b/telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry/S3ExporterTest.java similarity index 88% rename from insight-plugin/src/test/java/software/amazon/lambda/durable/insight/S3ExporterTest.java rename to telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry/S3ExporterTest.java index 37a7e93bf9..e3fd8405e0 100644 --- a/insight-plugin/src/test/java/software/amazon/lambda/durable/insight/S3ExporterTest.java +++ b/telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry/S3ExporterTest.java @@ -1,6 +1,6 @@ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 -package software.amazon.lambda.durable.insight; +package software.amazon.lambda.durable.telemetry; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -17,12 +17,12 @@ import software.amazon.awssdk.services.s3.S3Client; import software.amazon.awssdk.services.s3.model.PutObjectRequest; import software.amazon.awssdk.services.s3.model.PutObjectResponse; -import software.amazon.lambda.durable.insight.exporters.S3Exporter; +import software.amazon.lambda.durable.telemetry.exporters.S3Exporter; class S3ExporterTest { - private WorkflowInsightRecord sampleRecord() { - WorkflowInsightRecord r = new WorkflowInsightRecord(); + private DurableExecutionTelemetryRecord sampleRecord() { + DurableExecutionTelemetryRecord r = new DurableExecutionTelemetryRecord(); r.executionArn = "arn:aws:lambda:us-west-2:1:function:f:$LATEST/durable-execution/exec-1/invocation-1"; r.executionName = "exec-1"; r.functionName = "f"; @@ -55,7 +55,7 @@ void putsCanonicalOperationsArrayObjectKeyedByExecutionName() throws Exception { verify(client).putObject(req.capture(), body.capture()); assertEquals("my-bucket", req.getValue().bucket()); - assertEquals("workflow-insight/exec-1.json", req.getValue().key()); + assertEquals("durable-execution-telemetry/exec-1.json", req.getValue().key()); assertEquals("application/json", req.getValue().contentType()); String json = readBody(body.getValue()); diff --git a/insight-plugin/src/test/java/software/amazon/lambda/durable/insight/SQSExporterTest.java b/telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry/SQSExporterTest.java similarity index 89% rename from insight-plugin/src/test/java/software/amazon/lambda/durable/insight/SQSExporterTest.java rename to telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry/SQSExporterTest.java index cc05793190..2688d57711 100644 --- a/insight-plugin/src/test/java/software/amazon/lambda/durable/insight/SQSExporterTest.java +++ b/telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry/SQSExporterTest.java @@ -1,6 +1,6 @@ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 -package software.amazon.lambda.durable.insight; +package software.amazon.lambda.durable.telemetry; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; @@ -16,17 +16,17 @@ import software.amazon.awssdk.services.sqs.SqsClient; import software.amazon.awssdk.services.sqs.model.SendMessageRequest; import software.amazon.awssdk.services.sqs.model.SendMessageResponse; -import software.amazon.lambda.durable.insight.exporters.OperationsFormat; -import software.amazon.lambda.durable.insight.exporters.SQSExporter; +import software.amazon.lambda.durable.telemetry.exporters.OperationsFormat; +import software.amazon.lambda.durable.telemetry.exporters.SQSExporter; class SQSExporterTest { private static final String ARN = "arn:aws:lambda:us-east-1:123456789012:function:fn:$LATEST"; - private static final String STANDARD = "https://sqs.us-east-1.amazonaws.com/123456789012/insight"; + private static final String STANDARD = "https://sqs.us-east-1.amazonaws.com/123456789012/telemetry"; private static final String FIFO = STANDARD + ".fifo"; - private WorkflowInsightRecord sampleRecord() { - WorkflowInsightRecord r = new WorkflowInsightRecord(); + private DurableExecutionTelemetryRecord sampleRecord() { + DurableExecutionTelemetryRecord r = new DurableExecutionTelemetryRecord(); r.emittedAt = "2026-07-15T12:00:00.000Z"; r.executionArn = ARN; r.functionName = "fn"; @@ -37,7 +37,7 @@ private WorkflowInsightRecord sampleRecord() { return r; } - private static SendMessageRequest export(SQSExporter.Builder builder, WorkflowInsightRecord record) { + private static SendMessageRequest export(SQSExporter.Builder builder, DurableExecutionTelemetryRecord record) { SqsClient client = mock(SqsClient.class); when(client.sendMessage(any(SendMessageRequest.class))) .thenReturn(SendMessageResponse.builder().build()); @@ -49,7 +49,7 @@ private static SendMessageRequest export(SQSExporter.Builder builder, WorkflowIn @Test void sendsStandardQueueMessageWithAttributesAndNoFifoFields() { - WorkflowInsightRecord record = sampleRecord(); + DurableExecutionTelemetryRecord record = sampleRecord(); SendMessageRequest req = export(SQSExporter.builder().queueUrl(STANDARD), record); assertEquals(STANDARD, req.queueUrl()); @@ -70,7 +70,7 @@ void setsFifoGroupAndDeduplicationIds() { @Test void boundsFifoIdsToOneHundredTwentyEightCharacters() { - WorkflowInsightRecord record = sampleRecord(); + DurableExecutionTelemetryRecord record = sampleRecord(); record.executionArn = "arn:aws:lambda:us-east-1:123456789012:function:" + "f".repeat(80) + ":$LATEST/durable-execution/" + "e".repeat(40) + "/1"; SendMessageRequest req = export(SQSExporter.builder().queueUrl(FIFO), record); diff --git a/insight-plugin/src/test/java/software/amazon/lambda/durable/insight/StateCleanupLifecycleTest.java b/telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry/StateCleanupLifecycleTest.java similarity index 81% rename from insight-plugin/src/test/java/software/amazon/lambda/durable/insight/StateCleanupLifecycleTest.java rename to telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry/StateCleanupLifecycleTest.java index da27686025..3079b9ed63 100644 --- a/insight-plugin/src/test/java/software/amazon/lambda/durable/insight/StateCleanupLifecycleTest.java +++ b/telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry/StateCleanupLifecycleTest.java @@ -1,6 +1,6 @@ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 -package software.amazon.lambda.durable.insight; +package software.amazon.lambda.durable.telemetry; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -25,11 +25,11 @@ class StateCleanupLifecycleTest { private static final Instant START = Instant.parse("2026-08-05T00:00:00Z"); - private static final class CapturingExporter implements InsightExporter { - final List records = new ArrayList<>(); + private static final class CapturingExporter implements TelemetryExporter { + final List records = new ArrayList<>(); @Override - public void export(WorkflowInsightRecord record) { + public void export(DurableExecutionTelemetryRecord record) { records.add(record); } } @@ -60,8 +60,8 @@ private static Map ops() { @Test void nDistinctPendingExecutionsLeaveNoRetainedState() { - var plugin = (WorkflowInsight.InsightPlugin) - WorkflowInsight.workflowInsight(WorkflowInsightConfig.builder().build()); + var plugin = (DurableExecutionTelemetry.TelemetryPlugin) DurableExecutionTelemetry.durableExecutionTelemetry( + DurableExecutionTelemetryConfig.builder().build()); int n = 25; for (int i = 0; i < n; i++) { @@ -77,8 +77,8 @@ void nDistinctPendingExecutionsLeaveNoRetainedState() { @Test void retryingSuspendAlsoLeavesNoRetainedState() { - var plugin = (WorkflowInsight.InsightPlugin) - WorkflowInsight.workflowInsight(WorkflowInsightConfig.builder().build()); + var plugin = (DurableExecutionTelemetry.TelemetryPlugin) DurableExecutionTelemetry.durableExecutionTelemetry( + DurableExecutionTelemetryConfig.builder().build()); String arn = arn(0); plugin.onInvocationStart(new InvocationInfo("req", arn, true, START, "in", ops(), Map.of())); plugin.onInvocationEnd( @@ -89,10 +89,11 @@ void retryingSuspendAlsoLeavesNoRetainedState() { @Test void resumeReSeedsStableStartTimeAndInput() { var exporter = new CapturingExporter(); - var plugin = (WorkflowInsight.InsightPlugin) WorkflowInsight.workflowInsight(WorkflowInsightConfig.builder() - .emitMode(WorkflowInsightConfig.EmitMode.ON_CHANGE) - .addExporter(exporter) - .build()); + var plugin = (DurableExecutionTelemetry.TelemetryPlugin) + DurableExecutionTelemetry.durableExecutionTelemetry(DurableExecutionTelemetryConfig.builder() + .emitMode(DurableExecutionTelemetryConfig.EmitMode.ON_CHANGE) + .addExporter(exporter) + .build()); String arn = arn(0); // First invocation with input "alpha", then suspend (state removed). diff --git a/insight-plugin/src/test/java/software/amazon/lambda/durable/insight/TransformContractTest.java b/telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry/TransformContractTest.java similarity index 82% rename from insight-plugin/src/test/java/software/amazon/lambda/durable/insight/TransformContractTest.java rename to telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry/TransformContractTest.java index ee8219bc79..c3a682dda5 100644 --- a/insight-plugin/src/test/java/software/amazon/lambda/durable/insight/TransformContractTest.java +++ b/telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry/TransformContractTest.java @@ -1,6 +1,6 @@ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 -package software.amazon.lambda.durable.insight; +package software.amazon.lambda.durable.telemetry; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertInstanceOf; @@ -37,11 +37,11 @@ class TransformContractTest { "arn:aws:lambda:us-west-2:1:function:f:$LATEST/durable-execution/exec-1/invocation-1"; private static final Instant START = Instant.parse("2026-08-05T00:00:00Z"); - private static final class CapturingExporter implements InsightExporter { - final List records = Collections.synchronizedList(new ArrayList<>()); + private static final class CapturingExporter implements TelemetryExporter { + final List records = Collections.synchronizedList(new ArrayList<>()); @Override - public void export(WorkflowInsightRecord record) { + public void export(DurableExecutionTelemetryRecord record) { records.add(record); } } @@ -79,12 +79,15 @@ private Map ops() { return m; } - private WorkflowInsightRecord runOnce(Object input, Function inputTransform) { + private DurableExecutionTelemetryRecord runOnce(Object input, Function inputTransform) { var exporter = new CapturingExporter(); - DurableExecutionPlugin plugin = WorkflowInsight.workflowInsight(WorkflowInsightConfig.builder() - .content(ContentConfig.builder().inputTransform(inputTransform).build()) - .addExporter(exporter) - .build()); + DurableExecutionPlugin plugin = + DurableExecutionTelemetry.durableExecutionTelemetry(DurableExecutionTelemetryConfig.builder() + .content(ContentConfig.builder() + .inputTransform(inputTransform) + .build()) + .addExporter(exporter) + .build()); plugin.onInvocationStart(new InvocationInfo("req", ARN, true, START, input, ops(), Map.of())); plugin.onInvocationEnd( new InvocationEndInfo("req", ARN, true, START, ops(), InvocationStatus.SUCCEEDED, null, input, "out")); @@ -126,11 +129,13 @@ void eachTransformInvocationReceivesAFreshDetachedCopy() { m.put("injected-" + m.size(), Boolean.TRUE); // mutate the argument in place return m; }; - DurableExecutionPlugin plugin = WorkflowInsight.workflowInsight(WorkflowInsightConfig.builder() - .emitMode(WorkflowInsightConfig.EmitMode.ON_CHANGE) - .content(ContentConfig.builder().inputTransform(mutating).build()) - .addExporter(exporter) - .build()); + DurableExecutionPlugin plugin = + DurableExecutionTelemetry.durableExecutionTelemetry(DurableExecutionTelemetryConfig.builder() + .emitMode(DurableExecutionTelemetryConfig.EmitMode.ON_CHANGE) + .content( + ContentConfig.builder().inputTransform(mutating).build()) + .addExporter(exporter) + .build()); Map input = new LinkedHashMap<>(); input.put("a", 1); @@ -150,7 +155,7 @@ void eachTransformInvocationReceivesAFreshDetachedCopy() { @Test void throwingTransformOmitsInputWithoutFailingExecution() { var exporter = new CapturingExporter(); - var plugin = WorkflowInsight.workflowInsight(WorkflowInsightConfig.builder() + var plugin = DurableExecutionTelemetry.durableExecutionTelemetry(DurableExecutionTelemetryConfig.builder() .content(ContentConfig.builder() .inputTransform(v -> { throw new AssertionError("redactor blew up"); diff --git a/insight-plugin/src/test/java/software/amazon/lambda/durable/insight/TruncationTest.java b/telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry/TruncationTest.java similarity index 78% rename from insight-plugin/src/test/java/software/amazon/lambda/durable/insight/TruncationTest.java rename to telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry/TruncationTest.java index d843bee853..384561ceec 100644 --- a/insight-plugin/src/test/java/software/amazon/lambda/durable/insight/TruncationTest.java +++ b/telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry/TruncationTest.java @@ -1,6 +1,6 @@ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 -package software.amazon.lambda.durable.insight; +package software.amazon.lambda.durable.telemetry; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNull; @@ -10,8 +10,8 @@ class TruncationTest { - private WorkflowInsightRecord recordWithResults(int bytesEach) { - WorkflowInsightRecord r = new WorkflowInsightRecord(); + private DurableExecutionTelemetryRecord recordWithResults(int bytesEach) { + DurableExecutionTelemetryRecord r = new DurableExecutionTelemetryRecord(); r.executionArn = "arn:aws:lambda:us-west-2:1:function:f:$LATEST/durable-execution/e/i"; r.status = "SUCCEEDED"; r.startTime = "2026-08-05T00:00:00Z"; @@ -42,9 +42,10 @@ private WorkflowInsightRecord recordWithResults(int bytesEach) { @Test void phase1DropsResultsOldestFirstAndKeepsNewest() { - WorkflowInsightRecord r = recordWithResults(2000); + DurableExecutionTelemetryRecord r = recordWithResults(2000); // Big enough for all three result-stripped ops, too small for the ~2 KB results. - WorkflowInsightRecord out = Truncation.truncateRecord(r, 4096, WorkflowInsightRecord::toWireMap); + DurableExecutionTelemetryRecord out = + Truncation.truncateRecord(r, 4096, DurableExecutionTelemetryRecord::toWireMap); assertEquals(Boolean.TRUE, out.truncated); assertEquals(3, out.operations().size()); assertNull(out.operations().get(0).result(), "oldest result dropped"); @@ -56,7 +57,7 @@ void phase1DropsResultsOldestFirstAndKeepsNewest() { @Test void phase2DropsWholeOperationsOldestFirst() { // No results to drop, tiny limit → whole operations dropped oldest-first. - WorkflowInsightRecord r = new WorkflowInsightRecord(); + DurableExecutionTelemetryRecord r = new DurableExecutionTelemetryRecord(); r.executionArn = "arn:aws:lambda:us-west-2:1:function:f:$LATEST/durable-execution/e/i"; r.status = "SUCCEEDED"; r.startTime = "2026-08-05T00:00:00Z"; @@ -70,7 +71,8 @@ void phase2DropsWholeOperationsOldestFirst() { } int base = Json.byteSize(r.toWireMap()); // Force at least one whole-operation drop. - WorkflowInsightRecord out = Truncation.truncateRecord(r, base - 60, WorkflowInsightRecord::toWireMap); + DurableExecutionTelemetryRecord out = + Truncation.truncateRecord(r, base - 60, DurableExecutionTelemetryRecord::toWireMap); assertEquals(Boolean.TRUE, out.truncated); assertTrue(out.droppedOperations != null && out.droppedOperations >= 1); boolean bulk1Present = out.operations().stream().anyMatch(o -> "bulk-1".equals(o.name())); @@ -81,8 +83,9 @@ void phase2DropsWholeOperationsOldestFirst() { @Test void noTruncationWhenUnderLimit() { - WorkflowInsightRecord r = recordWithResults(10); - WorkflowInsightRecord out = Truncation.truncateRecord(r, 5_000_000, WorkflowInsightRecord::toWireMap); + DurableExecutionTelemetryRecord r = recordWithResults(10); + DurableExecutionTelemetryRecord out = + Truncation.truncateRecord(r, 5_000_000, DurableExecutionTelemetryRecord::toWireMap); assertNull(out.truncated); } } diff --git a/insight-plugin/src/test/java/software/amazon/lambda/durable/insight/UnrecoverableErrorUnwrapTest.java b/telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry/UnrecoverableErrorUnwrapTest.java similarity index 84% rename from insight-plugin/src/test/java/software/amazon/lambda/durable/insight/UnrecoverableErrorUnwrapTest.java rename to telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry/UnrecoverableErrorUnwrapTest.java index ccd32782f5..7f78056f09 100644 --- a/insight-plugin/src/test/java/software/amazon/lambda/durable/insight/UnrecoverableErrorUnwrapTest.java +++ b/telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry/UnrecoverableErrorUnwrapTest.java @@ -1,6 +1,6 @@ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 -package software.amazon.lambda.durable.insight; +package software.amazon.lambda.durable.telemetry; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; @@ -31,11 +31,11 @@ class UnrecoverableErrorUnwrapTest { "arn:aws:lambda:us-west-2:1:function:f:$LATEST/durable-execution/exec-1/invocation-1"; private static final Instant START = Instant.parse("2026-08-05T00:00:00Z"); - private static final class CapturingExporter implements InsightExporter { - final List records = new ArrayList<>(); + private static final class CapturingExporter implements TelemetryExporter { + final List records = new ArrayList<>(); @Override - public void export(WorkflowInsightRecord record) { + public void export(DurableExecutionTelemetryRecord record) { records.add(record); } } @@ -71,8 +71,8 @@ private static Map ops(OperationStatus status) @Test void failedExecutionUnwrapsUnrecoverableErrorObject() { var exporter = new CapturingExporter(); - DurableExecutionPlugin plugin = WorkflowInsight.workflowInsight( - WorkflowInsightConfig.builder().addExporter(exporter).build()); + DurableExecutionPlugin plugin = DurableExecutionTelemetry.durableExecutionTelemetry( + DurableExecutionTelemetryConfig.builder().addExporter(exporter).build()); Throwable execError = unrecoverable("PoisonPayload", "cannot deserialize checkpoint"); plugin.onInvocationEnd(new InvocationEndInfo( @@ -88,10 +88,11 @@ void failedExecutionUnwrapsUnrecoverableErrorObject() { @Test void retryingExecutionUnwrapsUnrecoverableErrorObjectInOnChangeMode() { var exporter = new CapturingExporter(); - DurableExecutionPlugin plugin = WorkflowInsight.workflowInsight(WorkflowInsightConfig.builder() - .emitMode(WorkflowInsightConfig.EmitMode.ON_CHANGE) - .addExporter(exporter) - .build()); + DurableExecutionPlugin plugin = + DurableExecutionTelemetry.durableExecutionTelemetry(DurableExecutionTelemetryConfig.builder() + .emitMode(DurableExecutionTelemetryConfig.EmitMode.ON_CHANGE) + .addExporter(exporter) + .build()); Throwable execError = unrecoverable("TransientBackendError", "retry scheduled"); // RETRYING maps to a non-terminal RUNNING status but still emits in ON_CHANGE mode. @@ -117,8 +118,8 @@ void retryingExecutionUnwrapsUnrecoverableErrorObjectInOnChangeMode() { @Test void fallsBackToThrowableFieldsWhenUnrecoverableErrorTypeMissing() { var exporter = new CapturingExporter(); - DurableExecutionPlugin plugin = WorkflowInsight.workflowInsight( - WorkflowInsightConfig.builder().addExporter(exporter).build()); + DurableExecutionPlugin plugin = DurableExecutionTelemetry.durableExecutionTelemetry( + DurableExecutionTelemetryConfig.builder().addExporter(exporter).build()); ErrorObject partial = ErrorObject.builder().errorMessage("only a message").build(); diff --git a/insight-plugin/src/test/java/software/amazon/lambda/durable/insight/exporters/LazyClientTest.java b/telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry/exporters/LazyClientTest.java similarity index 96% rename from insight-plugin/src/test/java/software/amazon/lambda/durable/insight/exporters/LazyClientTest.java rename to telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry/exporters/LazyClientTest.java index bf79cadb7b..d8fe8e68fe 100644 --- a/insight-plugin/src/test/java/software/amazon/lambda/durable/insight/exporters/LazyClientTest.java +++ b/telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry/exporters/LazyClientTest.java @@ -1,6 +1,6 @@ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 -package software.amazon.lambda.durable.insight.exporters; +package software.amazon.lambda.durable.telemetry.exporters; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertInstanceOf; diff --git a/insight-plugin/src/test/java/software/amazon/lambda/durable/insight/exporters/OptionalArtifactTest.java b/telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry/exporters/OptionalArtifactTest.java similarity index 96% rename from insight-plugin/src/test/java/software/amazon/lambda/durable/insight/exporters/OptionalArtifactTest.java rename to telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry/exporters/OptionalArtifactTest.java index aac18c5fe4..82f553e371 100644 --- a/insight-plugin/src/test/java/software/amazon/lambda/durable/insight/exporters/OptionalArtifactTest.java +++ b/telemetry-exporter/src/test/java/software/amazon/lambda/durable/telemetry/exporters/OptionalArtifactTest.java @@ -1,6 +1,6 @@ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 -package software.amazon.lambda.durable.insight.exporters; +package software.amazon.lambda.durable.telemetry.exporters; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; @@ -16,9 +16,9 @@ import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; -import software.amazon.lambda.durable.insight.InsightExporter; -import software.amazon.lambda.durable.insight.LocalHttpServer; -import software.amazon.lambda.durable.insight.RecordFactory; +import software.amazon.lambda.durable.telemetry.LocalHttpServer; +import software.amazon.lambda.durable.telemetry.RecordFactory; +import software.amazon.lambda.durable.telemetry.TelemetryExporter; /** * Optional AWS SDK artifacts must not be needed to build an exporter: a configured exporter whose artifact is absent @@ -41,7 +41,7 @@ public Scenario(String exporter, String endpoint) { /** Returns the export failure message, or {@link #EXPORTED} when the record was delivered. */ @Override public String get() { - InsightExporter built = build(); + TelemetryExporter built = build(); try { built.export(RecordFactory.sample()); } catch (IllegalStateException e) { @@ -50,7 +50,7 @@ public String get() { return EXPORTED; } - private InsightExporter build() { + private TelemetryExporter build() { switch (exporter) { case "OpenSearchExporter:sigv4": return OpenSearchExporter.builder()