[APMSVLS-442] Adding azure frontdoor support#8861
Conversation
BenchmarksBenchmark execution time: 2026-07-07 23:02:41 Comparing candidate commit dd648ca in PR branch Found 2 performance improvements and 1 performance regressions! Performance is the same for 69 metrics, 0 unstable metrics, 61 known flaky benchmarks, 65 flaky benchmarks without significant changes.
|
Execution-Time Benchmarks Report ⏱️Execution-time results for samples comparing This PR (8861) and master. ✅ No regressions detected - check the details below Full Metrics ComparisonFakeDbCommand
HttpMessageHandler
Comparison explanationExecution-time benchmarks measure the whole time it takes to execute a program, and are intended to measure the one-off costs. Cases where the execution time results for the PR are worse than latest master results are highlighted in **red**. The following thresholds were used for comparing the execution times:
Note that these results are based on a single point-in-time result for each branch. For full results, see the dashboard. Graphs show the p99 interval based on the mean and StdDev of the test run, as well as the mean value of the run (shown as a diamond below the graph). Duration chartsFakeDbCommand (.NET Framework 4.8)gantt
title Execution time (ms) FakeDbCommand (.NET Framework 4.8)
dateFormat x
axisFormat %Q
todayMarker off
section Baseline
This PR (8861) - mean (70ms) : 67, 72
master - mean (71ms) : 68, 73
section Bailout
This PR (8861) - mean (75ms) : 71, 80
master - mean (74ms) : 73, 75
section CallTarget+Inlining+NGEN
This PR (8861) - mean (1,088ms) : 1027, 1148
master - mean (1,089ms) : 1039, 1138
FakeDbCommand (.NET Core 3.1)gantt
title Execution time (ms) FakeDbCommand (.NET Core 3.1)
dateFormat x
axisFormat %Q
todayMarker off
section Baseline
This PR (8861) - mean (109ms) : 106, 112
master - mean (110ms) : 105, 115
section Bailout
This PR (8861) - mean (115ms) : 109, 122
master - mean (110ms) : 108, 112
section CallTarget+Inlining+NGEN
This PR (8861) - mean (775ms) : 752, 797
master - mean (783ms) : 759, 806
FakeDbCommand (.NET 6)gantt
title Execution time (ms) FakeDbCommand (.NET 6)
dateFormat x
axisFormat %Q
todayMarker off
section Baseline
This PR (8861) - mean (100ms) : 95, 104
master - mean (98ms) : 93, 103
section Bailout
This PR (8861) - mean (97ms) : 95, 100
master - mean (101ms) : 96, 106
section CallTarget+Inlining+NGEN
This PR (8861) - mean (936ms) : 893, 979
master - mean (936ms) : 900, 973
FakeDbCommand (.NET 8)gantt
title Execution time (ms) FakeDbCommand (.NET 8)
dateFormat x
axisFormat %Q
todayMarker off
section Baseline
This PR (8861) - mean (94ms) : 92, 97
master - mean (95ms) : 92, 97
section Bailout
This PR (8861) - mean (98ms) : 92, 104
master - mean (96ms) : 94, 98
section CallTarget+Inlining+NGEN
This PR (8861) - mean (814ms) : 768, 860
master - mean (816ms) : 773, 860
HttpMessageHandler (.NET Framework 4.8)gantt
title Execution time (ms) HttpMessageHandler (.NET Framework 4.8)
dateFormat x
axisFormat %Q
todayMarker off
section Baseline
This PR (8861) - mean (203ms) : 198, 209
master - mean (203ms) : 197, 209
section Bailout
This PR (8861) - mean (207ms) : 203, 211
master - mean (207ms) : 203, 211
section CallTarget+Inlining+NGEN
This PR (8861) - mean (1,213ms) : 1159, 1268
master - mean (1,213ms) : 1168, 1258
HttpMessageHandler (.NET Core 3.1)gantt
title Execution time (ms) HttpMessageHandler (.NET Core 3.1)
dateFormat x
axisFormat %Q
todayMarker off
section Baseline
This PR (8861) - mean (290ms) : 283, 297
master - mean (289ms) : 281, 298
section Bailout
This PR (8861) - mean (291ms) : 284, 298
master - mean (291ms) : 286, 295
section CallTarget+Inlining+NGEN
This PR (8861) - mean (974ms) : 950, 998
master - mean (972ms) : 954, 991
HttpMessageHandler (.NET 6)gantt
title Execution time (ms) HttpMessageHandler (.NET 6)
dateFormat x
axisFormat %Q
todayMarker off
section Baseline
This PR (8861) - mean (279ms) : 274, 284
master - mean (282ms) : 275, 288
section Bailout
This PR (8861) - mean (281ms) : 275, 287
master - mean (279ms) : 273, 284
section CallTarget+Inlining+NGEN
This PR (8861) - mean (1,166ms) : 1121, 1210
master - mean (1,164ms) : 1125, 1203
HttpMessageHandler (.NET 8)gantt
title Execution time (ms) HttpMessageHandler (.NET 8)
dateFormat x
axisFormat %Q
todayMarker off
section Baseline
This PR (8861) - mean (280ms) : 274, 287
master - mean (277ms) : 270, 283
section Bailout
This PR (8861) - mean (279ms) : 273, 286
master - mean (274ms) : 266, 282
section CallTarget+Inlining+NGEN
This PR (8861) - mean (1,048ms) : 1005, 1090
master - mean (1,042ms) : 998, 1086
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 025d9ec808
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
Summary of changes
This PR implements Azure FrontDoor. This is an upstream proxy service that Azure offers.
Azure Front Door
Azure Front Door is a edge computing CDN proxy that provides load balancing and regional routing to azure web apps and containers. Customers use this ensure their application has a single entry point across multiple regions.
One special case is that azure front door lacks the ability to insert timestamps in the headers. This may change in the future but due to this I modified the process to add a timespan at header detection which means that the accuracy of the timeline decreases but we still get a usable span and the proxy is represented. If this does change and the ability to insert timestamps does get implemented on Azure's side the code is thoughtful enough to not overwrite an existing timestamp header and making it less of an urgent change to remove the code I am introducing.
Reason for change
This is a proxy service from Azure. It would be great to provide observability coverage for customers to see in their traces.
Implementation details
I added Azure Front Door support to the inferred proxy span pipeline, following the same pattern already established for Azure API Management and AWS API Gateway.
The core of the work is two new classes: AzureFrontDoorExtractor and AzureFrontDoorSpanFactory. The extractor reads the standard inferred proxy headers (start time, domain, HTTP method, path, region) from the incoming request and returns an InferredProxyData struct. Unlike APIM and API Gateway, Azure Front Door does not inject a timestamp header, so if one isn't present the extractor synthesizes a start time from the current time — but if a start time header is present it will be used instead. The span factory takes that data and creates a web-type span with operation name azure.frontdoor, setting resource name, HTTP tags, region, and using the domain name as the service name.
I wired these into InferredProxySpanHelper so that when the x-dd-proxy header value is azure-fd, the coordinator is initialized with the Front Door extractor and factory and produces the inferred proxy scope.
I also updated AzureFunctionsCommon to recognize azure.frontdoor as a proxy operation name — same as it already does for azure.apim — so that Azure Functions doesn't overwrite the inferred proxy span as the root.
Finally, I added the constant AzureFrontDoorName = "azure.frontdoor" to AzureFunctionsConstants, and wrote unit tests for both the extractor and the span factory covering the happy path, missing optional headers, and invalid/missing start time.
Test coverage
AzureFrontDoorExtractorTests has 7 tests total (4 via [Theory], 3 [Fact]):
I verify that when all headers are present and valid, TryExtract returns true and correctly populates ProxyName, StartTime, HttpMethod, Path, Stage, and Region.
I verify that when only the required start time header is present (optional headers removed), extraction still succeeds and the optional fields come back null.
I cover 4 invalid start time cases (null, empty string, non-numeric, and an overflowing value) via a theory — all should return false with a default InferredProxyData.
I verify that a completely missing start time header also returns false.
AzureFrontDoorSpanFactoryTests has 1 test:
I verify that CreateSpan produces a span with the correct operation name (azure.frontdoor), resource name (GET /api/v1/users), span type (web), start time, and all expected tags (http.method, component, http.url, http.route).
Other details