Skip to content

Commit 46cc9a9

Browse files
committed
Add implementation and test for SFN -> SNS -> Lambda
1 parent 7daaa7e commit 46cc9a9

2 files changed

Lines changed: 63 additions & 2 deletions

File tree

src/trace/context/extractors/sns.spec.ts

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { SNSEvent } from "aws-lambda";
22
import { TracerWrapper } from "../../tracer-wrapper";
33
import { SNSEventTraceExtractor } from "./sns";
4+
import { StepFunctionContextService } from "../../step-function-service";
45

56
let mockSpanContext: any = null;
67

@@ -256,5 +257,51 @@ describe("SNSEventTraceExtractor", () => {
256257
expect(traceContext?.sampleMode()).toBe("1");
257258
expect(traceContext?.source).toBe("event");
258259
});
260+
261+
it("extracts trace context from Step Function SNS event", () => {
262+
// Reset StepFunctionContextService instance
263+
StepFunctionContextService["_instance"] = undefined as any;
264+
265+
const tracerWrapper = new TracerWrapper();
266+
267+
const payload: SNSEvent = {
268+
Records: [
269+
{
270+
EventSource: "aws:sns",
271+
EventVersion: "1.0",
272+
EventSubscriptionArn: "arn:aws:sns:sa-east-1:123456123456:rstrat-sfn-sns-demo-dev-process-event-topic:f18241f8-a4f7-4586-80db-97bd1939a557",
273+
Sns: {
274+
Type: "Notification",
275+
MessageId: "46d2665c-7ee2-50ba-a4cd-06acf35f5d5f",
276+
TopicArn: "arn:aws:sns:sa-east-1:123456123456:rstrat-sfn-sns-demo-dev-process-event-topic",
277+
Message: "{\"source\":\"demo.stepfunction\",\"detailType\":\"ProcessEvent\",\"message\":\"Test event from Step Functions\",\"customData\":{\"userId\":\"12345\",\"action\":\"test\"}}",
278+
Timestamp: "2025-07-15T17:10:21.503Z",
279+
SignatureVersion: "1",
280+
Signature: "fHeJta0GWCs/lHhI6wesXiT+66i1SZ+XH58pyd8mKHKD8bepXsnWvfQdDsOkO2AVv2CqPBF58sAWQae6yob2aMawe/vo8eeahJCaguK8a/3HLj7kP+nXGjgSGvzQm4CdYEyAUco453/mfE/BSf0SkdctxW0rjMs27T2l964Lt2Y/vJeiXVibs/AqEIu3ImekbM8+EIfNMOLBdRBVE47650vawazMkcpPtg5o/8LCA/jNUNj9VCTJrvzep8/vVJEcuHbZ3pcmajA9UJmP3000G0+to0cXwZ5YaakOxQTv81I+cfC99yQJoogLklbgiu+4bqEeNWbwW9KdQz1U+79NgA==",
281+
SigningCertUrl: "https://sns.sa-east-1.amazonaws.com/SimpleNotificationService-9c6465fa7f48f5cacd23014631ec1136.pem",
282+
Subject: "Event from Step Functions",
283+
UnsubscribeUrl: "https://sns.sa-east-1.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:sa-east-1:123456123456:rstrat-sfn-sns-demo-dev-process-event-topic:f18241f8-a4f7-4586-80db-97bd1939a557",
284+
MessageAttributes: {
285+
_datadog: {
286+
Type: "String",
287+
Value: "{\"Execution\":{\"Id\":\"arn:aws:states:sa-east-1:123456123456:execution:rstrat-sfn-sns-demo-dev-state-machine:79049e80-5cc6-49da-9dc0-f19ba2921772\",\"StartTime\":\"2025-07-15T17:10:21.328Z\",\"Name\":\"79049e80-5cc6-49da-9dc0-f19ba2921772\",\"RoleArn\":\"arn:aws:iam::123456123456:role/rstrat-sfn-sns-demo-dev-StepFunctionsExecutionRole-LrsdDm6wMmBh\",\"RedriveCount\":0},\"StateMachine\":{\"Id\":\"arn:aws:states:sa-east-1:123456123456:stateMachine:rstrat-sfn-sns-demo-dev-state-machine\",\"Name\":\"rstrat-sfn-sns-demo-dev-state-machine\"},\"State\":{\"Name\":\"PublishToSNS\",\"EnteredTime\":\"2025-07-15T17:10:21.354Z\",\"RetryCount\":0},\"RootExecutionId\":\"arn:aws:states:sa-east-1:123456123456:execution:rstrat-sfn-sns-demo-dev-state-machine:79049e80-5cc6-49da-9dc0-f19ba2921772\",\"serverless-version\":\"v1\"}"
288+
}
289+
}
290+
}
291+
}
292+
]
293+
};
294+
295+
const extractor = new SNSEventTraceExtractor(tracerWrapper);
296+
297+
const traceContext = extractor.extract(payload);
298+
expect(traceContext).not.toBeNull();
299+
300+
// The StepFunctionContextService generates deterministic trace IDs
301+
expect(traceContext?.toTraceId()).toBe("3995810302240690842");
302+
expect(traceContext?.toSpanId()).toBe("8347071195300897803");
303+
expect(traceContext?.sampleMode()).toBe("1");
304+
expect(traceContext?.source).toBe("event");
305+
});
259306
});
260307
});

src/trace/context/extractors/sns.ts

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { logDebug } from "../../../utils";
44
import { EventTraceExtractor } from "../extractor";
55
import { SpanContextWrapper } from "../../span-context-wrapper";
66
import { XrayService, AMZN_TRACE_ID_ENV_VAR } from "../../xray-service";
7+
import { StepFunctionContextService } from "../../step-function-service";
78

89
export class SNSEventTraceExtractor implements EventTraceExtractor {
910
constructor(private tracerWrapper: TracerWrapper) {}
@@ -22,13 +23,26 @@ export class SNSEventTraceExtractor implements EventTraceExtractor {
2223
headers = JSON.parse(decodedValue);
2324
}
2425

26+
// First try to extract as regular trace headers
2527
const traceContext = this.tracerWrapper.extract(headers);
2628
if (traceContext) {
2729
logDebug("Extracted trace context from SNS event");
2830
return traceContext;
29-
} else {
30-
logDebug("Failed to extract trace context from SNS event");
3131
}
32+
33+
// If that fails, check if this is a Step Function context
34+
const stepFunctionInstance = StepFunctionContextService.instance(headers);
35+
const stepFunctionContext = stepFunctionInstance.context;
36+
37+
if (stepFunctionContext !== undefined) {
38+
const spanContext = stepFunctionInstance.spanContext;
39+
if (spanContext !== null) {
40+
logDebug("Extracted Step Function trace context from SNS event", { spanContext, event });
41+
return spanContext;
42+
}
43+
}
44+
45+
logDebug("Failed to extract trace context from SNS event");
3246
}
3347
// Then try to extract trace context from _X_AMZN_TRACE_ID header (Upstream Java apps can
3448
// pass down Datadog trace id (parent id wrong) in the env in SNS case)

0 commit comments

Comments
 (0)