Skip to content

Conversation

@andrewlock
Copy link
Member

@andrewlock andrewlock commented Oct 28, 2025

Summary of changes

Instead of exposing settings like ServiceVerion and Environment on TracerSettings, only expose them on MutableSettings

Reason for change

This is all part of the refactoring towards having TracerSettings being an immutable settings object, that's created once on app startup, and fixed for the lifetime. ServiceVerion and Environment currently delegate to the MutableSettings object stored on TracerSettings, but are going to move that elsewhere shortly so that consumers can subscribe to changes

Implementation details

For this PR, it's just a case of changing TracerSettings.XXX => TracerSettings.Mutable.XXX. A future PR will then subsequently "fix" these usages properly. This is just a small step to be able to remove the mutable properties from TracerSettings

Test coverage

Just a refactoring, covered by existing tests.

Other details

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

Part of a config stack

@andrewlock andrewlock requested review from a team as code owners October 28, 2025 13:42
@andrewlock andrewlock added the area:tracer The core tracer library (Datadog.Trace, does not include OpenTracing, native code, or integrations) label Oct 28, 2025
@andrewlock andrewlock requested a review from a team as a code owner October 28, 2025 13:42
@andrewlock andrewlock force-pushed the andrew/settings/5-move-mutable-settings-off-tracer-settings branch from e347879 to 8c472a5 Compare October 28, 2025 15:02
@pr-commenter
Copy link

pr-commenter bot commented Oct 28, 2025

Benchmarks

Benchmarks Report for benchmark platform 🐌

Benchmarks for #7723 compared to master:

  • 4 benchmarks are faster, with geometric mean 1.436
  • 1 benchmarks are slower, with geometric mean 1.122
  • 9 benchmarks have fewer allocations
  • 3 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.2μs 56.6ns 335ns 0 0 0 5.52 KB
master StartStopWithChild netcoreapp3.1 13.9μs 69.1ns 324ns 0 0 0 5.71 KB
master StartStopWithChild net472 22.4μs 121ns 663ns 0.914 0.229 0 6.07 KB
#7723 StartStopWithChild net6.0 10.8μs 51.6ns 213ns 0 0 0 5.5 KB
#7723 StartStopWithChild netcoreapp3.1 13.7μs 69.7ns 304ns 0 0 0 5.71 KB
#7723 StartStopWithChild net472 22.1μs 121ns 714ns 0.868 0.217 0 6.04 KB
Benchmarks.Trace.AgentWriterBenchmark - Same speed ✔️ Same allocations ✔️

Raw results

Branch Method Toolchain Mean StdError StdDev Gen 0 Gen 1 Gen 2 Allocated
master WriteAndFlushEnrichedTraces net6.0 935μs 465ns 1.8μs 0 0 0 2.7 KB
master WriteAndFlushEnrichedTraces netcoreapp3.1 1.02ms 836ns 3.24μs 0 0 0 2.7 KB
master WriteAndFlushEnrichedTraces net472 1.2ms 1.26μs 4.71μs 0 0 0 3.31 KB
#7723 WriteAndFlushEnrichedTraces net6.0 936μs 37.5ns 140ns 0 0 0 2.7 KB
#7723 WriteAndFlushEnrichedTraces netcoreapp3.1 1.02ms 55.6ns 208ns 0 0 0 2.7 KB
#7723 WriteAndFlushEnrichedTraces net472 1.21ms 70.1ns 262ns 0 0 0 3.31 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.1μs 1.56ns 6.03ns 0 0 0 1.22 KB
master AllCycleSimpleBody netcoreapp3.1 1.41μs 7.97ns 52.2ns 0 0 0 1.2 KB
master AllCycleSimpleBody net472 1.03μs 2.6ns 10.1ns 0.193 0 0 1.23 KB
master AllCycleMoreComplexBody net6.0 7.4μs 5.62ns 21.8ns 0 0 0 4.72 KB
master AllCycleMoreComplexBody netcoreapp3.1 9.06μs 43.5ns 185ns 0 0 0 4.62 KB
master AllCycleMoreComplexBody net472 7.69μs 4.77ns 18.5ns 0.731 0 0 4.74 KB
master ObjectExtractorSimpleBody net6.0 341ns 1.66ns 6.84ns 0 0 0 280 B
master ObjectExtractorSimpleBody netcoreapp3.1 395ns 2.15ns 11.9ns 0 0 0 272 B
master ObjectExtractorSimpleBody net472 300ns 0.0279ns 0.108ns 0.0443 0 0 281 B
master ObjectExtractorMoreComplexBody net6.0 6.34μs 29.2ns 117ns 0 0 0 3.78 KB
master ObjectExtractorMoreComplexBody netcoreapp3.1 7.79μs 38.5ns 149ns 0 0 0 3.69 KB
master ObjectExtractorMoreComplexBody net472 6.68μs 1.6ns 6ns 0.601 0 0 3.8 KB
#7723 AllCycleSimpleBody net6.0 1.08μs 3.85ns 14.4ns 0 0 0 1.22 KB
#7723 AllCycleSimpleBody netcoreapp3.1 1.4μs 7.74ns 44.5ns 0 0 0 1.2 KB
#7723 AllCycleSimpleBody net472 1.01μs 0.156ns 0.583ns 0.191 0 0 1.23 KB
#7723 AllCycleMoreComplexBody net6.0 7.38μs 34.4ns 133ns 0 0 0 4.72 KB
#7723 AllCycleMoreComplexBody netcoreapp3.1 9.18μs 38.8ns 145ns 0 0 0 4.62 KB
#7723 AllCycleMoreComplexBody net472 7.68μs 4.13ns 16ns 0.73 0 0 4.74 KB
#7723 ObjectExtractorSimpleBody net6.0 323ns 1.65ns 8.24ns 0 0 0 280 B
#7723 ObjectExtractorSimpleBody netcoreapp3.1 403ns 2.27ns 14.1ns 0 0 0 272 B
#7723 ObjectExtractorSimpleBody net472 297ns 0.0761ns 0.295ns 0.0433 0 0 281 B
#7723 ObjectExtractorMoreComplexBody net6.0 6.22μs 31.5ns 151ns 0 0 0 3.78 KB
#7723 ObjectExtractorMoreComplexBody netcoreapp3.1 7.92μs 31.3ns 117ns 0 0 0 3.69 KB
#7723 ObjectExtractorMoreComplexBody net472 6.6μs 1.45ns 5.6ns 0.596 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.6μs 21.6ns 77.9ns 0 0 0 32.4 KB
master EncodeArgs netcoreapp3.1 98.3μs 286ns 1.11μs 0 0 0 32.4 KB
master EncodeArgs net472 112μs 18.7ns 72.2ns 5.02 0 0 32.51 KB
master EncodeLegacyArgs net6.0 143μs 89.3ns 346ns 0 0 0 2.15 KB
master EncodeLegacyArgs netcoreapp3.1 201μs 436ns 1.69μs 0 0 0 2.14 KB
master EncodeLegacyArgs net472 265μs 69.1ns 258ns 0 0 0 2.16 KB
#7723 EncodeArgs net6.0 77.6μs 17.9ns 69.5ns 0 0 0 32.4 KB
#7723 EncodeArgs netcoreapp3.1 97.5μs 336ns 1.26μs 0 0 0 32.4 KB
#7723 EncodeArgs net472 112μs 347ns 1.34μs 5.1 0 0 32.5 KB
#7723 EncodeLegacyArgs net6.0 146μs 50.4ns 195ns 0 0 0 2.15 KB
#7723 EncodeLegacyArgs netcoreapp3.1 198μs 205ns 795ns 0 0 0 2.15 KB
#7723 EncodeLegacyArgs net472 263μs 43.8ns 164ns 0 0 0 2.16 KB
Benchmarks.Trace.Asm.AppSecWafBenchmark - Same speed ✔️ Fewer allocations 🎉

Fewer allocations 🎉 in #7723

Benchmark Base Allocated Diff Allocated Change Change %
Benchmarks.Trace.Asm.AppSecWafBenchmark.RunWafRealisticBenchmarkWithAttack‑net6.0 3.79 KB 2.83 KB -960 B -25.32%
Benchmarks.Trace.Asm.AppSecWafBenchmark.RunWafRealisticBenchmark‑net472 8.19 KB 0 b -8.19 KB -100.00%
Benchmarks.Trace.Asm.AppSecWafBenchmark.RunWafRealisticBenchmarkWithAttack‑net472 8.19 KB 0 b -8.19 KB -100.00%

Raw results

Branch Method Toolchain Mean StdError StdDev Gen 0 Gen 1 Gen 2 Allocated
master RunWafRealisticBenchmark net6.0 424μs 830ns 2.99μs 0 0 0 5.48 KB
master RunWafRealisticBenchmark netcoreapp3.1 465μs 2.95μs 28.3μs 0 0 0 4.58 KB
master RunWafRealisticBenchmark net472 496μs 603ns 2.33μs 0 0 0 8.19 KB
master RunWafRealisticBenchmarkWithAttack net6.0 313μs 923ns 3.81μs 0 0 0 3.79 KB
master RunWafRealisticBenchmarkWithAttack netcoreapp3.1 367μs 3.77μs 36.6μs 0 0 0 2.32 KB
master RunWafRealisticBenchmarkWithAttack net472 372μs 265ns 954ns 0 0 0 8.19 KB
#7723 RunWafRealisticBenchmark net6.0 429μs 725ns 2.62μs 0 0 0 5.48 KB
#7723 RunWafRealisticBenchmark netcoreapp3.1 464μs 2.6μs 17.4μs 0 0 0 4.58 KB
#7723 RunWafRealisticBenchmark net472 492μs 453ns 1.57μs 0 0 0 0 b
#7723 RunWafRealisticBenchmarkWithAttack net6.0 311μs 794ns 2.86μs 0 0 0 2.83 KB
#7723 RunWafRealisticBenchmarkWithAttack netcoreapp3.1 348μs 3.96μs 38μs 0 0 0 2.32 KB
#7723 RunWafRealisticBenchmarkWithAttack net472 380μs 343ns 1.24μs 0 0 0 0 b
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 60.3μs 100ns 360ns 0 0 0 14.52 KB
master SendRequest netcoreapp3.1 71.5μs 205ns 895ns 0 0 0 17.42 KB
master SendRequest net472 0.155ns 0.00363ns 0.0141ns 0 0 0 0 b
#7723 SendRequest net6.0 60.7μs 39.7ns 154ns 0 0 0 14.52 KB
#7723 SendRequest netcoreapp3.1 72.1μs 94.7ns 328ns 0 0 0 17.42 KB
#7723 SendRequest net472 0.0107ns 0.00255ns 0.00987ns 0 0 0 0 b
Benchmarks.Trace.CharSliceBenchmark - Slower ⚠️ More allocations ⚠️

Slower ⚠️ in #7723

Benchmark diff/base Base Median (ns) Diff Median (ns) Modality
Benchmarks.Trace.CharSliceBenchmark.OptimizedCharSliceWithPool‑net6.0 1.122 1,002,700.00 1,124,600.00

Faster 🎉 in #7723

Benchmark base/diff Base Median (ns) Diff Median (ns) Modality
Benchmarks.Trace.CharSliceBenchmark.OriginalCharSlice‑netcoreapp3.1 1.833 3,917,150.00 2,137,400.00
Benchmarks.Trace.CharSliceBenchmark.OptimizedCharSlice‑netcoreapp3.1 1.626 2,766,550.00 1,700,950.00

More allocations ⚠️ in #7723

Benchmark Base Allocated Diff Allocated Change Change %
Benchmarks.Trace.CharSliceBenchmark.OptimizedCharSlice‑net6.0 304 B 640 B 336 B 110.53%

Fewer allocations 🎉 in #7723

Benchmark Base Allocated Diff Allocated Change Change %
Benchmarks.Trace.CharSliceBenchmark.OptimizedCharSlice‑net472 8.19 KB 0 b -8.19 KB -100.00%
Benchmarks.Trace.CharSliceBenchmark.OptimizedCharSliceWithPool‑net472 8.19 KB 0 b -8.19 KB -100.00%

Raw results

Branch Method Toolchain Mean StdError StdDev Gen 0 Gen 1 Gen 2 Allocated
master OriginalCharSlice net6.0 1.89ms 651ns 2.35μs 0 0 0 640.3 KB
master OriginalCharSlice netcoreapp3.1 3.92ms 1.67μs 6.45μs 0 0 0 640.1 KB
master OriginalCharSlice net472 2.59ms 418ns 1.51μs 0 0 0 647.17 KB
master OptimizedCharSlice net6.0 1.48ms 921ns 3.45μs 0 0 0 304 B
master OptimizedCharSlice netcoreapp3.1 2.77ms 941ns 3.52μs 0 0 0 104 B
master OptimizedCharSlice net472 2ms 970ns 3.76μs 0 0 0 8.19 KB
master OptimizedCharSliceWithPool net6.0 1ms 364ns 1.31μs 0 0 0 640 B
master OptimizedCharSliceWithPool netcoreapp3.1 1.86ms 1.58μs 6.1μs 0 0 0 104 B
master OptimizedCharSliceWithPool net472 1.13ms 479ns 1.85μs 0 0 0 8.19 KB
#7723 OriginalCharSlice net6.0 1.99ms 1.25μs 4.83μs 0 0 0 640.64 KB
#7723 OriginalCharSlice netcoreapp3.1 2.14ms 9.24μs 62.7μs 0 0 0 640.1 KB
#7723 OriginalCharSlice net472 2.6ms 963ns 3.47μs 0 0 0 647.17 KB
#7723 OptimizedCharSlice net6.0 1.48ms 475ns 1.78μs 0 0 0 640 B
#7723 OptimizedCharSlice netcoreapp3.1 1.71ms 9.6μs 62.2μs 0 0 0 104 B
#7723 OptimizedCharSlice net472 2.06ms 1.24μs 4.81μs 0 0 0 0 b
#7723 OptimizedCharSliceWithPool net6.0 1.12ms 688ns 2.67μs 0 0 0 640 B
#7723 OptimizedCharSliceWithPool netcoreapp3.1 1.89ms 1.55μs 5.81μs 0 0 0 104 B
#7723 OptimizedCharSliceWithPool net472 1.16ms 322ns 1.25μs 0 0 0 0 b
Benchmarks.Trace.CIVisibilityProtocolWriterBenchmark - Faster 🎉 More allocations ⚠️

Faster 🎉 in #7723

Benchmark base/diff Base Median (ns) Diff Median (ns) Modality
Benchmarks.Trace.CIVisibilityProtocolWriterBenchmark.WriteAndFlushEnrichedTraces‑netcoreapp3.1 1.236 804,968.75 651,017.50 several?

More allocations ⚠️ in #7723

Benchmark Base Allocated Diff Allocated Change Change %
Benchmarks.Trace.CIVisibilityProtocolWriterBenchmark.WriteAndFlushEnrichedTraces‑net472 55.91 KB 56.32 KB 410 B 0.73%

Fewer allocations 🎉 in #7723

Benchmark Base Allocated Diff Allocated Change Change %
Benchmarks.Trace.CIVisibilityProtocolWriterBenchmark.WriteAndFlushEnrichedTraces‑net6.0 42.55 KB 41.9 KB -647 B -1.52%

Raw results

Branch Method Toolchain Mean StdError StdDev Gen 0 Gen 1 Gen 2 Allocated
master WriteAndFlushEnrichedTraces net6.0 654μs 3.07μs 11.5μs 0 0 0 42.55 KB
master WriteAndFlushEnrichedTraces netcoreapp3.1 803μs 3.78μs 14.6μs 0 0 0 41.8 KB
master WriteAndFlushEnrichedTraces net472 923μs 2.56μs 9.57μs 8.33 0 0 55.91 KB
#7723 WriteAndFlushEnrichedTraces net6.0 693μs 1.05μs 4.05μs 0 0 0 41.9 KB
#7723 WriteAndFlushEnrichedTraces netcoreapp3.1 663μs 3.82μs 29.8μs 0 0 0 41.84 KB
#7723 WriteAndFlushEnrichedTraces net472 942μs 4.42μs 17.1μs 8.33 0 0 56.32 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.92μs 7.06ns 26.4ns 0 0 0 1.02 KB
master ExecuteNonQuery netcoreapp3.1 2.59μs 5.44ns 21.1ns 0 0 0 1.02 KB
master ExecuteNonQuery net472 2.72μs 0.557ns 2.09ns 0.149 0 0 987 B
#7723 ExecuteNonQuery net6.0 1.87μs 0.731ns 2.83ns 0 0 0 1.02 KB
#7723 ExecuteNonQuery netcoreapp3.1 2.65μs 8.59ns 33.3ns 0 0 0 1.02 KB
#7723 ExecuteNonQuery net472 2.74μs 4.26ns 16.5ns 0.149 0 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.77μs 8.1ns 31.4ns 0 0 0 1.03 KB
master CallElasticsearch netcoreapp3.1 2.31μs 11ns 46.8ns 0 0 0 1.03 KB
master CallElasticsearch net472 3.53μs 5.31ns 20.6ns 0.158 0 0 1.04 KB
master CallElasticsearchAsync net6.0 1.83μs 9.71ns 47.6ns 0 0 0 1.01 KB
master CallElasticsearchAsync netcoreapp3.1 2.43μs 1.47ns 5.49ns 0 0 0 1.08 KB
master CallElasticsearchAsync net472 3.66μs 4.36ns 16.9ns 0.165 0 0 1.1 KB
#7723 CallElasticsearch net6.0 1.79μs 2.82ns 10.9ns 0 0 0 1.03 KB
#7723 CallElasticsearch netcoreapp3.1 2.28μs 9.83ns 38.1ns 0 0 0 1.03 KB
#7723 CallElasticsearch net472 3.52μs 3.72ns 14.4ns 0.158 0 0 1.04 KB
#7723 CallElasticsearchAsync net6.0 1.8μs 6.61ns 25.6ns 0 0 0 1.01 KB
#7723 CallElasticsearchAsync netcoreapp3.1 2.52μs 7.23ns 28ns 0 0 0 1.08 KB
#7723 CallElasticsearchAsync net472 3.74μs 3.34ns 12.1ns 0.167 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.88μs 0.882ns 3.42ns 0 0 0 952 B
master ExecuteAsync netcoreapp3.1 2.35μs 1.18ns 4.58ns 0 0 0 952 B
master ExecuteAsync net472 2.6μs 0.491ns 1.84ns 0.143 0 0 915 B
#7723 ExecuteAsync net6.0 1.83μs 9.03ns 40.4ns 0 0 0 952 B
#7723 ExecuteAsync netcoreapp3.1 2.41μs 11.5ns 44.4ns 0 0 0 952 B
#7723 ExecuteAsync net472 2.73μs 0.77ns 2.98ns 0.136 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.86μs 14.8ns 55.4ns 0 0 0 2.36 KB
master SendAsync netcoreapp3.1 8.59μs 26ns 101ns 0 0 0 2.9 KB
master SendAsync net472 12.2μs 5.67ns 22ns 0.487 0 0 3.18 KB
#7723 SendAsync net6.0 6.93μs 24.2ns 93.7ns 0 0 0 2.36 KB
#7723 SendAsync netcoreapp3.1 8.57μs 5.62ns 21.8ns 0 0 0 2.9 KB
#7723 SendAsync net472 12μs 13.4ns 52ns 0.482 0 0 3.18 KB
Benchmarks.Trace.Iast.StringAspectsBenchmark - Same speed ✔️ More allocations ⚠️

More allocations ⚠️ in #7723

Benchmark Base Allocated Diff Allocated Change Change %
Benchmarks.Trace.Iast.StringAspectsBenchmark.StringConcatAspectBenchmark‑net472 275.84 KB 286.72 KB 10.88 KB 3.94%

Fewer allocations 🎉 in #7723

Benchmark Base Allocated Diff Allocated Change Change %
Benchmarks.Trace.Iast.StringAspectsBenchmark.StringConcatBenchmark‑netcoreapp3.1 42.86 KB 42.64 KB -216 B -0.50%
Benchmarks.Trace.Iast.StringAspectsBenchmark.StringConcatAspectBenchmark‑net6.0 274.3 KB 256.02 KB -18.28 KB -6.66%
Benchmarks.Trace.Iast.StringAspectsBenchmark.StringConcatBenchmark‑net472 65.54 KB 57.34 KB -8.19 KB -12.50%

Raw results

Branch Method Toolchain Mean StdError StdDev Gen 0 Gen 1 Gen 2 Allocated
master StringConcatBenchmark net6.0 44.1μs 226ns 1.01μs 0 0 0 43.87 KB
master StringConcatBenchmark netcoreapp3.1 50.2μs 402ns 3.79μs 0 0 0 42.86 KB
master StringConcatBenchmark net472 58μs 235ns 908ns 0 0 0 65.54 KB
master StringConcatAspectBenchmark net6.0 462μs 1.83μs 6.59μs 0 0 0 274.3 KB
master StringConcatAspectBenchmark netcoreapp3.1 518μs 1.64μs 6.57μs 0 0 0 275.52 KB
master StringConcatAspectBenchmark net472 406μs 2.16μs 15.4μs 0 0 0 275.84 KB
#7723 StringConcatBenchmark net6.0 44.9μs 263ns 2.23μs 0 0 0 43.78 KB
#7723 StringConcatBenchmark netcoreapp3.1 49.8μs 241ns 1.49μs 0 0 0 42.64 KB
#7723 StringConcatBenchmark net472 55.6μs 172ns 620ns 0 0 0 57.34 KB
#7723 StringConcatAspectBenchmark net6.0 444μs 2.11μs 8.18μs 0 0 0 256.02 KB
#7723 StringConcatAspectBenchmark netcoreapp3.1 516μs 1.41μs 5.09μs 0 0 0 276.74 KB
#7723 StringConcatAspectBenchmark net472 410μs 2.15μs 11.2μs 0 0 0 286.72 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.79μs 11.4ns 44.2ns 0 0 0 1.7 KB
master EnrichedLog netcoreapp3.1 3.66μs 16ns 62ns 0 0 0 1.7 KB
master EnrichedLog net472 3.7μs 2.04ns 7.92ns 0.258 0 0 1.64 KB
#7723 EnrichedLog net6.0 2.63μs 12.1ns 48.5ns 0 0 0 1.7 KB
#7723 EnrichedLog netcoreapp3.1 3.65μs 17.4ns 69.7ns 0 0 0 1.7 KB
#7723 EnrichedLog net472 3.82μs 1.73ns 6.23ns 0.248 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 124μs 170ns 588ns 0 0 0 4.31 KB
master EnrichedLog netcoreapp3.1 128μs 390ns 1.41μs 0 0 0 4.31 KB
master EnrichedLog net472 171μs 677ns 2.34μs 0 0 0 4.52 KB
#7723 EnrichedLog net6.0 123μs 139ns 539ns 0 0 0 4.31 KB
#7723 EnrichedLog netcoreapp3.1 129μs 446ns 1.73μs 0 0 0 4.31 KB
#7723 EnrichedLog net472 168μs 155ns 599ns 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 5.12μs 16.5ns 61.7ns 0 0 0 2.26 KB
master EnrichedLog netcoreapp3.1 6.63μs 12.9ns 50.1ns 0 0 0 2.26 KB
master EnrichedLog net472 7.5μs 3.94ns 13.7ns 0.299 0 0 2.08 KB
#7723 EnrichedLog net6.0 4.86μs 18.7ns 70.1ns 0 0 0 2.26 KB
#7723 EnrichedLog netcoreapp3.1 6.84μs 27.4ns 106ns 0 0 0 2.26 KB
#7723 EnrichedLog net472 7.41μs 6.32ns 24.5ns 0.297 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 2.01μs 9.19ns 36.7ns 0 0 0 1.2 KB
master SendReceive netcoreapp3.1 2.58μs 11ns 42.6ns 0 0 0 1.2 KB
master SendReceive net472 3μs 6.33ns 24.5ns 0.178 0 0 1.2 KB
#7723 SendReceive net6.0 1.95μs 9.74ns 42.4ns 0 0 0 1.2 KB
#7723 SendReceive netcoreapp3.1 2.51μs 9.09ns 34ns 0 0 0 1.2 KB
#7723 SendReceive net472 2.94μs 2.17ns 8.39ns 0.191 0 0 1.2 KB
Benchmarks.Trace.SerilogBenchmark - Faster 🎉 Same allocations ✔️

Faster 🎉 in #7723

Benchmark base/diff Base Median (ns) Diff Median (ns) Modality
Benchmarks.Trace.SerilogBenchmark.EnrichedLog‑net6.0 1.152 4,895.85 4,248.04

Raw results

Branch Method Toolchain Mean StdError StdDev Gen 0 Gen 1 Gen 2 Allocated
master EnrichedLog net6.0 4.88μs 18.2ns 70.4ns 0 0 0 1.58 KB
master EnrichedLog netcoreapp3.1 5.93μs 9.42ns 35.3ns 0 0 0 1.63 KB
master EnrichedLog net472 6.42μs 5.33ns 19.9ns 0.319 0 0 2.03 KB
#7723 EnrichedLog net6.0 4.24μs 14.6ns 54.5ns 0 0 0 1.58 KB
#7723 EnrichedLog netcoreapp3.1 5.9μs 5.43ns 20.3ns 0 0 0 1.63 KB
#7723 EnrichedLog net472 6.71μs 4.9ns 18.3ns 0.301 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 799ns 0.185ns 0.715ns 0 0 0 576 B
master StartFinishSpan netcoreapp3.1 965ns 5.01ns 23.5ns 0 0 0 576 B
master StartFinishSpan net472 905ns 0.201ns 0.695ns 0.0908 0 0 578 B
master StartFinishScope net6.0 937ns 0.445ns 1.67ns 0 0 0 696 B
master StartFinishScope netcoreapp3.1 1.19μs 5.43ns 21ns 0 0 0 696 B
master StartFinishScope net472 1.1μs 0.179ns 0.693ns 0.0996 0 0 658 B
#7723 StartFinishSpan net6.0 809ns 2.1ns 8.13ns 0 0 0 576 B
#7723 StartFinishSpan netcoreapp3.1 948ns 4.02ns 15.6ns 0 0 0 576 B
#7723 StartFinishSpan net472 912ns 0.472ns 1.83ns 0.0916 0 0 578 B
#7723 StartFinishScope net6.0 925ns 4.61ns 20.1ns 0 0 0 696 B
#7723 StartFinishScope netcoreapp3.1 1.13μs 4.87ns 18.9ns 0 0 0 696 B
#7723 StartFinishScope net472 1.1μs 0.339ns 1.31ns 0.0996 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.08μs 0.99ns 3.83ns 0 0 0 696 B
master RunOnMethodBegin netcoreapp3.1 1.43μs 0.831ns 3.22ns 0 0 0 696 B
master RunOnMethodBegin net472 1.4μs 1.42ns 5.49ns 0.104 0 0 658 B
#7723 RunOnMethodBegin net6.0 1.08μs 0.891ns 3.45ns 0 0 0 696 B
#7723 RunOnMethodBegin netcoreapp3.1 1.42μs 4.87ns 18.2ns 0 0 0 696 B
#7723 RunOnMethodBegin net472 1.47μs 1.19ns 4.6ns 0.103 0 0 658 B

@andrewlock andrewlock force-pushed the andrew/settings/5-move-mutable-settings-off-tracer-settings branch from 8c472a5 to 8e19e3a Compare October 28, 2025 15:20
@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/5-move-mutable-settings-off-tracer-settings branch from 8e19e3a to 7940c31 Compare October 28, 2025 18:13
@andrewlock andrewlock requested review from a team as code owners October 28, 2025 18:13
@andrewlock andrewlock requested review from zacharycmontoya and removed request for a team October 28, 2025 18:13
@andrewlock andrewlock force-pushed the andrew/settings/4-mutable-settings-service branch from c691a0e to a52caed Compare October 28, 2025 18:13
@datadog-datadog-prod-us1
Copy link

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

⚠️ Tests

⚠️ Warnings

❄️ 1 New flaky test detected

TestReceiveMessagesAsyncIntegration from Datadog.Trace.ClrProfiler.IntegrationTests.Azure.AzureServiceBusAPMTests (Datadog)
Expected linkedSendSpan not to be <null> because Receive span 18262316137143385621 has link to span 12684159696604130500 in trace 16802901378780602481, but corresponding send span not found.
Expected linkedSendSpan not to be <null> because Receive span 71320086548193563 has link to span 12684159696604130500 in trace 16802901378780602481, but corresponding send span not found.

ℹ️ Info

🧪 All tests passed

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

Copy link
Member Author

@andrewlock andrewlock left a comment

Choose a reason for hiding this comment

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

Automated code review by Claude Code

This PR successfully refactors TracerSettings to remove mutable properties and require explicit access through MutableSettings. The changes are generally consistent and well-executed. I've identified a few specific issues below for consideration.

Copy link
Member Author

@andrewlock andrewlock left a comment

Choose a reason for hiding this comment

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

Automated code review by Claude Code

This PR successfully refactors TracerSettings to remove mutable properties and require explicit access through MutableSettings. The changes are generally consistent and well-executed.

// Move the creation of these settings inside SettingsManager?
var initialMutableSettings = MutableSettings.CreateInitialMutableSettings(source, telemetry, errorLog, this);
Manager = new(this, initialMutableSettings, Exporter);
MutableSettings = initialMutableSettings;
Copy link
Collaborator

Choose a reason for hiding this comment

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

Was the order of operations here changed on purpose? Manager / MutableSettings got flipped around but I don't see anything really so just wondering

Copy link
Member Author

Choose a reason for hiding this comment

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

No, no reason, I think that was just accidental in amongst all the refactoring 😅 It's moot in the next PR where we remove MutableSettings entirely 😅

@andrewlock andrewlock force-pushed the andrew/settings/5-move-mutable-settings-off-tracer-settings branch from 8ae168d to b538e28 Compare November 11, 2025 10:04
@andrewlock andrewlock force-pushed the andrew/settings/4-mutable-settings-service branch from 9aa97ec to 98a10b7 Compare November 11, 2025 10:04
@andrewlock andrewlock force-pushed the andrew/settings/5-move-mutable-settings-off-tracer-settings branch from b538e28 to 99a2868 Compare November 14, 2025 07:41
@andrewlock andrewlock force-pushed the andrew/settings/4-mutable-settings-service branch from 98a10b7 to 696fee1 Compare November 14, 2025 07:41
@andrewlock andrewlock force-pushed the andrew/settings/5-move-mutable-settings-off-tracer-settings branch from 99a2868 to 209f533 Compare November 25, 2025 16:46
@andrewlock andrewlock force-pushed the andrew/settings/4-mutable-settings-service branch from 696fee1 to 438ebc1 Compare November 25, 2025 16:46
Base automatically changed from andrew/settings/4-mutable-settings-service to master November 26, 2025 08:14
andrewlock added a commit that referenced this pull request Nov 26, 2025
…ttings (#7695)

## 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

- #7522
- #7525
- #7530
- #7532
- #7543
- #7544
- #7721
- #7722
- #7695 👈
- #7723
- #7724
- #7796

---------

Co-authored-by: Lucas Pimentel <[email protected]>
@andrewlock andrewlock force-pushed the andrew/settings/5-move-mutable-settings-off-tracer-settings branch from 209f533 to 2bb4dd4 Compare November 26, 2025 08:17
@andrewlock andrewlock enabled auto-merge (squash) November 26, 2025 09:27
@andrewlock andrewlock merged commit 0941efa into master Nov 26, 2025
153 of 154 checks passed
@andrewlock andrewlock deleted the andrew/settings/5-move-mutable-settings-off-tracer-settings branch November 26, 2025 11:06
@github-actions github-actions bot added this to the vNext-v3 milestone Nov 26, 2025
andrewlock added a commit that referenced this pull request Nov 26, 2025
… config changes (#7796)

## Summary of changes

A fix for #7724 to handle telemetry reporting in dynamic config "reset"
scenarios

## Reason for change

The system tests for #7724 were failing in some dynamic configuration
scenarios. Specifically, the tests were sending remote config _without_
any configuration values "i.e. 'reset to use defaults'" and were waiting
a telemetry update. However, we never sent it, because there was "no
telemetry to record".

Note that we _did_ correctly apply the new configuration, we just didn't
report the telemetry correctly, primarily due to limitations in the
telemetry protocol. This PR adds a fix for that, and will be merged into
#7724.

## Implementation details

The solution is to "remember" the telemetry from the default mutable
configuration values, _without_ any dynamic sources, and "replay" this
telemetry when we update telemetry. This feels kind of hacky, but it's
something I suspected we might need to do, and had been avoiding up to
this point because we do a "full reconfigure" anyway.

## Test coverage

Added a specific unit test that mimics the behaviour of the system-test
(i.e. an "empty" dynamic config response) and confirms the telemetry is
recorded as expected

## Other details

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

Part of a config stack

- #7522
- #7525
- #7530
- #7532
- #7543
- #7544
- #7721
- #7722
- #7695
- #7723
- #7724
- #7796 👈

Unlike other PRs in the stack, I'll merge this directly into #7724 to
fix the tests there, just thought I'd keep this separate for easier
reviewing
andrewlock added a commit that referenced this pull request Nov 26, 2025
## Summary of changes

- Fix broken `master` due to concurrent merges of conflicting 

## Reason for change

#7698 moved to defining references in yaml, and in #7723, some of those
references moved, which broke the build

## Implementation details

Update the YAML file and rebuild

## Test coverage

If it builds, we're good!
andrewlock added a commit that referenced this pull request Nov 26, 2025
… config changes (#7796)

## Summary of changes

A fix for #7724 to handle telemetry reporting in dynamic config "reset"
scenarios

## Reason for change

The system tests for #7724 were failing in some dynamic configuration
scenarios. Specifically, the tests were sending remote config _without_
any configuration values "i.e. 'reset to use defaults'" and were waiting
a telemetry update. However, we never sent it, because there was "no
telemetry to record".

Note that we _did_ correctly apply the new configuration, we just didn't
report the telemetry correctly, primarily due to limitations in the
telemetry protocol. This PR adds a fix for that, and will be merged into
#7724.

## Implementation details

The solution is to "remember" the telemetry from the default mutable
configuration values, _without_ any dynamic sources, and "replay" this
telemetry when we update telemetry. This feels kind of hacky, but it's
something I suspected we might need to do, and had been avoiding up to
this point because we do a "full reconfigure" anyway.

## Test coverage

Added a specific unit test that mimics the behaviour of the system-test
(i.e. an "empty" dynamic config response) and confirms the telemetry is
recorded as expected

## Other details

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

Part of a config stack

- #7522
- #7525
- #7530
- #7532
- #7543
- #7544
- #7721
- #7722
- #7695
- #7723
- #7724
- #7796 👈

Unlike other PRs in the stack, I'll merge this directly into #7724 to
fix the tests there, just thought I'd keep this separate for easier
reviewing
andrewlock added a commit that referenced this pull request Nov 26, 2025
…building (#7724)

## Summary of changes

- This is the big one
- Update services to dynamically update when mutable settings or
exporter settings change
- Stop rebuilding everything when there's manual/remote configuration

## Reason for change

This is the "endpoint" that we've been heading for - services only being
disposed/rebuilt at the end of the app, and otherwise only rebuilding
the _necessary_ parts. For example - we don't need to tear down all the
API factories when a customer changes a global tag via remote config;
they only need to change if the `ExporterSettings` change.

The hope is that overall this reduces the overhead of using
configuration in code and/or remote configuration, while also reducing
the number of issues due to managing disposal of services.

## Implementation details

Overall, this PR is kind of a pain. Moving from the "rebuild everything"
to "reconfigure each service" couldn't be done piecemeal, so this is the
one-shot PR. What's more, different services need different patterns
(though we can probably consolidate some of them, this has taken a _lot_
of work and I likely changed patterns unnecessarily in some places).

In general, there's a couple of patterns:

- CI Vis doesn't let you change settings at runtime, so it _never_ needs
to respond to changes. It always just uses the "initial" settings
- Debugger _today_ doesn't respond to changes at runtime (except its own
dynamic config), so for now we ignore Debugger too as it's not really a
regression. I hope we can fix this soon though.
- I've introduced the concept of `Managed*` versions of some services
- These services generally "wrap" the existing type, delegating access
to the underlying service, and handling settings changes
- Many services only care about a sub-set of mutable settings, so they
only update if they need to
- Somewhat annoyingly, setting updates occur on a background thread, so
we need to be careful about thread safety. Where necessary (most places)
I've made sure access to a now-mutable service is done using
`Volatile.Read()` (to ensure changes are visible) and are generally
cached to a local variable (as the underlying field may be updated in
the background).

## Test coverage

In the vast majority of places, this should be covered by existing tests

I plan to add some additional integration tests around reconfiguring and
a bunch of manual testing to make sure I'm confident.

## Other details

I strongly recommend reviewing commit-by-commit. They're generally
self-contained, and hopefully simple enough to understand one commit at
a time.

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

Part of a config stack

- #7522
- #7525
- #7530
- #7532
- #7543
- #7544
- #7721
- #7722
- #7695
- #7723
- #7724 👈
- #7796

This isn't the final PR in the stack, as there will be a bunch of
cleaning up to do, but it's the final "implementation" PR
andrewlock added a commit that referenced this pull request Nov 27, 2025
## Summary of changes

Updates a couple of places where we're calling `Tracer.Instance` where
we don't need to

## Reason for change

In one of my other PRs I accidentally broke something that should _only_
have affected integration tests, but a bunch of unit tests broke. It
highlighted where they were using `Tracer.Instance` and setting the
global tracer for tests. In other places, it revealed that code that
tests that _looked_ independent of other tests really wasn't...

Calling `Tracer.Instance` potentially does a _lot_ of work, as it
initializes the tracer. It's also hard to follow if we're making static
calls out in places we don't need to. So just pass through the settings
we want instead.

## Implementation details

Instead of calling `Tracer.Instance.Settings`, use the value of `Tracer`
or `TracerSettings` that's already available wherever possible. It makes
the tests cleaner too.

## Test coverage

Same coverage, just a bit cleaner 

## Other details

Included as part of the config stack, just because I already refactored
some of this code, and can't be bothered to faff with merge conflicts:

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

- #7522
- #7525
- #7530
- #7532
- #7543
- #7544
- #7721
- #7722
- #7695
- #7723
- #7724
- #7744 👈
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

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.

8 participants