diff --git a/src/trace/durable-function-context.spec.ts b/src/trace/durable-function-context.spec.ts index ff1ca6ed..689caa5d 100644 --- a/src/trace/durable-function-context.spec.ts +++ b/src/trace/durable-function-context.spec.ts @@ -58,9 +58,47 @@ describe("durable-function-context", () => { expect(result).toEqual({ "aws_lambda.durable_function.execution_name": "my-execution", "aws_lambda.durable_function.execution_id": "550e8400-e29b-41d4-a716-446655440004", + "aws_lambda.durable_function.first_invocation": "false", }); }); + it("sets first_invocation to true when Operations has exactly one entry", () => { + const event = { + DurableExecutionArn: + "arn:aws:lambda:us-east-1:123456789012:function:my-func:1/durable-execution/my-execution/550e8400-e29b-41d4-a716-446655440004", + InitialExecutionState: { + Operations: [{ type: "TaskScheduled" }], + }, + }; + const result = extractDurableFunctionContext(event); + + expect(result?.["aws_lambda.durable_function.first_invocation"]).toBe("true"); + }); + + it("sets first_invocation to false when Operations has more than one entry", () => { + const event = { + DurableExecutionArn: + "arn:aws:lambda:us-east-1:123456789012:function:my-func:1/durable-execution/my-execution/550e8400-e29b-41d4-a716-446655440004", + InitialExecutionState: { + Operations: [{ type: "TaskScheduled" }, { type: "TaskCompleted" }], + }, + }; + const result = extractDurableFunctionContext(event); + + expect(result?.["aws_lambda.durable_function.first_invocation"]).toBe("false"); + }); + + it("omits first_invocation when InitialExecutionState is absent", () => { + const event = { + DurableExecutionArn: + "arn:aws:lambda:us-east-1:123456789012:function:my-func:1/durable-execution/my-execution/550e8400-e29b-41d4-a716-446655440004", + }; + const result = extractDurableFunctionContext(event); + + expect(result).toBeDefined(); + expect(result?.["aws_lambda.durable_function.first_invocation"]).toBeUndefined(); + }); + it("returns undefined for regular Lambda event without DurableExecutionArn", () => { const event = { body: '{"key": "value"}', diff --git a/src/trace/durable-function-context.ts b/src/trace/durable-function-context.ts index 2acf5765..29d4c53c 100644 --- a/src/trace/durable-function-context.ts +++ b/src/trace/durable-function-context.ts @@ -3,6 +3,7 @@ import { logDebug } from "../utils"; export interface DurableFunctionContext { "aws_lambda.durable_function.execution_name": string; "aws_lambda.durable_function.execution_id": string; + "aws_lambda.durable_function.first_invocation"?: string; } export function extractDurableFunctionContext(event: any): DurableFunctionContext | undefined { @@ -18,10 +19,18 @@ export function extractDurableFunctionContext(event: any): DurableFunctionContex return undefined; } - return { + const context: DurableFunctionContext = { "aws_lambda.durable_function.execution_name": parsed.executionName, "aws_lambda.durable_function.execution_id": parsed.executionId, }; + + // Use the number of operations to determine if it's the first invocation. + const operations = event?.InitialExecutionState?.Operations; + if (Array.isArray(operations)) { + context["aws_lambda.durable_function.first_invocation"] = String(operations.length === 1); + } + + return context; } /**