aws / aws-xray-sdk-node

The official AWS X-Ray SDK for Node.js.
Apache License 2.0
271 stars 155 forks source link

need a hook or some other way to utilize the segment context elsewhere #489

Open codekitchen opened 2 years ago

codekitchen commented 2 years ago

Hi! I'm struggling to find a reasonable way to read and update the root Segment in an express app in automatic mode. This seems like a gap in functionality, apologies if I'm just missing something.

A few examples of things I'm trying to do:

I was hoping to just use an express middleware for this, something like:

function addXRayContext(req, res, next) {
    if (req.user)
        AWSXRay.getSegment()?.setUser(req.user.id.toString())

    const traceID = AWSXRay.getSegment()?.trace_id
    if (traceID)
        res.header('X-Amzn-Trace-Id', traceID)

    next()
}

But if I inject that into my middleware stack I get the cls-hooked errors that the README warns about:

app.use(AWSXRay.express.openSegment('solflow-api'))
app.use(addXRayContext)  // doesn't work here
app.use(router)
app.use(AWSXRay.express.closeSegment())

I've dug through all the publicly exposed methods in the core and express packages and I haven't found anything that looks like it'll help me here -- the only option I can think of is to add a call to addXRayContext in every single route handler in our app, which of course would not be fun to maintain.

I think what I'm probably looking for is some way to hook into traceRequestResponseCycle after the root Segment is created. But maybe there's a better solution?

srprash commented 2 years ago

Hi @codekitchen Once you get the current segment, you should be able to set and get its attribute the way you've mentioned. I don't currently know why it doesn't work. Can you provide a simple reproduction code? Thanks.

codekitchen commented 2 years ago

hi @srprash I think there must be something more going on here, because when I tried to boil it down to a minimal repro I do not get an error adding that middleware to the stack between AWSXRay.express.openSegment and the app routes. We do get errors from cls-hooked when trying to do the same within our full application, though.

I was under the impression that this error was expected because of this section of the AWSXRay.express README, where it says:

In automatic mode, the openSegment middleware must be the last middleware added before defining routes, and the closeSegment middleware must be the first middleware added after defining routes. Otherwise issues with the cls-hooked context may occur.

However it appears that is not always the case, which I see it says may occur. Do you know more details about under what situations adding a middleware here can cause cls-hooked errors?