Skip to content

Conversation

@anna-git
Copy link
Contributor

@anna-git anna-git commented Oct 21, 2025

Context

Part of Configuration Inversion (Step 4) - Stack progress:

  1. #7548 - Add GitLab step and JSON configuration file
  2. #7688 - Cleanup configuration / platform keys + analyzers
  3. #7698 - Source generator for ConfigurationKeys
  4. #7689 - Aliases handling and analyzers (this PR)
  5. #7697 - Replace manual ConfigurationKeys with generated version

Summary

Adds source generator for configuration key aliases, integrates alias resolution into ConfigurationBuilder, and adds Roslyn analyzers to enforce proper configuration key usage.

Changes

Alias Source Generator:

  • ConfigKeyAliasesSwitcherGenerator reads aliases from supported-configurations.json
  • Auto-generates switch statements to resolve primary keys from aliases
  • Generated for all target frameworks (net461, netstandard2.0, netcoreapp3.1, net6.0)

ConfigurationBuilder Improvements:

  • Integrated alias resolution directly into ConfigurationBuilder.WithKeys()
  • Removed manual fallback overloads throughout codebase
  • Added GetKeyWithAlias() method to IConfigurationSource interface

IntegrationSettings Special Handling:

  • Updated to use pattern-based key construction (e.g., DD_TRACE_{INTEGRATION}_ENABLED)
  • Simplified configuration reading by leveraging alias system

Roslyn Analyzers:

  • DD0007: PlatformKeysAnalyzer - Enforces use of PlatformKeys for external platform environment variables
  • DD0008: ConfigurationBuilderWithKeysAnalyzer - Enforces use of ConfigurationKeys/PlatformKeys constants in ConfigurationBuilder.WithKeys() calls

Special Cases:

  • Fixed DatadogLoggingFactory to handle deprecated DD_TRACE_LOG_PATH with proper analyzer suppression
  • Updated configuration tests to work with alias resolution

Motivation

Completes configuration inversion by:

  • Auto-generating alias resolution from supported-configurations.json
  • Eliminating manual fallback chains
  • Enforcing compile-time validation of configuration keys
  • Preventing hardcoded strings and typos

Test Coverage

  • Added ConfigKeyAliasesSwitcherGeneratorTests with comprehensive test coverage
  • Added PlatformKeysAnalyzerTests with 146 lines of tests
  • Added ConfigurationBuilderWithKeysAnalyzerTests with 538 lines of tests
  • Updated existing configuration tests for alias support
  • All tests pass with new alias system

Related Work

Builds on #7548 (configuration registry), #7688 (PlatformKeys separation), and #7698 (source generator for ConfigurationKeys).

@anna-git anna-git marked this pull request as ready for review October 21, 2025 16:24
@anna-git anna-git requested review from a team as code owners October 21, 2025 16:24
@anna-git anna-git requested a review from link04 October 21, 2025 16:24
@anna-git anna-git changed the base branch from master to anna/config-inversion-configuration-aliases-switch-3 October 21, 2025 16:25
@anna-git anna-git marked this pull request as draft October 21, 2025 16:25
@anna-git anna-git changed the title anna/config-inversion-configuration-analyzers-4 [Config registry] Analyzers for ConfigurationBuilder, ConfigurationKeys, PlatformKeys Oct 21, 2025
@anna-git anna-git force-pushed the anna/config-inversion-configuration-aliases-switch-3 branch from be32003 to c983088 Compare October 21, 2025 16:41
@anna-git anna-git force-pushed the anna/config-inversion-configuration-analyzers-4 branch from acaf6cf to c1f7943 Compare October 21, 2025 16:42
@pr-commenter
Copy link

pr-commenter bot commented Oct 21, 2025

Benchmarks

Benchmarks Report for benchmark platform 🐌

Benchmarks for #7689 compared to master:

  • 1 benchmarks are faster, with geometric mean 1.139
  • 2 benchmarks are slower, with geometric mean 1.416
  • 7 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.7μs 58.9ns 372ns 0 0 0 5.52 KB
master StartStopWithChild netcoreapp3.1 14.1μs 70.5ns 299ns 0 0 0 5.73 KB
master StartStopWithChild net472 21.8μs 120ns 700ns 0.879 0.22 0 6.09 KB
#7689 StartStopWithChild net6.0 11μs 56.4ns 258ns 0 0 0 5.51 KB
#7689 StartStopWithChild netcoreapp3.1 13.4μs 69.8ns 349ns 0 0 0 5.71 KB
#7689 StartStopWithChild net472 21.8μs 114ns 569ns 0.874 0.219 0 6.1 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 88.7ns 332ns 0 0 0 2.71 KB
master WriteAndFlushEnrichedTraces netcoreapp3.1 1.05ms 254ns 916ns 0 0 0 2.7 KB
master WriteAndFlushEnrichedTraces net472 1.2ms 72.6ns 262ns 0 0 0 3.31 KB
#7689 WriteAndFlushEnrichedTraces net6.0 926μs 29ns 109ns 0 0 0 2.7 KB
#7689 WriteAndFlushEnrichedTraces netcoreapp3.1 1.04ms 176ns 680ns 0 0 0 2.7 KB
#7689 WriteAndFlushEnrichedTraces net472 1.2ms 850ns 3.29μs 0 0 0 3.31 KB
Benchmarks.Trace.Asm.AppSecBodyBenchmark - Unknown 🤷 Same allocations ✔️

Raw results

Branch Method Toolchain Mean StdError StdDev Gen 0 Gen 1 Gen 2 Allocated
master AllCycleSimpleBody net6.0 N/A N/A N/A NaN NaN NaN 0 b
master AllCycleSimpleBody netcoreapp3.1 N/A N/A N/A NaN NaN NaN 0 b
master AllCycleSimpleBody net472 N/A N/A N/A NaN NaN NaN 0 b
master AllCycleMoreComplexBody net6.0 N/A N/A N/A NaN NaN NaN 0 b
master AllCycleMoreComplexBody netcoreapp3.1 N/A N/A N/A NaN NaN NaN 0 b
master AllCycleMoreComplexBody net472 N/A N/A N/A NaN NaN NaN 0 b
master ObjectExtractorSimpleBody net6.0 317ns 1.78ns 10.7ns 0 0 0 280 B
master ObjectExtractorSimpleBody netcoreapp3.1 403ns 1.94ns 8.01ns 0 0 0 272 B
master ObjectExtractorSimpleBody net472 297ns 0.0342ns 0.133ns 0.0432 0 0 281 B
master ObjectExtractorMoreComplexBody net6.0 6.25μs 29.6ns 115ns 0 0 0 3.78 KB
master ObjectExtractorMoreComplexBody netcoreapp3.1 7.9μs 31.6ns 122ns 0 0 0 3.69 KB
master ObjectExtractorMoreComplexBody net472 6.68μs 8.12ns 31.4ns 0.602 0 0 3.8 KB
#7689 AllCycleSimpleBody net6.0 N/A N/A N/A NaN NaN NaN 0 b
#7689 AllCycleSimpleBody netcoreapp3.1 N/A N/A N/A NaN NaN NaN 0 b
#7689 AllCycleSimpleBody net472 N/A N/A N/A NaN NaN NaN 0 b
#7689 AllCycleMoreComplexBody net6.0 N/A N/A N/A NaN NaN NaN 0 b
#7689 AllCycleMoreComplexBody netcoreapp3.1 N/A N/A N/A NaN NaN NaN 0 b
#7689 AllCycleMoreComplexBody net472 N/A N/A N/A NaN NaN NaN 0 b
#7689 ObjectExtractorSimpleBody net6.0 335ns 1.84ns 10.9ns 0 0 0 280 B
#7689 ObjectExtractorSimpleBody netcoreapp3.1 396ns 2.26ns 15ns 0 0 0 272 B
#7689 ObjectExtractorSimpleBody net472 297ns 0.128ns 0.478ns 0.0441 0 0 281 B
#7689 ObjectExtractorMoreComplexBody net6.0 6.39μs 26.3ns 102ns 0 0 0 3.78 KB
#7689 ObjectExtractorMoreComplexBody netcoreapp3.1 7.73μs 27.5ns 107ns 0 0 0 3.69 KB
#7689 ObjectExtractorMoreComplexBody net472 6.69μs 0.854ns 3.2ns 0.601 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 75.9μs 202ns 783ns 0 0 0 32.4 KB
master EncodeArgs netcoreapp3.1 96.6μs 198ns 765ns 0 0 0 32.4 KB
master EncodeArgs net472 112μs 10.3ns 40ns 5.06 0 0 32.51 KB
master EncodeLegacyArgs net6.0 143μs 36.4ns 141ns 0 0 0 2.15 KB
master EncodeLegacyArgs netcoreapp3.1 201μs 718ns 2.78μs 0 0 0 2.14 KB
master EncodeLegacyArgs net472 263μs 15.7ns 54.3ns 0 0 0 2.16 KB
#7689 EncodeArgs net6.0 81.5μs 33.7ns 131ns 0 0 0 32.4 KB
#7689 EncodeArgs netcoreapp3.1 97.1μs 173ns 648ns 0 0 0 32.4 KB
#7689 EncodeArgs net472 110μs 51.6ns 200ns 4.96 0 0 32.51 KB
#7689 EncodeLegacyArgs net6.0 142μs 43.1ns 161ns 0 0 0 2.15 KB
#7689 EncodeLegacyArgs netcoreapp3.1 196μs 199ns 772ns 0 0 0 2.14 KB
#7689 EncodeLegacyArgs net472 263μs 23.1ns 86.4ns 0 0 0 2.16 KB
Benchmarks.Trace.Asm.AppSecWafBenchmark - Slower ⚠️ Same allocations ✔️

Slower ⚠️ in #7689

Benchmark diff/base Base Median (ns) Diff Median (ns) Modality
Benchmarks.Trace.Asm.AppSecWafBenchmark.RunWafRealisticBenchmarkWithAttack‑netcoreapp3.1 1.719 296,327.98 509,345.68

Raw results

Branch Method Toolchain Mean StdError StdDev Gen 0 Gen 1 Gen 2 Allocated
master RunWafRealisticBenchmark net6.0 399μs 74.4ns 278ns 0 0 0 4.55 KB
master RunWafRealisticBenchmark netcoreapp3.1 410μs 49.2ns 177ns 0 0 0 4.48 KB
master RunWafRealisticBenchmark net472 426μs 27.3ns 98.4ns 0 0 0 4.66 KB
master RunWafRealisticBenchmarkWithAttack net6.0 284μs 59.7ns 231ns 0 0 0 2.24 KB
master RunWafRealisticBenchmarkWithAttack netcoreapp3.1 297μs 408ns 1.58μs 0 0 0 2.22 KB
master RunWafRealisticBenchmarkWithAttack net472 309μs 24.8ns 95.9ns 0 0 0 2.29 KB
#7689 RunWafRealisticBenchmark net6.0 404μs 93.3ns 349ns 0 0 0 4.55 KB
#7689 RunWafRealisticBenchmark netcoreapp3.1 414μs 359ns 1.39μs 0 0 0 4.48 KB
#7689 RunWafRealisticBenchmark net472 436μs 110ns 425ns 0 0 0 4.66 KB
#7689 RunWafRealisticBenchmarkWithAttack net6.0 286μs 26.8ns 100ns 0 0 0 2.24 KB
#7689 RunWafRealisticBenchmarkWithAttack netcoreapp3.1 492μs 7.19μs 71.9μs 0 0 0 2.22 KB
#7689 RunWafRealisticBenchmarkWithAttack net472 318μs 30.7ns 119ns 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 60.6μs 76.1ns 295ns 0 0 0 14.52 KB
master SendRequest netcoreapp3.1 71.2μs 96.7ns 362ns 0 0 0 17.42 KB
master SendRequest net472 0.00505ns 0.00176ns 0.00682ns 0 0 0 0 b
#7689 SendRequest net6.0 60.9μs 51.8ns 201ns 0 0 0 14.52 KB
#7689 SendRequest netcoreapp3.1 71.1μs 59ns 228ns 0 0 0 17.42 KB
#7689 SendRequest net472 0.00753ns 0.00245ns 0.00948ns 0 0 0 0 b
Benchmarks.Trace.CharSliceBenchmark - Same speed ✔️ More allocations ⚠️

More allocations ⚠️ in #7689

Benchmark Base Allocated Diff Allocated Change Change %
Benchmarks.Trace.CharSliceBenchmark.OptimizedCharSliceWithPool‑net6.0 1 B 3 B 2 B 200.00%

Fewer allocations 🎉 in #7689

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

Raw results

Branch Method Toolchain Mean StdError StdDev Gen 0 Gen 1 Gen 2 Allocated
master OriginalCharSlice net6.0 1.9ms 4.97μs 18.6μs 0 0 0 640.01 KB
master OriginalCharSlice netcoreapp3.1 2.11ms 5.43μs 21μs 0 0 0 640 KB
master OriginalCharSlice net472 2.63ms 180ns 675ns 100 0 0 641.95 KB
master OptimizedCharSlice net6.0 1.43ms 343ns 1.33μs 0 0 0 6 B
master OptimizedCharSlice netcoreapp3.1 1.67ms 367ns 1.37μs 0 0 0 1 B
master OptimizedCharSlice net472 1.91ms 299ns 1.16μs 0 0 0 0 b
master OptimizedCharSliceWithPool net6.0 903μs 33.7ns 130ns 0 0 0 1 B
master OptimizedCharSliceWithPool netcoreapp3.1 812μs 117ns 454ns 0 0 0 1 B
master OptimizedCharSliceWithPool net472 1.14ms 84.4ns 316ns 0 0 0 0 b
#7689 OriginalCharSlice net6.0 1.92ms 842ns 3.04μs 0 0 0 640.01 KB
#7689 OriginalCharSlice netcoreapp3.1 2.14ms 655ns 2.27μs 0 0 0 640 KB
#7689 OriginalCharSlice net472 2.62ms 1.71μs 6.62μs 100 0 0 641.95 KB
#7689 OptimizedCharSlice net6.0 1.36ms 242ns 937ns 0 0 0 6 B
#7689 OptimizedCharSlice netcoreapp3.1 1.66ms 343ns 1.33μs 0 0 0 1 B
#7689 OptimizedCharSlice net472 1.95ms 298ns 1.15μs 0 0 0 0 b
#7689 OptimizedCharSliceWithPool net6.0 829μs 47.7ns 178ns 0 0 0 3 B
#7689 OptimizedCharSliceWithPool netcoreapp3.1 836μs 200ns 775ns 0 0 0 0 b
#7689 OptimizedCharSliceWithPool net472 1.14ms 154ns 557ns 0 0 0 0 b
Benchmarks.Trace.CIVisibilityProtocolWriterBenchmark - Faster 🎉 More allocations ⚠️

Faster 🎉 in #7689

Benchmark base/diff Base Median (ns) Diff Median (ns) Modality
Benchmarks.Trace.CIVisibilityProtocolWriterBenchmark.WriteAndFlushEnrichedTraces‑net472 1.139 1,029,175.83 903,637.50

More allocations ⚠️ in #7689

Benchmark Base Allocated Diff Allocated Change Change %
Benchmarks.Trace.CIVisibilityProtocolWriterBenchmark.WriteAndFlushEnrichedTraces‑net6.0 41.51 KB 41.84 KB 334 B 0.80%

Fewer allocations 🎉 in #7689

Benchmark Base Allocated Diff Allocated Change Change %
Benchmarks.Trace.CIVisibilityProtocolWriterBenchmark.WriteAndFlushEnrichedTraces‑netcoreapp3.1 42.11 KB 41.84 KB -277 B -0.66%
Benchmarks.Trace.CIVisibilityProtocolWriterBenchmark.WriteAndFlushEnrichedTraces‑net472 56.46 KB 55.76 KB -701 B -1.24%

Raw results

Branch Method Toolchain Mean StdError StdDev Gen 0 Gen 1 Gen 2 Allocated
master WriteAndFlushEnrichedTraces net6.0 749μs 4.34μs 34.7μs 0 0 0 41.51 KB
master WriteAndFlushEnrichedTraces netcoreapp3.1 682μs 697ns 2.7μs 0 0 0 42.11 KB
master WriteAndFlushEnrichedTraces net472 1.03ms 3.46μs 12.5μs 8.33 0 0 56.46 KB
#7689 WriteAndFlushEnrichedTraces net6.0 683μs 812ns 3.04μs 0 0 0 41.84 KB
#7689 WriteAndFlushEnrichedTraces netcoreapp3.1 657μs 1.35μs 4.68μs 0 0 0 41.84 KB
#7689 WriteAndFlushEnrichedTraces net472 908μs 4μs 15μs 4.46 0 0 55.76 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 8.5ns 36.1ns 0 0 0 1.02 KB
master ExecuteNonQuery netcoreapp3.1 2.57μs 9.83ns 38.1ns 0 0 0 1.02 KB
master ExecuteNonQuery net472 2.93μs 14.5ns 61.6ns 0.144 0.0144 0 987 B
#7689 ExecuteNonQuery net6.0 1.9μs 9.77ns 43.7ns 0 0 0 1.02 KB
#7689 ExecuteNonQuery netcoreapp3.1 2.75μs 9.15ns 35.5ns 0 0 0 1.02 KB
#7689 ExecuteNonQuery net472 3.01μs 6.44ns 25ns 0.148 0.0148 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.67μs 8.19ns 34.7ns 0 0 0 1.03 KB
master CallElasticsearch netcoreapp3.1 2.26μs 11.4ns 49.6ns 0 0 0 1.03 KB
master CallElasticsearch net472 3.76μs 3.38ns 13.1ns 0.15 0 0 1.04 KB
master CallElasticsearchAsync net6.0 1.87μs 1.53ns 5.91ns 0 0 0 1.01 KB
master CallElasticsearchAsync netcoreapp3.1 2.34μs 3.99ns 15.5ns 0 0 0 1.08 KB
master CallElasticsearchAsync net472 3.75μs 6.56ns 25.4ns 0.168 0 0 1.1 KB
#7689 CallElasticsearch net6.0 1.7μs 8.53ns 40ns 0 0 0 1.03 KB
#7689 CallElasticsearch netcoreapp3.1 2.24μs 6.73ns 25.2ns 0 0 0 1.03 KB
#7689 CallElasticsearch net472 3.45μs 4.25ns 16.5ns 0.157 0 0 1.04 KB
#7689 CallElasticsearchAsync net6.0 1.86μs 5.17ns 20ns 0 0 0 1.01 KB
#7689 CallElasticsearchAsync netcoreapp3.1 2.41μs 8.25ns 32ns 0 0 0 1.08 KB
#7689 CallElasticsearchAsync net472 3.76μs 2.71ns 10.5ns 0.169 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.91μs 9.31ns 38.4ns 0 0 0 952 B
master ExecuteAsync netcoreapp3.1 2.43μs 10.1ns 39.1ns 0 0 0 952 B
master ExecuteAsync net472 2.52μs 0.816ns 2.94ns 0.138 0 0 915 B
#7689 ExecuteAsync net6.0 1.91μs 9.07ns 36.3ns 0 0 0 952 B
#7689 ExecuteAsync netcoreapp3.1 2.53μs 3.04ns 11ns 0 0 0 952 B
#7689 ExecuteAsync net472 2.71μs 8.01ns 31ns 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.82μs 6.43ns 24.9ns 0 0 0 2.36 KB
master SendAsync netcoreapp3.1 8.43μs 28.5ns 111ns 0 0 0 2.9 KB
master SendAsync net472 12.5μs 12.1ns 46.7ns 0.5 0 0 3.18 KB
#7689 SendAsync net6.0 7.01μs 13.7ns 52.9ns 0 0 0 2.36 KB
#7689 SendAsync netcoreapp3.1 8.51μs 28.7ns 111ns 0 0 0 2.9 KB
#7689 SendAsync net472 12.4μs 10.5ns 40.7ns 0.493 0 0 3.18 KB
Benchmarks.Trace.Iast.StringAspectsBenchmark - Slower ⚠️ More allocations ⚠️

Slower ⚠️ in #7689

Benchmark diff/base Base Median (ns) Diff Median (ns) Modality
Benchmarks.Trace.Iast.StringAspectsBenchmark.StringConcatAspectBenchmark‑net6.0 1.167 454,600.00 530,500.00

More allocations ⚠️ in #7689

Benchmark Base Allocated Diff Allocated Change Change %
Benchmarks.Trace.Iast.StringAspectsBenchmark.StringConcatAspectBenchmark‑net6.0 259.18 KB 279.89 KB 20.7 KB 7.99%

Fewer allocations 🎉 in #7689

Benchmark Base Allocated Diff Allocated Change Change %
Benchmarks.Trace.Iast.StringAspectsBenchmark.StringConcatAspectBenchmark‑net472 279.7 KB 274.08 KB -5.62 KB -2.01%
Benchmarks.Trace.Iast.StringAspectsBenchmark.StringConcatBenchmark‑netcoreapp3.1 44.72 KB 42.64 KB -2.08 KB -4.65%
Benchmarks.Trace.Iast.StringAspectsBenchmark.StringConcatAspectBenchmark‑netcoreapp3.1 275.55 KB 255.05 KB -20.5 KB -7.44%
Benchmarks.Trace.Iast.StringAspectsBenchmark.StringConcatBenchmark‑net6.0 48.46 KB 43.87 KB -4.59 KB -9.48%

Raw results

Branch Method Toolchain Mean StdError StdDev Gen 0 Gen 1 Gen 2 Allocated
master StringConcatBenchmark net6.0 46.1μs 259ns 1.7μs 0 0 0 48.46 KB
master StringConcatBenchmark netcoreapp3.1 46.3μs 205ns 1.14μs 0 0 0 44.72 KB
master StringConcatBenchmark net472 56.9μs 238ns 922ns 0 0 0 65.54 KB
master StringConcatAspectBenchmark net6.0 457μs 1.5μs 7.05μs 0 0 0 259.18 KB
master StringConcatAspectBenchmark netcoreapp3.1 510μs 2.1μs 7.28μs 0 0 0 275.55 KB
master StringConcatAspectBenchmark net472 404μs 1.98μs 13.4μs 0 0 0 279.7 KB
#7689 StringConcatBenchmark net6.0 42μs 207ns 903ns 0 0 0 43.87 KB
#7689 StringConcatBenchmark netcoreapp3.1 49.4μs 252ns 2.03μs 0 0 0 42.64 KB
#7689 StringConcatBenchmark net472 57.4μs 209ns 755ns 0 0 0 65.54 KB
#7689 StringConcatAspectBenchmark net6.0 533μs 2.32μs 11.1μs 0 0 0 279.89 KB
#7689 StringConcatAspectBenchmark netcoreapp3.1 484μs 1.38μs 5.17μs 0 0 0 255.05 KB
#7689 StringConcatAspectBenchmark net472 404μs 2.2μs 12.2μs 0 0 0 274.08 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.66μs 12.4ns 49.6ns 0 0 0 1.7 KB
master EnrichedLog netcoreapp3.1 3.67μs 2.02ns 7.83ns 0 0 0 1.7 KB
master EnrichedLog net472 3.84μs 3.3ns 12.8ns 0.25 0 0 1.64 KB
#7689 EnrichedLog net6.0 2.66μs 12.3ns 47.6ns 0 0 0 1.7 KB
#7689 EnrichedLog netcoreapp3.1 3.69μs 17.7ns 70.8ns 0 0 0 1.7 KB
#7689 EnrichedLog net472 4.11μs 6.03ns 23.4ns 0.247 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 106ns 381ns 0 0 0 4.31 KB
master EnrichedLog netcoreapp3.1 128μs 412ns 1.48μs 0 0 0 4.31 KB
master EnrichedLog net472 167μs 49ns 183ns 0 0 0 4.52 KB
#7689 EnrichedLog net6.0 122μs 124ns 430ns 0 0 0 4.31 KB
#7689 EnrichedLog netcoreapp3.1 127μs 199ns 718ns 0 0 0 4.31 KB
#7689 EnrichedLog net472 167μs 169ns 633ns 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.91μs 23.3ns 98.8ns 0 0 0 2.26 KB
master EnrichedLog netcoreapp3.1 6.76μs 27ns 105ns 0 0 0 2.26 KB
master EnrichedLog net472 7.56μs 5.6ns 20.9ns 0.303 0 0 2.08 KB
#7689 EnrichedLog net6.0 5.22μs 23.6ns 91.4ns 0 0 0 2.26 KB
#7689 EnrichedLog netcoreapp3.1 6.68μs 22.7ns 88ns 0 0 0 2.26 KB
#7689 EnrichedLog net472 7.76μs 6.54ns 25.3ns 0.309 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.05μs 10.1ns 41.7ns 0 0 0 1.2 KB
master SendReceive netcoreapp3.1 2.68μs 13.8ns 61.6ns 0 0 0 1.2 KB
master SendReceive net472 3.1μs 1.36ns 4.91ns 0.185 0 0 1.2 KB
#7689 SendReceive net6.0 2.08μs 8.18ns 31.7ns 0 0 0 1.2 KB
#7689 SendReceive netcoreapp3.1 2.65μs 7.8ns 30.2ns 0 0 0 1.2 KB
#7689 SendReceive net472 3.07μs 5.2ns 20.2ns 0.185 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.26μs 7.92ns 30.7ns 0 0 0 1.58 KB
master EnrichedLog netcoreapp3.1 5.53μs 12.6ns 48.9ns 0 0 0 1.63 KB
master EnrichedLog net472 6.54μs 5.46ns 20.4ns 0.292 0 0 2.03 KB
#7689 EnrichedLog net6.0 4.44μs 13.9ns 51.9ns 0 0 0 1.58 KB
#7689 EnrichedLog netcoreapp3.1 5.48μs 12.6ns 48.7ns 0 0 0 1.63 KB
#7689 EnrichedLog net472 6.52μs 7.99ns 30.9ns 0.293 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 786ns 4.1ns 20.1ns 0 0 0 576 B
master StartFinishSpan netcoreapp3.1 941ns 5.08ns 26.9ns 0 0 0 576 B
master StartFinishSpan net472 952ns 0.193ns 0.723ns 0.0905 0 0 578 B
master StartFinishScope net6.0 925ns 4.37ns 17.5ns 0 0 0 696 B
master StartFinishScope netcoreapp3.1 1.18μs 6.36ns 35.4ns 0 0 0 696 B
master StartFinishScope net472 1.13μs 0.625ns 2.42ns 0.102 0 0 658 B
#7689 StartFinishSpan net6.0 788ns 0.256ns 0.99ns 0 0 0 576 B
#7689 StartFinishSpan netcoreapp3.1 979ns 4.85ns 22.8ns 0 0 0 576 B
#7689 StartFinishSpan net472 933ns 0.427ns 1.65ns 0.0892 0 0 578 B
#7689 StartFinishScope net6.0 921ns 4.7ns 25.8ns 0 0 0 696 B
#7689 StartFinishScope netcoreapp3.1 1.18μs 6.09ns 27.2ns 0 0 0 696 B
#7689 StartFinishScope net472 1.17μs 0.905ns 3.5ns 0.0998 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.05μs 0.494ns 1.85ns 0 0 0 696 B
master RunOnMethodBegin netcoreapp3.1 1.4μs 5.24ns 20.3ns 0 0 0 696 B
master RunOnMethodBegin net472 1.43μs 0.494ns 1.91ns 0.1 0 0 658 B
#7689 RunOnMethodBegin net6.0 1.09μs 0.344ns 1.24ns 0 0 0 696 B
#7689 RunOnMethodBegin netcoreapp3.1 1.41μs 6.94ns 28.6ns 0 0 0 696 B
#7689 RunOnMethodBegin net472 1.47μs 1.74ns 6.72ns 0.102 0 0 658 B

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

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

Execution-Time Benchmarks Report ⏱️

Execution-time results for samples comparing the following branches/commits:

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 shown 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).

gantt
    title Execution time (ms) FakeDbCommand (.NET Framework 4.8) 
    dateFormat  X
    axisFormat %s
    todayMarker off
    section Bailout
    This PR (7689) - mean (78ms)  : 75, 82
     .   : milestone, 78,
    master - mean (79ms)  : 76, 82
     .   : milestone, 79,

    section Baseline
    This PR (7689) - mean (74ms)  : 71, 77
     .   : milestone, 74,
    master - mean (75ms)  : 73, 78
     .   : milestone, 75,

    section CallTarget+Inlining+NGEN
    This PR (7689) - mean (1,109ms)  : 1049, 1169
     .   : milestone, 1109,
    master - mean (1,104ms)  : 1052, 1155
     .   : milestone, 1104,

Loading
gantt
    title Execution time (ms) FakeDbCommand (.NET Core 3.1) 
    dateFormat  X
    axisFormat %s
    todayMarker off
    section Bailout
    This PR (7689) - mean (116ms)  : 113, 119
     .   : milestone, 116,
    master - mean (118ms)  : 114, 121
     .   : milestone, 118,

    section Baseline
    This PR (7689) - mean (116ms)  : 113, 119
     .   : milestone, 116,
    master - mean (116ms)  : 112, 121
     .   : milestone, 116,

    section CallTarget+Inlining+NGEN
    This PR (7689) - mean (796ms)  : 764, 827
     .   : milestone, 796,
    master - mean (789ms)  : 757, 821
     .   : milestone, 789,

Loading
gantt
    title Execution time (ms) FakeDbCommand (.NET 6) 
    dateFormat  X
    axisFormat %s
    todayMarker off
    section Bailout
    This PR (7689) - mean (104ms)  : 101, 107
     .   : milestone, 104,
    master - mean (104ms)  : 101, 107
     .   : milestone, 104,

    section Baseline
    This PR (7689) - mean (103ms)  : 100, 106
     .   : milestone, 103,
    master - mean (103ms)  : 100, 107
     .   : milestone, 103,

    section CallTarget+Inlining+NGEN
    This PR (7689) - mean (752ms)  : 713, 791
     .   : milestone, 752,
    master - mean (744ms)  : 718, 770
     .   : milestone, 744,

Loading
gantt
    title Execution time (ms) FakeDbCommand (.NET 8) 
    dateFormat  X
    axisFormat %s
    todayMarker off
    section Bailout
    This PR (7689) - mean (101ms)  : 99, 104
     .   : milestone, 101,
    master - mean (105ms)  : 98, 112
     .   : milestone, 105,

    section Baseline
    This PR (7689) - mean (101ms)  : 98, 104
     .   : milestone, 101,
    master - mean (103ms)  : 98, 107
     .   : milestone, 103,

    section CallTarget+Inlining+NGEN
    This PR (7689) - mean (703ms)  : 685, 722
     .   : milestone, 703,
    master - mean (710ms)  : 693, 727
     .   : milestone, 710,

Loading
gantt
    title Execution time (ms) HttpMessageHandler (.NET Framework 4.8) 
    dateFormat  X
    axisFormat %s
    todayMarker off
    section Bailout
    This PR (7689) - mean (196ms)  : 193, 199
     .   : milestone, 196,
    master - mean (196ms)  : 193, 199
     .   : milestone, 196,

    section Baseline
    This PR (7689) - mean (192ms)  : 189, 196
     .   : milestone, 192,
    master - mean (194ms)  : 190, 198
     .   : milestone, 194,

    section CallTarget+Inlining+NGEN
    This PR (7689) - mean (1,185ms)  : 1110, 1261
     .   : milestone, 1185,
    master - mean (1,161ms)  : 1110, 1212
     .   : milestone, 1161,

Loading
gantt
    title Execution time (ms) HttpMessageHandler (.NET Core 3.1) 
    dateFormat  X
    axisFormat %s
    todayMarker off
    section Bailout
    This PR (7689) - mean (277ms)  : 271, 282
     .   : milestone, 277,
    master - mean (279ms)  : 274, 284
     .   : milestone, 279,

    section Baseline
    This PR (7689) - mean (276ms)  : 272, 280
     .   : milestone, 276,
    master - mean (279ms)  : 273, 285
     .   : milestone, 279,

    section CallTarget+Inlining+NGEN
    This PR (7689) - mean (952ms)  : 896, 1007
     .   : milestone, 952,
    master - mean (956ms)  : 912, 1000
     .   : milestone, 956,

Loading
gantt
    title Execution time (ms) HttpMessageHandler (.NET 6) 
    dateFormat  X
    axisFormat %s
    todayMarker off
    section Bailout
    This PR (7689) - mean (269ms)  : 265, 273
     .   : milestone, 269,
    master - mean (270ms)  : 266, 275
     .   : milestone, 270,

    section Baseline
    This PR (7689) - mean (268ms)  : 264, 273
     .   : milestone, 268,
    master - mean (270ms)  : 264, 276
     .   : milestone, 270,

    section CallTarget+Inlining+NGEN
    This PR (7689) - mean (937ms)  : 882, 993
     .   : milestone, 937,
    master - mean (928ms)  : 882, 973
     .   : milestone, 928,

Loading
gantt
    title Execution time (ms) HttpMessageHandler (.NET 8) 
    dateFormat  X
    axisFormat %s
    todayMarker off
    section Bailout
    This PR (7689) - mean (268ms)  : 265, 272
     .   : milestone, 268,
    master - mean (271ms)  : 266, 277
     .   : milestone, 271,

    section Baseline
    This PR (7689) - mean (267ms)  : 263, 272
     .   : milestone, 267,
    master - mean (270ms)  : 266, 274
     .   : milestone, 270,

    section CallTarget+Inlining+NGEN
    This PR (7689) - mean (855ms)  : 832, 878
     .   : milestone, 855,
    master - mean (856ms)  : 839, 873
     .   : milestone, 856,

Loading

@anna-git anna-git changed the title [Config registry] Analyzers for ConfigurationBuilder, ConfigurationKeys, PlatformKeys [ConfigRegistry] Analyzers for platform and ConfigurationBuilder Oct 22, 2025
@anna-git anna-git force-pushed the anna/config-inversion-configuration-aliases-switch-3 branch from c983088 to 9e2a61b Compare October 22, 2025 17:26
@anna-git anna-git force-pushed the anna/config-inversion-configuration-analyzers-4 branch from c1f7943 to 56bd199 Compare October 22, 2025 17:26
@anna-git anna-git force-pushed the anna/config-inversion-configuration-aliases-switch-3 branch 2 times, most recently from f242046 to 153e7b3 Compare October 22, 2025 18:14
@anna-git anna-git force-pushed the anna/config-inversion-configuration-analyzers-4 branch from 56bd199 to e52fd10 Compare October 22, 2025 18:14
@anna-git anna-git force-pushed the anna/config-inversion-configuration-aliases-switch-3 branch from 153e7b3 to bd34118 Compare October 22, 2025 18:27
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".

Comment on lines +22 to +39
public HasKeys WithIntegrationKey(string integrationName) => new(
_source,
_telemetry,
string.Format(IntegrationSettings.IntegrationEnabledKey, integrationName.ToUpperInvariant()),
[
string.Format(IntegrationSettings.IntegrationEnabledKey, integrationName),
$"DD_{integrationName}_ENABLED"
]);

public HasKeys WithIntegrationAnalyticsKey(string integrationName) => new(
_source,
_telemetry,
#pragma warning disable 618 // App analytics is deprecated, but still used
string.Format(IntegrationSettings.AnalyticsEnabledKey, integrationName.ToUpperInvariant()),
[
string.Format(IntegrationSettings.AnalyticsEnabledKey, integrationName),
#pragma warning restore 618
$"DD_{integrationName}_ANALYTICS_ENABLED"

Choose a reason for hiding this comment

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

P1 Badge Uppercase integration aliases to preserve DD_ compatibility*

The new integration helpers build alias keys using the raw integrationName string (string.Format(..., integrationName) and "DD_{integrationName}_ENABLED"). For most integrations that value is mixed‑case (e.g., Kafka, AspNetCore). On Linux and other case‑sensitive configuration sources, these aliases will no longer match the documented uppercase aliases such as DD_KAFKA_ENABLED or DD_ASPNETCORE_ENABLED, so existing deployments relying on the legacy keys will stop working. The main key still resolves because it’s uppercased, but the alias is effectively broken. Consider uppercasing the alias strings (integrationName.ToUpperInvariant()) so the fallback works regardless of platform casing.

Useful? React with 👍 / 👎.

Copy link
Member

Choose a reason for hiding this comment

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

I'm not sure this makes sense to me - AFAICT what you have today is correct 🤔

@anna-git anna-git force-pushed the anna/config-inversion-configuration-aliases-switch-3 branch from a31063c to 1d5b555 Compare October 27, 2025 14:20
@anna-git anna-git force-pushed the anna/config-inversion-configuration-analyzers-4 branch from 59b8625 to acdece9 Compare October 27, 2025 14:20
@anna-git anna-git force-pushed the anna/config-inversion-configuration-aliases-switch-3 branch from 1d5b555 to 5018466 Compare October 27, 2025 19:21
@anna-git anna-git force-pushed the anna/config-inversion-configuration-analyzers-4 branch from acdece9 to 86d6dbd Compare October 27, 2025 19:21
@anna-git anna-git force-pushed the anna/config-inversion-configuration-aliases-switch-3 branch from 5018466 to 783a308 Compare October 27, 2025 20:56
@anna-git anna-git force-pushed the anna/config-inversion-configuration-analyzers-4 branch from 86d6dbd to fc26b53 Compare October 27, 2025 20:56
@anna-git anna-git force-pushed the anna/config-inversion-configuration-aliases-switch-3 branch from 783a308 to aa52b7f Compare October 28, 2025 14:33
@anna-git anna-git force-pushed the anna/config-inversion-configuration-analyzers-4 branch from fc26b53 to cc850d6 Compare October 28, 2025 14:33
@anna-git anna-git force-pushed the anna/config-inversion-configuration-aliases-switch-3 branch from aa52b7f to 0c28972 Compare October 28, 2025 14:55
@anna-git anna-git force-pushed the anna/config-inversion-configuration-analyzers-4 branch from cc850d6 to 2a09875 Compare October 28, 2025 14:55
anna-git added a commit that referenced this pull request Oct 28, 2025
… yaml for doc (#7548)

## Context

Part of **Configuration Inversion (Step 1)** - Stack progress:
1. **→ [#7548](#7548) -
Add GitLab step and JSON configuration file (this PR)**
2. [#7688](#7688) -
Reorganize keys, split config keys and platform keys
3. [#7698](#7698) -
Generate ConfigurationKeys with source generator
4. [#7689](#7689) -
Aliases handling and analyzers
5. [#7697](#7697) -
Replace manual ConfigurationKeys by generated ones in the whole solution



## Summary

Adds centralized configuration registry (`supported-configurations.json`
+
[supported-configurations-docs.yaml](cci:7://file:///Users/anna.yafi/go/src/github.com/DataDog/dd-trace-dotnet3/tracer/src/Datadog.Trace/Configuration/supported-configurations-docs.yaml:0:0-0:0))
containing ~280 configuration keys with automated GitLab CI validation.

## Changes

**Configuration Files:**
- `supported-configurations.json` - Machine-readable registry of all
configuration keys with versions, aliases, and deprecations
-
[supported-configurations-docs.yaml](cci:7://file:///Users/anna.yafi/go/src/github.com/DataDog/dd-trace-dotnet3/tracer/src/Datadog.Trace/Configuration/supported-configurations-docs.yaml:0:0-0:0)
- Human-readable documentation for each configuration key

**CI/CD:**
- Added `validate_supported_configurations_local_file` step to
`.gitlab-ci.yml`
- Updated `.gitlab/one-pipeline.locked.yaml` to reference validation
template

**File Structure:**
```json
{
  "supportedConfigurations": { "DD_TRACE_ENABLED": { "version": ["A"] }, ... },
  "aliases": { "DD_AGENT_HOST": ["DD_TRACE_AGENT_HOSTNAME", ...], ... },
  "deprecations": { "DD_TRACE_ANALYTICS_ENABLED": "Deprecated - ...", ... }
}
```

## Motivation

Provides single source of truth for configuration keys to enable:
- Automated documentation validation
- Cross-tracer compatibility checks
- Configuration migration tooling
- Automated doc generation

See: [Configuration Registry Design
Doc](https://docs.google.com/document/d/1VIvOyQPfuQIWBIgNY68A9hzLir0-3eJijTwmpWASO8s/edit?tab=t.0#heading=h.jy2ajbk2b8ba)

## Validation

GitLab CI validates JSON structure, naming conventions, and schema
compliance on every build.

## Commit Details

**`2639cf0` - Initial Configuration Registry**
- Added `supported-configurations.json` with ~280 configuration keys
organized by version (A/B/C)
- Includes `aliases` section mapping primary keys to
deprecated/alternative names
- Includes `deprecations` section with deprecation messages
- Added GitLab CI validation step to ensure file integrity
- Updated one-pipeline lock file to reference validation template

**`70e632e` - Configuration Documentation**
- Added
[supported-configurations-docs.yaml](cci:7://file:///Users/anna.yafi/go/src/github.com/DataDog/dd-trace-dotnet3/tracer/src/Datadog.Trace/Configuration/supported-configurations-docs.yaml:0:0-0:0)
with detailed XML documentation for each configuration key
- Provides human-readable descriptions, default values, and usage
examples
- Includes `<seealso>` references to relevant code classes
- Complements the machine-readable JSON with developer-friendly
documentation
- Enables automated generation of configuration documentation from a
single source
Copy link
Member

@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.

Nice work 👍

var aliasSection = additionalText.Collect()
.Select(static (files, ct) =>
{
if (files.Length == 0)
Copy link
Member

Choose a reason for hiding this comment

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

I'm not sure this will ever fire 🤔 Given we filter out non-matching texts, I don't think it will. So we can probably just remove the Collect, remove the diagnostic, and make this Select operate on a single file

#pragma warning disable 618 // ProfilerLogPath is deprecated but still supported
var nativeLogFile = config.WithKeys(ConfigurationKeys.ProfilerLogPath).AsString();
#pragma warning restore 618
// ProfilerLogPath is deprecated but still supported. For now, we bypass the WithKeys analyzer, but later we want to pull deprecations differently as part of centralized file
Copy link
Member

Choose a reason for hiding this comment

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

Later, as in later in this config stack, or as in after that?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

later as later in config registry v2 😅

Comment on lines +22 to +39
public HasKeys WithIntegrationKey(string integrationName) => new(
_source,
_telemetry,
string.Format(IntegrationSettings.IntegrationEnabledKey, integrationName.ToUpperInvariant()),
[
string.Format(IntegrationSettings.IntegrationEnabledKey, integrationName),
$"DD_{integrationName}_ENABLED"
]);

public HasKeys WithIntegrationAnalyticsKey(string integrationName) => new(
_source,
_telemetry,
#pragma warning disable 618 // App analytics is deprecated, but still used
string.Format(IntegrationSettings.AnalyticsEnabledKey, integrationName.ToUpperInvariant()),
[
string.Format(IntegrationSettings.AnalyticsEnabledKey, integrationName),
#pragma warning restore 618
$"DD_{integrationName}_ANALYTICS_ENABLED"
Copy link
Member

Choose a reason for hiding this comment

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

I'm not sure this makes sense to me - AFAICT what you have today is correct 🤔

Comment on lines 506 to 510
{
var result = selector(Source, Key, Telemetry, validator, recordValue);
if (result.ShouldFallBack && FallbackKey1 is not null)
{
result = selector(Source, FallbackKey1, Telemetry, validator, recordValue);
}

if (result.ShouldFallBack && FallbackKey2 is not null)
{
result = selector(Source, FallbackKey2, Telemetry, validator, recordValue);
}

if (result.ShouldFallBack && FallbackKey3 is not null)
{
result = selector(Source, FallbackKey3, Telemetry, validator, recordValue);
}

return result;
var source = Source;
var telemetry = Telemetry;
return GetResultWithFallback(key => selector(source, key, telemetry, validator, recordValue));
}
Copy link
Member

Choose a reason for hiding this comment

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

nit: can probably just simplify these calls. There's a typo on key though that definitely needs to be fixed (otherwise you're accessing the constructor parameter)

        private ConfigurationResult<T> GetResult<T>(Func<IConfigurationSource, string, IConfigurationTelemetry, Func<T, bool>?, bool, ConfigurationResult<T>> selector, Func<T, bool>? validator, bool recordValue)
            => GetResultWithFallback(key => selector(Source, Key, Telemetry, validator, recordValue));

public HasKeys WithKeys(string key, string fallbackKey1, string fallbackKey2, string fallbackKey3) => new(_source, _telemetry, key, fallbackKey1, fallbackKey2, fallbackKey3);

internal readonly struct HasKeys
public HasKeys WithIntegrationKey(string integrationName) => new(
Copy link
Member

Choose a reason for hiding this comment

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

Such a pain 😅 Part of me wonders if instead of doing string.Format() here, we should have a source-generated mapping from integrationName => keys, but that's totally separate, and something we can investigate later to see if it improves perf


// Filter out tags with empty keys or empty values, and trim whitespaces
var headerTags = InitializeHeaderTags(config, ConfigurationKeys.HeaderTags, headerTagsNormalizationFixEnabled) ?? ReadOnlyDictionary.Empty;
var headerTags = InitializeHeaderTags(config.WithKeys(ConfigurationKeys.HeaderTags), headerTagsNormalizationFixEnabled) ?? ReadOnlyDictionary.Empty;
Copy link
Member

Choose a reason for hiding this comment

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

Example of at callsite:

Suggested change
var headerTags = InitializeHeaderTags(config.WithKeys(ConfigurationKeys.HeaderTags), headerTagsNormalizationFixEnabled) ?? ReadOnlyDictionary.Empty;
var headerTagsConfig = config.WithKeys(ConfigurationKeys.HeaderTags);
var headerTags = InitializeHeaderTags(in headerTagsConfig, headerTagsNormalizationFixEnabled) ?? ReadOnlyDictionary.Empty;

.AsBool(defaultValue: false);

var httpServerErrorStatusCodesString = config
#pragma warning disable 618 // This config key has been replaced but may still be used
Copy link
Member

Choose a reason for hiding this comment

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

ooh, that's a nice benefit where only the aliases are deprecated

Comment on lines +1376 to +1390
internal bool IsErrorStatusCode(int statusCode, bool serverStatusCode)
=> MutableSettings.IsErrorStatusCode(statusCode, serverStatusCode);

internal bool IsIntegrationEnabled(IntegrationId integration, bool defaultValue = true)
=> MutableSettings.IsIntegrationEnabled(integration, defaultValue);

[Obsolete(DeprecationMessages.AppAnalytics)]
internal double? GetIntegrationAnalyticsSampleRate(IntegrationId integration, bool enabledWithGlobalSetting)
=> MutableSettings.GetIntegrationAnalyticsSampleRate(integration, enabledWithGlobalSetting);
Copy link
Member

Choose a reason for hiding this comment

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

Do we need to add these here? 🤔

Comment on lines +29 to +33
return new string[]
{
"DATADOG_TRACE_AGENT_HOSTNAME",
"DD_TRACE_AGENT_HOSTNAME"
};
Copy link
Member

Choose a reason for hiding this comment

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

IMO we should update the source generator to use a switch expression and to use collection expressions so that it looks like this:

public static string[] GetAliases(string mainKey)
    => mainKey switch
    {
        "DD_AGENT_HOST" => [ "DATADOG_TRACE_AGENT_HOSTNAME", "DD_TRACE_AGENT_HOSTNAME" ],
        // the rest
        _ => [],
    };

Comment on lines -38 to +39
data.Add(kvp.Key, kvp.Value?.ToString());
// use FormattableString.Invariant as europeans might have 1.23.ToString()=1,23 which makes tests fail
data.Add(kvp.Key, kvp.Value is null ? null : FormattableString.Invariant($"{kvp.Value}"));
Copy link
Member

Choose a reason for hiding this comment

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

TIL about FormattableString

@anna-git anna-git force-pushed the anna/config-inversion-configuration-aliases-switch-3 branch from 0c28972 to bea714d Compare October 29, 2025 17:15
@anna-git anna-git force-pushed the anna/config-inversion-configuration-analyzers-4 branch from 2a09875 to 279b292 Compare October 29, 2025 17:15
@anna-git anna-git force-pushed the anna/config-inversion-configuration-aliases-switch-3 branch from bea714d to a6668f3 Compare October 29, 2025 17:48
@anna-git anna-git force-pushed the anna/config-inversion-configuration-analyzers-4 branch from 279b292 to 9860a88 Compare October 29, 2025 17:49
anna-git added a commit that referenced this pull request Oct 30, 2025
… keys (#7688)

## Context

Part of **Configuration Inversion (Step 2)** - Stack progress:
1. [#7548](#7548) - Add
GitLab step and JSON configuration file
2. **→ [#7688](#7688) -
[Config registry] Reorganize keys, split config keys and platform
keys(this PR)**
3. [#7698](#7698) -
Generate ConfigurationKeys with source generator
4. [#7689](#7689) -
Aliases handling and analyzers
5. [#7697](#7697) -
Replace manual ConfigurationKeys by generated ones in the whole solution
## Summary

Separates platform-specific environment variables into `PlatformKeys`
class and adds Roslyn analyzers to enforce proper usage of configuration
keys throughout the codebase.

## Changes

**Platform Keys Separation:**
- Created `PlatformKeys` class for external platform environment
variables (AWS, Azure, GCP, Kubernetes, CLR Profiler), those that don't
start with DD_ and come from other platforms.
- Updated all references throughout codebase to use `PlatformKeys` for
platform-specific variables
- Keeps `ConfigurationKeys` focused only on Datadog configuration

**Roslyn Analyzers:**
- **DD0007**: Platform key analyzer - Enforces use of `PlatformKeys` for
external platform environment variables
- **DD0008**: ConfigurationBuilder analyzer - Enforces use of
`ConfigurationKeys` or `PlatformKeys` constants in
`ConfigurationBuilder.WithKeys()` calls
- Prevents hardcoded strings and ensures type safety

**Configuration Mapping:**
- Added `configuration_keys_mapping.json` to map environment variable
names to their `ConfigurationKeys` constant names, so that we avoid
renaming hundreds of variables according to automatically source
generated deducted ones.
- Enables preservation of original constant names during refactoring
- Supports source generator integration

**Code Updates:**
- Updated `TracerSettings`, test files, and profiler code to use
`PlatformKeys`
- Replaced manual `ConfigurationKeys` with generated version from
`supported-configurations.json`
- Added missing `DD_TRACE_LOG_PATH` to configuration registry

## Motivation

Ensures clean separation between Datadog and platform configuration by:
- Preventing accidental mixing of platform and Datadog keys
- Enforcing compile-time validation of configuration key usage
- Making it clear which keys are owned by Datadog vs external platforms
- Catching configuration errors at build time instead of runtime

## Validation

- Roslyn analyzers run on every build
- All existing tests pass with updated key references
- Analyzers report clear diagnostic messages for violations

## Related Work

This PR builds on the configuration registry foundation established in
#7548:
- **Commit `2639cf0`** added `supported-configurations.json` with ~280
keys, aliases, deprecations, and GitLab CI validation
- **Commit `70e632e`** added
[supported-configurations-docs.yaml](cci:7://file:///Users/anna.yafi/go/src/github.com/DataDog/dd-trace-dotnet3/tracer/src/Datadog.Trace/Configuration/supported-configurations-docs.yaml:0:0-0:0)
with XML documentation for automated doc generation
@anna-git anna-git force-pushed the anna/config-inversion-configuration-aliases-switch-3 branch from a6668f3 to d90d571 Compare October 30, 2025 18:03
@anna-git anna-git force-pushed the anna/config-inversion-configuration-analyzers-4 branch 2 times, most recently from 3197af6 to e6d6574 Compare October 30, 2025 20:47
@anna-git anna-git force-pushed the anna/config-inversion-configuration-aliases-switch-3 branch from 6ccb01e to ed3a6bc Compare October 31, 2025 01:39
@anna-git anna-git force-pushed the anna/config-inversion-configuration-analyzers-4 branch from e6d6574 to dcd2f3c Compare October 31, 2025 01:39
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.

4 participants