ApplicationInsights-node.js icon indicating copy to clipboard operation
ApplicationInsights-node.js copied to clipboard

Paths redirected in Azure Static Web Apps are logged as the path of the function

Open tlaundal opened this issue 1 year ago • 4 comments

When using setAutoCollectIncomingRequestAzureFunctions(true), requests which are redirected by Azure Static Web Apps are logged with the URL of the function itself, not the URL the user requested.

Knowing which function was invoked is of course useful, but what URL the user requested is imperative information when debugging. As an example, some app frameworks (such as SvelteKit with the svelte-adapter-azure-swa adapter), will redirect every request to a single function. With this setup, all requests in application insights have an URL like https://<some uuid>.azurewebsites.net/api/__render.

In the case of Azure Static Web Apps, and I suspect other Azure services as well, the original URL request by the user is stored in the x-ms-original-url header.

It seems a sensible fix would be to check for the header and set the URL correctly here: https://github.com/microsoft/ApplicationInsights-node.js/blob/45e06c608a291442ad2a100dee771fc1e8908d74/AutoCollection/AzureFunctionsHook.ts#L128

I'd be happy to submit a PR for this, if it is likely to be accepted.

tlaundal avatar May 11 '23 21:05 tlaundal

@tlaundal thanks for reporting the issue, changing the URL could be a breaking change for others, correct fix here would be to populate contextObjects with request and response objects, after that you can add a telemetry processor on your side to enhance the telemetry using the contextObjects, there you can grab the headers and modify the telemetry as you see fit, more info here feel free to create a PR if not we will take care of this soon before next release of the SDK

hectorhdzg avatar May 11 '23 23:05 hectorhdzg

A telemetry processor seems like a good solution, but it doesn't seem to contain any reference to the original request? Thus there is no way to directly get the x-ms-original-url header it seems. When I attach a processor, the envelope argument contains only the data that is transmitted to AI, and the contextObjects argument contains only a correlationContext object which further contains operation and customProperties. Neither of these seem to provide a way to access the headers of the original request.

For now I've worked around this by overwriting the url property of the request object when handling it, such that it has the correct URL when azure functions hooks logs it.

EDIT: Another way to work around this restriction is to store the correct URL in CorrelationContextManager.getCurrentContext()?.customProperties sometime during request handling and then access it through context?.correlationContext?.customProperties in the telemetry processor.

As for implementing an easy way of doing it directly here, I think we can either:

  1. Have some sort of config or flag instructing the AzureFunctionsHook to use the url from x-ms-original-url, or
  2. Introduce a AzureSWAHook, which would use the telemetry processor trick (or something similar) to overwrite the url logged by AzureFunctionsHook.

tlaundal avatar May 12 '23 08:05 tlaundal

@tlaundal the proposal I have in mind is basically adding the original request reference that we have there in AzureFunctionsHook "_createIncomingRequestTelemetry" method and put it in the contextObjects so it can be read later in the telemetry processor, I know is not there but that is the proposal for a fix, are you saying this would not work for you?, that is the way we allow headers to be added in HTTP incoming requests outside of Azure Functions.

hectorhdzg avatar May 12 '23 15:05 hectorhdzg

@hectorhdzg That would certainly work, and make my workaround a bit neater.

I would like to see a more out-of-the-box solution to this, though, but perhaps that's something for the SWA team?

tlaundal avatar May 12 '23 16:05 tlaundal