-
Notifications
You must be signed in to change notification settings - Fork 146
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feature Request: support for tracing NodeJs 18 native fetch
calls
#1619
Comments
Thanks for opening your first issue here! We'll come back to you as soon as we can. |
Hey @RaphaelManke, thanks for raising the issue. After a closer look it seems like this is x-ray SDK specific, since we are using it. The related issue and discussion is here aws/aws-xray-sdk-node#531 . |
fetch
calls are not tracedfetch
calls
We have been tracking this for a while and at the moment we are blocked by the X-Ray SDK that we use for our Tracer utility, which does not support this. We are aware of a potential workaround (mentioned in the issue Alex mentioned), however since I'm adding the |
This probably won't make much of a difference in terms of your prioritization, but:
If I'm not mistaken, |
I stand corrected, you are definitely right - I have updated my comment above and linked it to yours. Thank you for clarifying! Additionally, to provide more context on why |
I totally get the limitation now and thank you for clarifying this. I think that there should be a statement in the info box highlighting this limitation in the info box on the tracer page. In the business context I see two kind of people who will run into the same issue. The other group are those people that are upgrading there NodeJS runtime to NodeJS 18 and get rid of unneeded dependencies and therefore remove the For both use cases a hint in the documentation would be helpful. |
I totally agree, we'll be adding a notice to the docs in the next few hours. Thanks for the suggestion! |
So I did came up with a workaround. It's just a POC and I am not sure if its something the powertools would implement or x-ray. The workaround uses the undici diagnostic channels to add subsegments. const segments = new Map<
any,
{ subsegment: Subsegment; parentSubsegment: Segment | Subsegment }
>();
function addNativeFetchTracing(tracer: Tracer) {
/**
* This is the first event emitted when a request is created.
* Based on this event a new subsegment is created.
* To have a reference to the subsegment created, it is stored in a map.
*/
diagnosticsChannel
.channel("undici:request:create")
.subscribe(({ request }: any) => {
const parentSubsegment = tracer.getSegment(); // This is the subsegment currently active
let subsegment;
if (parentSubsegment) {
const [_, baseUrl] = request.origin.split("//");
subsegment = parentSubsegment.addNewSubsegment(baseUrl);
tracer.setSegment(subsegment);
subsegment.addAttribute("namespace", "remote");
}
segments.set(request, {
subsegment: subsegment!,
parentSubsegment: parentSubsegment!,
});
});
/**
* When the response is received, the response data and headers are added to the subsegment.
*/
diagnosticsChannel
.channel("undici:request:headers")
.subscribe(async ({ request, response }: any) => {
const { subsegment, parentSubsegment } = segments.get(request)!;
if (parentSubsegment && subsegment) {
const [protocol, host] = request.origin.split("//");
// Undici returns the headers as an buffer array of key-value pairs.
const headers = arrayToObject(response.headers);
// The expected request does not match and need to be modified
subsegment.addRemoteRequestData(
{
...request,
host,
agent: {
protocol,
},
},
{
...response,
headers: headers,
}
);
}
});
/**
* The subsegment is closed when the response is finished.
*/
diagnosticsChannel
.channel("undici:request:trailers")
.subscribe(({ request }: any) => {
const { subsegment, parentSubsegment } = segments.get(request)!;
if (parentSubsegment && subsegment) {
subsegment.close();
tracer.setSegment(parentSubsegment);
segments.delete(request);
}
});
}
function arrayToObject(arr: any[]): { [key: string]: any } {
const result: { [key: string]: any } = {};
if (arr.length % 2 !== 0) {
throw new Error("Array length should be even to form key-value pairs.");
}
for (let i = 0; i < arr.length; i += 2) {
const key = arr[i].toString().toLowerCase();
const value = arr[i + 1].toString();
result[key] = value;
}
return result;
} Its also added to the reproduction repo RaphaelManke/aws-powertools-node-18-tracing-fetch-bug@823864f What do you think? Is this something that should go into powertools or is it too experimental 😓 |
Hi @RaphaelManke thank you for sharing this! Coincidentally I was also looking into a workaround and was able to find one, although taking a different route (similar to the workaround described in the X-Ray issue linked above). You can see the implementation here: https://github.com/aws-powertools/powertools-lambda-typescript/blob/feat/tracer/nativefetch/packages/tracer/src/provider/ProviderService.ts#L170 All things considered it seems we have already two options, so we are considering implementing one of them in the Tracer in the next release or the one afterwards (we are planning on releasing today or Monday, and we might not make it in time). Let me spend some time looking at your implementation. |
I also found an open PR at the x-ray-node repo going into that direction. |
Hi Raphael, I just wanted to share an update before checking out for the day. First of all, I really like your implementation! I think using the My two main concerns around that implementation are: 1/ support to the API is listed as experimental, and 2/ according to the undici page you linked the module is available in Node.js 16+. Regarding point 1: I have used undici as a user in the past, and I know that the native If major changes to Regarding point 2: I am not clear on whether Both points might be mitigated with some additional investigation and tests, however at the moment I'm not able to provide an ETA. For context: our current stance is to support all current AWS Lambda runtimes ( We are going to need a bit more time to continue investigating a solution that fits all runtimes (which might be among the two discussed so far) and after that we'll need to run some manual testing and implement automated ones. At that point we will be in a better position to share an ETA. For now, I have moved the issue to the backlog and changed its status to reflect the fact that we are going to actively look into this and try to find a solution. This feature is a priority for us, so if we find a viable implementation we'd be happy to include it in Powertools. |
@dreamorosi do you have a update on implementation plan? |
I'll try and get the PR moving again. I had run out of time/bandwidth before. Maybe I can shepherd it through this time. |
I found an implementation for otel. It might be helpful |
Looks like aws/aws-xray-sdk-node#590 was merged 🎉 This didn't get into 2.0, but can we get it for a patch release? Thanks! |
The AWS SDK did merge that PR but it was released under a separate package Additionally their implementation is based on the same logic as the patching for the I'll try to prioritize this feature since there's a lot of demand, alternatively if anyone is interested in contributing I'd be happy to advise on the design and provide timely reviews to get it merged. |
It should work with recent Node's "built-in" fetch as well as the older node-fetch. Are you having issues with it? |
No, the instrumentation works. I'm mainly concerned about ESM support, and overall I would prefer to move away from CJS-only code as much as possible. The Additionally, we are not going to target In the long term I'd like to move the tracing of |
I like that this topic gets some traction 🙂 |
Hi everyone, I understand that this is an in demand feature and I acknowledge that it's overdue on our side. Unfortunately due to circumstances outside of my control the team did not have the bandwidth to work on this sooner, so I appreciate everyone's patience and continued support for the project. I have started working on a PR (#2293) that uses an implementation based on I hope this shows that I want to prioritize this and that I want to get it merged as soon as possible but without compromising on quality and long term vision for Powertools. The code in the PR is already working and generating traces for requests made using In the meantime, if you want to adopt the version that was merged in the X-Ray SDK core, you can already do so like this: import { Tracer } from "@aws-lambda-powertools/tracer";
import { captureLambdaHandler } from "@aws-lambda-powertools/tracer/middleware";
import { captureFetchGlobal } from "aws-xray-sdk-fetch"; // npm i aws-xray-sdk-fetch
import middy from "@middy/core";
const tracer = new Tracer();
captureFetchGlobal();
export const handler = middy(async (event: unknown) => {
await fetch("http://httpbin.org/status/500");
}).use(captureLambdaHandler(tracer)); I have tested it and it seem to work well with Tracer, you should be able to make it work by only installing the module and calling |
Just to manage everyone's expectations, the team is based in EMEA and we're starting a long weekend - so assuming everything works and we can write integration tests for it - the PR won't be merged before mid next week at the earliest. |
Just a small update from our side: I've completed the implementation, tests, and docs and the PR is now ready for review. |
This issue is now closed. Please be mindful that future comments are hard for our team to see. If you need more assistance, please either tag a team member or open a new issue that references this one. If you wish to keep having a conversation with other community members under this issue feel free to do so. |
This is now released under v2.0.4 version! |
Expected Behaviour
In our Team we use the native nodeJS 18 fetch module to make api calls.
We were expecting that fetch calls would be traced the same as they where when we used
node-fetch
.Current Behaviour
The fetch calls are not traced whereas the node-fetch calls are traced.
The x-ray traces show only the api calls made with node-fetch.
Code snippet
Steps to Reproduce
Possible Solution
No response
Powertools for AWS Lambda (TypeScript) version
1.11.1
AWS Lambda function runtime
18.x
Packaging format used
npm
Execution logs
No response
The text was updated successfully, but these errors were encountered: