microsoft / ApplicationInsights-JS

Microsoft Application Insights SDK for JavaScript
MIT License
652 stars 242 forks source link

[BUG] Application Insights and NextJS hybrid app #2145

Open nunes-bruno-m opened 1 year ago

nunes-bruno-m commented 1 year ago

Hello,

Using Application Insights Web in a NextJS hybrid application doesn't fully work. It can track events but, on the server side requests, there is no correlation id and the entry structure is not the best.

The Node version, using a preloader, doesn't work as it doesn't add any info to the headers.

What is the solution to have Distributed Tracing using Application Insights and NextJs hybrid app?

Thanks!

MSNev commented 1 year ago

Hello, I'm going to need a little more information to fully understand and hopefully provide some meaningful assistance.

First, what versions of the SDK(s) are you using? This is primarily the browser side of the SDK, but what SDK are you using on the server (assuming node) will determine how it handles the request received from the browser / next JS environment. It MUST be at least version 2.x.x (or later) and SHOULD be at least 2.8.x or later.

on the server side requests, there is no correlation id Are you seeing the traceparent and/or Request-Id being sent with the Ajax requests (fetch / XMLHttpRequest)?

If you not then

If you are seeing these headers getting sent then it sounds like the server side is not "handling" these headers (which node should be by default), so I suspect the above.

jorupp commented 1 year ago

@nunes-bruno-m In my next 13.4.19 app, I was seeing multiple processes get created to run different parts of the app and saw the same thing you did - requests seemingly not getting tracked. In 13.5.2, I no longer see the extra processes, and things are getting linked up as I expected (after I initialize app insights in a custom server.js).

nunes-bruno-m commented 1 year ago

Hello, I'm going to need a little more information to fully understand and hopefully provide some meaningful assistance.

First, what versions of the SDK(s) are you using? This is primarily the browser side of the SDK, but what SDK are you using on the server (assuming node) will determine how it handles the request received from the browser / next JS environment. It MUST be at least version 2.x.x (or later) and SHOULD be at least 2.8.x or later.

on the server side requests, there is no correlation id Are you seeing the traceparent and/or Request-Id being sent with the Ajax requests (fetch / XMLHttpRequest)?

If you not then

  • this (might) be just a configuration issue, if the host (page) domain is the same domain as the server receiving the Ajax requests then these headers should be getting sent by default (depending of the version of the SDK), if the server receiving the Ajax requests is different from the hosting page then you will need to enable the enableCorsCorrelation configuration to allow the SDK to include these headers to ALL Ajax requests ALL of the endpoints sent from the browser WILL need to have thier OPTIONS call return that they will allow these headers or they will be dropped.
  • Or it could be the way the runtime is "sending" the request by things like

    • The framework is "caching" the fetch instance before the Application Insights "hooks" (replaces the entrypoint) - but you normally don't get the events then either
    • The framework is creating the "header" being passed into the fetch call as frozen / sealed so we can't add additional headers (later versions of the SDK get around this by always creating a new headers instance and copying over all contained headers)
    • XMLHttpRequest's generally don't have the above issue, but the "hooking" issue can still occur as we hook the prototype functions of the XMLHttpRequest API, so if the framework creates instance level "overrides" which reuse any previously cached prototype functions (before the SDK "hooks" (replaces) them) then the same will occur. Depending on which functions are affected you can still get the events but the setRequestHeader call does not work so the traceparent header is not added.

If you are seeing these headers getting sent then it sounds like the server side is not "handling" these headers (which node should be by default), so I suspect the above.

Hello MSNev,

Thank you for the feedback and sorry for the late answer, this has gone under the radar. About versions, they are: "@microsoft/applicationinsights-react-js": "^3.4.2", "@microsoft/applicationinsights-web": "^3.0.2", The requests to the server side are going without traceparent or Request-Id in the headers and the domain is the same.

I'm not sure if I will say something dumb but I will do my best to explain :D This NextJS app uses NextJS way of running the server , which doesn't allow to use of the node version of applicationinsights. There was a preloader tactic but then we couldn't use the instance and, as far as I remember, it was complaining about the fact it is running on Edge Runtime, which has fewer Node APIs available.

nunes-bruno-m commented 1 year ago

@nunes-bruno-m In my next 13.4.19 app, I was seeing multiple processes get created to run different parts of the app and saw the same thing you did - requests seemingly not getting tracked. In 13.5.2, I no longer see the extra processes, and things are getting linked up as I expected (after I initialize app insights in a custom server.js).

Thanks for the feedback! Unfortunately, the app is stuck in 13.4.1 due to an incompatibility between NextJS, Next Auth and Azure Static Web App, last upgrade tryout was on 13.4.14. But it's time to reevaluate if this new "major" 13.5 version makes the magic :D

Edit I just saw now the part "(after I initialize app insights in a custom server.js)", without it, the behaviour is the same as before then?

MSNev commented 1 year ago

server side are going without traceparent or Request-Id

I have several possible ideas here,

Either way, I think the path forward will be to manually debug into the ajax.ts file around where we "hook" and add the headers to see if your code is patching (hooking) the objects and / or if it is hooking them, then when you code attempts an ajax request are the hooks being called.

The "entrypoint" for where we instrument the code is here with the fetch hooking being here and XmlHttpRequest here if the if check is failing then that will be config related and if the hook req: callback is not getting called then it's most likely the caching issue above.

There is one other option, the hooking can fail if the runtime has frozen the objects / function and does not let us override them, I don't have a workaround for that scenario at this point.

jorupp commented 1 year ago

Thank you for the feedback and sorry for the late answer, this has gone under the radar. About versions, they are: "@microsoft/applicationinsights-react-js": "^3.4.2", "@microsoft/applicationinsights-web": "^3.0.2", The requests to the server side are going without traceparent or Request-Id in the headers and the domain is the same.

@nunes-bruno-m, If you're seeing this behavior only with server actions (but other calls are getting those parameters), #2165 should fix that part.

github-actions[bot] commented 2 weeks ago

This Issue will be closed in 30 days. Please remove the "Stale" label or comment to avoid closure with no action.