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