aws/aws-xray-sdk-node

capturePromise needs to be called in handler middleware in Lambda

cloudlena opened this issue · 2 comments

I have the following setup where helloHandler does some async calls using Axios:

import express from "express";
import serverless from "serverless-http";
import AWSXRay from "aws-xray-sdk-core";
import xrayExpress from "aws-xray-sdk-express";
import http from "http";
import https from "https";

AWSXRay.captureHTTPsGlobal(http);
AWSXRay.captureHTTPsGlobal(https);
AWSXRay.capturePromise();

import helloHandler from "./helloHandler";

const app = express();

app.use(xrayExpress.openSegment("my-app"));

app.use("/hello", helloHandler);

app.use(xrayExpress.closeSegment());

export default serverless(app);

When I run this in Lambda, I see many Error: Missing AWS Lambda trace data for X-Ray. Ensure Active Tracing is enabled and no subsegments are created outside the function handler errors in CloudWatch. However, with the following setup, I don't get these errors:

import express from "express";
import serverless from "serverless-http";
import AWSXRay from "aws-xray-sdk-core";
import xrayExpress from "aws-xray-sdk-express";
import http from "http";
import https from "https";

AWSXRay.captureHTTPsGlobal(http);
AWSXRay.captureHTTPsGlobal(https);

import helloHandler from "./helloHandler";

const app = express();

app.use((req, res, next) => {
  AWSXRay.capturePromise();
  next();
});

app.use(xrayExpress.openSegment("my-app"));

app.use("/hello", helloHandler);

app.use(xrayExpress.closeSegment());

export default serverless(app);

Is that expected? Why does capturePromise have to be called in the handler?

Hi @cloudlena ,

In Lambda, the X-Ray SDK will only create subsegments, which will all be attached to the segment generated by Lambda. Any subsegment that exists outside the Lambda handler will cause the error you saw and that's the reason why the second instrumentation code works.