Description
Component
OpenTelemetry.Instrumentation.AspNetCore
Package Version
Package Name | Version |
---|---|
Azure.Monitor.OpenTelemetry.AspNetCore | 1.3.0-beta.2 |
OpenTelemetry.Exporter.Console | 1.9.0 |
OpenTelemetry.Instrumentation.AspNetCore (transitive) | 1.9.0 |
Runtime Version
net8.0
Description
Because the current AspNetCore integration sets all request telemetry in the OnStart() method, it does not work correctly in situations where the webapp is receiving traffic behind a proxy where X-Forwarded-*
-type headers are being used to forward the original ClientIP, Scheme, Path, etc.
ASP.NET includes middleware that by default will recognize:
X-Forwarded-For
(original clientIP)X-Forwarded-Host
(original Host header)X-Forwarded-Proto
(HTTP vs HTTPS)X-Forwarded-Prefix
(original base path - for proxies that rewrite paths when forwarding to backend)
In my case, I am running an ASP.NET8.0 app in Azure WebApps for Linux, which terminates TLS and forwards client context via headers like X-Forwarded-For
, X-Forwarded-Proto
, etc. I am using the Forwarded Headers Middleware to propagate those headers to the HttpContext, (which I've verified is working), but the OpenTelemetry framework is still using the original values when publishing telemetry.
Compare this with the native Application Insights SDK. If I configure OpenTelemetry and Application Insights side-by-side, sending to the same Application Insights resource, here are the request logs I see on the Azure portal:
As expected, there are 2 copies of each request because I'm double-logging traces with 2 frameworks. However, the OpenTelemetry version has not correctly recognized that the original client connection was over HTTPS, whereas the ApplicationInsights one has.
I believe this is because these values change after the "Activity" is started, once the Forwarded Headers Middleware kicks in. But by that time the Activity has already been created with the original values. Therefore, it would seem the only way to support that scenario would be to set/reset these values from the HttpContext in the OnStop()
method as well. (Or by some other fancier means of tying into ASP.NET Core's middleware pipeline...)
Steps to Reproduce
- Create a standard ASP.NET8.0 app with the
Azure.Monitor.OpenTelemetry.AspNetCore
OpenTelemetry distro and the nativeMicrosoft.ApplicationInsights.AspNetCore
SDK:
e.g.builder.Services.AddOpenTelemetry().UseAzureMonitor(); // Configures `AspNetCoreInstrumentation` builder.Services.AddApplicationInsightsTelemetry();
- Provision Application Insights and Azure WebApps/AppService instances in Azure.
- Configure
APPLICATIONINSIGHTS_CONNECTION_STRING
appropriately - Deploy .NET app to WebApp, and make a few requests, ensuring you are using HTTPS
- Azure WebApps will automatically add the
X-Forwarded-*
headers when it terminates TLS and forwards the requests to your app
- Azure WebApps will automatically add the
- Open Application Insights instance > Logs tab >
requests
table
UPDATE: Added a comment where I provided a localhost repro: link
Expected Result
I expect to see both log messages are mostly identical, at least w.r.t. basic properties like request URL and ClientIP/Client Location.
Actual Result
Application Insights-generated log is correct, but OpenTelemetry-generated log as incorrect Scheme and ClientIP/Client Location.
Additional Context
This is somewhat related to #1786.
This has also been logged in Microsoft's distro (link), but was deemed to be a defect in the underlying SDK OpenTelemetry.Instrumentation.AspNetCore
and therefore closed.