2

I have an AWS Lambda function which is triggered by an API Gateway event. The API Gateway is configured to use X-Ray.

As the Lambda tracing configuration defaults to PassTrough it is also shown in X-Ray (service map, etc.).

The invoked Lambda uses the node.js aws-sdk to invoke another lambda. If I understand correctly the Tracing ID has to be passed on to the next Invocation in order to show this Lambda also in X-Ray. In the API of the SDK I found no option for this.

const result = await lambda
        .invoke(lambdaParamsCreateUser)
        .promise()

How can I achieve this? How can I trace also the invocation of the original request?

With the tips of @Balu Vyamajala I changed the AWS-SDK import to the following:

import AWS from "aws-sdk";

import AwsXRay from "aws-xray-sdk-core";
const aws = AwsXRay.captureAWS(AWS);
export default aws;

I use it when I invoice my second function like this:

import AWS from "aws";
const Lambda = AWS.Lambda;
// ...
const lambda = new Lambda({ region: "eu-central-1" });
const lambdaPromise = lambda
        .invoke({
            FunctionName: AUTH_CREATE_USER_FUNC,
            InvocationType: "RequestResponse",
            Qualifier: AUTH_CREATE_USER_FUNC_VERSION,
            Payload: JSON.stringify({
                eMail: eMail,
                device: device,
                customerId: customerId,
            }),
            LogType: "Tail",
        })
        .promise()

But in X-Ray there is no invocation chain :-(

https://i.stack.imgur.com/8FsWT.jpg

Do I make a mistake?

thopaw
  • 3,796
  • 2
  • 17
  • 24

1 Answers1

5

if we enable X-Ray for both Lambda functions , trace-id is automatically passed and will be same for both Lambdas.

In the code, we can enable X-Ray simply by wrapping it around aws-sdk

JavaScript:

const AWSXRay = require("aws-xray-sdk-core");
const AWS = AWSXRay.captureAWS(require("aws-sdk"));    

Typescript:

import AWSXRay from 'aws-xray-sdk';
import aws from 'aws-sdk';
const AWS = AWSXRay.captureAWS(aws)

Here is a sample test to confirm.

balu-test >> sample-test

Lambda 1 (balu-test) :

const AWSXRay = require("aws-xray-sdk-core");
const AWS = AWSXRay.captureAWS(require("aws-sdk"));    
const lambda = new AWS.Lambda();

exports.handler = async function (event, context) {
  var params = {
    FunctionName: "sample-test",
    InvocationType: "RequestResponse",
    Payload: '{ "name" : "foo" }',
  };
  
  const response = await lambda.invoke(params).promise();
  console.log('response',response);

  return "sucess";
};

Lambda 2(sample-test):

const AWSXRay = require("aws-xray-sdk-core");
const AWS = AWSXRay.captureAWS(require("aws-sdk"));    
let region = "us-east-1"
let secretName = "SomeSecret"
let secret
let decodedBinarySecret    
var client = new AWS.SecretsManager({
  region: region,
});

exports.handler = (event, context, callback) => {
  client.getSecretValue({ SecretId: secretName }, function (err, data) {
    if (err) {
      callback(err);
    } else {
      if ("SecretString" in data) {
        secret = data.SecretString;
      } else {
        let buff = new Buffer(data.SecretBinary, "base64");
        decodedBinarySecret = buff.toString("ascii");
      }
      callback(null, secret);
    }
  });
};

TraceId is same and X-Ray points to same graph for both Lambda invocations. Same thing happens when first api is called from Api-Gateway. First time trace-id is generated and is passed along as http header to downstream processes.

enter image description here

enter image description here

Balu Vyamajala
  • 9,287
  • 1
  • 20
  • 42
  • Hey Balu. Thanks for this answer. I will check that as soon as I am back at my laptop. Do you know how to do this with typescript? Or I have to figure that out by my own ☺️ – thopaw Mar 13 '21 at 16:48
  • i added a couple more lines for typescript. @thopaw – Balu Vyamajala Mar 13 '21 at 19:29
  • Thank you very much. I was able to change the AWS SDK with the instrumented one the way you described. But the invoked lambda is not shown in X Ray :-( https://imgur.com/wDMlNzb – thopaw Mar 13 '21 at 20:08
  • Updated my Question with some changes you suggested – thopaw Mar 13 '21 at 20:16
  • @thopaw it looks fine, you did that for both lambda functions? – Balu Vyamajala Mar 13 '21 at 22:50
  • No, only the invoking one. The invoked one doesn't need the aws sdk at all – thopaw Mar 13 '21 at 23:34
  • we still need to enable X-Ray I believe for the second lambda also, though we don't make any sdk calls. – Balu Vyamajala Mar 14 '21 at 03:33
  • Sorry, but I don't get it. I deploy both functions with AWS SAM and enabled Tracing in The API Gateway. Following the docs in https://docs.aws.amazon.com/vsts/latest/userguide/lambda-deploy.html the tracing config should be defaulted to PassTrough and should kick in when the upstream service has tracing enabled. – thopaw Mar 14 '21 at 07:54
  • Yes. that is good enough. i am not sure why your diagram is not updated. – Balu Vyamajala Mar 14 '21 at 09:28
  • Ok. Thank you very much, anyway. Perhaps it is a problem in the setup with Lambda layers, aws sam, etc. – thopaw Mar 14 '21 at 09:45