|  | 
|  | 1 | +# Adding New Configuration Keys | 
|  | 2 | + | 
|  | 3 | +This guide explains how to add new configuration keys to the .NET Tracer. Configuration keys are automatically generated from JSON and YAML source files using source generators. | 
|  | 4 | + | 
|  | 5 | +## Table of Contents | 
|  | 6 | + | 
|  | 7 | +- [Overview](#overview) | 
|  | 8 | +- [Step-by-Step Guide](#step-by-step-guide) | 
|  | 9 | +  - [1. Add the Configuration Key Definition](#1-add-the-configuration-key-definition) | 
|  | 10 | +  - [2. Add Documentation](#2-add-documentation) | 
|  | 11 | +  - [3. (Optional) Add Fallback Keys](#3-optional-add-fallback-keys-aliases) | 
|  | 12 | +  - [4. (Optional) Override Constant Name](#4-optional-override-constant-name) | 
|  | 13 | +  - [5. Build to Generate Code](#5-build-to-generate-code) | 
|  | 14 | +  - [6. Use the Generated Key](#6-use-the-generated-key) | 
|  | 15 | +  - [7. Add to Telemetry Normalization Rules](#7-add-to-telemetry-normalization-rules) | 
|  | 16 | +  - [8. Test Your Changes](#8-test-your-changes) | 
|  | 17 | +- [Configuration Key Organization](#configuration-key-organization) | 
|  | 18 | +- [Examples](#examples) | 
|  | 19 | +- [Troubleshooting](#troubleshooting) | 
|  | 20 | + | 
|  | 21 | +## Overview | 
|  | 22 | + | 
|  | 23 | +Configuration keys in the .NET Tracer are defined in two source files: | 
|  | 24 | + | 
|  | 25 | +- **`tracer/src/Datadog.Trace/Configuration/supported-configurations.json`** - Defines the configuration keys, their environment variable names, and fallback chains | 
|  | 26 | +- **`tracer/src/Datadog.Trace/Configuration/supported-configurations-docs.yaml`** - Contains XML documentation for each key | 
|  | 27 | + | 
|  | 28 | +Two source generators read these files at build time: | 
|  | 29 | + | 
|  | 30 | +1. **`ConfigurationKeysGenerator`** - Generates the configuration key constants: | 
|  | 31 | +   - `ConfigurationKeys.g.cs` - Main configuration keys class with all constants | 
|  | 32 | +   - `ConfigurationKeys.<Product>.g.cs` - Product-specific partial classes (e.g., `ConfigurationKeys.OpenTelemetry.g.cs`) | 
|  | 33 | + | 
|  | 34 | +2. **`ConfigurationKeyMatcherGenerator`** - Generates the fallback/alias resolution logic: | 
|  | 35 | +   - `ConfigurationKeyMatcher.g.cs` - Handles key lookups with fallback chain support | 
|  | 36 | + | 
|  | 37 | +## Step-by-Step Guide | 
|  | 38 | + | 
|  | 39 | +### 1. Add the Configuration Key Definition | 
|  | 40 | + | 
|  | 41 | +Add your new configuration key to `tracer/src/Datadog.Trace/Configuration/supported-configurations.json`. | 
|  | 42 | + | 
|  | 43 | +**Example:** | 
|  | 44 | +```json | 
|  | 45 | +{ | 
|  | 46 | +  "supportedConfigurations": { | 
|  | 47 | +    "DD_TRACE_SAMPLE_RATE": { | 
|  | 48 | +      "version": ["A"] | 
|  | 49 | +    }, | 
|  | 50 | +    "OTEL_EXPORTER_OTLP_TIMEOUT": { | 
|  | 51 | +      "version": ["A"], | 
|  | 52 | +      "product": "OpenTelemetry" | 
|  | 53 | +    } | 
|  | 54 | +  } | 
|  | 55 | +} | 
|  | 56 | +``` | 
|  | 57 | + | 
|  | 58 | +This generates: | 
|  | 59 | +- `ConfigurationKeys.TraceSampleRate` (no product) | 
|  | 60 | +- `ConfigurationKeys.OpenTelemetry.ExporterOtlpTimeout` (with product) | 
|  | 61 | + | 
|  | 62 | +### 2. Add Documentation | 
|  | 63 | + | 
|  | 64 | +Add XML documentation for your key in `tracer/src/Datadog.Trace/Configuration/supported-configurations-docs.yaml`. | 
|  | 65 | + | 
|  | 66 | +**Format:** | 
|  | 67 | +```yaml | 
|  | 68 | +OTEL_EXPORTER_OTLP_LOGS_TIMEOUT: | | 
|  | 69 | +  Configuration key for the timeout in milliseconds for OTLP logs export. | 
|  | 70 | +  Falls back to <see cref="ConfigurationKeys.OpenTelemetry.ExporterOtlpTimeoutMs"/> if not set. | 
|  | 71 | +  Default value is 10000ms (10 seconds). | 
|  | 72 | +  <seealso cref="Datadog.Trace.Configuration.TracerSettings.OtlpLogsTimeoutMs"/> | 
|  | 73 | +``` | 
|  | 74 | +
 | 
|  | 75 | +**Important Notes:** | 
|  | 76 | +- The YAML key must **exactly match** the JSON key (environment variable name) | 
|  | 77 | +- **Do NOT include `<summary>` tags** - the source generator automatically wraps your documentation in `<summary>` tags | 
|  | 78 | +- You can include `<seealso>` and `<see>` tags directly in the content - the source generator will extract `<seealso>` tags and place them outside the `<summary>` section as needed | 
|  | 79 | + | 
|  | 80 | +### 3. (Optional) Add Fallback Keys (Aliases) | 
|  | 81 | + | 
|  | 82 | +Configuration keys can have **fallback keys** (also called aliases) that are checked in order of appearance when the primary key is not found. Add them to the `fallbacks` section in `supported-configurations.json`: | 
|  | 83 | + | 
|  | 84 | +```json | 
|  | 85 | +{ | 
|  | 86 | +  "fallbacks": { | 
|  | 87 | +    "OTEL_EXPORTER_OTLP_LOGS_TIMEOUT": [ | 
|  | 88 | +      "OTEL_EXPORTER_OTLP_TIMEOUT" | 
|  | 89 | +    ] | 
|  | 90 | +  } | 
|  | 91 | +} | 
|  | 92 | +``` | 
|  | 93 | + | 
|  | 94 | +**How it works:** | 
|  | 95 | +1. The configuration system first looks for `OTEL_EXPORTER_OTLP_LOGS_TIMEOUT` | 
|  | 96 | +2. If not found, it checks `OTEL_EXPORTER_OTLP_TIMEOUT` (the fallback) | 
|  | 97 | +3. If still not found, it uses the default value | 
|  | 98 | + | 
|  | 99 | +**Use cases:** | 
|  | 100 | +- **Specific → General fallback:** A specific key (e.g., logs timeout) falls back to a general key (e.g., overall timeout) | 
|  | 101 | +- **Backward compatibility:** Renamed keys can fall back to their old names to maintain compatibility | 
|  | 102 | +- **Hierarchical configuration:** More specific settings fall back to broader settings | 
|  | 103 | + | 
|  | 104 | +### 4. (Optional) Override Constant Name | 
|  | 105 | + | 
|  | 106 | +By default, the source generator automatically converts environment variable names to PascalCase constant names: | 
|  | 107 | +- `DD_TRACE_ENABLED` → `TraceEnabled` | 
|  | 108 | +- `OTEL_EXPORTER_OTLP_TIMEOUT` → `ExporterOtlpTimeout` | 
|  | 109 | + | 
|  | 110 | +If you need to explicitly control the constant name (e.g., for backward compatibility), add an entry to `tracer/src/Datadog.Trace/Configuration/configuration_keys_mapping.json`: | 
|  | 111 | + | 
|  | 112 | +```json | 
|  | 113 | +{ | 
|  | 114 | +  "DD_YOUR_CUSTOM_KEY": "YourPreferredConstantName" | 
|  | 115 | +} | 
|  | 116 | +``` | 
|  | 117 | + | 
|  | 118 | +**Note:** This mapping file exists primarily for backward compatibility with existing constant names. For new keys, it's recommended to let the generator automatically deduce the name from the environment variable. | 
|  | 119 | + | 
|  | 120 | +### 5. Build to Generate Code | 
|  | 121 | + | 
|  | 122 | +Build the `Datadog.Trace` project to run the source generator: | 
|  | 123 | + | 
|  | 124 | +```bash | 
|  | 125 | +# From repository root | 
|  | 126 | +dotnet build tracer/src/Datadog.Trace/Datadog.Trace.csproj | 
|  | 127 | +``` | 
|  | 128 | + | 
|  | 129 | +The generator will create/update files in: | 
|  | 130 | +- `tracer/src/Datadog.Trace/Generated/<tfm>/Datadog.Trace.SourceGenerators/ConfigurationKeysGenerator/` | 
|  | 131 | + | 
|  | 132 | +**Generated files:** | 
|  | 133 | +- `ConfigurationKeys.g.cs` - Main file with all keys | 
|  | 134 | +- `ConfigurationKeys.<Product>.g.cs` - Product-specific partial classes (if using `product` field) | 
|  | 135 | + | 
|  | 136 | +### 6. Use the Generated Key | 
|  | 137 | + | 
|  | 138 | +After building, you can use the generated constant in your code: | 
|  | 139 | + | 
|  | 140 | +```csharp | 
|  | 141 | +// Without product grouping | 
|  | 142 | +var enabled = source.GetBool(ConfigurationKeys.TraceEnabled); | 
|  | 143 | +
 | 
|  | 144 | +// With product grouping | 
|  | 145 | +var timeout = source.GetInt32(ConfigurationKeys.OpenTelemetry.ExporterOtlpLogsTimeout); | 
|  | 146 | +``` | 
|  | 147 | + | 
|  | 148 | +**Note:** The generated constants are in the `Datadog.Trace.Configuration` namespace. | 
|  | 149 | + | 
|  | 150 | +### 7. Add to Telemetry Normalization Rules | 
|  | 151 | + | 
|  | 152 | +Configuration keys are reported in telemetry with normalized names. Add your key to the normalization rules: | 
|  | 153 | + | 
|  | 154 | +**File:** `tracer/test/Datadog.Trace.Tests/Telemetry/config_norm_rules.json` | 
|  | 155 | + | 
|  | 156 | +```json | 
|  | 157 | +{ | 
|  | 158 | +  "YOUR_ENV_VAR_NAME": "normalized_telemetry_name" | 
|  | 159 | +} | 
|  | 160 | +``` | 
|  | 161 | + | 
|  | 162 | +**Example:** | 
|  | 163 | +```json | 
|  | 164 | +{ | 
|  | 165 | +  "OTEL_EXPORTER_OTLP_LOGS_TIMEOUT": "otel_exporter_otlp_logs_timeout" | 
|  | 166 | +} | 
|  | 167 | +``` | 
|  | 168 | + | 
|  | 169 | +**Important:** The `config_norm_rules.json` file is a copy from the [dd-go repository](https://github.com/DataDog/dd-go). After updating this file locally, you must also submit a PR to update the canonical version in the dd-go repository to keep the normalization rules synchronized across all Datadog tracers. | 
|  | 170 | + | 
|  | 171 | +### 8. Test Your Changes | 
|  | 172 | + | 
|  | 173 | +1. **Verify generation:** Check that your key appears in the generated files | 
|  | 174 | +2. **Telemetry tests:** Ensure telemetry normalization tests pass in `tracer/test/Datadog.Trace.Tests/Telemetry/` | 
|  | 175 | +3. **Integration tests:** Test the configuration key in real scenarios where it's used | 
|  | 176 | + | 
|  | 177 | +## Configuration Key Organization | 
|  | 178 | + | 
|  | 179 | +### Product Grouping | 
|  | 180 | + | 
|  | 181 | +Use the `product` field to organize related keys into nested classes: | 
|  | 182 | + | 
|  | 183 | +```json | 
|  | 184 | +{ | 
|  | 185 | +  "OTEL_EXPORTER_OTLP_ENDPOINT": { | 
|  | 186 | +    "product": "OpenTelemetry" | 
|  | 187 | +  } | 
|  | 188 | +} | 
|  | 189 | +``` | 
|  | 190 | + | 
|  | 191 | +Generates: `ConfigurationKeys.OpenTelemetry.ExporterOtlpEndpoint` | 
|  | 192 | + | 
|  | 193 | +**Common products:** | 
|  | 194 | +- `OpenTelemetry` - OpenTelemetry-related keys | 
|  | 195 | +- `CIVisibility` - CI Visibility keys | 
|  | 196 | +- `Telemetry` - Telemetry configuration | 
|  | 197 | +- `AppSec` - Application Security | 
|  | 198 | +- `Debugger` - Dynamic Instrumentation | 
|  | 199 | +- `Iast` - Interactive Application Security Testing | 
|  | 200 | +- `FeatureFlags` - Feature flag toggles | 
|  | 201 | +- `Proxy` - Proxy configuration | 
|  | 202 | +- `Debug` - Debug/diagnostic keys | 
|  | 203 | + | 
|  | 204 | +## Examples | 
|  | 205 | + | 
|  | 206 | +### Example 1: Simple Configuration Key | 
|  | 207 | + | 
|  | 208 | +**supported-configurations.json:** | 
|  | 209 | +```json | 
|  | 210 | +{ | 
|  | 211 | +  "supportedConfigurations": { | 
|  | 212 | +    "DD_TRACE_SAMPLE_RATE": { | 
|  | 213 | +      "version": ["A"] | 
|  | 214 | +    } | 
|  | 215 | +  } | 
|  | 216 | +} | 
|  | 217 | +``` | 
|  | 218 | + | 
|  | 219 | +**supported-configurations-docs.yaml:** | 
|  | 220 | +```yaml | 
|  | 221 | +DD_TRACE_SAMPLE_RATE: | | 
|  | 222 | +  Configuration key for setting the global sampling rate. | 
|  | 223 | +  Value should be between 0.0 and 1.0. | 
|  | 224 | +  Default value is 1.0 (100% sampling). | 
|  | 225 | +  <seealso cref="Datadog.Trace.Configuration.TracerSettings.GlobalSamplingRate"/> | 
|  | 226 | +``` | 
|  | 227 | + | 
|  | 228 | +**Usage:** | 
|  | 229 | +```csharp | 
|  | 230 | +var rate = source.GetDouble(ConfigurationKeys.GlobalSamplingRate); | 
|  | 231 | +``` | 
|  | 232 | + | 
|  | 233 | +### Example 2: Configuration Key with Fallback | 
|  | 234 | + | 
|  | 235 | +**supported-configurations.json:** | 
|  | 236 | +```json | 
|  | 237 | +{ | 
|  | 238 | +  "supportedConfigurations": { | 
|  | 239 | +    "OTEL_EXPORTER_OTLP_LOGS_TIMEOUT": { | 
|  | 240 | +      "version": ["A"], | 
|  | 241 | +      "product": "OpenTelemetry" | 
|  | 242 | +    }, | 
|  | 243 | +    "OTEL_EXPORTER_OTLP_TIMEOUT": { | 
|  | 244 | +      "version": ["A"], | 
|  | 245 | +      "product": "OpenTelemetry" | 
|  | 246 | +    } | 
|  | 247 | +  }, | 
|  | 248 | +  "fallbacks": { | 
|  | 249 | +    "OTEL_EXPORTER_OTLP_LOGS_TIMEOUT": [ | 
|  | 250 | +      "OTEL_EXPORTER_OTLP_TIMEOUT" | 
|  | 251 | +    ] | 
|  | 252 | +  } | 
|  | 253 | +} | 
|  | 254 | +``` | 
|  | 255 | + | 
|  | 256 | +**supported-configurations-docs.yaml:** | 
|  | 257 | +```yaml | 
|  | 258 | +OTEL_EXPORTER_OTLP_LOGS_TIMEOUT: | | 
|  | 259 | +  Configuration key for the timeout in milliseconds for OTLP logs export. | 
|  | 260 | +  Falls back to <see cref="ConfigurationKeys.OpenTelemetry.ExporterOtlpTimeoutMs"/> if not set. | 
|  | 261 | +  Default value is 10000ms. | 
|  | 262 | +  <seealso cref="Datadog.Trace.Configuration.TracerSettings.OtlpLogsTimeoutMs"/> | 
|  | 263 | +
 | 
|  | 264 | +OTEL_EXPORTER_OTLP_TIMEOUT: | | 
|  | 265 | +  Configuration key for the general OTLP export timeout in milliseconds. | 
|  | 266 | +  Used as fallback for specific timeout configurations. | 
|  | 267 | +  Default value is 10000ms. | 
|  | 268 | +``` | 
|  | 269 | + | 
|  | 270 | +**Usage:** | 
|  | 271 | +```csharp | 
|  | 272 | +// Reads OTEL_EXPORTER_OTLP_LOGS_TIMEOUT, falls back to OTEL_EXPORTER_OTLP_TIMEOUT | 
|  | 273 | +var timeout = source.GetInt32( | 
|  | 274 | +    ConfigurationKeys.OpenTelemetry.ExporterOtlpLogsTimeout, | 
|  | 275 | +    ConfigurationKeys.OpenTelemetry.ExporterOtlpTimeout); | 
|  | 276 | +``` | 
|  | 277 | + | 
|  | 278 | +### Example 3: Feature Flag | 
|  | 279 | + | 
|  | 280 | +**supported-configurations.json:** | 
|  | 281 | +```json | 
|  | 282 | +{ | 
|  | 283 | +  "supportedConfigurations": { | 
|  | 284 | +    "DD_TRACE_128_BIT_TRACEID_GENERATION_ENABLED": { | 
|  | 285 | +      "version": ["A"], | 
|  | 286 | +      "product": "FeatureFlags" | 
|  | 287 | +    } | 
|  | 288 | +  } | 
|  | 289 | +} | 
|  | 290 | +``` | 
|  | 291 | + | 
|  | 292 | +**supported-configurations-docs.yaml:** | 
|  | 293 | +```yaml | 
|  | 294 | +DD_TRACE_128_BIT_TRACEID_GENERATION_ENABLED: | | 
|  | 295 | +  Enables generating 128-bit trace ids instead of 64-bit trace ids. | 
|  | 296 | +  Note that a 128-bit trace id may be received from an upstream service or from | 
|  | 297 | +  an Activity even if we are not generating them ourselves. | 
|  | 298 | +  Default value is <c>true</c> (enabled). | 
|  | 299 | +``` | 
|  | 300 | + | 
|  | 301 | +**Usage:** | 
|  | 302 | +```csharp | 
|  | 303 | +var enabled = source.GetBool(ConfigurationKeys.FeatureFlags.TraceId128BitGenerationEnabled); | 
|  | 304 | +``` | 
|  | 305 | + | 
|  | 306 | +## Troubleshooting | 
|  | 307 | + | 
|  | 308 | +### Generated files are not updated | 
|  | 309 | + | 
|  | 310 | +**Solution:** Clean and rebuild: | 
|  | 311 | +```bash | 
|  | 312 | +dotnet clean tracer/src/Datadog.Trace/Datadog.Trace.csproj | 
|  | 313 | +dotnet build tracer/src/Datadog.Trace/Datadog.Trace.csproj | 
|  | 314 | +``` | 
|  | 315 | + | 
|  | 316 | +### Key not found in generated code | 
|  | 317 | + | 
|  | 318 | +**Check:** | 
|  | 319 | +1. JSON key matches YAML key exactly (case-sensitive) | 
|  | 320 | +2. JSON is valid (no trailing commas, proper escaping) | 
|  | 321 | +3. Build succeeded without errors | 
|  | 322 | +4. Looking in the correct namespace/product class | 
|  | 323 | + | 
|  | 324 | +### Telemetry tests failing | 
|  | 325 | + | 
|  | 326 | +**Check:** | 
|  | 327 | +1. Added key to `config_norm_rules.json` | 
|  | 328 | +2. Normalized name matches `telemetry_name` in JSON | 
|  | 329 | +3. All tests in `tracer/test/Datadog.Trace.Tests/Telemetry/` pass | 
|  | 330 | + | 
|  | 331 | +### Documentation not appearing | 
|  | 332 | + | 
|  | 333 | +**Check:** | 
|  | 334 | +1. YAML key exactly matches JSON key | 
|  | 335 | +2. YAML syntax is correct (proper indentation, pipe `|` for multi-line) | 
|  | 336 | +3. XML tags are properly closed | 
|  | 337 | +4. Rebuild after YAML changes | 
|  | 338 | + | 
|  | 339 | +### Fallback not working | 
|  | 340 | + | 
|  | 341 | +**Check:** | 
|  | 342 | +1. Fallback key is defined in `configurations` section | 
|  | 343 | +2. Fallback array is in correct order (first fallback is tried first) | 
|  | 344 | +3. Using the correct overload of `GetXxx()` method that accepts fallback keys | 
|  | 345 | + | 
|  | 346 | +## Related Files | 
|  | 347 | + | 
|  | 348 | +- **Source generator:** `tracer/src/Datadog.Trace.SourceGenerators/Configuration/ConfigurationKeysGenerator.cs` | 
|  | 349 | +- **Configuration source:** `tracer/src/Datadog.Trace/Configuration/supported-configurations.json` | 
|  | 350 | +- **Documentation source:** `tracer/src/Datadog.Trace/Configuration/supported-configurations-docs.yaml` | 
|  | 351 | +- **Telemetry rules:** `tracer/test/Datadog.Trace.Tests/Telemetry/config_norm_rules.json` | 
|  | 352 | +- **Generated output:** `tracer/src/Datadog.Trace/Generated/<tfm>/Datadog.Trace.SourceGenerators/ConfigurationKeysGenerator/` | 
0 commit comments