ApplicationInsights-node.js
ApplicationInsights-node.js copied to clipboard
Paths redirected in Azure Static Web Apps are logged as the path of the function
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 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
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:
- Have some sort of config or flag instructing the
AzureFunctionsHook
to use the url fromx-ms-original-url
, or - Introduce a
AzureSWAHook
, which would use the telemetry processor trick (or something similar) to overwrite the url logged byAzureFunctionsHook
.
@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 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?