1

I am trying to trace a serverless express Lambda function using AWSXRay. I have tried several different approaches to this and nothing seems to work.

If I leave out the aws-xray-sdk-express middleware, I will see all my segments in the Timeline, and see my Lambda function appearing twice in the Trace Map. If I include the express middleware, I will see the middleware segment ('Super Dooper Trace Function') in the Trace Map and just the first subsegment ('MyFirstTrace') in the Timeline (not in the Trace Map).

I am trying to get all Subsegments to appear in both the Timelines and Node Graphs

const AWSXray = require('aws-xray-sdk');
const xrayExpress = require('aws-xray-sdk-express');
const express = require('express');
const awsServerlessExpress = require('aws-serverless-express');


module.exports.handler = async (event, context) => {
    const app = express();
    app.use(xrayExpress.openSegment('Super Dooper Trace Function'));

    app.get('/test', async (req, res) => {
        const result = await doWork();
        res.send(result); 
    });

    app.use(xrayExpress.closeSegment());

    const server = awsServerlessExpress.createServer(app);
    return awsServerlessExpress.proxy(server, event, context, 'PROMISE').promise;

}

const doWork = async () => {
    const res1 =  await traceMyFunction('MyFirstTrace', 3000)
    const res2 = await traceMyFunction('MySecondTrace', 3000);
    const res3 = await traceMyFunction('MyThirdTrace', 2000);
    return [res1, res2, res3];
}


const traceMyFunction = (name, delayMs) => {
    return trace(name, async () => {
        return delay(delayMs)
    });
}


function trace(name, promiseFunction) {
    return new Promise((resolve, reject) => {
        AWSXray.captureAsyncFunc(name, (subSegment) => {
            promiseFunction(subSegment)
                .then((result) => {
                    resolve(result);
                    subSegment.close();
                }).catch((e) => {
                    subSegment.close();
                    reject(e)
                });
        });     
    });
}

const delay = (ms) => {
    return new Promise((res, rej) => {
        setTimeout(() => res({ time: ms }), ms)
    });
};

This is the resultant XRay Trace

And this is the Trace Raw Data

{
    "Duration": 8.278,
    "Id": "1-5e2f6cc3-a99e6c08f02ce0aec7ab7121",
    "Segments": [
        {
            "Document": {
                "id": "87ca46b60ded68e1",
                "name": "Super Dooper Trace Function",
                "start_time": 1580166338.92,
                "end_time": 1580166347.198,
                "http": {
                    "request": {
                        "url": "http://localhost/test",
                        "method": "GET",
                        "user_agent": "",
                        "client_ip": ""
                    },
                    "response": {
                        "status": 200
                    }
                },
                "aws": {
                    "xray": {
                        "sdk": "X-Ray for Node.js",
                        "sdk_version": "2.5.0",
                        "package": "aws-xray-sdk"
                    }
                },
                "service": {
                    "version": "unknown",
                    "runtime": "node",
                    "runtime_version": "v12.13.0",
                    "name": "unknown"
                },
                "trace_id": "1-5e2f6cc3-a99e6c08f02ce0aec7ab7121",
                "subsegments": [
                    {
                        "id": "98e9f32273700e6e",
                        "name": "MyFirstTrace",
                        "start_time": 1580166339.078,
                        "end_time": 1580166342.082
                    }
                ]
            },
            "Id": "87ca46b60ded68e1"
        }
    ]
}

1 Answer 1

1

Serverless Express has known incompatabilities with the current X-Ray SDK - due to the fact Lambda generates its own Segment, then the Express middleware tries to create one as well. We're planning to address this in the near future.

https://github.com/aws/aws-xray-sdk-node/issues/45

For the full explanation, see this thread: https://github.com/aws/aws-xray-sdk-node/issues/30

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for the reply. The problem is though, If I don't use express middleware, or don't use express at all in the lambda function i.e. just make a call to doWork() in my handler function I do get the timeline of my segments displayed, but the node graph, just displays two nodes, each of them being a Lambda function and I see none of my Subsegments (in the Node Graph).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.