aws / aws-xray-sdk-go

AWS X-Ray SDK for the Go programming language.
Apache License 2.0
276 stars 117 forks source link

The v2 version xray doesn't work for dynamodb putItem api #408

Open zhaoyi0113 opened 1 year ago

zhaoyi0113 commented 1 year ago

I am deploying code to Lambda and use below code to instrument dynamodb requests. It works fine for query but doesn't work for putItem.

awsv2.AWSV2Instrumentor(&cfg.APIOptions)
    // Using the Config value, create the DynamoDB client
    svc := dynamodb.NewFromConfig(cfg)

I got below error:

Suppressing AWS X-Ray context missing panic: failed to begin subsegment named 'DynamoDB': segment cannot be found.

Is there any other configuration needed for putItem?

wangzlei commented 1 year ago

This panic is xray sdk creates a subsegment but cannot find available parent segment from context, it happens in asynchronous case for example:

seg, ctx := xray.BeginSegment()
defer seg.Close()
go xray.BeginSubsegment(ctx)  // create subsegment after parent segment is closed.

So, probably your putItem method is running in async case but query is not.

Alternatively, user can use ADOT, it is xray's long term strategy to move from xray sdk to ADOT. ADOT supports async in a better solution, would not have context missing panic. Please refer to a Lambda go example https://aws-otel.github.io/docs/getting-started/lambda/lambda-go

zhaoyi0113 commented 1 year ago

I am not running anything inside go routine, there should not be any async calls. My application is running inside lambda and I thought the segment is created by lambda automatically. I don't need to call BeginSegment in my code for automatic tracing?

wangzlei commented 1 year ago

In AWS Lambda scenario, X-Ray SDK will automatically find parent trace context from Lambda environment variable _X_AMZN_TRACE_ID, user no need call BeginSegment. But it only works inside of user Lambda handler function. If user instruments his aws sdk and makes a call before Lambda handler function it will show segment cannot be found. error.

client = xray.instrument(client)
client.call()   // not support, Lambda does not env variable _X_AMZN_TRACE_ID yet

handler() { 
  client.call()  // support, because there is env variable _X_AMZN_TRACE_ID
}