SQS supports X-Ray tracing but it does not propagate the trace to Lambda function. Lambda always starts a new trace with an immutable facade segment.
This is a known issue, see:
- aws-xray-sdk-node: https://github.com/aws/aws-xray-sdk-node/issues/208
- aws-xray-sdk-dotnet: https://github.com/aws/aws-xray-sdk-dotnet/issues/110
Workaround
There were some workaround discussions in the above issues.
The following is a solution I implemented for a demo:
- Create a new segment to replace the facade segment created by Lambda, and
- assign with the retrieved trace ID and parent ID from the trace header of the SQS segment.
Example in typescript:
import { Handler, SQSEvent, SQSRecord } from "aws-lambda"
import { Segment, setSegment, utils } from "aws-xray-sdk"
...
// Create a new Segment
const traceHeaderStr = sqsRecord.attributes.AWSTraceHeader
const traceData = utils.processTraceData(traceHeaderStr)
const sqsSegmentEndTime = Number(sqsRecord.attributes.ApproximateFirstReceiveTimestamp) / 1000
const lambdaSegment = new Segment(
functionName,
traceData.root,
traceData.parent
)
lambdaSegment.origin = "AWS::Lambda::Function"
lambdaSegment.start_time = lambdaExecStartTime - (lambdaExecStartTime - sqsSegmentEndTime)
lambdaSegment.addPluginData({
function_arn: functionArn,
region: sqsRecord.awsRegion,
request_id: awsRequestId
})
// Set it as the current Segment
setSegment(lambdaSegment)
// Do something
// Close the segment
lambdaSegment.close()
From Trace Map console:
Example code can be found here on GitHub kyhau/aws-tools/b/X-Ray/xray-sqs-to-lambda/handler.ts.
Top comments (1)
hope this work. i will try to use tomorrow.
btw: why don't you use new Date() for Lambda start Time. You can make it optional at least