Skip to content

Conversation

@dudikeleti
Copy link
Contributor

@dudikeleti dudikeleti commented Jan 21, 2026

Reason for change

Code Origin for Spans was already supported on ASP.NET Core entry spans, but classic ASP.NET (.NET Framework) MVC/Web API entry spans (aspnet.request) were missing _dd.code_origin.* tags, preventing file/line enrichment and consistent “entry span origin” behavior across runtimes. There is open customer ticket for this.

Implementation details

MVC: Added code origin tagging for root entry span (aspnet.request) in ControllerActionInvoker_InvokeAction_Integration.

Web API: Added code origin tagging for root entry span root entry span (aspnet.request) in ReflectedHttpActionDescriptor_ExecuteAsync_Integration.

PDB enrichment support: Extended EndpointDetector to recognize .NET Framework MVC/Web API controller endpoints so sequence points can be loaded for file/line/column.

Out of scope of this PR

This change focuses only on entry spans for .NET Framework ASP.NET MVC 4/5 and Web API 2. It does not add Code Origin for Spans support for the following:

  • WCF spans (support will be added in a follow-up PR),
  • WebForms or generic IHttpHandler (support may be added if required),
  • OWIN and others, which are currently not supported.

Test coverage

Unit tests:
Updated EndpointDetectorTests to validate detection of .NET Framework MVC/WebApi2 endpoints.

Integration tests:
AspNetMvc5CodeOriginTests & AspNetWebApi2CodeOriginTests
Enabled code origin via env var and verified emitted span snapshots include code origin tags.

@dd-trace-dotnet-ci-bot
Copy link

dd-trace-dotnet-ci-bot bot commented Jan 21, 2026

Execution-Time Benchmarks Report ⏱️

Execution-time results for samples comparing This PR (8083) and master.

✅ No regressions detected - check the details below

Full Metrics Comparison

FakeDbCommand

Metric Master (Mean ± 95% CI) Current (Mean ± 95% CI) Change Status
.NET Framework 4.8 - Baseline
duration68.23 ± (68.26 - 68.58) ms68.38 ± (68.44 - 68.67) ms+0.2%✅⬆️
.NET Framework 4.8 - Bailout
duration72.14 ± (72.05 - 72.29) ms72.22 ± (72.16 - 72.34) ms+0.1%✅⬆️
.NET Framework 4.8 - CallTarget+Inlining+NGEN
duration1015.80 ± (1017.16 - 1023.60) ms1021.42 ± (1025.05 - 1036.62) ms+0.6%✅⬆️
.NET Core 3.1 - Baseline
process.internal_duration_ms21.78 ± (21.75 - 21.81) ms21.84 ± (21.81 - 21.88) ms+0.3%✅⬆️
process.time_to_main_ms78.80 ± (78.62 - 78.98) ms79.07 ± (78.89 - 79.26) ms+0.3%✅⬆️
runtime.dotnet.exceptions.count0 ± (0 - 0)0 ± (0 - 0)+0.0%
runtime.dotnet.mem.committed10.90 ± (10.89 - 10.90) MB10.90 ± (10.90 - 10.91) MB+0.0%✅⬆️
runtime.dotnet.threads.count12 ± (12 - 12)12 ± (12 - 12)+0.0%
.NET Core 3.1 - Bailout
process.internal_duration_ms21.78 ± (21.76 - 21.81) ms21.74 ± (21.72 - 21.76) ms-0.2%
process.time_to_main_ms79.79 ± (79.70 - 79.87) ms80.25 ± (80.15 - 80.36) ms+0.6%✅⬆️
runtime.dotnet.exceptions.count0 ± (0 - 0)0 ± (0 - 0)+0.0%
runtime.dotnet.mem.committed10.93 ± (10.93 - 10.93) MB10.94 ± (10.94 - 10.95) MB+0.1%✅⬆️
runtime.dotnet.threads.count13 ± (13 - 13)13 ± (13 - 13)+0.0%
.NET Core 3.1 - CallTarget+Inlining+NGEN
process.internal_duration_ms239.21 ± (235.54 - 242.87) ms249.71 ± (246.34 - 253.08) ms+4.4%✅⬆️
process.time_to_main_ms474.58 ± (474.10 - 475.07) ms475.21 ± (474.70 - 475.73) ms+0.1%✅⬆️
runtime.dotnet.exceptions.count0 ± (0 - 0)0 ± (0 - 0)+0.0%
runtime.dotnet.mem.committed48.58 ± (48.56 - 48.60) MB48.59 ± (48.56 - 48.61) MB+0.0%✅⬆️
runtime.dotnet.threads.count28 ± (28 - 28)28 ± (28 - 28)+0.1%✅⬆️
.NET 6 - Baseline
process.internal_duration_ms20.65 ± (20.62 - 20.67) ms20.72 ± (20.69 - 20.76) ms+0.4%✅⬆️
process.time_to_main_ms68.36 ± (68.22 - 68.50) ms68.83 ± (68.72 - 68.94) ms+0.7%✅⬆️
runtime.dotnet.exceptions.count0 ± (0 - 0)0 ± (0 - 0)+0.0%
runtime.dotnet.mem.committed10.61 ± (10.60 - 10.61) MB10.63 ± (10.63 - 10.64) MB+0.3%✅⬆️
runtime.dotnet.threads.count10 ± (10 - 10)10 ± (10 - 10)+0.0%
.NET 6 - Bailout
process.internal_duration_ms20.58 ± (20.55 - 20.60) ms20.50 ± (20.48 - 20.53) ms-0.4%
process.time_to_main_ms69.19 ± (69.12 - 69.25) ms69.33 ± (69.26 - 69.39) ms+0.2%✅⬆️
runtime.dotnet.exceptions.count0 ± (0 - 0)0 ± (0 - 0)+0.0%
runtime.dotnet.mem.committed10.66 ± (10.65 - 10.66) MB10.74 ± (10.74 - 10.75) MB+0.8%✅⬆️
runtime.dotnet.threads.count11 ± (11 - 11)11 ± (11 - 11)+0.0%
.NET 6 - CallTarget+Inlining+NGEN
process.internal_duration_ms250.11 ± (248.99 - 251.23) ms250.71 ± (249.81 - 251.60) ms+0.2%✅⬆️
process.time_to_main_ms452.99 ± (452.48 - 453.49) ms452.41 ± (451.84 - 452.98) ms-0.1%
runtime.dotnet.exceptions.count0 ± (0 - 0)0 ± (0 - 0)+0.0%
runtime.dotnet.mem.committed49.39 ± (49.36 - 49.42) MB49.30 ± (49.27 - 49.33) MB-0.2%
runtime.dotnet.threads.count28 ± (28 - 28)28 ± (28 - 28)-0.0%
.NET 8 - Baseline
process.internal_duration_ms18.72 ± (18.70 - 18.75) ms18.87 ± (18.85 - 18.89) ms+0.8%✅⬆️
process.time_to_main_ms67.35 ± (67.25 - 67.44) ms67.47 ± (67.37 - 67.58) ms+0.2%✅⬆️
runtime.dotnet.exceptions.count0 ± (0 - 0)0 ± (0 - 0)+0.0%
runtime.dotnet.mem.committed7.67 ± (7.67 - 7.68) MB7.67 ± (7.66 - 7.68) MB+0.0%✅⬆️
runtime.dotnet.threads.count10 ± (10 - 10)10 ± (10 - 10)+0.0%
.NET 8 - Bailout
process.internal_duration_ms18.79 ± (18.76 - 18.81) ms18.87 ± (18.85 - 18.90) ms+0.5%✅⬆️
process.time_to_main_ms68.42 ± (68.36 - 68.48) ms68.58 ± (68.52 - 68.63) ms+0.2%✅⬆️
runtime.dotnet.exceptions.count0 ± (0 - 0)0 ± (0 - 0)+0.0%
runtime.dotnet.mem.committed7.76 ± (7.75 - 7.77) MB7.72 ± (7.71 - 7.73) MB-0.5%
runtime.dotnet.threads.count11 ± (11 - 11)11 ± (11 - 11)+0.0%
.NET 8 - CallTarget+Inlining+NGEN
process.internal_duration_ms177.17 ± (176.30 - 178.04) ms177.79 ± (176.89 - 178.69) ms+0.4%✅⬆️
process.time_to_main_ms434.46 ± (433.89 - 435.02) ms435.13 ± (434.55 - 435.70) ms+0.2%✅⬆️
runtime.dotnet.exceptions.count0 ± (0 - 0)0 ± (0 - 0)+0.0%
runtime.dotnet.mem.committed36.65 ± (36.62 - 36.67) MB36.69 ± (36.66 - 36.72) MB+0.1%✅⬆️
runtime.dotnet.threads.count26 ± (26 - 26)26 ± (26 - 27)+0.0%

HttpMessageHandler

Metric Master (Mean ± 95% CI) Current (Mean ± 95% CI) Change Status
.NET Framework 4.8 - Baseline
duration195.34 ± (195.95 - 196.95) ms195.28 ± (195.06 - 195.85) ms-0.0%
.NET Framework 4.8 - Bailout
duration203.12 ± (202.51 - 203.97) ms199.32 ± (199.22 - 200.09) ms-1.9%
.NET Framework 4.8 - CallTarget+Inlining+NGEN
duration1153.57 ± (1155.32 - 1165.18) ms1149.32 ± (1148.95 - 1157.21) ms-0.4%
.NET Core 3.1 - Baseline
process.internal_duration_ms188.70 ± (188.37 - 189.02) ms189.36 ± (189.03 - 189.70) ms+0.4%✅⬆️
process.time_to_main_ms81.80 ± (81.55 - 82.05) ms81.93 ± (81.64 - 82.22) ms+0.2%✅⬆️
runtime.dotnet.exceptions.count3 ± (3 - 3)3 ± (3 - 3)+0.0%
runtime.dotnet.mem.committed16.11 ± (16.08 - 16.13) MB16.13 ± (16.10 - 16.16) MB+0.1%✅⬆️
runtime.dotnet.threads.count20 ± (19 - 20)20 ± (20 - 20)+0.4%✅⬆️
.NET Core 3.1 - Bailout
process.internal_duration_ms187.91 ± (187.59 - 188.22) ms188.72 ± (188.40 - 189.04) ms+0.4%✅⬆️
process.time_to_main_ms82.62 ± (82.44 - 82.79) ms83.13 ± (82.95 - 83.31) ms+0.6%✅⬆️
runtime.dotnet.exceptions.count3 ± (3 - 3)3 ± (3 - 3)+0.0%
runtime.dotnet.mem.committed16.17 ± (16.15 - 16.20) MB16.13 ± (16.10 - 16.16) MB-0.3%
runtime.dotnet.threads.count21 ± (20 - 21)21 ± (20 - 21)+0.2%✅⬆️
.NET Core 3.1 - CallTarget+Inlining+NGEN
process.internal_duration_ms422.67 ± (419.31 - 426.03) ms433.18 ± (430.14 - 436.23) ms+2.5%✅⬆️
process.time_to_main_ms480.43 ± (479.68 - 481.18) ms486.53 ± (485.64 - 487.41) ms+1.3%✅⬆️
runtime.dotnet.exceptions.count3 ± (3 - 3)3 ± (3 - 3)+0.0%
runtime.dotnet.mem.committed59.12 ± (59.00 - 59.24) MB58.93 ± (58.82 - 59.04) MB-0.3%
runtime.dotnet.threads.count29 ± (29 - 29)30 ± (29 - 30)+0.1%✅⬆️
.NET 6 - Baseline
process.internal_duration_ms192.98 ± (192.62 - 193.34) ms197.11 ± (196.45 - 197.78) ms+2.1%✅⬆️
process.time_to_main_ms70.83 ± (70.60 - 71.06) ms72.11 ± (71.86 - 72.36) ms+1.8%✅⬆️
runtime.dotnet.exceptions.count4 ± (4 - 4)4 ± (4 - 4)+0.0%
runtime.dotnet.mem.committed16.04 ± (15.90 - 16.19) MB16.31 ± (16.29 - 16.33) MB+1.7%✅⬆️
runtime.dotnet.threads.count19 ± (18 - 19)19 ± (19 - 19)+3.0%✅⬆️
.NET 6 - Bailout
process.internal_duration_ms193.02 ± (192.60 - 193.44) ms197.10 ± (196.47 - 197.73) ms+2.1%✅⬆️
process.time_to_main_ms71.91 ± (71.76 - 72.06) ms73.65 ± (73.36 - 73.94) ms+2.4%✅⬆️
runtime.dotnet.exceptions.count4 ± (4 - 4)4 ± (4 - 4)+0.0%
runtime.dotnet.mem.committed16.13 ± (16.00 - 16.27) MB16.36 ± (16.34 - 16.38) MB+1.4%✅⬆️
runtime.dotnet.threads.count20 ± (19 - 20)20 ± (20 - 20)+2.5%✅⬆️
.NET 6 - CallTarget+Inlining+NGEN
process.internal_duration_ms443.41 ± (439.98 - 446.83) ms442.56 ± (438.92 - 446.20) ms-0.2%
process.time_to_main_ms460.59 ± (459.90 - 461.28) ms463.62 ± (462.88 - 464.35) ms+0.7%✅⬆️
runtime.dotnet.exceptions.count4 ± (4 - 4)4 ± (4 - 4)+0.0%
runtime.dotnet.mem.committed59.13 ± (59.00 - 59.26) MB59.08 ± (58.94 - 59.22) MB-0.1%
runtime.dotnet.threads.count29 ± (29 - 29)29 ± (29 - 29)+0.1%✅⬆️
.NET 8 - Baseline
process.internal_duration_ms192.52 ± (192.11 - 192.93) ms193.92 ± (193.46 - 194.38) ms+0.7%✅⬆️
process.time_to_main_ms70.57 ± (70.37 - 70.77) ms71.04 ± (70.82 - 71.26) ms+0.7%✅⬆️
runtime.dotnet.exceptions.count4 ± (4 - 4)4 ± (4 - 4)+0.0%
runtime.dotnet.mem.committed11.77 ± (11.74 - 11.79) MB11.73 ± (11.71 - 11.75) MB-0.3%
runtime.dotnet.threads.count18 ± (18 - 18)18 ± (18 - 18)-0.1%
.NET 8 - Bailout
process.internal_duration_ms192.55 ± (192.07 - 193.02) ms193.37 ± (192.94 - 193.80) ms+0.4%✅⬆️
process.time_to_main_ms71.90 ± (71.72 - 72.08) ms72.36 ± (72.17 - 72.55) ms+0.6%✅⬆️
runtime.dotnet.exceptions.count4 ± (4 - 4)4 ± (4 - 4)+0.0%
runtime.dotnet.mem.committed11.76 ± (11.74 - 11.78) MB11.77 ± (11.75 - 11.80) MB+0.1%✅⬆️
runtime.dotnet.threads.count19 ± (19 - 19)19 ± (19 - 19)+0.0%✅⬆️
.NET 8 - CallTarget+Inlining+NGEN
process.internal_duration_ms371.25 ± (369.87 - 372.62) ms369.40 ± (368.11 - 370.68) ms-0.5%
process.time_to_main_ms446.99 ± (446.05 - 447.93) ms445.17 ± (444.35 - 445.99) ms-0.4%
runtime.dotnet.exceptions.count4 ± (4 - 4)4 ± (4 - 4)+0.0%
runtime.dotnet.mem.committed48.45 ± (48.42 - 48.48) MB48.38 ± (48.35 - 48.41) MB-0.1%
runtime.dotnet.threads.count29 ± (29 - 29)29 ± (29 - 29)-0.2%
Comparison explanation

Execution-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:

  • Welch test with statistical test for significance of 5%
  • Only results indicating a difference greater than 5% and 5 ms are considered.

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 charts
FakeDbCommand (.NET Framework 4.8)
gantt
    title Execution time (ms) FakeDbCommand (.NET Framework 4.8)
    dateFormat  x
    axisFormat %Q
    todayMarker off
    section Baseline
    This PR (8083) - mean (69ms)  : 67, 70
    master - mean (68ms)  : 66, 70

    section Bailout
    This PR (8083) - mean (72ms)  : 71, 73
    master - mean (72ms)  : 71, 73

    section CallTarget+Inlining+NGEN
    This PR (8083) - mean (1,031ms)  : 962, 1099
    master - mean (1,020ms)  : 975, 1066

Loading
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 (8083) - mean (106ms)  : 104, 109
    master - mean (106ms)  : 104, 108

    section Bailout
    This PR (8083) - mean (107ms)  : 106, 108
    master - mean (107ms)  : 106, 108

    section CallTarget+Inlining+NGEN
    This PR (8083) - mean (749ms)  : 699, 800
    master - mean (741ms)  : 684, 797

Loading
FakeDbCommand (.NET 6)
gantt
    title Execution time (ms) FakeDbCommand (.NET 6)
    dateFormat  x
    axisFormat %Q
    todayMarker off
    section Baseline
    This PR (8083) - mean (94ms)  : 92, 97
    master - mean (94ms)  : 92, 96

    section Bailout
    This PR (8083) - mean (95ms)  : 93, 96
    master - mean (94ms)  : 94, 95

    section CallTarget+Inlining+NGEN
    This PR (8083) - mean (728ms)  : 705, 751
    master - mean (728ms)  : 700, 756

Loading
FakeDbCommand (.NET 8)
gantt
    title Execution time (ms) FakeDbCommand (.NET 8)
    dateFormat  x
    axisFormat %Q
    todayMarker off
    section Baseline
    This PR (8083) - mean (92ms)  : 90, 95
    master - mean (92ms)  : 90, 94

    section Bailout
    This PR (8083) - mean (93ms)  : 92, 95
    master - mean (93ms)  : 92, 94

    section CallTarget+Inlining+NGEN
    This PR (8083) - mean (640ms)  : 623, 657
    master - mean (640ms)  : 625, 655

Loading
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 (8083) - mean (195ms)  : 192, 199
    master - mean (196ms)  : 189, 204

    section Bailout
    This PR (8083) - mean (200ms)  : 196, 204
    master - mean (203ms)  : 193, 213

    section CallTarget+Inlining+NGEN
    This PR (8083) - mean (1,153ms)  : 1094, 1212
    master - mean (1,160ms)  : 1086, 1234

Loading
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 (8083) - mean (280ms)  : 275, 286
    master - mean (279ms)  : 273, 284

    section Bailout
    This PR (8083) - mean (280ms)  : 276, 284
    master - mean (279ms)  : 275, 283

    section CallTarget+Inlining+NGEN
    This PR (8083) - mean (950ms)  : 897, 1002
    master - mean (933ms)  : 878, 989

Loading
HttpMessageHandler (.NET 6)
gantt
    title Execution time (ms) HttpMessageHandler (.NET 6)
    dateFormat  x
    axisFormat %Q
    todayMarker off
    section Baseline
    This PR (8083) - mean (278ms)  : 264, 291
    master - mean (272ms)  : 266, 279

    section Bailout
    This PR (8083) - mean (279ms)  : 266, 293
    master - mean (273ms)  : 268, 279

    section CallTarget+Inlining+NGEN
    This PR (8083) - mean (937ms)  : 884, 990
    master - mean (936ms)  : 888, 984

Loading
HttpMessageHandler (.NET 8)
gantt
    title Execution time (ms) HttpMessageHandler (.NET 8)
    dateFormat  x
    axisFormat %Q
    todayMarker off
    section Baseline
    This PR (8083) - mean (275ms)  : 269, 280
    master - mean (273ms)  : 264, 283

    section Bailout
    This PR (8083) - mean (276ms)  : 269, 282
    master - mean (275ms)  : 260, 290

    section CallTarget+Inlining+NGEN
    This PR (8083) - mean (847ms)  : 828, 866
    master - mean (849ms)  : 823, 874

Loading

@dudikeleti dudikeleti marked this pull request as ready for review January 27, 2026 14:00
@dudikeleti dudikeleti requested review from a team as code owners January 27, 2026 14:00
Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 962ba7063e

ℹ️ About Codex in GitHub

Your team has set up Codex to 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 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@dudikeleti dudikeleti force-pushed the dudik/co/add-netframework-support branch from 962ba70 to 34ebc7e Compare January 27, 2026 15:34
@dudikeleti dudikeleti marked this pull request as draft January 27, 2026 15:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants