Skip to content

Conversation

@andrewlock
Copy link
Member

@andrewlock andrewlock commented Oct 22, 2025

Summary of changes

  • Introduces SettingsManager responsible for managing MutableSettings and ExporterSettings

Reason for change

We need to be notified about runtime changes to settings (i.e. config in code or remote config) but don't want to tear down the world and rebuild every time. SettingsManager is responsible for handling this. Consumers subscribe to changes and can be notified about updates.

This is a first step which just introduces the type, but doesn't force users to consume changes or remove the current places settings are exposed. Instead, it just encapsulates the changes.

Implementation details

  • Introduce SettingsManager
  • Move code duplicated in DynamicConfigurationManager and ConfigureIntegration into SettingsManager
  • Create a new instance of SettingsManager (and maintain it throughout the app lifetime)
  • Subscribe to changes one time in TracerManager to do the "full rebuild"
    • This is a stop gap before we use it "properly" and stop exposing the settings on TracerSettings

Test coverage

  • Mostly a refactor so covered by integration tests
  • Unit tests for SettingsManager functionality

Other details

https://datadoghq.atlassian.net/browse/LANGPLAT-819

Part of a config stack

@andrewlock andrewlock added area:tracer The core tracer library (Datadog.Trace, does not include OpenTracing, native code, or integrations) type:refactor area:dynamic-configuration labels Oct 22, 2025
andrewlock added a commit that referenced this pull request Oct 22, 2025
…tIntegrationAnalyticsSampleRate()` (#7544)

## Summary of changes

Fix usages of `IsIntegrationEnabled()`, `IsErrorStatusCode()`, and
`GetIntegrationAnalyticsSampleRate()` to use `MutableSettings` instead
of `TracerSettings`

## Reason for change

These functions are dependent on `MutableSettings`, and are exposed
there, so making sure we call the methods there, and remove the
delegation from `TracerSettings` entirely.

## Implementation details

- Find and replace usages
- Remove the old delegating methods

## Test coverage

Just a refactor, so covered by existing tests

## Other details

https://datadoghq.atlassian.net/browse/LANGPLAT-819

Part of a config stack

- #7522
- #7525
- #7530
- #7532
- #7543
- #7544 👈
- #7695
Base automatically changed from andrew/settings/4b-fix-integration-enabled to master October 22, 2025 12:16
@dd-trace-dotnet-ci-bot
Copy link

dd-trace-dotnet-ci-bot bot commented Oct 22, 2025

Execution-Time Benchmarks Report ⏱️

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

⚠️ Potential regressions detected

FakeDbCommand

Metric Master (Mean ± 95% CI) Current (Mean ± 95% CI) Change Status
.NET Framework 4.8 - CallTarget+Inlining+NGEN
duration1117.66 ± (1119.26 - 1129.74) ms1185.48 ± (1186.19 - 1213.63) ms+6.1%❌⬆️
Full Metrics Comparison

FakeDbCommand

Metric Master (Mean ± 95% CI) Current (Mean ± 95% CI) Change Status
.NET Framework 4.8 - Baseline
duration74.35 ± (74.28 - 75.12) ms74.68 ± (74.66 - 75.29) ms+0.4%✅⬆️
.NET Framework 4.8 - Bailout
duration80.22 ± (79.93 - 80.66) ms79.41 ± (78.91 - 79.64) ms-1.0%
.NET Framework 4.8 - CallTarget+Inlining+NGEN
duration1117.66 ± (1119.26 - 1129.74) ms1185.48 ± (1186.19 - 1213.63) ms+6.1%❌⬆️
.NET Core 3.1 - Baseline
process.internal_duration_ms22.89 ± (22.82 - 22.97) ms23.55 ± (23.43 - 23.67) ms+2.8%✅⬆️
process.time_to_main_ms86.97 ± (86.66 - 87.28) ms88.90 ± (88.49 - 89.30) ms+2.2%✅⬆️
runtime.dotnet.exceptions.count0 ± (0 - 0)0 ± (0 - 0)+0.0%
runtime.dotnet.mem.committed10.91 ± (10.91 - 10.91) MB10.91 ± (10.91 - 10.92) MB+0.0%✅⬆️
runtime.dotnet.threads.count12 ± (12 - 12)12 ± (12 - 12)+0.0%
.NET Core 3.1 - Bailout
process.internal_duration_ms22.61 ± (22.56 - 22.67) ms23.14 ± (23.04 - 23.24) ms+2.3%✅⬆️
process.time_to_main_ms87.33 ± (87.02 - 87.64) ms89.25 ± (88.84 - 89.66) ms+2.2%✅⬆️
runtime.dotnet.exceptions.count0 ± (0 - 0)0 ± (0 - 0)+0.0%
runtime.dotnet.mem.committed10.95 ± (10.95 - 10.95) MB10.96 ± (10.96 - 10.97) MB+0.1%✅⬆️
runtime.dotnet.threads.count13 ± (13 - 13)13 ± (13 - 13)+0.0%
.NET Core 3.1 - CallTarget+Inlining+NGEN
process.internal_duration_ms218.42 ± (216.98 - 219.87) ms219.20 ± (217.69 - 220.71) ms+0.4%✅⬆️
process.time_to_main_ms548.34 ± (547.21 - 549.46) ms544.02 ± (542.84 - 545.20) ms-0.8%
runtime.dotnet.exceptions.count0 ± (0 - 0)0 ± (0 - 0)+0.0%
runtime.dotnet.mem.committed52.48 ± (52.46 - 52.50) MB52.47 ± (52.45 - 52.49) MB-0.0%
runtime.dotnet.threads.count28 ± (28 - 28)28 ± (28 - 28)+0.0%✅⬆️
.NET 6 - Baseline
process.internal_duration_ms21.65 ± (21.59 - 21.72) ms21.93 ± (21.83 - 22.03) ms+1.3%✅⬆️
process.time_to_main_ms75.20 ± (74.86 - 75.53) ms77.34 ± (76.77 - 77.90) ms+2.8%✅⬆️
runtime.dotnet.exceptions.count0 ± (0 - 0)0 ± (0 - 0)+0.0%
runtime.dotnet.mem.committed10.60 ± (10.60 - 10.60) MB10.63 ± (10.62 - 10.63) MB+0.3%✅⬆️
runtime.dotnet.threads.count10 ± (10 - 10)10 ± (10 - 10)+0.0%
.NET 6 - Bailout
process.internal_duration_ms21.70 ± (21.62 - 21.77) ms21.78 ± (21.71 - 21.85) ms+0.4%✅⬆️
process.time_to_main_ms77.97 ± (77.53 - 78.40) ms76.85 ± (76.51 - 77.19) ms-1.4%
runtime.dotnet.exceptions.count0 ± (0 - 0)0 ± (0 - 0)+0.0%
runtime.dotnet.mem.committed10.68 ± (10.67 - 10.68) MB10.66 ± (10.66 - 10.67) MB-0.1%
runtime.dotnet.threads.count11 ± (11 - 11)11 ± (11 - 11)+0.0%
.NET 6 - CallTarget+Inlining+NGEN
process.internal_duration_ms208.08 ± (206.52 - 209.65) ms204.39 ± (203.05 - 205.73) ms-1.8%
process.time_to_main_ms517.01 ± (515.90 - 518.11) ms507.27 ± (506.18 - 508.36) ms-1.9%
runtime.dotnet.exceptions.count0 ± (0 - 0)0 ± (0 - 0)+0.0%
runtime.dotnet.mem.committed51.60 ± (51.57 - 51.63) MB51.69 ± (51.67 - 51.72) MB+0.2%✅⬆️
runtime.dotnet.threads.count28 ± (28 - 28)28 ± (28 - 28)+0.0%✅⬆️
.NET 8 - Baseline
process.internal_duration_ms19.66 ± (19.60 - 19.72) ms20.02 ± (19.95 - 20.08) ms+1.8%✅⬆️
process.time_to_main_ms74.09 ± (73.76 - 74.42) ms75.20 ± (74.92 - 75.48) ms+1.5%✅⬆️
runtime.dotnet.exceptions.count0 ± (0 - 0)0 ± (0 - 0)+0.0%
runtime.dotnet.mem.committed7.65 ± (7.65 - 7.66) MB7.65 ± (7.65 - 7.66) MB+0.0%✅⬆️
runtime.dotnet.threads.count10 ± (10 - 10)10 ± (10 - 10)+0.0%
.NET 8 - Bailout
process.internal_duration_ms19.74 ± (19.68 - 19.80) ms19.64 ± (19.58 - 19.71) ms-0.5%
process.time_to_main_ms76.38 ± (76.06 - 76.69) ms75.59 ± (75.30 - 75.87) ms-1.0%
runtime.dotnet.exceptions.count0 ± (0 - 0)0 ± (0 - 0)+0.0%
runtime.dotnet.mem.committed7.71 ± (7.71 - 7.72) MB7.70 ± (7.69 - 7.70) MB-0.2%
runtime.dotnet.threads.count11 ± (11 - 11)11 ± (11 - 11)+0.0%
.NET 8 - CallTarget+Inlining+NGEN
process.internal_duration_ms190.34 ± (189.38 - 191.29) ms191.56 ± (190.68 - 192.44) ms+0.6%✅⬆️
process.time_to_main_ms489.56 ± (488.57 - 490.54) ms485.54 ± (484.57 - 486.51) ms-0.8%
runtime.dotnet.exceptions.count0 ± (0 - 0)0 ± (0 - 0)+0.0%
runtime.dotnet.mem.committed38.85 ± (38.81 - 38.88) MB38.89 ± (38.85 - 38.92) MB+0.1%✅⬆️
runtime.dotnet.threads.count27 ± (27 - 27)27 ± (27 - 27)+0.0%✅⬆️

HttpMessageHandler

Metric Master (Mean ± 95% CI) Current (Mean ± 95% CI) Change Status
.NET Framework 4.8 - Baseline
duration192.93 ± (193.00 - 193.85) ms192.40 ± (192.34 - 193.23) ms-0.3%
.NET Framework 4.8 - Bailout
duration195.89 ± (195.70 - 196.15) ms195.51 ± (195.32 - 195.77) ms-0.2%
.NET Framework 4.8 - CallTarget+Inlining+NGEN
duration1167.84 ± (1170.49 - 1180.26) ms1167.55 ± (1170.06 - 1179.42) ms-0.0%
.NET Core 3.1 - Baseline
process.internal_duration_ms187.65 ± (187.23 - 188.07) ms187.70 ± (187.43 - 187.98) ms+0.0%✅⬆️
process.time_to_main_ms80.39 ± (80.20 - 80.59) ms80.43 ± (80.22 - 80.63) ms+0.0%✅⬆️
runtime.dotnet.exceptions.count3 ± (3 - 3)3 ± (3 - 3)+0.0%
runtime.dotnet.mem.committed16.07 ± (16.04 - 16.10) MB16.07 ± (16.04 - 16.09) MB-0.0%
runtime.dotnet.threads.count20 ± (20 - 20)19 ± (19 - 20)-0.8%
.NET Core 3.1 - Bailout
process.internal_duration_ms187.30 ± (186.99 - 187.61) ms187.73 ± (187.32 - 188.14) ms+0.2%✅⬆️
process.time_to_main_ms81.56 ± (81.44 - 81.68) ms81.98 ± (81.82 - 82.14) ms+0.5%✅⬆️
runtime.dotnet.exceptions.count3 ± (3 - 3)3 ± (3 - 3)+0.0%
runtime.dotnet.mem.committed16.15 ± (16.12 - 16.17) MB16.13 ± (16.10 - 16.16) MB-0.1%
runtime.dotnet.threads.count21 ± (20 - 21)21 ± (20 - 21)+0.1%✅⬆️
.NET Core 3.1 - CallTarget+Inlining+NGEN
process.internal_duration_ms391.93 ± (389.73 - 394.14) ms397.17 ± (394.71 - 399.63) ms+1.3%✅⬆️
process.time_to_main_ms514.76 ± (514.10 - 515.42) ms515.49 ± (514.83 - 516.15) ms+0.1%✅⬆️
runtime.dotnet.exceptions.count3 ± (3 - 3)3 ± (3 - 3)+0.0%
runtime.dotnet.mem.committed62.85 ± (62.70 - 63.01) MB62.88 ± (62.73 - 63.03) MB+0.0%✅⬆️
runtime.dotnet.threads.count29 ± (29 - 29)29 ± (29 - 30)+0.1%✅⬆️
.NET 6 - Baseline
process.internal_duration_ms191.69 ± (191.29 - 192.08) ms192.41 ± (191.99 - 192.82) ms+0.4%✅⬆️
process.time_to_main_ms69.58 ± (69.41 - 69.75) ms69.69 ± (69.47 - 69.90) ms+0.2%✅⬆️
runtime.dotnet.exceptions.count4 ± (4 - 4)4 ± (4 - 4)+0.0%
runtime.dotnet.mem.committed16.08 ± (15.94 - 16.22) MB15.86 ± (15.71 - 16.02) MB-1.3%
runtime.dotnet.threads.count18 ± (18 - 18)18 ± (18 - 18)-0.4%
.NET 6 - Bailout
process.internal_duration_ms190.48 ± (190.15 - 190.81) ms191.17 ± (190.83 - 191.52) ms+0.4%✅⬆️
process.time_to_main_ms70.42 ± (70.31 - 70.53) ms70.60 ± (70.47 - 70.73) ms+0.3%✅⬆️
runtime.dotnet.exceptions.count4 ± (4 - 4)4 ± (4 - 4)+0.0%
runtime.dotnet.mem.committed15.98 ± (15.82 - 16.13) MB15.88 ± (15.71 - 16.04) MB-0.6%
runtime.dotnet.threads.count19 ± (19 - 19)19 ± (19 - 19)+0.1%✅⬆️
.NET 6 - CallTarget+Inlining+NGEN
process.internal_duration_ms413.82 ± (410.59 - 417.04) ms405.24 ± (402.86 - 407.61) ms-2.1%
process.time_to_main_ms485.74 ± (485.15 - 486.32) ms482.44 ± (481.72 - 483.15) ms-0.7%
runtime.dotnet.exceptions.count4 ± (4 - 4)4 ± (4 - 4)+0.0%
runtime.dotnet.mem.committed62.09 ± (61.95 - 62.23) MB62.04 ± (61.89 - 62.19) MB-0.1%
runtime.dotnet.threads.count29 ± (29 - 29)30 ± (29 - 30)+0.3%✅⬆️
.NET 8 - Baseline
process.internal_duration_ms189.57 ± (189.19 - 189.95) ms189.40 ± (189.06 - 189.74) ms-0.1%
process.time_to_main_ms69.10 ± (68.89 - 69.31) ms68.98 ± (68.83 - 69.13) ms-0.2%
runtime.dotnet.exceptions.count4 ± (4 - 4)4 ± (4 - 4)+0.0%
runtime.dotnet.mem.committed11.77 ± (11.73 - 11.82) MB11.73 ± (11.71 - 11.76) MB-0.3%
runtime.dotnet.threads.count18 ± (18 - 18)18 ± (18 - 18)+0.0%✅⬆️
.NET 8 - Bailout
process.internal_duration_ms189.00 ± (188.71 - 189.29) ms189.37 ± (189.02 - 189.72) ms+0.2%✅⬆️
process.time_to_main_ms69.85 ± (69.75 - 69.95) ms70.10 ± (69.97 - 70.24) ms+0.4%✅⬆️
runtime.dotnet.exceptions.count4 ± (4 - 4)4 ± (4 - 4)+0.0%
runtime.dotnet.mem.committed11.85 ± (11.81 - 11.88) MB11.75 ± (11.69 - 11.82) MB-0.8%
runtime.dotnet.threads.count19 ± (19 - 19)19 ± (19 - 19)-0.6%
.NET 8 - CallTarget+Inlining+NGEN
process.internal_duration_ms361.34 ± (359.79 - 362.89) ms362.84 ± (361.51 - 364.17) ms+0.4%✅⬆️
process.time_to_main_ms463.68 ± (463.03 - 464.32) ms458.11 ± (457.51 - 458.70) ms-1.2%
runtime.dotnet.exceptions.count4 ± (4 - 4)4 ± (4 - 4)+0.0%
runtime.dotnet.mem.committed50.34 ± (50.30 - 50.38) MB50.40 ± (50.36 - 50.43) MB+0.1%✅⬆️
runtime.dotnet.threads.count29 ± (29 - 29)29 ± (29 - 29)-0.1%
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 (7695) - mean (75ms)  : 70, 80
    master - mean (75ms)  : 69, 80

    section Bailout
    This PR (7695) - mean (79ms)  : 74, 85
    master - mean (80ms)  : 75, 86

    section CallTarget+Inlining+NGEN
    This PR (7695) - mean (1,200ms)  : crit, 985, 1414
    master - mean (1,125ms)  : 1046, 1203

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 (7695) - mean (121ms)  : 113, 128
    master - mean (117ms)  : 112, 123

    section Bailout
    This PR (7695) - mean (120ms)  : 113, 127
    master - mean (117ms)  : 111, 124

    section CallTarget+Inlining+NGEN
    This PR (7695) - mean (801ms)  : 748, 855
    master - mean (799ms)  : 749, 848

Loading
FakeDbCommand (.NET 6)
gantt
    title Execution time (ms) FakeDbCommand (.NET 6)
    dateFormat  x
    axisFormat %Q
    todayMarker off
    section Baseline
    This PR (7695) - mean (106ms)  : 97, 115
    master - mean (104ms)  : 97, 111

    section Bailout
    This PR (7695) - mean (106ms)  : 98, 114
    master - mean (106ms)  : 98, 115

    section CallTarget+Inlining+NGEN
    This PR (7695) - mean (745ms)  : 702, 788
    master - mean (757ms)  : 715, 800

Loading
FakeDbCommand (.NET 8)
gantt
    title Execution time (ms) FakeDbCommand (.NET 8)
    dateFormat  x
    axisFormat %Q
    todayMarker off
    section Baseline
    This PR (7695) - mean (104ms)  : 99, 109
    master - mean (102ms)  : 95, 110

    section Bailout
    This PR (7695) - mean (104ms)  : 98, 109
    master - mean (105ms)  : 98, 112

    section CallTarget+Inlining+NGEN
    This PR (7695) - mean (709ms)  : 679, 740
    master - mean (709ms)  : 681, 737

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 (7695) - mean (193ms)  : 189, 197
    master - mean (193ms)  : 188, 199

    section Bailout
    This PR (7695) - mean (196ms)  : 193, 198
    master - mean (196ms)  : 194, 198

    section CallTarget+Inlining+NGEN
    This PR (7695) - mean (1,175ms)  : 1104, 1246
    master - mean (1,175ms)  : 1101, 1250

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 (7695) - mean (277ms)  : 273, 280
    master - mean (277ms)  : 272, 282

    section Bailout
    This PR (7695) - mean (278ms)  : 273, 282
    master - mean (277ms)  : 273, 281

    section CallTarget+Inlining+NGEN
    This PR (7695) - mean (943ms)  : 904, 982
    master - mean (939ms)  : 900, 978

Loading
HttpMessageHandler (.NET 6)
gantt
    title Execution time (ms) HttpMessageHandler (.NET 6)
    dateFormat  x
    axisFormat %Q
    todayMarker off
    section Baseline
    This PR (7695) - mean (270ms)  : 265, 275
    master - mean (270ms)  : 264, 275

    section Bailout
    This PR (7695) - mean (270ms)  : 265, 275
    master - mean (269ms)  : 265, 273

    section CallTarget+Inlining+NGEN
    This PR (7695) - mean (918ms)  : 878, 958
    master - mean (929ms)  : 873, 986

Loading
HttpMessageHandler (.NET 8)
gantt
    title Execution time (ms) HttpMessageHandler (.NET 8)
    dateFormat  x
    axisFormat %Q
    todayMarker off
    section Baseline
    This PR (7695) - mean (268ms)  : 263, 273
    master - mean (269ms)  : 262, 276

    section Bailout
    This PR (7695) - mean (269ms)  : 263, 275
    master - mean (268ms)  : 264, 272

    section CallTarget+Inlining+NGEN
    This PR (7695) - mean (853ms)  : 833, 873
    master - mean (858ms)  : 837, 879

Loading

@andrewlock andrewlock force-pushed the andrew/settings/4-mutable-settings-service branch from c29eb56 to 9c790a3 Compare October 22, 2025 14:05
@pr-commenter
Copy link

pr-commenter bot commented Oct 22, 2025

Benchmarks

Benchmarks Report for benchmark platform 🐌

Benchmarks for #7695 compared to master:

  • 1 benchmarks are faster, with geometric mean 1.146
  • 1 benchmarks are slower, with geometric mean 1.519
  • 8 benchmarks have fewer allocations
  • 6 benchmarks have more allocations

The following thresholds were used for comparing the benchmark speeds:

  • Mann–Whitney U test with statistical test for significance of 5%
  • Only results indicating a difference greater than 10% and 0.3 ns are considered.

Allocation changes below 0.5% are ignored.

Benchmark details

Benchmarks.Trace.ActivityBenchmark - Same speed ✔️ Same allocations ✔️

Raw results

Branch Method Toolchain Mean StdError StdDev Gen 0 Gen 1 Gen 2 Allocated
master StartStopWithChild net6.0 10.6μs 59.8ns 410ns 0 0 0 5.49 KB
master StartStopWithChild netcoreapp3.1 13.7μs 72.7ns 364ns 0 0 0 5.7 KB
master StartStopWithChild net472 22.2μs 124ns 830ns 0.874 0.219 0 6.09 KB
#7695 StartStopWithChild net6.0 10.2μs 57.3ns 409ns 0 0 0 5.5 KB
#7695 StartStopWithChild netcoreapp3.1 13.7μs 71.1ns 326ns 0 0 0 5.67 KB
#7695 StartStopWithChild net472 22.1μs 82.7ns 341ns 0.894 0.224 0 6.07 KB
Benchmarks.Trace.AgentWriterBenchmark - Same speed ✔️ More allocations ⚠️

More allocations ⚠️ in #7695

Benchmark Base Allocated Diff Allocated Change Change %
Benchmarks.Trace.AgentWriterBenchmark.WriteAndFlushEnrichedTraces‑net472 3.31 KB 3.35 KB 46 B 1.39%

Fewer allocations 🎉 in #7695

Benchmark Base Allocated Diff Allocated Change Change %
Benchmarks.Trace.AgentWriterBenchmark.WriteAndFlushEnrichedTraces‑netcoreapp3.1 2.71 KB 2.7 KB -15 B -0.55%

Raw results

Branch Method Toolchain Mean StdError StdDev Gen 0 Gen 1 Gen 2 Allocated
master WriteAndFlushEnrichedTraces net6.0 939μs 367ns 1.42μs 0 0 0 2.7 KB
master WriteAndFlushEnrichedTraces netcoreapp3.1 1.03ms 552ns 2.06μs 0 0 0 2.71 KB
master WriteAndFlushEnrichedTraces net472 1.2ms 125ns 484ns 0 0 0 3.31 KB
#7695 WriteAndFlushEnrichedTraces net6.0 946μs 198ns 766ns 0 0 0 2.7 KB
#7695 WriteAndFlushEnrichedTraces netcoreapp3.1 1.04ms 785ns 3.04μs 0 0 0 2.7 KB
#7695 WriteAndFlushEnrichedTraces net472 1.22ms 897ns 3.36μs 0 0 0 3.35 KB
Benchmarks.Trace.Asm.AppSecBodyBenchmark - Same speed ✔️ Same allocations ✔️

Raw results

Branch Method Toolchain Mean StdError StdDev Gen 0 Gen 1 Gen 2 Allocated
master AllCycleSimpleBody net6.0 1.12μs 0.877ns 3.4ns 0 0 0 1.22 KB
master AllCycleSimpleBody netcoreapp3.1 1.42μs 7.76ns 43.9ns 0 0 0 1.2 KB
master AllCycleSimpleBody net472 1.02μs 2.6ns 10.1ns 0.192 0 0 1.23 KB
master AllCycleMoreComplexBody net6.0 7.24μs 32.3ns 125ns 0 0 0 4.72 KB
master AllCycleMoreComplexBody netcoreapp3.1 9.06μs 43.5ns 179ns 0 0 0 4.62 KB
master AllCycleMoreComplexBody net472 7.57μs 4.62ns 17.9ns 0.721 0 0 4.74 KB
master ObjectExtractorSimpleBody net6.0 326ns 1.75ns 9.43ns 0 0 0 280 B
master ObjectExtractorSimpleBody netcoreapp3.1 418ns 2.38ns 15.9ns 0 0 0 272 B
master ObjectExtractorSimpleBody net472 298ns 0.0238ns 0.0857ns 0.0439 0 0 281 B
master ObjectExtractorMoreComplexBody net6.0 6.34μs 29.8ns 115ns 0 0 0 3.78 KB
master ObjectExtractorMoreComplexBody netcoreapp3.1 7.91μs 36.3ns 141ns 0 0 0 3.69 KB
master ObjectExtractorMoreComplexBody net472 6.7μs 9.57ns 37.1ns 0.6 0 0 3.8 KB
#7695 AllCycleSimpleBody net6.0 1.07μs 6.25ns 58.7ns 0 0 0 1.22 KB
#7695 AllCycleSimpleBody netcoreapp3.1 1.4μs 7.73ns 47ns 0 0 0 1.2 KB
#7695 AllCycleSimpleBody net472 1μs 0.247ns 0.924ns 0.191 0 0 1.23 KB
#7695 AllCycleMoreComplexBody net6.0 7.22μs 36.3ns 158ns 0 0 0 4.72 KB
#7695 AllCycleMoreComplexBody netcoreapp3.1 9.04μs 45.9ns 215ns 0 0 0 4.62 KB
#7695 AllCycleMoreComplexBody net472 7.48μs 3.75ns 14.5ns 0.748 0 0 4.74 KB
#7695 ObjectExtractorSimpleBody net6.0 324ns 0.394ns 1.53ns 0 0 0 280 B
#7695 ObjectExtractorSimpleBody netcoreapp3.1 399ns 2.2ns 13ns 0 0 0 272 B
#7695 ObjectExtractorSimpleBody net472 295ns 0.0359ns 0.139ns 0.0441 0 0 281 B
#7695 ObjectExtractorMoreComplexBody net6.0 6.44μs 21.7ns 84.2ns 0 0 0 3.78 KB
#7695 ObjectExtractorMoreComplexBody netcoreapp3.1 7.77μs 27.7ns 107ns 0 0 0 3.69 KB
#7695 ObjectExtractorMoreComplexBody net472 6.65μs 1.72ns 6.66ns 0.597 0 0 3.8 KB
Benchmarks.Trace.Asm.AppSecEncoderBenchmark - Same speed ✔️ Same allocations ✔️

Raw results

Branch Method Toolchain Mean StdError StdDev Gen 0 Gen 1 Gen 2 Allocated
master EncodeArgs net6.0 76.9μs 24ns 89.7ns 0 0 0 32.4 KB
master EncodeArgs netcoreapp3.1 96.2μs 276ns 1.07μs 0 0 0 32.4 KB
master EncodeArgs net472 118μs 17.2ns 66.5ns 4.69 0 0 32.5 KB
master EncodeLegacyArgs net6.0 147μs 38.7ns 145ns 0 0 0 2.15 KB
master EncodeLegacyArgs netcoreapp3.1 199μs 348ns 1.35μs 0 0 0 2.14 KB
master EncodeLegacyArgs net472 267μs 28ns 108ns 0 0 0 2.16 KB
#7695 EncodeArgs net6.0 76.2μs 358ns 1.34μs 0 0 0 32.4 KB
#7695 EncodeArgs netcoreapp3.1 96.9μs 319ns 1.23μs 0 0 0 32.4 KB
#7695 EncodeArgs net472 110μs 27.4ns 106ns 4.94 0 0 32.51 KB
#7695 EncodeLegacyArgs net6.0 143μs 46ns 178ns 0 0 0 2.15 KB
#7695 EncodeLegacyArgs netcoreapp3.1 198μs 160ns 618ns 0 0 0 2.14 KB
#7695 EncodeLegacyArgs net472 265μs 85.3ns 330ns 0 0 0 2.16 KB
Benchmarks.Trace.Asm.AppSecWafBenchmark - Slower ⚠️ Same allocations ✔️

Slower ⚠️ in #7695

Benchmark diff/base Base Median (ns) Diff Median (ns) Modality
Benchmarks.Trace.Asm.AppSecWafBenchmark.RunWafRealisticBenchmark‑netcoreapp3.1 1.519 410,850.94 624,064.52 multimodal

Raw results

Branch Method Toolchain Mean StdError StdDev Gen 0 Gen 1 Gen 2 Allocated
master RunWafRealisticBenchmark net6.0 397μs 76ns 274ns 0 0 0 4.55 KB
master RunWafRealisticBenchmark netcoreapp3.1 411μs 285ns 1.07μs 0 0 0 4.48 KB
master RunWafRealisticBenchmark net472 427μs 63.3ns 245ns 0 0 0 4.66 KB
master RunWafRealisticBenchmarkWithAttack net6.0 284μs 41.3ns 160ns 0 0 0 2.24 KB
master RunWafRealisticBenchmarkWithAttack netcoreapp3.1 298μs 62.7ns 226ns 0 0 0 2.22 KB
master RunWafRealisticBenchmarkWithAttack net472 311μs 21.9ns 85ns 0 0 0 2.29 KB
#7695 RunWafRealisticBenchmark net6.0 403μs 69.1ns 268ns 0 0 0 4.55 KB
#7695 RunWafRealisticBenchmark netcoreapp3.1 694μs 14.8μs 148μs 0 0 0 4.48 KB
#7695 RunWafRealisticBenchmark net472 432μs 64.8ns 251ns 0 0 0 4.66 KB
#7695 RunWafRealisticBenchmarkWithAttack net6.0 286μs 81.6ns 316ns 0 0 0 2.24 KB
#7695 RunWafRealisticBenchmarkWithAttack netcoreapp3.1 296μs 72.1ns 250ns 0 0 0 2.22 KB
#7695 RunWafRealisticBenchmarkWithAttack net472 309μs 45.6ns 177ns 0 0 0 2.29 KB
Benchmarks.Trace.AspNetCoreBenchmark - Same speed ✔️ Same allocations ✔️

Raw results

Branch Method Toolchain Mean StdError StdDev Gen 0 Gen 1 Gen 2 Allocated
master SendRequest net6.0 61μs 72.2ns 279ns 0 0 0 14.52 KB
master SendRequest netcoreapp3.1 70.8μs 66ns 247ns 0 0 0 17.42 KB
master SendRequest net472 0.00512ns 0.00217ns 0.00841ns 0 0 0 0 b
#7695 SendRequest net6.0 60.6μs 81.3ns 282ns 0 0 0 14.52 KB
#7695 SendRequest netcoreapp3.1 71.5μs 239ns 862ns 0 0 0 17.42 KB
#7695 SendRequest net472 0.00366ns 0.00137ns 0.00531ns 0 0 0 0 b
Benchmarks.Trace.CharSliceBenchmark - Same speed ✔️ More allocations ⚠️

More allocations ⚠️ in #7695

Benchmark Base Allocated Diff Allocated Change Change %
Benchmarks.Trace.CharSliceBenchmark.OptimizedCharSliceWithPool‑netcoreapp3.1 0 b 1 B 1 B

Fewer allocations 🎉 in #7695

Benchmark Base Allocated Diff Allocated Change Change %
Benchmarks.Trace.CharSliceBenchmark.OptimizedCharSlice‑net6.0 7 B 4 B -3 B -42.86%
Benchmarks.Trace.CharSliceBenchmark.OptimizedCharSliceWithPool‑net6.0 4 B 1 B -3 B -75.00%
Benchmarks.Trace.CharSliceBenchmark.OptimizedCharSlice‑net472 73 B 0 b -73 B -100.00%
Benchmarks.Trace.CharSliceBenchmark.OptimizedCharSliceWithPool‑net472 47 B 0 b -47 B -100.00%

Raw results

Branch Method Toolchain Mean StdError StdDev Gen 0 Gen 1 Gen 2 Allocated
master OriginalCharSlice net6.0 1.96ms 5.54μs 21.4μs 0 0 0 640.01 KB
master OriginalCharSlice netcoreapp3.1 2.08ms 2.29μs 8.25μs 0 0 0 640 KB
master OriginalCharSlice net472 2.72ms 130ns 504ns 100 0 0 641.95 KB
master OptimizedCharSlice net6.0 1.35ms 290ns 1.05μs 0 0 0 7 B
master OptimizedCharSlice netcoreapp3.1 1.66ms 498ns 1.93μs 0 0 0 1 B
master OptimizedCharSlice net472 1.99ms 418ns 1.62μs 0 0 0 73 B
master OptimizedCharSliceWithPool net6.0 849μs 60.4ns 218ns 0 0 0 4 B
master OptimizedCharSliceWithPool netcoreapp3.1 809μs 37.6ns 136ns 0 0 0 0 b
master OptimizedCharSliceWithPool net472 1.15ms 124ns 482ns 0 0 0 47 B
#7695 OriginalCharSlice net6.0 1.93ms 422ns 1.64μs 0 0 0 640.01 KB
#7695 OriginalCharSlice netcoreapp3.1 2.13ms 1.97μs 7.09μs 0 0 0 640 KB
#7695 OriginalCharSlice net472 2.73ms 1.07μs 4.15μs 100 0 0 641.95 KB
#7695 OptimizedCharSlice net6.0 1.41ms 472ns 1.83μs 0 0 0 4 B
#7695 OptimizedCharSlice netcoreapp3.1 1.65ms 790ns 3.06μs 0 0 0 1 B
#7695 OptimizedCharSlice net472 1.91ms 276ns 1.07μs 0 0 0 0 b
#7695 OptimizedCharSliceWithPool net6.0 856μs 39.2ns 141ns 0 0 0 1 B
#7695 OptimizedCharSliceWithPool netcoreapp3.1 810μs 58ns 217ns 0 0 0 1 B
#7695 OptimizedCharSliceWithPool net472 1.2ms 152ns 589ns 0 0 0 0 b
Benchmarks.Trace.CIVisibilityProtocolWriterBenchmark - Faster 🎉 Fewer allocations 🎉

Faster 🎉 in #7695

Benchmark base/diff Base Median (ns) Diff Median (ns) Modality
Benchmarks.Trace.CIVisibilityProtocolWriterBenchmark.WriteAndFlushEnrichedTraces‑netcoreapp3.1 1.146 771,584.74 673,336.61

Fewer allocations 🎉 in #7695

Benchmark Base Allocated Diff Allocated Change Change %
Benchmarks.Trace.CIVisibilityProtocolWriterBenchmark.WriteAndFlushEnrichedTraces‑net472 56.5 KB 56.11 KB -397 B -0.70%

Raw results

Branch Method Toolchain Mean StdError StdDev Gen 0 Gen 1 Gen 2 Allocated
master WriteAndFlushEnrichedTraces net6.0 716μs 3.07μs 11.9μs 0 0 0 41.54 KB
master WriteAndFlushEnrichedTraces netcoreapp3.1 755μs 4.85μs 46.5μs 0 0 0 42.07 KB
master WriteAndFlushEnrichedTraces net472 866μs 3.74μs 14μs 8.93 0 0 56.5 KB
#7695 WriteAndFlushEnrichedTraces net6.0 650μs 1.4μs 5.41μs 0 0 0 41.6 KB
#7695 WriteAndFlushEnrichedTraces netcoreapp3.1 669μs 2.98μs 11.5μs 0 0 0 42.05 KB
#7695 WriteAndFlushEnrichedTraces net472 912μs 4.57μs 19.9μs 4.46 0 0 56.11 KB
Benchmarks.Trace.DbCommandBenchmark - Same speed ✔️ Same allocations ✔️

Raw results

Branch Method Toolchain Mean StdError StdDev Gen 0 Gen 1 Gen 2 Allocated
master ExecuteNonQuery net6.0 1.89μs 1.66ns 6.43ns 0 0 0 1.02 KB
master ExecuteNonQuery netcoreapp3.1 2.62μs 8.01ns 31ns 0 0 0 1.02 KB
master ExecuteNonQuery net472 3.03μs 3.89ns 15.1ns 0.152 0.0152 0 987 B
#7695 ExecuteNonQuery net6.0 1.98μs 7.76ns 28ns 0 0 0 1.02 KB
#7695 ExecuteNonQuery netcoreapp3.1 2.51μs 3.6ns 13.5ns 0 0 0 1.02 KB
#7695 ExecuteNonQuery net472 2.79μs 2.15ns 7.44ns 0.153 0.0139 0 987 B
Benchmarks.Trace.ElasticsearchBenchmark - Same speed ✔️ Same allocations ✔️

Raw results

Branch Method Toolchain Mean StdError StdDev Gen 0 Gen 1 Gen 2 Allocated
master CallElasticsearch net6.0 1.72μs 0.731ns 2.83ns 0 0 0 1.03 KB
master CallElasticsearch netcoreapp3.1 2.29μs 7.79ns 30.2ns 0 0 0 1.03 KB
master CallElasticsearch net472 3.59μs 6.94ns 26.9ns 0.16 0 0 1.04 KB
master CallElasticsearchAsync net6.0 1.82μs 5.68ns 22ns 0 0 0 1.01 KB
master CallElasticsearchAsync netcoreapp3.1 2.44μs 11.9ns 51.9ns 0 0 0 1.08 KB
master CallElasticsearchAsync net472 3.79μs 4.34ns 16.8ns 0.17 0 0 1.1 KB
#7695 CallElasticsearch net6.0 1.79μs 4.07ns 15.8ns 0 0 0 1.03 KB
#7695 CallElasticsearch netcoreapp3.1 2.26μs 10.5ns 42.1ns 0 0 0 1.03 KB
#7695 CallElasticsearch net472 3.5μs 3.37ns 12.6ns 0.159 0 0 1.04 KB
#7695 CallElasticsearchAsync net6.0 1.76μs 1.43ns 5.35ns 0 0 0 1.01 KB
#7695 CallElasticsearchAsync netcoreapp3.1 2.49μs 8.81ns 33ns 0 0 0 1.08 KB
#7695 CallElasticsearchAsync net472 3.62μs 4.58ns 17.7ns 0.163 0 0 1.1 KB
Benchmarks.Trace.GraphQLBenchmark - Same speed ✔️ Same allocations ✔️

Raw results

Branch Method Toolchain Mean StdError StdDev Gen 0 Gen 1 Gen 2 Allocated
master ExecuteAsync net6.0 1.85μs 8.98ns 35.9ns 0 0 0 952 B
master ExecuteAsync netcoreapp3.1 2.44μs 1.79ns 6.68ns 0 0 0 952 B
master ExecuteAsync net472 2.58μs 4.33ns 16.8ns 0.141 0 0 915 B
#7695 ExecuteAsync net6.0 1.87μs 3ns 11.6ns 0 0 0 952 B
#7695 ExecuteAsync netcoreapp3.1 2.54μs 10.4ns 39ns 0 0 0 952 B
#7695 ExecuteAsync net472 2.54μs 2.09ns 7.82ns 0.14 0 0 915 B
Benchmarks.Trace.HttpClientBenchmark - Same speed ✔️ Same allocations ✔️

Raw results

Branch Method Toolchain Mean StdError StdDev Gen 0 Gen 1 Gen 2 Allocated
master SendAsync net6.0 6.77μs 4.53ns 16.9ns 0 0 0 2.36 KB
master SendAsync netcoreapp3.1 8.65μs 27.9ns 108ns 0 0 0 2.9 KB
master SendAsync net472 12.6μs 5.72ns 20.6ns 0.505 0 0 3.18 KB
#7695 SendAsync net6.0 7.2μs 15.1ns 58.6ns 0 0 0 2.36 KB
#7695 SendAsync netcoreapp3.1 8.58μs 18ns 69.7ns 0 0 0 2.9 KB
#7695 SendAsync net472 12.4μs 8.39ns 32.5ns 0.496 0 0 3.18 KB
Benchmarks.Trace.Iast.StringAspectsBenchmark - Same speed ✔️ More allocations ⚠️

More allocations ⚠️ in #7695

Benchmark Base Allocated Diff Allocated Change Change %
Benchmarks.Trace.Iast.StringAspectsBenchmark.StringConcatAspectBenchmark‑net472 274.06 KB 339.65 KB 65.58 KB 23.93%
Benchmarks.Trace.Iast.StringAspectsBenchmark.StringConcatBenchmark‑net472 57.34 KB 65.54 KB 8.19 KB 14.29%
Benchmarks.Trace.Iast.StringAspectsBenchmark.StringConcatAspectBenchmark‑netcoreapp3.1 257.18 KB 274.15 KB 16.98 KB 6.60%
Benchmarks.Trace.Iast.StringAspectsBenchmark.StringConcatBenchmark‑net6.0 43.97 KB 45.87 KB 1.9 KB 4.33%

Fewer allocations 🎉 in #7695

Benchmark Base Allocated Diff Allocated Change Change %
Benchmarks.Trace.Iast.StringAspectsBenchmark.StringConcatBenchmark‑netcoreapp3.1 43.22 KB 42.92 KB -296 B -0.68%
Benchmarks.Trace.Iast.StringAspectsBenchmark.StringConcatAspectBenchmark‑net6.0 276.89 KB 260.28 KB -16.61 KB -6.00%

Raw results

Branch Method Toolchain Mean StdError StdDev Gen 0 Gen 1 Gen 2 Allocated
master StringConcatBenchmark net6.0 46.5μs 276ns 2.66μs 0 0 0 43.97 KB
master StringConcatBenchmark netcoreapp3.1 49.8μs 257ns 1.63μs 0 0 0 43.22 KB
master StringConcatBenchmark net472 57.8μs 286ns 1.18μs 0 0 0 57.34 KB
master StringConcatAspectBenchmark net6.0 469μs 1.99μs 7.18μs 0 0 0 276.89 KB
master StringConcatAspectBenchmark netcoreapp3.1 524μs 2.19μs 7.91μs 0 0 0 257.18 KB
master StringConcatAspectBenchmark net472 410μs 1.88μs 9.78μs 0 0 0 274.06 KB
#7695 StringConcatBenchmark net6.0 44.3μs 288ns 2.65μs 0 0 0 45.87 KB
#7695 StringConcatBenchmark netcoreapp3.1 48.7μs 245ns 1.07μs 0 0 0 42.92 KB
#7695 StringConcatBenchmark net472 57.7μs 271ns 1.3μs 0 0 0 65.54 KB
#7695 StringConcatAspectBenchmark net6.0 477μs 1.52μs 5.46μs 0 0 0 260.28 KB
#7695 StringConcatAspectBenchmark netcoreapp3.1 526μs 1.76μs 8.46μs 0 0 0 274.15 KB
#7695 StringConcatAspectBenchmark net472 411μs 2.16μs 11.2μs 0 0 0 339.65 KB
Benchmarks.Trace.ILoggerBenchmark - Same speed ✔️ Same allocations ✔️

Raw results

Branch Method Toolchain Mean StdError StdDev Gen 0 Gen 1 Gen 2 Allocated
master EnrichedLog net6.0 2.7μs 14.6ns 83.7ns 0 0 0 1.7 KB
master EnrichedLog netcoreapp3.1 3.63μs 12.2ns 47.3ns 0 0 0 1.7 KB
master EnrichedLog net472 4.01μs 2.3ns 8.91ns 0.26 0 0 1.64 KB
#7695 EnrichedLog net6.0 2.71μs 14.3ns 68.4ns 0 0 0 1.7 KB
#7695 EnrichedLog netcoreapp3.1 3.62μs 16.6ns 64.3ns 0 0 0 1.7 KB
#7695 EnrichedLog net472 3.87μs 4.28ns 16.6ns 0.253 0 0 1.64 KB
Benchmarks.Trace.Log4netBenchmark - Same speed ✔️ Same allocations ✔️

Raw results

Branch Method Toolchain Mean StdError StdDev Gen 0 Gen 1 Gen 2 Allocated
master EnrichedLog net6.0 122μs 49.2ns 190ns 0 0 0 4.31 KB
master EnrichedLog netcoreapp3.1 128μs 209ns 809ns 0 0 0 4.31 KB
master EnrichedLog net472 169μs 75.6ns 293ns 0 0 0 4.52 KB
#7695 EnrichedLog net6.0 124μs 114ns 443ns 0 0 0 4.31 KB
#7695 EnrichedLog netcoreapp3.1 127μs 105ns 378ns 0 0 0 4.31 KB
#7695 EnrichedLog net472 167μs 126ns 487ns 0 0 0 4.52 KB
Benchmarks.Trace.NLogBenchmark - Same speed ✔️ Same allocations ✔️

Raw results

Branch Method Toolchain Mean StdError StdDev Gen 0 Gen 1 Gen 2 Allocated
master EnrichedLog net6.0 4.88μs 20.8ns 80.8ns 0 0 0 2.26 KB
master EnrichedLog netcoreapp3.1 6.8μs 17.1ns 66.3ns 0 0 0 2.26 KB
master EnrichedLog net472 7.49μs 4.38ns 17ns 0.3 0 0 2.08 KB
#7695 EnrichedLog net6.0 4.87μs 16.9ns 65.6ns 0 0 0 2.26 KB
#7695 EnrichedLog netcoreapp3.1 6.83μs 23.9ns 92.7ns 0 0 0 2.26 KB
#7695 EnrichedLog net472 7.48μs 5.48ns 21.2ns 0.301 0 0 2.08 KB
Benchmarks.Trace.RedisBenchmark - Same speed ✔️ Same allocations ✔️

Raw results

Branch Method Toolchain Mean StdError StdDev Gen 0 Gen 1 Gen 2 Allocated
master SendReceive net6.0 1.94μs 10.2ns 50ns 0 0 0 1.2 KB
master SendReceive netcoreapp3.1 2.56μs 12.5ns 48.4ns 0 0 0 1.2 KB
master SendReceive net472 3.01μs 3.07ns 11.5ns 0.183 0 0 1.2 KB
#7695 SendReceive net6.0 1.94μs 10.1ns 48.3ns 0 0 0 1.2 KB
#7695 SendReceive netcoreapp3.1 2.61μs 12.7ns 54ns 0 0 0 1.2 KB
#7695 SendReceive net472 3.18μs 2.82ns 10.9ns 0.177 0 0 1.2 KB
Benchmarks.Trace.SerilogBenchmark - Same speed ✔️ Same allocations ✔️

Raw results

Branch Method Toolchain Mean StdError StdDev Gen 0 Gen 1 Gen 2 Allocated
master EnrichedLog net6.0 4.34μs 6.48ns 25.1ns 0 0 0 1.58 KB
master EnrichedLog netcoreapp3.1 5.54μs 17.2ns 66.8ns 0 0 0 1.63 KB
master EnrichedLog net472 6.83μs 7.27ns 28.2ns 0.307 0 0 2.03 KB
#7695 EnrichedLog net6.0 4.29μs 11.1ns 40.2ns 0 0 0 1.58 KB
#7695 EnrichedLog netcoreapp3.1 5.5μs 25.7ns 103ns 0 0 0 1.63 KB
#7695 EnrichedLog net472 6.54μs 7.79ns 30.2ns 0.292 0 0 2.03 KB
Benchmarks.Trace.SpanBenchmark - Same speed ✔️ Same allocations ✔️

Raw results

Branch Method Toolchain Mean StdError StdDev Gen 0 Gen 1 Gen 2 Allocated
master StartFinishSpan net6.0 769ns 4.17ns 25ns 0 0 0 576 B
master StartFinishSpan netcoreapp3.1 961ns 5.1ns 25.5ns 0 0 0 576 B
master StartFinishSpan net472 974ns 0.344ns 1.33ns 0.0883 0 0 578 B
master StartFinishScope net6.0 902ns 4.53ns 20.7ns 0 0 0 696 B
master StartFinishScope netcoreapp3.1 1.17μs 5.91ns 27.7ns 0 0 0 696 B
master StartFinishScope net472 1.18μs 0.388ns 1.5ns 0.0996 0 0 658 B
#7695 StartFinishSpan net6.0 766ns 3.57ns 14.7ns 0 0 0 576 B
#7695 StartFinishSpan netcoreapp3.1 979ns 4.66ns 19.8ns 0 0 0 576 B
#7695 StartFinishSpan net472 961ns 2.79ns 10.8ns 0.0883 0 0 578 B
#7695 StartFinishScope net6.0 922ns 0.892ns 3.45ns 0 0 0 696 B
#7695 StartFinishScope netcoreapp3.1 1.16μs 5.42ns 21ns 0 0 0 696 B
#7695 StartFinishScope net472 1.2μs 1.17ns 4.52ns 0.101 0 0 658 B
Benchmarks.Trace.TraceAnnotationsBenchmark - Same speed ✔️ Same allocations ✔️

Raw results

Branch Method Toolchain Mean StdError StdDev Gen 0 Gen 1 Gen 2 Allocated
master RunOnMethodBegin net6.0 1.07μs 5.21ns 22.1ns 0 0 0 696 B
master RunOnMethodBegin netcoreapp3.1 1.5μs 7.08ns 30ns 0 0 0 696 B
master RunOnMethodBegin net472 1.43μs 0.251ns 0.938ns 0.1 0 0 658 B
#7695 RunOnMethodBegin net6.0 1.07μs 1.57ns 6.09ns 0 0 0 696 B
#7695 RunOnMethodBegin netcoreapp3.1 1.46μs 7.45ns 35.7ns 0 0 0 696 B
#7695 RunOnMethodBegin net472 1.45μs 0.792ns 2.96ns 0.102 0 0 658 B

@andrewlock andrewlock force-pushed the andrew/settings/4-mutable-settings-service branch from 9c790a3 to 9f05223 Compare October 22, 2025 16:39
@andrewlock
Copy link
Member Author

@codex review

@chatgpt-codex-connector
Copy link

Codex Review: Didn't find any major issues. Chef's kiss.

ℹ️ 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".

@andrewlock andrewlock force-pushed the andrew/settings/4-mutable-settings-service branch from 9f05223 to 6b9a134 Compare October 24, 2025 16:42
@datadog-datadog-prod-us1
Copy link

datadog-datadog-prod-us1 bot commented Oct 24, 2025

⚠️ Tests

⚠️ Warnings

🧪 1 Test failed

SubmitsTraces from Datadog.Trace.ClrProfiler.IntegrationTests.StackExchangeRedisTests (Datadog)
Results do not match.
Differences:
Received: StackExchangeRedisTests.Latest.SchemaV0.received.txt
Verified: StackExchangeRedisTests.Latest.SchemaV0.verified.txt
Compare Result:
  [
    {
      TraceId: Id_1,
      SpanId: Id_2,
      Name: redis.command,
...

ℹ️ Info

❄️ No new flaky tests detected

This comment will be updated automatically if new data arrives.
🔗 Commit SHA: 438ebc1 | Docs | Datadog PR Page | Was this helpful? Give us feedback!

@andrewlock andrewlock force-pushed the andrew/settings/4-mutable-settings-service branch from 6b9a134 to c04decc Compare October 28, 2025 12:46
@andrewlock andrewlock changed the base branch from master to andrew/settings/4b-helper October 28, 2025 13:11
@andrewlock andrewlock force-pushed the andrew/settings/4-mutable-settings-service branch from c04decc to 60c7874 Compare October 28, 2025 13:41
@andrewlock andrewlock force-pushed the andrew/settings/4b-helper branch from a6b40ae to 1ed4e84 Compare October 28, 2025 13:41
@andrewlock andrewlock marked this pull request as ready for review October 28, 2025 13:41
@andrewlock andrewlock requested review from a team as code owners October 28, 2025 13:41
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.

ℹ️ 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".

@andrewlock andrewlock force-pushed the andrew/settings/4-mutable-settings-service branch from 60c7874 to c691a0e Compare October 28, 2025 15:20
@andrewlock andrewlock force-pushed the andrew/settings/4b-helper branch from 1ed4e84 to 1477479 Compare October 28, 2025 15:20
andrewlock

This comment was marked as resolved.

andrewlock

This comment was marked as resolved.

@andrewlock andrewlock force-pushed the andrew/settings/4-mutable-settings-service branch 2 times, most recently from 21e9e1c to 67beb6a Compare November 6, 2025 08:32
{
if (BuildNewSettings(dynamicConfigSource, manualSource, centralTelemetry) is { } newSettings)
{
NotifySubscribers(newSettings);
Copy link
Member

Choose a reason for hiding this comment

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

If two threads call UpdateSettings(), could there be a race condition where NotifySubscribers() is also called twice, since both can see the same _latest value in BuildNewSettings() below?

Ignore if you already considered this and decided that was acceptable.

Copy link
Member Author

Choose a reason for hiding this comment

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

Hmmm, yeah, good catch 🤔 This could happen if a customer calls Tracer.Configure() with manual instrumentation at the same time as remote config does a dynamic config update. I'd always expect two distinct calls in that case, and I think there would be races elsewhere, before this is called that I need to 👀 again (despite considering this at the time 😅)

Maybe I should stop trying to be cute and should just lock this whole UpdateSettings call... I was a bit concerned about doing that because it's relatively expensive, but I think otherwise we're just going to be fighting edge cases...

Copy link
Member

Choose a reason for hiding this comment

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

To be fair, calling NotifySubscribers() twice with the same settings is not the worst thing in the world.

Copy link
Member Author

Choose a reason for hiding this comment

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

Yeah, my (minor) concern is more around a mis-match of settings, if manual and remote config is happening at the same time. I think, currently, in that scenario, you could end up with a weird situation where you get the following:

  • Initially: no manual config, no remote config
  • Manual config and remote config happens at the same time, with conflicting values
    • Manual updates the "global" manual config source
    • Remote updates the "global" remote config source
    • This happens concurrently, and neither "sees" the update changes
  • Consumers get two updates:
  • One with the new manual config and the old remote config
  • One with the old manual config and the new remote config
  • Neither is correct 😅

So I think we need some locks around the global config updates... I'll add those in (technically not related to this PR, but makes sense to include here)

Copy link
Member Author

Choose a reason for hiding this comment

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

I reworked this quite a lot:

  • Instead of storing the manual and dynamic config sources as static globals, store them on SettingsManager
    • This is practically equivalent, because we only create a single TracerSettings instance in production, but it makes things much easier to reason about and manage
  • Have specific methods for "update manual" and "update dynamic config". That way we can lock inside these methods and avoid the specific scenario I described above
  • Locking around the whole update process avoids any future edge cases we might hit. They're very much edge cases, but given these updates should be relatively rare, I think playing it safest makes sense. There's not much to be gained by trying to reduce how long the lock is held.

Thanks for the 👀!

@andrewlock andrewlock force-pushed the andrew/settings/4-mutable-settings-service branch from 67beb6a to 920071a Compare November 7, 2025 18:09
Copy link
Collaborator

@bouwkast bouwkast left a comment

Choose a reason for hiding this comment

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

👍

@andrewlock andrewlock force-pushed the andrew/settings/4-mutable-settings-service branch 2 times, most recently from 98a10b7 to 696fee1 Compare November 14, 2025 07:41
@anna-git anna-git removed their request for review November 18, 2025 12:26
@andrewlock andrewlock force-pushed the andrew/settings/4-mutable-settings-service branch from 696fee1 to 438ebc1 Compare November 25, 2025 16:46
@andrewlock andrewlock enabled auto-merge (squash) November 26, 2025 07:33
@andrewlock andrewlock merged commit 0a4d09b into master Nov 26, 2025
150 of 151 checks passed
@andrewlock andrewlock deleted the andrew/settings/4-mutable-settings-service branch November 26, 2025 08:14
@github-actions github-actions bot added this to the vNext-v3 milestone Nov 26, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:dynamic-configuration area:tracer The core tracer library (Datadog.Trace, does not include OpenTracing, native code, or integrations) type:refactor

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants