aws/aws-xray-sdk-node

Simplest way to add subsegment to a NodeJS Lambda.

Opened this issue · 8 comments

Hi!

Shouldn't this work?

export const handler = async () => {
    const segment = AWSXRay.getSegment();
    const subSegment = segment.addNewSubsegment('ExternalCall');
    // do stuff...
    subSegment.close();
}

When debugging, I'm getting this: Ignoring flush on subsegment 846f3500400178a9. Associated segment is marked as not sampled.

And, most importantly, nothing gets registered or displayed on XRay.

Hi @andrestone,

This would work if the segment is sampled. By default, the first request every second and 5% of subsequent requests within that second are sampled, meaning they are recorded and sent to the X-Ray backend. Unsample requests are not sent to the backend as a cost-saving measure. See more in the docs.

If you have an APIGW in front of your Lambda, you can configure your centralized sampling rules so that APIGW will sample more requests.

Hey, @willarmiros! Thanks for your comment.

Unfortunately, even when raising the sampling rate by several orders of magnitude it still didn't work.

This is what has worked for me, with default sampling rate settings.

export const traceWithXRay: <T>(name: string, asyncCall: Promise<T>) => Promise<T> = async (name, asyncCall) => {
  const traceData = AWSXRay.utils.processTraceData(process.env._X_AMZN_TRACE_ID!);
  const subSegment = new AWSXRay.Segment(name, traceData.root, traceData.parent);
  subSegment.start_time = new Date().getTime() / 1000;
  const ret = await asyncCall;
  subSegment.close();
  return ret;
};

I wonder if this has anything to do with the workarounds due to Lambda segment immutability.

Is the Lambda node the root node of your service? If so, Lambda does not respect centralized sampling rules and sticks with the default rate I mentioned above. Glad to see you have the workaround though!

Nope. Trace starts on AppSync.

Hey @andrestone!

Thanks for giving us more information. I found something similar to your original example on the public docs here and tried to reproduce it myself.

Using just the Lambda (without AppSync) I got the subsegments to appear with the following steps:

  1. I created a Lambda function for Node.js 14.x and enabled tracing with X-Ray
  2. I created a simple Node.js program locally using npm init, ran npm install aws-xray-sdk, and wrote an index.js file like this:
var AWSXRay = require('aws-xray-sdk');

exports.handler = async (event) => {
    const segment = AWSXRay.getSegment();
    const subSegment = segment.addNewSubsegment('subseg');
    subSegment.close();

    return "Handler complete.";
};
  1. I zipped all those files together (including node_modules) and uploaded the zip file to my lambda function
  2. I made sure that Deploy was grayed out, and ran Test with the default configuration
  3. Finally, I went to X-Ray and saw that the subsegment I created was indeed there:
    image

I only have the default sampling rate that @willarmiros mentioned above:

$ aws xray get-sampling-rules | tee
{
    "SamplingRuleRecords": [
        {
            "SamplingRule": {
                "RuleName": "Default",
                "RuleARN": "arn:aws:xray:us-west-2:330374072857:sampling-rule/Default",
                "ResourceARN": "*",
                "Priority": 10000,
                "FixedRate": 0.05,
                "ReservoirSize": 1,
                "ServiceName": "*",
                "ServiceType": "*",
                "Host": "*",
                "HTTPMethod": "*",
                "URLPath": "*",
                "Version": 1,
                "Attributes": {}
            },
            "CreatedAt": "1969-12-31T16:00:00-08:00",
            "ModifiedAt": "1969-12-31T16:00:00-08:00"
        }
    ]
}

Let me know if these steps work for you? If they don't, it would be awesome if you could help me describe your architecture! For example, does Lambda get invoked by polling DyanmoDB or perhaps it's acting as a resolver for AppSync?

stale commented

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs in next 7 days. Thank you for your contributions.

I have the same issue, in short, I have a lambda, that call other lambda, the second lambda is always had sample with 0, and give me the same message, Ignoring flush on subsegment 846f3500400178a9. Associated segment is marked as not sampled.

Hi @MostafaaRamadan - thanks for raising this, have you tried enabling active tracing on your first lambda? That is necessary for now to get your use case to work