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