diff --git a/docs/GettingStarted.md b/docs/GettingStarted.md index 9511eb503cb..9a20e703aed 100644 --- a/docs/GettingStarted.md +++ b/docs/GettingStarted.md @@ -913,6 +913,8 @@ The `instrument :graphql` method accepts the following parameters. Additional op | `service_name` | | `String` | Service name used for graphql instrumentation | `'ruby-graphql'` | | `error_extensions` | `DD_TRACE_GRAPHQL_ERROR_EXTENSIONS` | `Array` | List of extension keys to include in the span event reported for GraphQL queries with errors. | `[]` | | `error_tracking` | `DD_TRACE_GRAPHQL_ERROR_TRACKING` | `Bool` | (Recommended) Surface GraphQL errors in Error Tracking. | `false` | +| `capture_variables` | `DD_TRACE_GRAPHQL_CAPTURE_VARIABLES` | `Array` | List of `operationName:variableName` pairs to capture as span tags. Format: `GetUser:id,CreatePost:title`. By default, no variables are captured. | `[]` | +| `capture_variables_except` | `DD_TRACE_GRAPHQL_CAPTURE_VARIABLES_EXCEPT` | `Array` | List of `operationName:variableName` pairs to exclude from capture. When `DD_TRACE_GRAPHQL_CAPTURE_VARIABLES` is `nil`, all variables except those listed in this optiion are captured. | `[]` | Once an instrumentation strategy is selected (`with_unified_tracer: true`, `with_deprecated_tracer: true`, or *no option set* which defaults to `GraphQL::Tracing::DataDogTrace`), it is not possible to change the instrumentation strategy in the same Ruby process. diff --git a/gemfiles/ruby_2.7_graphql_2.3.gemfile.lock b/gemfiles/ruby_2.7_graphql_2.3.gemfile.lock index 2c83a2becfa..94ca0330c9d 100644 --- a/gemfiles/ruby_2.7_graphql_2.3.gemfile.lock +++ b/gemfiles/ruby_2.7_graphql_2.3.gemfile.lock @@ -94,10 +94,13 @@ GEM erubi (1.13.0) extlz4 (0.3.4) ffi (1.17.2-aarch64-linux-gnu) + ffi (1.17.2-arm64-darwin) ffi (1.17.2-x86_64-linux-gnu) globalid (1.2.1) activesupport (>= 6.1) - google-protobuf (3.25.4) + google-protobuf (3.25.4-aarch64-linux) + google-protobuf (3.25.4-arm64-darwin) + google-protobuf (3.25.4-x86_64-linux) graphql (2.3.6) base64 hashdiff (1.1.0) @@ -105,10 +108,13 @@ GEM concurrent-ruby (~> 1.0) json-schema (2.8.1) addressable (>= 2.4) + libdatadog (18.1.0.1.0) libdatadog (18.1.0.1.0-aarch64-linux) libdatadog (18.1.0.1.0-x86_64-linux) libddwaf (1.24.1.2.1-aarch64-linux) ffi (~> 1.0) + libddwaf (1.24.1.2.1-arm64-darwin) + ffi (~> 1.0) libddwaf (1.24.1.2.1-x86_64-linux) ffi (~> 1.0) logger (1.7.0) @@ -129,6 +135,7 @@ GEM memory_profiler (0.9.14) method_source (1.1.0) mini_mime (1.1.5) + mini_portile2 (2.8.9) minitest (5.24.1) msgpack (1.8.0) net-imap (0.4.14) @@ -141,9 +148,8 @@ GEM net-smtp (0.5.0) net-protocol nio4r (2.7.3) - nokogiri (1.15.6-aarch64-linux) - racc (~> 1.4) - nokogiri (1.15.6-x86_64-linux) + nokogiri (1.15.6) + mini_portile2 (~> 2.8.2) racc (~> 1.4) os (1.1.4) pry (0.14.2) @@ -239,6 +245,7 @@ GEM PLATFORMS aarch64-linux + arm64-darwin-23 x86_64-linux DEPENDENCIES diff --git a/gemfiles/ruby_3.1_graphql_2.0.gemfile.lock b/gemfiles/ruby_3.1_graphql_2.0.gemfile.lock index 17cec805e4a..ddb8490b975 100644 --- a/gemfiles/ruby_3.1_graphql_2.0.gemfile.lock +++ b/gemfiles/ruby_3.1_graphql_2.0.gemfile.lock @@ -95,9 +95,11 @@ GEM erubi (1.13.0) extlz4 (0.3.4) ffi (1.17.2-aarch64-linux-gnu) + ffi (1.17.2-arm64-darwin) ffi (1.17.2-x86_64-linux-gnu) globalid (1.2.1) activesupport (>= 6.1) + google-protobuf (3.25.2) google-protobuf (3.25.2-aarch64-linux) google-protobuf (3.25.2-x86_64-linux) graphql (2.0.28) @@ -111,10 +113,13 @@ GEM reline (>= 0.4.2) json-schema (2.8.1) addressable (>= 2.4) + libdatadog (18.1.0.1.0) libdatadog (18.1.0.1.0-aarch64-linux) libdatadog (18.1.0.1.0-x86_64-linux) libddwaf (1.24.1.2.1-aarch64-linux) ffi (~> 1.0) + libddwaf (1.24.1.2.1-arm64-darwin) + ffi (~> 1.0) libddwaf (1.24.1.2.1-x86_64-linux) ffi (~> 1.0) logger (1.7.0) @@ -149,6 +154,8 @@ GEM nio4r (2.7.3) nokogiri (1.16.6-aarch64-linux) racc (~> 1.4) + nokogiri (1.16.6-arm64-darwin) + racc (~> 1.4) nokogiri (1.16.6-x86_64-linux) racc (~> 1.4) os (1.1.4) @@ -257,6 +264,7 @@ GEM PLATFORMS aarch64-linux + arm64-darwin-23 x86_64-linux DEPENDENCIES diff --git a/gemfiles/ruby_3.3_graphql_2.0.gemfile.lock b/gemfiles/ruby_3.3_graphql_2.0.gemfile.lock index a2edc67b574..2988f397dcf 100644 --- a/gemfiles/ruby_3.3_graphql_2.0.gemfile.lock +++ b/gemfiles/ruby_3.3_graphql_2.0.gemfile.lock @@ -95,6 +95,7 @@ GEM erubi (1.13.0) extlz4 (0.3.4) ffi (1.17.2-aarch64-linux-gnu) + ffi (1.17.2-arm64-darwin) ffi (1.17.2-x86_64-linux-gnu) globalid (1.2.1) activesupport (>= 6.1) @@ -110,10 +111,15 @@ GEM reline (>= 0.4.2) json-schema (2.8.1) addressable (>= 2.4) + libdatadog (18.1.0.1.0) libdatadog (18.1.0.1.0-aarch64-linux) libdatadog (18.1.0.1.0-x86_64-linux) libddwaf (1.24.1.2.1-aarch64-linux) ffi (~> 1.0) + libddwaf (1.24.1.1.0-arm64-darwin) + ffi (~> 1.0) + libddwaf (1.24.1.1.0-x86_64-linux) + ffi (~> 1.0) libddwaf (1.24.1.2.1-x86_64-linux) ffi (~> 1.0) logger (1.7.0) @@ -148,6 +154,8 @@ GEM nio4r (2.7.3) nokogiri (1.16.6-aarch64-linux) racc (~> 1.4) + nokogiri (1.16.6-arm64-darwin) + racc (~> 1.4) nokogiri (1.16.6-x86_64-linux) racc (~> 1.4) os (1.1.4) @@ -256,6 +264,7 @@ GEM PLATFORMS aarch64-linux + arm64-darwin-23 x86_64-linux DEPENDENCIES diff --git a/gemfiles/ruby_3.3_graphql_2.3.gemfile.lock b/gemfiles/ruby_3.3_graphql_2.3.gemfile.lock index 244d848d353..609a4cee174 100644 --- a/gemfiles/ruby_3.3_graphql_2.3.gemfile.lock +++ b/gemfiles/ruby_3.3_graphql_2.3.gemfile.lock @@ -97,10 +97,12 @@ GEM erubi (1.13.0) extlz4 (0.3.4) ffi (1.17.2-aarch64-linux-gnu) + ffi (1.17.2-arm64-darwin) ffi (1.17.2-x86_64-linux-gnu) globalid (1.2.1) activesupport (>= 6.1) google-protobuf (3.25.3-aarch64-linux) + google-protobuf (3.25.3-arm64-darwin) google-protobuf (3.25.3-x86_64-linux) graphql (2.3.6) base64 @@ -114,8 +116,13 @@ GEM reline (>= 0.4.2) json-schema (2.8.1) addressable (>= 2.4) + libdatadog (18.1.0.1.0) libdatadog (18.1.0.1.0-aarch64-linux) libdatadog (18.1.0.1.0-x86_64-linux) + libddwaf (1.24.1.1.0-arm64-darwin) + ffi (~> 1.0) + libddwaf (1.24.1.1.0-x86_64-linux) + ffi (~> 1.0) libddwaf (1.24.1.2.1-aarch64-linux) ffi (~> 1.0) libddwaf (1.24.1.2.1-x86_64-linux) @@ -152,6 +159,8 @@ GEM nio4r (2.7.3) nokogiri (1.16.6-aarch64-linux) racc (~> 1.4) + nokogiri (1.16.6-arm64-darwin) + racc (~> 1.4) nokogiri (1.16.6-x86_64-linux) racc (~> 1.4) os (1.1.4) @@ -260,6 +269,7 @@ GEM PLATFORMS aarch64-linux + arm64-darwin-23 x86_64-linux DEPENDENCIES diff --git a/gemfiles/ruby_3.3_relational_db.gemfile.lock b/gemfiles/ruby_3.3_relational_db.gemfile.lock index a7ed4a50fc9..32cb84adc72 100644 --- a/gemfiles/ruby_3.3_relational_db.gemfile.lock +++ b/gemfiles/ruby_3.3_relational_db.gemfile.lock @@ -47,6 +47,7 @@ GEM dogstatsd-ruby (5.6.1) extlz4 (0.3.4) ffi (1.17.2-aarch64-linux-gnu) + ffi (1.17.2-arm64-darwin) ffi (1.17.2-x86_64-linux-gnu) google-protobuf (3.24.3) hashdiff (1.0.1) @@ -59,10 +60,15 @@ GEM reline (>= 0.4.2) json-schema (2.8.1) addressable (>= 2.4) + libdatadog (18.1.0.1.0) libdatadog (18.1.0.1.0-aarch64-linux) libdatadog (18.1.0.1.0-x86_64-linux) libddwaf (1.24.1.2.1-aarch64-linux) ffi (~> 1.0) + libddwaf (1.24.1.1.0-arm64-darwin) + ffi (~> 1.0) + libddwaf (1.24.1.1.0-x86_64-linux) + ffi (~> 1.0) libddwaf (1.24.1.2.1-x86_64-linux) ffi (~> 1.0) logger (1.7.0) @@ -137,6 +143,7 @@ GEM PLATFORMS aarch64-linux + arm64-darwin-23 x86_64-linux DEPENDENCIES diff --git a/gemfiles/ruby_3.4_graphql_2.0.gemfile.lock b/gemfiles/ruby_3.4_graphql_2.0.gemfile.lock index f3d332b812a..580f9e7d7b2 100644 --- a/gemfiles/ruby_3.4_graphql_2.0.gemfile.lock +++ b/gemfiles/ruby_3.4_graphql_2.0.gemfile.lock @@ -97,10 +97,13 @@ GEM erubi (1.13.0) extlz4 (0.3.4) ffi (1.17.2-aarch64-linux-gnu) + ffi (1.17.2-arm64-darwin) ffi (1.17.2-x86_64-linux-gnu) globalid (1.2.1) activesupport (>= 6.1) - google-protobuf (3.25.3) + google-protobuf (3.25.3-aarch64-linux) + google-protobuf (3.25.3-arm64-darwin) + google-protobuf (3.25.3-x86_64-linux) graphql (2.0.31) base64 hashdiff (1.1.0) @@ -113,10 +116,13 @@ GEM reline (>= 0.4.2) json-schema (2.8.1) addressable (>= 2.4) + libdatadog (18.1.0.1.0) libdatadog (18.1.0.1.0-aarch64-linux) libdatadog (18.1.0.1.0-x86_64-linux) libddwaf (1.24.1.2.1-aarch64-linux) ffi (~> 1.0) + libddwaf (1.24.1.2.1-arm64-darwin) + ffi (~> 1.0) libddwaf (1.24.1.2.1-x86_64-linux) ffi (~> 1.0) logger (1.7.0) @@ -137,7 +143,6 @@ GEM memory_profiler (0.9.14) method_source (1.1.0) mini_mime (1.1.5) - mini_portile2 (2.8.7) minitest (5.24.1) msgpack (1.8.0) mutex_m (0.2.0) @@ -150,8 +155,11 @@ GEM timeout net-smtp (0.5.0) nio4r (2.7.3) - nokogiri (1.16.6) - mini_portile2 (~> 2.8.2) + nokogiri (1.16.6-aarch64-linux) + racc (~> 1.4) + nokogiri (1.16.6-arm64-darwin) + racc (~> 1.4) + nokogiri (1.16.6-x86_64-linux) racc (~> 1.4) os (1.1.4) ostruct (0.6.1) @@ -260,6 +268,7 @@ GEM PLATFORMS aarch64-linux + arm64-darwin-23 x86_64-linux DEPENDENCIES diff --git a/lib/datadog/core/configuration/supported_configurations.rb b/lib/datadog/core/configuration/supported_configurations.rb index 054847a86c7..6fb3a1478db 100644 --- a/lib/datadog/core/configuration/supported_configurations.rb +++ b/lib/datadog/core/configuration/supported_configurations.rb @@ -7,330 +7,332 @@ module Datadog module Core module Configuration SUPPORTED_CONFIGURATIONS = - {"DD_AGENT_HOST" => {version: ["A"]}, - "DD_API_KEY" => {version: ["A"]}, - "DD_API_SECURITY_ENABLED" => {version: ["A"]}, - "DD_API_SECURITY_REQUEST_SAMPLE_RATE" => {version: ["A"]}, - "DD_API_SECURITY_SAMPLE_DELAY" => {version: ["A"]}, - "DD_APM_TRACING_ENABLED" => {version: ["A"]}, - "DD_APPSEC_AUTOMATED_USER_EVENTS_TRACKING" => {version: ["A"]}, - "DD_APPSEC_AUTO_USER_INSTRUMENTATION_MODE" => {version: ["A"]}, - "DD_APPSEC_ENABLED" => {version: ["A"]}, - "DD_APPSEC_HTTP_BLOCKED_TEMPLATE_HTML" => {version: ["A"]}, - "DD_APPSEC_HTTP_BLOCKED_TEMPLATE_JSON" => {version: ["A"]}, - "DD_APPSEC_HTTP_BLOCKED_TEMPLATE_TEXT" => {version: ["A"]}, - "DD_APPSEC_MAX_STACK_TRACES" => {version: ["A"]}, - "DD_APPSEC_MAX_STACK_TRACE_DEPTH" => {version: ["A"]}, - "DD_APPSEC_MAX_STACK_TRACE_DEPTH_TOP_PERCENT" => {version: ["A"]}, - "DD_APPSEC_OBFUSCATION_PARAMETER_KEY_REGEXP" => {version: ["A"]}, - "DD_APPSEC_OBFUSCATION_PARAMETER_VALUE_REGEXP" => {version: ["A"]}, - "DD_APPSEC_RASP_ENABLED" => {version: ["A"]}, - "DD_APPSEC_RULES" => {version: ["A"]}, - "DD_APPSEC_SCA_ENABLED" => {version: ["A"]}, - "DD_APPSEC_STACK_TRACE_ENABLED" => {version: ["A"]}, - "DD_APPSEC_TRACE_RATE_LIMIT" => {version: ["A"]}, - "DD_APPSEC_WAF_DEBUG" => {version: ["A"]}, - "DD_APPSEC_WAF_TIMEOUT" => {version: ["A"]}, - "DD_CRASHTRACKING_ENABLED" => {version: ["A"]}, - "DD_DBM_PROPAGATION_MODE" => {version: ["A"]}, - "DD_DISABLE_DATADOG_RAILS" => {version: ["A"]}, - "DD_DYNAMIC_INSTRUMENTATION_ENABLED" => {version: ["A"]}, - "DD_DYNAMIC_INSTRUMENTATION_PROBE_FILE" => {version: ["A"]}, - "DD_DYNAMIC_INSTRUMENTATION_REDACTED_IDENTIFIERS" => {version: ["A"]}, - "DD_DYNAMIC_INSTRUMENTATION_REDACTED_TYPES" => {version: ["A"]}, - "DD_ENV" => {version: ["A"]}, - "DD_ERROR_TRACKING_HANDLED_ERRORS" => {version: ["A"]}, - "DD_ERROR_TRACKING_HANDLED_ERRORS_INCLUDE" => {version: ["A"]}, - "DD_GIT_COMMIT_SHA" => {version: ["A"]}, - "DD_GIT_REPOSITORY_URL" => {version: ["A"]}, - "DD_HEALTH_METRICS_ENABLED" => {version: ["A"]}, - "DD_INJECTION_ENABLED" => {version: ["A"]}, - "DD_INJECT_FORCE" => {version: ["A"]}, - "DD_INSTRUMENTATION_INSTALL_ID" => {version: ["A"]}, - "DD_INSTRUMENTATION_INSTALL_TIME" => {version: ["A"]}, - "DD_INSTRUMENTATION_INSTALL_TYPE" => {version: ["A"]}, - "DD_INSTRUMENTATION_TELEMETRY_ENABLED" => {version: ["A"]}, - "DD_INTEGRATION_SERVICE" => {version: ["A"]}, - "DD_LOGS_INJECTION" => {version: ["A"]}, - "DD_METRIC_AGENT_PORT" => {version: ["A"]}, - "DD_PROFILING_ALLOCATION_ENABLED" => {version: ["A"]}, - "DD_PROFILING_DIR_INTERRUPTION_WORKAROUND_ENABLED" => {version: ["A"]}, - "DD_PROFILING_ENABLED" => {version: ["A"]}, - "DD_PROFILING_ENDPOINT_COLLECTION_ENABLED" => {version: ["A"]}, - "DD_PROFILING_EXPERIMENTAL_HEAP_ENABLED" => {version: ["A"]}, - "DD_PROFILING_EXPERIMENTAL_HEAP_SAMPLE_RATE" => {version: ["A"]}, - "DD_PROFILING_EXPERIMENTAL_HEAP_SIZE_ENABLED" => {version: ["A"]}, - "DD_PROFILING_GC_ENABLED" => {version: ["A"]}, - "DD_PROFILING_GVL_ENABLED" => {version: ["A"]}, - "DD_PROFILING_HEAP_CLEAN_AFTER_GC_ENABLED" => {version: ["A"]}, - "DD_PROFILING_MAX_FRAMES" => {version: ["A"]}, - "DD_PROFILING_NATIVE_FILENAMES_ENABLED" => {version: ["A"]}, - "DD_PROFILING_NO_SIGNALS_WORKAROUND_ENABLED" => {version: ["A"]}, - "DD_PROFILING_OVERHEAD_TARGET_PERCENTAGE" => {version: ["A"]}, - "DD_PROFILING_PREVIEW_OTEL_CONTEXT_ENABLED" => {version: ["A"]}, - "DD_PROFILING_SIGHANDLER_SAMPLING_ENABLED" => {version: ["A"]}, - "DD_PROFILING_SKIP_MYSQL2_CHECK" => {version: ["A"]}, - "DD_PROFILING_TIMELINE_ENABLED" => {version: ["A"]}, - "DD_PROFILING_UPLOAD_PERIOD" => {version: ["A"]}, - "DD_PROFILING_UPLOAD_TIMEOUT" => {version: ["A"]}, - "DD_REDIS_COMMAND_ARGS" => {version: ["A"]}, - "DD_REMOTE_CONFIGURATION_ENABLED" => {version: ["A"]}, - "DD_REMOTE_CONFIG_BOOT_TIMEOUT_SECONDS" => {version: ["A"]}, - "DD_REMOTE_CONFIG_POLL_INTERVAL_SECONDS" => {version: ["A"]}, - "DD_RODA_ANALYTICS_ENABLED" => {version: ["A"]}, - "DD_RODA_ANALYTICS_SAMPLE_RATE" => {version: ["A"]}, - "DD_RUNTIME_METRICS_ENABLED" => {version: ["A"]}, - "DD_RUNTIME_METRICS_RUNTIME_ID_ENABLED" => {version: ["A"]}, - "DD_SERVICE" => {version: ["B"]}, - "DD_SITE" => {version: ["A"]}, - "DD_SPAN_SAMPLING_RULES" => {version: ["A"]}, - "DD_SPAN_SAMPLING_RULES_FILE" => {version: ["A"]}, - "DD_TAGS" => {version: ["B"]}, - "DD_TELEMETRY_AGENTLESS_URL" => {version: ["A"]}, - "DD_TELEMETRY_DEPENDENCY_COLLECTION_ENABLED" => {version: ["A"]}, - "DD_TELEMETRY_HEARTBEAT_INTERVAL" => {version: ["A"]}, - "DD_TELEMETRY_LOG_COLLECTION_ENABLED" => {version: ["A"]}, - "DD_TELEMETRY_METRICS_AGGREGATION_INTERVAL" => {version: ["A"]}, - "DD_TELEMETRY_METRICS_ENABLED" => {version: ["A"]}, - "DD_TRACE_128_BIT_TRACEID_GENERATION_ENABLED" => {version: ["A"]}, - "DD_TRACE_128_BIT_TRACEID_LOGGING_ENABLED" => {version: ["A"]}, - "DD_TRACE_ACTION_CABLE_ANALYTICS_ENABLED" => {version: ["A"]}, - "DD_TRACE_ACTION_CABLE_ANALYTICS_SAMPLE_RATE" => {version: ["A"]}, - "DD_TRACE_ACTION_CABLE_ENABLED" => {version: ["A"]}, - "DD_TRACE_ACTION_MAILER_ANALYTICS_ENABLED" => {version: ["A"]}, - "DD_TRACE_ACTION_MAILER_ANALYTICS_SAMPLE_RATE" => {version: ["A"]}, - "DD_TRACE_ACTION_MAILER_ENABLED" => {version: ["A"]}, - "DD_TRACE_ACTION_PACK_ANALYTICS_ENABLED" => {version: ["A"]}, - "DD_TRACE_ACTION_PACK_ANALYTICS_SAMPLE_RATE" => {version: ["A"]}, - "DD_TRACE_ACTION_PACK_ENABLED" => {version: ["A"]}, - "DD_TRACE_ACTION_VIEW_ANALYTICS_ENABLED" => {version: ["A"]}, - "DD_TRACE_ACTION_VIEW_ANALYTICS_SAMPLE_RATE" => {version: ["A"]}, - "DD_TRACE_ACTION_VIEW_ENABLED" => {version: ["A"]}, - "DD_TRACE_ACTIVE_JOB_ANALYTICS_ENABLED" => {version: ["A"]}, - "DD_TRACE_ACTIVE_JOB_ANALYTICS_SAMPLE_RATE" => {version: ["A"]}, - "DD_TRACE_ACTIVE_JOB_ENABLED" => {version: ["A"]}, - "DD_TRACE_ACTIVE_MODEL_SERIALIZERS_ANALYTICS_ENABLED" => {version: ["A"]}, - "DD_TRACE_ACTIVE_MODEL_SERIALIZERS_ANALYTICS_SAMPLE_RATE" => {version: ["A"]}, - "DD_TRACE_ACTIVE_MODEL_SERIALIZERS_ENABLED" => {version: ["A"]}, - "DD_TRACE_ACTIVE_RECORD_ANALYTICS_ENABLED" => {version: ["A"]}, - "DD_TRACE_ACTIVE_RECORD_ANALYTICS_SAMPLE_RATE" => {version: ["A"]}, - "DD_TRACE_ACTIVE_RECORD_ENABLED" => {version: ["A"]}, - "DD_TRACE_ACTIVE_SUPPORT_ANALYTICS_ENABLED" => {version: ["A"]}, - "DD_TRACE_ACTIVE_SUPPORT_ANALYTICS_SAMPLE_RATE" => {version: ["A"]}, - "DD_TRACE_ACTIVE_SUPPORT_ENABLED" => {version: ["A"]}, - "DD_TRACE_AGENT_PORT" => {version: ["A"]}, - "DD_TRACE_AGENT_TIMEOUT_SECONDS" => {version: ["A"]}, - "DD_TRACE_AGENT_URL" => {version: ["A"]}, - "DD_TRACE_ANALYTICS_ENABLED" => {version: ["A"]}, - "DD_TRACE_AWS_ANALYTICS_ENABLED" => {version: ["A"]}, - "DD_TRACE_AWS_ANALYTICS_SAMPLE_RATE" => {version: ["A"]}, - "DD_TRACE_AWS_ENABLED" => {version: ["A"]}, - "DD_TRACE_AWS_PEER_SERVICE" => {version: ["A"]}, - "DD_TRACE_AWS_SERVICE_NAME" => {version: ["A"]}, - "DD_TRACE_BAGGAGE_TAG_KEYS" => {version: ["A"]}, - "DD_TRACE_CLIENT_IP_ENABLED" => {version: ["A"]}, - "DD_TRACE_CLIENT_IP_HEADER" => {version: ["A"]}, - "DD_TRACE_CONCURRENT_RUBY_ENABLED" => {version: ["A"]}, - "DD_TRACE_DALLI_ANALYTICS_ENABLED" => {version: ["A"]}, - "DD_TRACE_DALLI_ANALYTICS_SAMPLE_RATE" => {version: ["A"]}, - "DD_TRACE_DALLI_ENABLED" => {version: ["A"]}, - "DD_TRACE_DALLI_PEER_SERVICE" => {version: ["A"]}, - "DD_TRACE_DALLI_SERVICE_NAME" => {version: ["A"]}, - "DD_TRACE_DEBUG" => {version: ["B"]}, - "DD_TRACE_DELAYED_JOB_ANALYTICS_ENABLED" => {version: ["A"]}, - "DD_TRACE_DELAYED_JOB_ANALYTICS_SAMPLE_RATE" => {version: ["A"]}, - "DD_TRACE_DELAYED_JOB_ENABLED" => {version: ["A"]}, - "DD_TRACE_ELASTICSEARCH_ANALYTICS_ENABLED" => {version: ["A"]}, - "DD_TRACE_ELASTICSEARCH_ANALYTICS_SAMPLE_RATE" => {version: ["A"]}, - "DD_TRACE_ELASTICSEARCH_ENABLED" => {version: ["A"]}, - "DD_TRACE_ELASTICSEARCH_PEER_SERVICE" => {version: ["A"]}, - "DD_TRACE_ELASTICSEARCH_SERVICE_NAME" => {version: ["A"]}, - "DD_TRACE_ENABLED" => {version: ["B"]}, - "DD_TRACE_ETHON_ANALYTICS_ENABLED" => {version: ["A"]}, - "DD_TRACE_ETHON_ANALYTICS_SAMPLE_RATE" => {version: ["A"]}, - "DD_TRACE_ETHON_ENABLED" => {version: ["A"]}, - "DD_TRACE_ETHON_PEER_SERVICE" => {version: ["A"]}, - "DD_TRACE_ETHON_SERVICE_NAME" => {version: ["A"]}, - "DD_TRACE_EXCON_ANALYTICS_ENABLED" => {version: ["A"]}, - "DD_TRACE_EXCON_ANALYTICS_SAMPLE_RATE" => {version: ["A"]}, - "DD_TRACE_EXCON_ENABLED" => {version: ["A"]}, - "DD_TRACE_EXCON_ERROR_STATUS_CODES" => {version: ["A"]}, - "DD_TRACE_EXCON_PEER_SERVICE" => {version: ["A"]}, - "DD_TRACE_EXCON_SERVICE_NAME" => {version: ["A"]}, - "DD_TRACE_FARADAY_ANALYTICS_ENABLED" => {version: ["A"]}, - "DD_TRACE_FARADAY_ANALYTICS_SAMPLE_RATE" => {version: ["A"]}, - "DD_TRACE_FARADAY_ENABLED" => {version: ["A"]}, - "DD_TRACE_FARADAY_ERROR_STATUS_CODES" => {version: ["A"]}, - "DD_TRACE_FARADAY_PEER_SERVICE" => {version: ["A"]}, - "DD_TRACE_FARADAY_SERVICE_NAME" => {version: ["A"]}, - "DD_TRACE_GRAPE_ANALYTICS_ENABLED" => {version: ["A"]}, - "DD_TRACE_GRAPE_ANALYTICS_SAMPLE_RATE" => {version: ["A"]}, - "DD_TRACE_GRAPE_ENABLED" => {version: ["A"]}, - "DD_TRACE_GRAPE_ERROR_STATUS_CODES" => {version: ["A"]}, - "DD_TRACE_GRAPHQL_ANALYTICS_ENABLED" => {version: ["A"]}, - "DD_TRACE_GRAPHQL_ANALYTICS_SAMPLE_RATE" => {version: ["A"]}, - "DD_TRACE_GRAPHQL_ENABLED" => {version: ["A"]}, - "DD_TRACE_GRAPHQL_ERROR_EXTENSIONS" => {version: ["A"]}, - "DD_TRACE_GRAPHQL_ERROR_TRACKING" => {version: ["A"]}, - "DD_TRACE_GRAPHQL_WITH_UNIFIED_TRACER" => {version: ["A"]}, - "DD_TRACE_GRPC_ANALYTICS_ENABLED" => {version: ["A"]}, - "DD_TRACE_GRPC_ANALYTICS_SAMPLE_RATE" => {version: ["A"]}, - "DD_TRACE_GRPC_ENABLED" => {version: ["A"]}, - "DD_TRACE_GRPC_PEER_SERVICE" => {version: ["A"]}, - "DD_TRACE_GRPC_SERVICE_NAME" => {version: ["A"]}, - "DD_TRACE_HANAMI_ENABLED" => {version: ["A"]}, - "DD_TRACE_HEADER_TAGS" => {version: ["A"]}, - "DD_TRACE_HTTPCLIENT_ANALYTICS_ENABLED" => {version: ["A"]}, - "DD_TRACE_HTTPCLIENT_ANALYTICS_SAMPLE_RATE" => {version: ["A"]}, - "DD_TRACE_HTTPCLIENT_ENABLED" => {version: ["A"]}, - "DD_TRACE_HTTPCLIENT_ERROR_STATUS_CODES" => {version: ["A"]}, - "DD_TRACE_HTTPCLIENT_PEER_SERVICE" => {version: ["A"]}, - "DD_TRACE_HTTPCLIENT_SERVICE_NAME" => {version: ["A"]}, - "DD_TRACE_HTTPRB_ANALYTICS_ENABLED" => {version: ["A"]}, - "DD_TRACE_HTTPRB_ANALYTICS_SAMPLE_RATE" => {version: ["A"]}, - "DD_TRACE_HTTPRB_ENABLED" => {version: ["A"]}, - "DD_TRACE_HTTPRB_ERROR_STATUS_CODES" => {version: ["A"]}, - "DD_TRACE_HTTPRB_PEER_SERVICE" => {version: ["A"]}, - "DD_TRACE_HTTPRB_SERVICE_NAME" => {version: ["A"]}, - "DD_TRACE_HTTP_ANALYTICS_ENABLED" => {version: ["A"]}, - "DD_TRACE_HTTP_ANALYTICS_SAMPLE_RATE" => {version: ["A"]}, - "DD_TRACE_HTTP_ENABLED" => {version: ["A"]}, - "DD_TRACE_HTTP_ERROR_STATUS_CODES" => {version: ["A"]}, - "DD_TRACE_KAFKA_ANALYTICS_ENABLED" => {version: ["A"]}, - "DD_TRACE_KAFKA_ANALYTICS_SAMPLE_RATE" => {version: ["A"]}, - "DD_TRACE_KAFKA_ENABLED" => {version: ["A"]}, - "DD_TRACE_KARAFKA_ENABLED" => {version: ["A"]}, - "DD_TRACE_LOGRAGE_ENABLED" => {version: ["A"]}, - "DD_TRACE_MEMCACHED_COMMAND_ENABLED" => {version: ["A"]}, - "DD_TRACE_MONGO_ANALYTICS_ENABLED" => {version: ["A"]}, - "DD_TRACE_MONGO_ANALYTICS_SAMPLE_RATE" => {version: ["A"]}, - "DD_TRACE_MONGO_ENABLED" => {version: ["A"]}, - "DD_TRACE_MONGO_JSON_COMMAND" => {version: ["A"]}, - "DD_TRACE_MONGO_PEER_SERVICE" => {version: ["A"]}, - "DD_TRACE_MONGO_SERVICE_NAME" => {version: ["A"]}, - "DD_TRACE_MYSQL2_ANALYTICS_ENABLED" => {version: ["A"]}, - "DD_TRACE_MYSQL2_ANALYTICS_SAMPLE_RATE" => {version: ["A"]}, - "DD_TRACE_MYSQL2_ENABLED" => {version: ["A"]}, - "DD_TRACE_MYSQL2_PEER_SERVICE" => {version: ["A"]}, - "DD_TRACE_MYSQL2_SERVICE_NAME" => {version: ["A"]}, - "DD_TRACE_NATIVE_SPAN_EVENTS" => {version: ["A"]}, - "DD_TRACE_NET_HTTP_PEER_SERVICE" => {version: ["A"]}, - "DD_TRACE_NET_HTTP_SERVICE_NAME" => {version: ["A"]}, - "DD_TRACE_OPENSEARCH_ANALYTICS_ENABLED" => {version: ["A"]}, - "DD_TRACE_OPENSEARCH_ANALYTICS_SAMPLE_RATE" => {version: ["A"]}, - "DD_TRACE_OPENSEARCH_ENABLED" => {version: ["A"]}, - "DD_TRACE_OPENSEARCH_PEER_SERVICE" => {version: ["A"]}, - "DD_TRACE_OPENSEARCH_RESOURCE_PATTERN" => {version: ["A"]}, - "DD_TRACE_OPENSEARCH_SERVICE_NAME" => {version: ["A"]}, - "DD_TRACE_PEER_SERVICE_DEFAULTS_ENABLED" => {version: ["A"]}, - "DD_TRACE_PEER_SERVICE_MAPPING" => {version: ["A"]}, - "DD_TRACE_PG_ANALYTICS_ENABLED" => {version: ["A"]}, - "DD_TRACE_PG_ANALYTICS_SAMPLE_RATE" => {version: ["A"]}, - "DD_TRACE_PG_ENABLED" => {version: ["A"]}, - "DD_TRACE_PG_PEER_SERVICE" => {version: ["A"]}, - "DD_TRACE_PG_SERVICE_NAME" => {version: ["A"]}, - "DD_TRACE_PRESTO_ANALYTICS_ENABLED" => {version: ["A"]}, - "DD_TRACE_PRESTO_ANALYTICS_SAMPLE_RATE" => {version: ["A"]}, - "DD_TRACE_PRESTO_ENABLED" => {version: ["A"]}, - "DD_TRACE_PRESTO_PEER_SERVICE" => {version: ["A"]}, - "DD_TRACE_PRESTO_SERVICE_NAME" => {version: ["A"]}, - "DD_TRACE_PROPAGATION_EXTRACT_FIRST" => {version: ["A"]}, - "DD_TRACE_PROPAGATION_STYLE" => {version: ["B"]}, - "DD_TRACE_PROPAGATION_STYLE_EXTRACT" => {version: ["A"]}, - "DD_TRACE_PROPAGATION_STYLE_INJECT" => {version: ["A"]}, - "DD_TRACE_QUE_ANALYTICS_ENABLED" => {version: ["A"]}, - "DD_TRACE_QUE_ANALYTICS_SAMPLE_RATE" => {version: ["A"]}, - "DD_TRACE_QUE_ENABLED" => {version: ["A"]}, - "DD_TRACE_QUE_TAG_ARGS_ENABLED" => {version: ["A"]}, - "DD_TRACE_QUE_TAG_DATA_ENABLED" => {version: ["A"]}, - "DD_TRACE_RACECAR_ANALYTICS_ENABLED" => {version: ["A"]}, - "DD_TRACE_RACECAR_ANALYTICS_SAMPLE_RATE" => {version: ["A"]}, - "DD_TRACE_RACECAR_ENABLED" => {version: ["A"]}, - "DD_TRACE_RACK_ANALYTICS_ENABLED" => {version: ["A"]}, - "DD_TRACE_RACK_ANALYTICS_SAMPLE_RATE" => {version: ["A"]}, - "DD_TRACE_RACK_ENABLED" => {version: ["A"]}, - "DD_TRACE_RAILS_ANALYTICS_ENABLED" => {version: ["A"]}, - "DD_TRACE_RAILS_ANALYTICS_SAMPLE_RATE" => {version: ["A"]}, - "DD_TRACE_RAILS_ENABLED" => {version: ["A"]}, - "DD_TRACE_RAKE_ANALYTICS_ENABLED" => {version: ["A"]}, - "DD_TRACE_RAKE_ANALYTICS_SAMPLE_RATE" => {version: ["A"]}, - "DD_TRACE_RAKE_ENABLED" => {version: ["A"]}, - "DD_TRACE_RATE_LIMIT" => {version: ["A"]}, - "DD_TRACE_REDIS_ANALYTICS_ENABLED" => {version: ["A"]}, - "DD_TRACE_REDIS_ANALYTICS_SAMPLE_RATE" => {version: ["A"]}, - "DD_TRACE_REDIS_ENABLED" => {version: ["A"]}, - "DD_TRACE_REDIS_PEER_SERVICE" => {version: ["A"]}, - "DD_TRACE_REDIS_SERVICE_NAME" => {version: ["A"]}, - "DD_TRACE_REMOVE_INTEGRATION_SERVICE_NAMES_ENABLED" => {version: ["A"]}, - "DD_TRACE_REPORT_HOSTNAME" => {version: ["A"]}, - "DD_TRACE_RESQUE_ANALYTICS_ENABLED" => {version: ["A"]}, - "DD_TRACE_RESQUE_ANALYTICS_SAMPLE_RATE" => {version: ["A"]}, - "DD_TRACE_RESQUE_ENABLED" => {version: ["A"]}, - "DD_TRACE_REST_CLIENT_ANALYTICS_ENABLED" => {version: ["A"]}, - "DD_TRACE_REST_CLIENT_ANALYTICS_SAMPLE_RATE" => {version: ["A"]}, - "DD_TRACE_REST_CLIENT_ENABLED" => {version: ["A"]}, - "DD_TRACE_REST_CLIENT_PEER_SERVICE" => {version: ["A"]}, - "DD_TRACE_REST_CLIENT_SERVICE_NAME" => {version: ["A"]}, - "DD_TRACE_RODA_ENABLED" => {version: ["A"]}, - "DD_TRACE_SAMPLE_RATE" => {version: ["B"]}, - "DD_TRACE_SAMPLING_RULES" => {version: ["A"]}, - "DD_TRACE_SEMANTIC_LOGGER_ENABLED" => {version: ["A"]}, - "DD_TRACE_SEQUEL_ANALYTICS_ENABLED" => {version: ["A"]}, - "DD_TRACE_SEQUEL_ANALYTICS_SAMPLE_RATE" => {version: ["A"]}, - "DD_TRACE_SEQUEL_ENABLED" => {version: ["A"]}, - "DD_TRACE_SHORYUKEN_ANALYTICS_ENABLED" => {version: ["A"]}, - "DD_TRACE_SHORYUKEN_ANALYTICS_SAMPLE_RATE" => {version: ["A"]}, - "DD_TRACE_SHORYUKEN_ENABLED" => {version: ["A"]}, - "DD_TRACE_SIDEKIQ_ANALYTICS_ENABLED" => {version: ["A"]}, - "DD_TRACE_SIDEKIQ_ANALYTICS_SAMPLE_RATE" => {version: ["A"]}, - "DD_TRACE_SIDEKIQ_ENABLED" => {version: ["A"]}, - "DD_TRACE_SINATRA_ANALYTICS_ENABLED" => {version: ["A"]}, - "DD_TRACE_SINATRA_ANALYTICS_SAMPLE_RATE" => {version: ["A"]}, - "DD_TRACE_SINATRA_ENABLED" => {version: ["A"]}, - "DD_TRACE_SNEAKERS_ANALYTICS_ENABLED" => {version: ["A"]}, - "DD_TRACE_SNEAKERS_ANALYTICS_SAMPLE_RATE" => {version: ["A"]}, - "DD_TRACE_SNEAKERS_ENABLED" => {version: ["A"]}, - "DD_TRACE_STARTUP_LOGS" => {version: ["A"]}, - "DD_TRACE_STRIPE_ANALYTICS_ENABLED" => {version: ["A"]}, - "DD_TRACE_STRIPE_ANALYTICS_SAMPLE_RATE" => {version: ["A"]}, - "DD_TRACE_STRIPE_ENABLED" => {version: ["A"]}, - "DD_TRACE_SUCKER_PUNCH_ANALYTICS_ENABLED" => {version: ["A"]}, - "DD_TRACE_SUCKER_PUNCH_ANALYTICS_SAMPLE_RATE" => {version: ["A"]}, - "DD_TRACE_SUCKER_PUNCH_ENABLED" => {version: ["A"]}, - "DD_TRACE_TEST_MODE_ENABLED" => {version: ["A"]}, - "DD_TRACE_TRILOGY_ANALYTICS_ENABLED" => {version: ["A"]}, - "DD_TRACE_TRILOGY_ANALYTICS_SAMPLE_RATE" => {version: ["A"]}, - "DD_TRACE_TRILOGY_ENABLED" => {version: ["A"]}, - "DD_TRACE_TRILOGY_PEER_SERVICE" => {version: ["A"]}, - "DD_TRACE_TRILOGY_SERVICE_NAME" => {version: ["A"]}, - "DD_TRACE_X_DATADOG_TAGS_MAX_LENGTH" => {version: ["A"]}, - "DD_VERSION" => {version: ["A"]}, - "OTEL_TRACES_SAMPLER_ARG" => {version: ["A"]}}.freeze + {'DD_AGENT_HOST' => {version: ['A']}, + 'DD_API_KEY' => {version: ['A']}, + 'DD_API_SECURITY_ENABLED' => {version: ['A']}, + 'DD_API_SECURITY_REQUEST_SAMPLE_RATE' => {version: ['A']}, + 'DD_API_SECURITY_SAMPLE_DELAY' => {version: ['A']}, + 'DD_APM_TRACING_ENABLED' => {version: ['A']}, + 'DD_APPSEC_AUTOMATED_USER_EVENTS_TRACKING' => {version: ['A']}, + 'DD_APPSEC_AUTO_USER_INSTRUMENTATION_MODE' => {version: ['A']}, + 'DD_APPSEC_ENABLED' => {version: ['A']}, + 'DD_APPSEC_HTTP_BLOCKED_TEMPLATE_HTML' => {version: ['A']}, + 'DD_APPSEC_HTTP_BLOCKED_TEMPLATE_JSON' => {version: ['A']}, + 'DD_APPSEC_HTTP_BLOCKED_TEMPLATE_TEXT' => {version: ['A']}, + 'DD_APPSEC_MAX_STACK_TRACES' => {version: ['A']}, + 'DD_APPSEC_MAX_STACK_TRACE_DEPTH' => {version: ['A']}, + 'DD_APPSEC_MAX_STACK_TRACE_DEPTH_TOP_PERCENT' => {version: ['A']}, + 'DD_APPSEC_OBFUSCATION_PARAMETER_KEY_REGEXP' => {version: ['A']}, + 'DD_APPSEC_OBFUSCATION_PARAMETER_VALUE_REGEXP' => {version: ['A']}, + 'DD_APPSEC_RASP_ENABLED' => {version: ['A']}, + 'DD_APPSEC_RULES' => {version: ['A']}, + 'DD_APPSEC_SCA_ENABLED' => {version: ['A']}, + 'DD_APPSEC_STACK_TRACE_ENABLED' => {version: ['A']}, + 'DD_APPSEC_TRACE_RATE_LIMIT' => {version: ['A']}, + 'DD_APPSEC_WAF_DEBUG' => {version: ['A']}, + 'DD_APPSEC_WAF_TIMEOUT' => {version: ['A']}, + 'DD_CRASHTRACKING_ENABLED' => {version: ['A']}, + 'DD_DBM_PROPAGATION_MODE' => {version: ['A']}, + 'DD_DISABLE_DATADOG_RAILS' => {version: ['A']}, + 'DD_DYNAMIC_INSTRUMENTATION_ENABLED' => {version: ['A']}, + 'DD_DYNAMIC_INSTRUMENTATION_PROBE_FILE' => {version: ['A']}, + 'DD_DYNAMIC_INSTRUMENTATION_REDACTED_IDENTIFIERS' => {version: ['A']}, + 'DD_DYNAMIC_INSTRUMENTATION_REDACTED_TYPES' => {version: ['A']}, + 'DD_ENV' => {version: ['A']}, + 'DD_ERROR_TRACKING_HANDLED_ERRORS' => {version: ['A']}, + 'DD_ERROR_TRACKING_HANDLED_ERRORS_INCLUDE' => {version: ['A']}, + 'DD_GIT_COMMIT_SHA' => {version: ['A']}, + 'DD_GIT_REPOSITORY_URL' => {version: ['A']}, + 'DD_HEALTH_METRICS_ENABLED' => {version: ['A']}, + 'DD_INJECTION_ENABLED' => {version: ['A']}, + 'DD_INJECT_FORCE' => {version: ['A']}, + 'DD_INSTRUMENTATION_INSTALL_ID' => {version: ['A']}, + 'DD_INSTRUMENTATION_INSTALL_TIME' => {version: ['A']}, + 'DD_INSTRUMENTATION_INSTALL_TYPE' => {version: ['A']}, + 'DD_INSTRUMENTATION_TELEMETRY_ENABLED' => {version: ['A']}, + 'DD_INTEGRATION_SERVICE' => {version: ['A']}, + 'DD_LOGS_INJECTION' => {version: ['A']}, + 'DD_METRIC_AGENT_PORT' => {version: ['A']}, + 'DD_PROFILING_ALLOCATION_ENABLED' => {version: ['A']}, + 'DD_PROFILING_DIR_INTERRUPTION_WORKAROUND_ENABLED' => {version: ['A']}, + 'DD_PROFILING_ENABLED' => {version: ['A']}, + 'DD_PROFILING_ENDPOINT_COLLECTION_ENABLED' => {version: ['A']}, + 'DD_PROFILING_EXPERIMENTAL_HEAP_ENABLED' => {version: ['A']}, + 'DD_PROFILING_EXPERIMENTAL_HEAP_SAMPLE_RATE' => {version: ['A']}, + 'DD_PROFILING_EXPERIMENTAL_HEAP_SIZE_ENABLED' => {version: ['A']}, + 'DD_PROFILING_GC_ENABLED' => {version: ['A']}, + 'DD_PROFILING_GVL_ENABLED' => {version: ['A']}, + 'DD_PROFILING_HEAP_CLEAN_AFTER_GC_ENABLED' => {version: ['A']}, + 'DD_PROFILING_MAX_FRAMES' => {version: ['A']}, + 'DD_PROFILING_NATIVE_FILENAMES_ENABLED' => {version: ['A']}, + 'DD_PROFILING_NO_SIGNALS_WORKAROUND_ENABLED' => {version: ['A']}, + 'DD_PROFILING_OVERHEAD_TARGET_PERCENTAGE' => {version: ['A']}, + 'DD_PROFILING_PREVIEW_OTEL_CONTEXT_ENABLED' => {version: ['A']}, + 'DD_PROFILING_SIGHANDLER_SAMPLING_ENABLED' => {version: ['A']}, + 'DD_PROFILING_SKIP_MYSQL2_CHECK' => {version: ['A']}, + 'DD_PROFILING_TIMELINE_ENABLED' => {version: ['A']}, + 'DD_PROFILING_UPLOAD_PERIOD' => {version: ['A']}, + 'DD_PROFILING_UPLOAD_TIMEOUT' => {version: ['A']}, + 'DD_REDIS_COMMAND_ARGS' => {version: ['A']}, + 'DD_REMOTE_CONFIGURATION_ENABLED' => {version: ['A']}, + 'DD_REMOTE_CONFIG_BOOT_TIMEOUT_SECONDS' => {version: ['A']}, + 'DD_REMOTE_CONFIG_POLL_INTERVAL_SECONDS' => {version: ['A']}, + 'DD_RODA_ANALYTICS_ENABLED' => {version: ['A']}, + 'DD_RODA_ANALYTICS_SAMPLE_RATE' => {version: ['A']}, + 'DD_RUNTIME_METRICS_ENABLED' => {version: ['A']}, + 'DD_RUNTIME_METRICS_RUNTIME_ID_ENABLED' => {version: ['A']}, + 'DD_SERVICE' => {version: ['B']}, + 'DD_SITE' => {version: ['A']}, + 'DD_SPAN_SAMPLING_RULES' => {version: ['A']}, + 'DD_SPAN_SAMPLING_RULES_FILE' => {version: ['A']}, + 'DD_TAGS' => {version: ['B']}, + 'DD_TELEMETRY_AGENTLESS_URL' => {version: ['A']}, + 'DD_TELEMETRY_DEPENDENCY_COLLECTION_ENABLED' => {version: ['A']}, + 'DD_TELEMETRY_HEARTBEAT_INTERVAL' => {version: ['A']}, + 'DD_TELEMETRY_LOG_COLLECTION_ENABLED' => {version: ['A']}, + 'DD_TELEMETRY_METRICS_AGGREGATION_INTERVAL' => {version: ['A']}, + 'DD_TELEMETRY_METRICS_ENABLED' => {version: ['A']}, + 'DD_TRACE_128_BIT_TRACEID_GENERATION_ENABLED' => {version: ['A']}, + 'DD_TRACE_128_BIT_TRACEID_LOGGING_ENABLED' => {version: ['A']}, + 'DD_TRACE_ACTION_CABLE_ANALYTICS_ENABLED' => {version: ['A']}, + 'DD_TRACE_ACTION_CABLE_ANALYTICS_SAMPLE_RATE' => {version: ['A']}, + 'DD_TRACE_ACTION_CABLE_ENABLED' => {version: ['A']}, + 'DD_TRACE_ACTION_MAILER_ANALYTICS_ENABLED' => {version: ['A']}, + 'DD_TRACE_ACTION_MAILER_ANALYTICS_SAMPLE_RATE' => {version: ['A']}, + 'DD_TRACE_ACTION_MAILER_ENABLED' => {version: ['A']}, + 'DD_TRACE_ACTION_PACK_ANALYTICS_ENABLED' => {version: ['A']}, + 'DD_TRACE_ACTION_PACK_ANALYTICS_SAMPLE_RATE' => {version: ['A']}, + 'DD_TRACE_ACTION_PACK_ENABLED' => {version: ['A']}, + 'DD_TRACE_ACTION_VIEW_ANALYTICS_ENABLED' => {version: ['A']}, + 'DD_TRACE_ACTION_VIEW_ANALYTICS_SAMPLE_RATE' => {version: ['A']}, + 'DD_TRACE_ACTION_VIEW_ENABLED' => {version: ['A']}, + 'DD_TRACE_ACTIVE_JOB_ANALYTICS_ENABLED' => {version: ['A']}, + 'DD_TRACE_ACTIVE_JOB_ANALYTICS_SAMPLE_RATE' => {version: ['A']}, + 'DD_TRACE_ACTIVE_JOB_ENABLED' => {version: ['A']}, + 'DD_TRACE_ACTIVE_MODEL_SERIALIZERS_ANALYTICS_ENABLED' => {version: ['A']}, + 'DD_TRACE_ACTIVE_MODEL_SERIALIZERS_ANALYTICS_SAMPLE_RATE' => {version: ['A']}, + 'DD_TRACE_ACTIVE_MODEL_SERIALIZERS_ENABLED' => {version: ['A']}, + 'DD_TRACE_ACTIVE_RECORD_ANALYTICS_ENABLED' => {version: ['A']}, + 'DD_TRACE_ACTIVE_RECORD_ANALYTICS_SAMPLE_RATE' => {version: ['A']}, + 'DD_TRACE_ACTIVE_RECORD_ENABLED' => {version: ['A']}, + 'DD_TRACE_ACTIVE_SUPPORT_ANALYTICS_ENABLED' => {version: ['A']}, + 'DD_TRACE_ACTIVE_SUPPORT_ANALYTICS_SAMPLE_RATE' => {version: ['A']}, + 'DD_TRACE_ACTIVE_SUPPORT_ENABLED' => {version: ['A']}, + 'DD_TRACE_AGENT_PORT' => {version: ['A']}, + 'DD_TRACE_AGENT_TIMEOUT_SECONDS' => {version: ['A']}, + 'DD_TRACE_AGENT_URL' => {version: ['A']}, + 'DD_TRACE_ANALYTICS_ENABLED' => {version: ['A']}, + 'DD_TRACE_AWS_ANALYTICS_ENABLED' => {version: ['A']}, + 'DD_TRACE_AWS_ANALYTICS_SAMPLE_RATE' => {version: ['A']}, + 'DD_TRACE_AWS_ENABLED' => {version: ['A']}, + 'DD_TRACE_AWS_PEER_SERVICE' => {version: ['A']}, + 'DD_TRACE_AWS_SERVICE_NAME' => {version: ['A']}, + 'DD_TRACE_BAGGAGE_TAG_KEYS' => {version: ['A']}, + 'DD_TRACE_CLIENT_IP_ENABLED' => {version: ['A']}, + 'DD_TRACE_CLIENT_IP_HEADER' => {version: ['A']}, + 'DD_TRACE_CONCURRENT_RUBY_ENABLED' => {version: ['A']}, + 'DD_TRACE_DALLI_ANALYTICS_ENABLED' => {version: ['A']}, + 'DD_TRACE_DALLI_ANALYTICS_SAMPLE_RATE' => {version: ['A']}, + 'DD_TRACE_DALLI_ENABLED' => {version: ['A']}, + 'DD_TRACE_DALLI_PEER_SERVICE' => {version: ['A']}, + 'DD_TRACE_DALLI_SERVICE_NAME' => {version: ['A']}, + 'DD_TRACE_DEBUG' => {version: ['B']}, + 'DD_TRACE_DELAYED_JOB_ANALYTICS_ENABLED' => {version: ['A']}, + 'DD_TRACE_DELAYED_JOB_ANALYTICS_SAMPLE_RATE' => {version: ['A']}, + 'DD_TRACE_DELAYED_JOB_ENABLED' => {version: ['A']}, + 'DD_TRACE_ELASTICSEARCH_ANALYTICS_ENABLED' => {version: ['A']}, + 'DD_TRACE_ELASTICSEARCH_ANALYTICS_SAMPLE_RATE' => {version: ['A']}, + 'DD_TRACE_ELASTICSEARCH_ENABLED' => {version: ['A']}, + 'DD_TRACE_ELASTICSEARCH_PEER_SERVICE' => {version: ['A']}, + 'DD_TRACE_ELASTICSEARCH_SERVICE_NAME' => {version: ['A']}, + 'DD_TRACE_ENABLED' => {version: ['B']}, + 'DD_TRACE_ETHON_ANALYTICS_ENABLED' => {version: ['A']}, + 'DD_TRACE_ETHON_ANALYTICS_SAMPLE_RATE' => {version: ['A']}, + 'DD_TRACE_ETHON_ENABLED' => {version: ['A']}, + 'DD_TRACE_ETHON_PEER_SERVICE' => {version: ['A']}, + 'DD_TRACE_ETHON_SERVICE_NAME' => {version: ['A']}, + 'DD_TRACE_EXCON_ANALYTICS_ENABLED' => {version: ['A']}, + 'DD_TRACE_EXCON_ANALYTICS_SAMPLE_RATE' => {version: ['A']}, + 'DD_TRACE_EXCON_ENABLED' => {version: ['A']}, + 'DD_TRACE_EXCON_ERROR_STATUS_CODES' => {version: ['A']}, + 'DD_TRACE_EXCON_PEER_SERVICE' => {version: ['A']}, + 'DD_TRACE_EXCON_SERVICE_NAME' => {version: ['A']}, + 'DD_TRACE_FARADAY_ANALYTICS_ENABLED' => {version: ['A']}, + 'DD_TRACE_FARADAY_ANALYTICS_SAMPLE_RATE' => {version: ['A']}, + 'DD_TRACE_FARADAY_ENABLED' => {version: ['A']}, + 'DD_TRACE_FARADAY_ERROR_STATUS_CODES' => {version: ['A']}, + 'DD_TRACE_FARADAY_PEER_SERVICE' => {version: ['A']}, + 'DD_TRACE_FARADAY_SERVICE_NAME' => {version: ['A']}, + 'DD_TRACE_GRAPE_ANALYTICS_ENABLED' => {version: ['A']}, + 'DD_TRACE_GRAPE_ANALYTICS_SAMPLE_RATE' => {version: ['A']}, + 'DD_TRACE_GRAPE_ENABLED' => {version: ['A']}, + 'DD_TRACE_GRAPE_ERROR_STATUS_CODES' => {version: ['A']}, + 'DD_TRACE_GRAPHQL_ANALYTICS_ENABLED' => {version: ['A']}, + 'DD_TRACE_GRAPHQL_ANALYTICS_SAMPLE_RATE' => {version: ['A']}, + 'DD_TRACE_GRAPHQL_ENABLED' => {version: ['A']}, + 'DD_TRACE_GRAPHQL_ERROR_EXTENSIONS' => {version: ['A']}, + 'DD_TRACE_GRAPHQL_ERROR_TRACKING' => {version: ['A']}, + 'DD_TRACE_GRAPHQL_CAPTURE_VARIABLES' => {version: ['A']}, + 'DD_TRACE_GRAPHQL_CAPTURE_VARIABLES_EXCEPT' => {version: ['A']}, + 'DD_TRACE_GRAPHQL_WITH_UNIFIED_TRACER' => {version: ['A']}, + 'DD_TRACE_GRPC_ANALYTICS_ENABLED' => {version: ['A']}, + 'DD_TRACE_GRPC_ANALYTICS_SAMPLE_RATE' => {version: ['A']}, + 'DD_TRACE_GRPC_ENABLED' => {version: ['A']}, + 'DD_TRACE_GRPC_PEER_SERVICE' => {version: ['A']}, + 'DD_TRACE_GRPC_SERVICE_NAME' => {version: ['A']}, + 'DD_TRACE_HANAMI_ENABLED' => {version: ['A']}, + 'DD_TRACE_HEADER_TAGS' => {version: ['A']}, + 'DD_TRACE_HTTPCLIENT_ANALYTICS_ENABLED' => {version: ['A']}, + 'DD_TRACE_HTTPCLIENT_ANALYTICS_SAMPLE_RATE' => {version: ['A']}, + 'DD_TRACE_HTTPCLIENT_ENABLED' => {version: ['A']}, + 'DD_TRACE_HTTPCLIENT_ERROR_STATUS_CODES' => {version: ['A']}, + 'DD_TRACE_HTTPCLIENT_PEER_SERVICE' => {version: ['A']}, + 'DD_TRACE_HTTPCLIENT_SERVICE_NAME' => {version: ['A']}, + 'DD_TRACE_HTTPRB_ANALYTICS_ENABLED' => {version: ['A']}, + 'DD_TRACE_HTTPRB_ANALYTICS_SAMPLE_RATE' => {version: ['A']}, + 'DD_TRACE_HTTPRB_ENABLED' => {version: ['A']}, + 'DD_TRACE_HTTPRB_ERROR_STATUS_CODES' => {version: ['A']}, + 'DD_TRACE_HTTPRB_PEER_SERVICE' => {version: ['A']}, + 'DD_TRACE_HTTPRB_SERVICE_NAME' => {version: ['A']}, + 'DD_TRACE_HTTP_ANALYTICS_ENABLED' => {version: ['A']}, + 'DD_TRACE_HTTP_ANALYTICS_SAMPLE_RATE' => {version: ['A']}, + 'DD_TRACE_HTTP_ENABLED' => {version: ['A']}, + 'DD_TRACE_HTTP_ERROR_STATUS_CODES' => {version: ['A']}, + 'DD_TRACE_KAFKA_ANALYTICS_ENABLED' => {version: ['A']}, + 'DD_TRACE_KAFKA_ANALYTICS_SAMPLE_RATE' => {version: ['A']}, + 'DD_TRACE_KAFKA_ENABLED' => {version: ['A']}, + 'DD_TRACE_KARAFKA_ENABLED' => {version: ['A']}, + 'DD_TRACE_LOGRAGE_ENABLED' => {version: ['A']}, + 'DD_TRACE_MEMCACHED_COMMAND_ENABLED' => {version: ['A']}, + 'DD_TRACE_MONGO_ANALYTICS_ENABLED' => {version: ['A']}, + 'DD_TRACE_MONGO_ANALYTICS_SAMPLE_RATE' => {version: ['A']}, + 'DD_TRACE_MONGO_ENABLED' => {version: ['A']}, + 'DD_TRACE_MONGO_JSON_COMMAND' => {version: ['A']}, + 'DD_TRACE_MONGO_PEER_SERVICE' => {version: ['A']}, + 'DD_TRACE_MONGO_SERVICE_NAME' => {version: ['A']}, + 'DD_TRACE_MYSQL2_ANALYTICS_ENABLED' => {version: ['A']}, + 'DD_TRACE_MYSQL2_ANALYTICS_SAMPLE_RATE' => {version: ['A']}, + 'DD_TRACE_MYSQL2_ENABLED' => {version: ['A']}, + 'DD_TRACE_MYSQL2_PEER_SERVICE' => {version: ['A']}, + 'DD_TRACE_MYSQL2_SERVICE_NAME' => {version: ['A']}, + 'DD_TRACE_NATIVE_SPAN_EVENTS' => {version: ['A']}, + 'DD_TRACE_NET_HTTP_PEER_SERVICE' => {version: ['A']}, + 'DD_TRACE_NET_HTTP_SERVICE_NAME' => {version: ['A']}, + 'DD_TRACE_OPENSEARCH_ANALYTICS_ENABLED' => {version: ['A']}, + 'DD_TRACE_OPENSEARCH_ANALYTICS_SAMPLE_RATE' => {version: ['A']}, + 'DD_TRACE_OPENSEARCH_ENABLED' => {version: ['A']}, + 'DD_TRACE_OPENSEARCH_PEER_SERVICE' => {version: ['A']}, + 'DD_TRACE_OPENSEARCH_RESOURCE_PATTERN' => {version: ['A']}, + 'DD_TRACE_OPENSEARCH_SERVICE_NAME' => {version: ['A']}, + 'DD_TRACE_PEER_SERVICE_DEFAULTS_ENABLED' => {version: ['A']}, + 'DD_TRACE_PEER_SERVICE_MAPPING' => {version: ['A']}, + 'DD_TRACE_PG_ANALYTICS_ENABLED' => {version: ['A']}, + 'DD_TRACE_PG_ANALYTICS_SAMPLE_RATE' => {version: ['A']}, + 'DD_TRACE_PG_ENABLED' => {version: ['A']}, + 'DD_TRACE_PG_PEER_SERVICE' => {version: ['A']}, + 'DD_TRACE_PG_SERVICE_NAME' => {version: ['A']}, + 'DD_TRACE_PRESTO_ANALYTICS_ENABLED' => {version: ['A']}, + 'DD_TRACE_PRESTO_ANALYTICS_SAMPLE_RATE' => {version: ['A']}, + 'DD_TRACE_PRESTO_ENABLED' => {version: ['A']}, + 'DD_TRACE_PRESTO_PEER_SERVICE' => {version: ['A']}, + 'DD_TRACE_PRESTO_SERVICE_NAME' => {version: ['A']}, + 'DD_TRACE_PROPAGATION_EXTRACT_FIRST' => {version: ['A']}, + 'DD_TRACE_PROPAGATION_STYLE' => {version: ['B']}, + 'DD_TRACE_PROPAGATION_STYLE_EXTRACT' => {version: ['A']}, + 'DD_TRACE_PROPAGATION_STYLE_INJECT' => {version: ['A']}, + 'DD_TRACE_QUE_ANALYTICS_ENABLED' => {version: ['A']}, + 'DD_TRACE_QUE_ANALYTICS_SAMPLE_RATE' => {version: ['A']}, + 'DD_TRACE_QUE_ENABLED' => {version: ['A']}, + 'DD_TRACE_QUE_TAG_ARGS_ENABLED' => {version: ['A']}, + 'DD_TRACE_QUE_TAG_DATA_ENABLED' => {version: ['A']}, + 'DD_TRACE_RACECAR_ANALYTICS_ENABLED' => {version: ['A']}, + 'DD_TRACE_RACECAR_ANALYTICS_SAMPLE_RATE' => {version: ['A']}, + 'DD_TRACE_RACECAR_ENABLED' => {version: ['A']}, + 'DD_TRACE_RACK_ANALYTICS_ENABLED' => {version: ['A']}, + 'DD_TRACE_RACK_ANALYTICS_SAMPLE_RATE' => {version: ['A']}, + 'DD_TRACE_RACK_ENABLED' => {version: ['A']}, + 'DD_TRACE_RAILS_ANALYTICS_ENABLED' => {version: ['A']}, + 'DD_TRACE_RAILS_ANALYTICS_SAMPLE_RATE' => {version: ['A']}, + 'DD_TRACE_RAILS_ENABLED' => {version: ['A']}, + 'DD_TRACE_RAKE_ANALYTICS_ENABLED' => {version: ['A']}, + 'DD_TRACE_RAKE_ANALYTICS_SAMPLE_RATE' => {version: ['A']}, + 'DD_TRACE_RAKE_ENABLED' => {version: ['A']}, + 'DD_TRACE_RATE_LIMIT' => {version: ['A']}, + 'DD_TRACE_REDIS_ANALYTICS_ENABLED' => {version: ['A']}, + 'DD_TRACE_REDIS_ANALYTICS_SAMPLE_RATE' => {version: ['A']}, + 'DD_TRACE_REDIS_ENABLED' => {version: ['A']}, + 'DD_TRACE_REDIS_PEER_SERVICE' => {version: ['A']}, + 'DD_TRACE_REDIS_SERVICE_NAME' => {version: ['A']}, + 'DD_TRACE_REMOVE_INTEGRATION_SERVICE_NAMES_ENABLED' => {version: ['A']}, + 'DD_TRACE_REPORT_HOSTNAME' => {version: ['A']}, + 'DD_TRACE_RESQUE_ANALYTICS_ENABLED' => {version: ['A']}, + 'DD_TRACE_RESQUE_ANALYTICS_SAMPLE_RATE' => {version: ['A']}, + 'DD_TRACE_RESQUE_ENABLED' => {version: ['A']}, + 'DD_TRACE_REST_CLIENT_ANALYTICS_ENABLED' => {version: ['A']}, + 'DD_TRACE_REST_CLIENT_ANALYTICS_SAMPLE_RATE' => {version: ['A']}, + 'DD_TRACE_REST_CLIENT_ENABLED' => {version: ['A']}, + 'DD_TRACE_REST_CLIENT_PEER_SERVICE' => {version: ['A']}, + 'DD_TRACE_REST_CLIENT_SERVICE_NAME' => {version: ['A']}, + 'DD_TRACE_RODA_ENABLED' => {version: ['A']}, + 'DD_TRACE_SAMPLE_RATE' => {version: ['B']}, + 'DD_TRACE_SAMPLING_RULES' => {version: ['A']}, + 'DD_TRACE_SEMANTIC_LOGGER_ENABLED' => {version: ['A']}, + 'DD_TRACE_SEQUEL_ANALYTICS_ENABLED' => {version: ['A']}, + 'DD_TRACE_SEQUEL_ANALYTICS_SAMPLE_RATE' => {version: ['A']}, + 'DD_TRACE_SEQUEL_ENABLED' => {version: ['A']}, + 'DD_TRACE_SHORYUKEN_ANALYTICS_ENABLED' => {version: ['A']}, + 'DD_TRACE_SHORYUKEN_ANALYTICS_SAMPLE_RATE' => {version: ['A']}, + 'DD_TRACE_SHORYUKEN_ENABLED' => {version: ['A']}, + 'DD_TRACE_SIDEKIQ_ANALYTICS_ENABLED' => {version: ['A']}, + 'DD_TRACE_SIDEKIQ_ANALYTICS_SAMPLE_RATE' => {version: ['A']}, + 'DD_TRACE_SIDEKIQ_ENABLED' => {version: ['A']}, + 'DD_TRACE_SINATRA_ANALYTICS_ENABLED' => {version: ['A']}, + 'DD_TRACE_SINATRA_ANALYTICS_SAMPLE_RATE' => {version: ['A']}, + 'DD_TRACE_SINATRA_ENABLED' => {version: ['A']}, + 'DD_TRACE_SNEAKERS_ANALYTICS_ENABLED' => {version: ['A']}, + 'DD_TRACE_SNEAKERS_ANALYTICS_SAMPLE_RATE' => {version: ['A']}, + 'DD_TRACE_SNEAKERS_ENABLED' => {version: ['A']}, + 'DD_TRACE_STARTUP_LOGS' => {version: ['A']}, + 'DD_TRACE_STRIPE_ANALYTICS_ENABLED' => {version: ['A']}, + 'DD_TRACE_STRIPE_ANALYTICS_SAMPLE_RATE' => {version: ['A']}, + 'DD_TRACE_STRIPE_ENABLED' => {version: ['A']}, + 'DD_TRACE_SUCKER_PUNCH_ANALYTICS_ENABLED' => {version: ['A']}, + 'DD_TRACE_SUCKER_PUNCH_ANALYTICS_SAMPLE_RATE' => {version: ['A']}, + 'DD_TRACE_SUCKER_PUNCH_ENABLED' => {version: ['A']}, + 'DD_TRACE_TEST_MODE_ENABLED' => {version: ['A']}, + 'DD_TRACE_TRILOGY_ANALYTICS_ENABLED' => {version: ['A']}, + 'DD_TRACE_TRILOGY_ANALYTICS_SAMPLE_RATE' => {version: ['A']}, + 'DD_TRACE_TRILOGY_ENABLED' => {version: ['A']}, + 'DD_TRACE_TRILOGY_PEER_SERVICE' => {version: ['A']}, + 'DD_TRACE_TRILOGY_SERVICE_NAME' => {version: ['A']}, + 'DD_TRACE_X_DATADOG_TAGS_MAX_LENGTH' => {version: ['A']}, + 'DD_VERSION' => {version: ['A']}, + 'OTEL_TRACES_SAMPLER_ARG' => {version: ['A']}}.freeze ALIASES = - {"DD_DISABLE_DATADOG_RAILS" => ["DISABLE_DATADOG_RAILS"], - "DD_PROFILING_GVL_ENABLED" => ["DD_PROFILING_PREVIEW_GVL_ENABLED"], - "DD_RUNTIME_METRICS_RUNTIME_ID_ENABLED" => ["DD_TRACE_EXPERIMENTAL_RUNTIME_ID_ENABLED"], - "DD_SERVICE" => ["OTEL_SERVICE_NAME"], - "DD_TAGS" => ["OTEL_RESOURCE_ATTRIBUTES"], - "DD_TRACE_DEBUG" => ["OTEL_LOG_LEVEL"], - "DD_TRACE_ENABLED" => ["OTEL_TRACES_EXPORTER"], - "DD_TRACE_PROPAGATION_STYLE" => ["OTEL_PROPAGATORS"], - "DD_TRACE_SAMPLE_RATE" => ["OTEL_TRACES_SAMPLER"]}.freeze + {'DD_DISABLE_DATADOG_RAILS' => ['DISABLE_DATADOG_RAILS'], + 'DD_PROFILING_GVL_ENABLED' => ['DD_PROFILING_PREVIEW_GVL_ENABLED'], + 'DD_RUNTIME_METRICS_RUNTIME_ID_ENABLED' => ['DD_TRACE_EXPERIMENTAL_RUNTIME_ID_ENABLED'], + 'DD_SERVICE' => ['OTEL_SERVICE_NAME'], + 'DD_TAGS' => ['OTEL_RESOURCE_ATTRIBUTES'], + 'DD_TRACE_DEBUG' => ['OTEL_LOG_LEVEL'], + 'DD_TRACE_ENABLED' => ['OTEL_TRACES_EXPORTER'], + 'DD_TRACE_PROPAGATION_STYLE' => ['OTEL_PROPAGATORS'], + 'DD_TRACE_SAMPLE_RATE' => ['OTEL_TRACES_SAMPLER']}.freeze DEPRECATIONS = - {"DD_PROFILING_PREVIEW_GVL_ENABLED" => "(This doesn't need a deprecation message since there's an alias for it)"}.freeze + {'DD_PROFILING_PREVIEW_GVL_ENABLED' => "(This doesn't need a deprecation message since there's an alias for it)"}.freeze ALIAS_TO_CANONICAL = - {"DD_PROFILING_PREVIEW_GVL_ENABLED" => "DD_PROFILING_GVL_ENABLED", - "DD_TRACE_EXPERIMENTAL_RUNTIME_ID_ENABLED" => "DD_RUNTIME_METRICS_RUNTIME_ID_ENABLED", - "DISABLE_DATADOG_RAILS" => "DD_DISABLE_DATADOG_RAILS", - "OTEL_LOG_LEVEL" => "DD_TRACE_DEBUG", - "OTEL_PROPAGATORS" => "DD_TRACE_PROPAGATION_STYLE", - "OTEL_RESOURCE_ATTRIBUTES" => "DD_TAGS", - "OTEL_SERVICE_NAME" => "DD_SERVICE", - "OTEL_TRACES_EXPORTER" => "DD_TRACE_ENABLED", - "OTEL_TRACES_SAMPLER" => "DD_TRACE_SAMPLE_RATE"}.freeze + {'DD_PROFILING_PREVIEW_GVL_ENABLED' => 'DD_PROFILING_GVL_ENABLED', + 'DD_TRACE_EXPERIMENTAL_RUNTIME_ID_ENABLED' => 'DD_RUNTIME_METRICS_RUNTIME_ID_ENABLED', + 'DISABLE_DATADOG_RAILS' => 'DD_DISABLE_DATADOG_RAILS', + 'OTEL_LOG_LEVEL' => 'DD_TRACE_DEBUG', + 'OTEL_PROPAGATORS' => 'DD_TRACE_PROPAGATION_STYLE', + 'OTEL_RESOURCE_ATTRIBUTES' => 'DD_TAGS', + 'OTEL_SERVICE_NAME' => 'DD_SERVICE', + 'OTEL_TRACES_EXPORTER' => 'DD_TRACE_ENABLED', + 'OTEL_TRACES_SAMPLER' => 'DD_TRACE_SAMPLE_RATE'}.freeze end end end diff --git a/lib/datadog/tracing/contrib/graphql/configuration/capture_variables.rb b/lib/datadog/tracing/contrib/graphql/configuration/capture_variables.rb new file mode 100644 index 00000000000..3fc3863a03f --- /dev/null +++ b/lib/datadog/tracing/contrib/graphql/configuration/capture_variables.rb @@ -0,0 +1,81 @@ +# frozen_string_literal: true + +require 'set' + +module Datadog + module Tracing + module Contrib + module GraphQL + module Configuration + # Processes GraphQL variable capture configuration for + # sanitization and fast matching. + class CaptureVariables + # Valid operation and variable names: alphanumeric characters or underscores + VALID_NAME_PATTERN = /\A[A-Za-z0-9_]+\z/.freeze + + EMPTY_MATCHER = Set.new.freeze + + # @param variables [String] Matching pairs from environment variable + # @param variables [Array] Matching pairs from programmatic configuration + def initialize(variables) + @variables = variables.is_a?(Array) ? variables.map(&:dup) : variables.split(',') + @variables_str = variables.is_a?(Array) ? variables.join(',') : variables.to_s + + @operation_vars = parse_config(@variables) + end + + # Get a variable matcher for a specific operation + # Returns frozen empty set if operation has no configured variables + # Returns a Set of variable names if operation has configured variables + # @param operation_name [String] GraphQL operation name + # @return [Set] set of variable names or empty set if no match + def matcher_for(operation_name) + @operation_vars[operation_name] || EMPTY_MATCHER + end + + # @return [Boolean] true if no variables are configured for capture + def empty? + @operation_vars.empty? + end + + # Returns the original configuration for inspection. + # Matches the environment variable format. + def to_s + @variables_str + end + + private + + # Parses comma-separated operation:variable pairs. + # Ignores invalid entries. + # + # @param values [Array] List of operation:variable pairs + # @return [Hash{String => Set}] Parsed configuration + def parse_config(values) + hash = {} + values.each do |fragment| + fragment.strip! + + next if fragment.empty? + + parts = fragment.split(':') + next unless parts.length == 2 + + operation_name = parts[0] + variable_name = parts[1] + + # Whitespaces left after splitting are invalid + next unless VALID_NAME_PATTERN.match?(operation_name) + next unless VALID_NAME_PATTERN.match?(variable_name) + + hash[operation_name] ||= Set.new + hash[operation_name] << variable_name + end + hash + end + end + end + end + end + end +end diff --git a/lib/datadog/tracing/contrib/graphql/configuration/settings.rb b/lib/datadog/tracing/contrib/graphql/configuration/settings.rb index d30b47599c9..e1d98dbd0ae 100644 --- a/lib/datadog/tracing/contrib/graphql/configuration/settings.rb +++ b/lib/datadog/tracing/contrib/graphql/configuration/settings.rb @@ -3,6 +3,7 @@ require_relative '../../configuration/settings' require_relative '../ext' require_relative 'error_extension_env_parser' +require_relative 'capture_variables' module Datadog module Tracing @@ -65,6 +66,22 @@ class Settings < Contrib::Configuration::Settings o.type :bool o.default false end + + # Variables to capture in GraphQL operations + option :capture_variables do |o| + o.env Ext::ENV_CAPTURE_VARIABLES + o.type :array, nilable: false + o.default [] + o.setter { |variable_tags, _| CaptureVariables.new(variable_tags) } + end + + # Variables to exclude from capture in GraphQL operations + option :capture_variables_except do |o| + o.env Ext::ENV_CAPTURE_VARIABLES_EXCEPT + o.type :array, nilable: false + o.default [] + o.setter { |variable_tags, _| CaptureVariables.new(variable_tags) } + end end end end diff --git a/lib/datadog/tracing/contrib/graphql/ext.rb b/lib/datadog/tracing/contrib/graphql/ext.rb index 16156d65bf8..45e755e43a5 100644 --- a/lib/datadog/tracing/contrib/graphql/ext.rb +++ b/lib/datadog/tracing/contrib/graphql/ext.rb @@ -14,6 +14,8 @@ module Ext ENV_WITH_UNIFIED_TRACER = 'DD_TRACE_GRAPHQL_WITH_UNIFIED_TRACER' ENV_ERROR_EXTENSIONS = 'DD_TRACE_GRAPHQL_ERROR_EXTENSIONS' ENV_ERROR_TRACKING = 'DD_TRACE_GRAPHQL_ERROR_TRACKING' + ENV_CAPTURE_VARIABLES = 'DD_TRACE_GRAPHQL_CAPTURE_VARIABLES' + ENV_CAPTURE_VARIABLES_EXCEPT = 'DD_TRACE_GRAPHQL_CAPTURE_VARIABLES_EXCEPT' SERVICE_NAME = 'graphql' TAG_COMPONENT = 'graphql' diff --git a/lib/datadog/tracing/contrib/graphql/unified_trace.rb b/lib/datadog/tracing/contrib/graphql/unified_trace.rb index 166517e17e7..dc593f701cd 100644 --- a/lib/datadog/tracing/contrib/graphql/unified_trace.rb +++ b/lib/datadog/tracing/contrib/graphql/unified_trace.rb @@ -23,6 +23,17 @@ def initialize(*args, **kwargs) @analytics_sample_rate = config[:analytics_sample_rate] @error_extensions_config = config[:error_extensions] + @capture_variables = config[:capture_variables] + @capture_variables_except = config[:capture_variables_except] + + @capture_mode = if !@capture_variables.empty? + :allowlist + elsif !@capture_variables_except.empty? + :denylist + else + nil # No variable capture configured + end + load_error_event_attributes(config[:error_tracking]) super @@ -97,9 +108,8 @@ def execute_query(*args, query:, **kwargs) query.selected_operation_name ) end - query.variables.instance_variable_get(:@storage).each do |key, value| - span.set_tag("graphql.variables.#{key}", value) - end + + capture_operation_variables(span, query) }, ->(span) { add_query_error_events(span, query.context.errors) }, query: query, @@ -122,6 +132,7 @@ def execute_field_span(callable, span_key, **kwargs) if platform_key trace(callable, span_key, platform_key, **kwargs) do |span| kwargs[:arguments].each do |key, value| + # DEV-3.0: Misnamed tag: fields have arguments, not variables. span.set_tag("graphql.variables.#{key}", value) end end @@ -178,6 +189,46 @@ def platform_resolve_type_key(type, *args, **kwargs) private + def capture_operation_variables(span, query) + return unless @capture_mode + + operation_name = query.selected_operation_name + return unless operation_name + + capture_vars = @capture_variables.matcher_for(operation_name) + except_vars = @capture_variables_except.matcher_for(operation_name) + + query.variables.to_h.each do |name, value| + if capture_variable?(name, capture_vars, except_vars) + # GraphQL variable `name` is always a valid span tag name, as per GraphQL spec + span.set_tag( + "graphql.operation.variable.#{name}", + serialize_variable_value(value) + ) + end + end + end + + def capture_variable?(name, capture_vars, except_vars) + if @capture_mode == :allowlist # Is in capture list and not in except list + capture_vars.member?(name) && !except_vars.member?(name) + elsif @capture_mode == :denylist # Capture if not in except list + !except_vars.member?(name) + end + end + + def serialize_variable_value(value) + case value + when TrueClass, FalseClass + value.to_s + when Integer, Float, String + value + else + # Fallback for string representation for other types + value.to_s + end + end + # Traces the given callable with the given trace key, resource, and kwargs. # # @param callable [Proc] the original method call diff --git a/spec/datadog/tracing/contrib/graphql/configuration/capture_variables_spec.rb b/spec/datadog/tracing/contrib/graphql/configuration/capture_variables_spec.rb new file mode 100644 index 00000000000..ec5714d4567 --- /dev/null +++ b/spec/datadog/tracing/contrib/graphql/configuration/capture_variables_spec.rb @@ -0,0 +1,191 @@ +# frozen_string_literal: true + +require 'datadog/tracing/contrib/graphql/configuration/capture_variables' + +RSpec.describe Datadog::Tracing::Contrib::GraphQL::Configuration::CaptureVariables do + describe '.new' do + subject(:config) { described_class.new(input) } + + context 'with empty array input' do + let(:input) { [] } + + it { expect(config.empty?).to be true } + end + + context 'with empty string' do + let(:input) { '' } + + it { expect(config.empty?).to be true } + end + + context 'with valid fragments' do + let(:input) { 'GetAd:id,ListIp:geo,AddKey:val' } + + it 'correctly parses operation and variable configuration' do + expect(config.matcher_for('GetAd')).to include('id') + expect(config.matcher_for('ListIp')).to include('geo') + expect(config.matcher_for('AddKey')).to include('val') + expect(config.matcher_for('GetAd')).not_to include('geo') + end + + it { expect(config.empty?).to be false } + end + + context 'with array input' do + let(:input) { ['GetAd:id', 'ListIp:geo', 'AddKey:val'] } + + it 'correctly parses operation and variable configuration' do + expect(config.matcher_for('GetAd')).to include('id') + expect(config.matcher_for('ListIp')).to include('geo') + expect(config.matcher_for('AddKey')).to include('val') + expect(config.matcher_for('GetAd')).not_to include('geo') + end + + it 'converts array to comma-separated string for to_s' do + expect(config.to_s).to eq('GetAd:id,ListIp:geo,AddKey:val') + end + + it { expect(config.empty?).to be false } + end + + context 'with duplicate operation:variable pairs' do + let(:input) { 'GetAd:id,GetAd:id,ListIp:geo' } + + it 'deduplicates entries' do + expect(config.matcher_for('GetAd')).to include('id') + expect(config.matcher_for('ListIp')).to include('geo') + end + end + + context 'with multiple variables for same operation' do + let(:input) { 'GetUser:id,GetUser:name,GetUser:email' } + + it 'groups variables under same operation' do + matcher = config.matcher_for('GetUser') + expect(matcher).to include('id', 'name', 'email') + expect(matcher).not_to include('other') + end + end + + context 'with same variable used by multiple operations' do + let(:input) { 'GetUser:id,GetPost:id,GetComment:id' } + + it 'handles same variable used by multiple operations' do + expect(config.matcher_for('GetUser')).to include('id') + expect(config.matcher_for('GetPost')).to include('id') + expect(config.matcher_for('GetComment')).to include('id') + expect(config.matcher_for('GetUser')).not_to include('name') + end + end + + context 'with whitespace around fragments' do + let(:input) { ' GetAd:id , ListIp:geo ' } + + it 'handles whitespace correctly' do + expect(config.matcher_for('GetAd')).to include('id') + expect(config.matcher_for('ListIp')).to include('geo') + end + end + + context 'with empty fragments' do + let(:input) { ',,GetAd:id,' } + + it 'skips empty fragments' do + expect(config.matcher_for('GetAd')).to include('id') + end + end + + context 'with invalid configurations' do + let(:valid_fragment) { 'ListIp:geo' } + + [ + {input: 'Get-Ad:bad,ListIp:geo', desc: 'invalid characters in operation name', invalid: ['Get-Ad', 'bad']}, + {input: 'GetAd:in-valid,ListIp:geo', desc: 'invalid characters in variable name', invalid: ['GetAd', 'in-valid']}, + {input: 'GetAd : bad,ListIp:geo', desc: 'whitespace around colon', invalid: ['GetAd ', 'bad']}, + {input: 'GetAd,ListIp:geo', desc: 'missing colon', invalid: ['GetAd', '']}, + {input: ':id,ListIp:geo', desc: 'empty operation name', invalid: ['', 'id']}, + {input: 'GetAd:,ListIp:geo', desc: 'empty variable name', invalid: ['GetAd', '']} + ].each do |test_case| + context "with #{test_case[:desc]}" do + let(:input) { test_case[:input] } + + it 'skips invalid fragments but keeps valid ones' do + expect(config.matcher_for('ListIp')).to include('geo') + matcher = config.matcher_for(test_case[:invalid][0]) + if matcher.empty? + expect(matcher).to be_empty + else + expect(matcher).not_to include(test_case[:invalid][1]) + end + end + end + end + end + + context 'with valid alphanumeric and underscore names' do + let(:input) { 'Get_Ad:var_1,Load_Ip:key_2' } + + it 'accepts valid names with underscores and numbers' do + expect(config.matcher_for('Get_Ad')).to include('var_1') + expect(config.matcher_for('Load_Ip')).to include('key_2') + end + end + + context 'with multiple colons' do + let(:input) { 'GetAd:id:bad,ListIp:geo' } + + it 'skips fragments with multiple colons' do + expect(config.matcher_for('ListIp')).to include('geo') + expect(config.matcher_for('GetAd')).to be_empty + end + end + end + + describe '#to_s' do + subject(:config) { described_class.new('GetUser:id,GetUser:name') } + + it 'returns the original configuration string' do + expect(config.to_s).to eq('GetUser:id,GetUser:name') + end + end + + describe '#matcher_for' do + subject(:config) { described_class.new('GetUser:id,GetUser:name,GetPost:title') } + + context 'with configured operation' do + it 'returns set of variable names for GetUser' do + matcher = config.matcher_for('GetUser') + expect(matcher).to be_a(Set) + expect(matcher).to include('id', 'name') + expect(matcher).not_to include('title') + end + + it 'returns set of variable names for GetPost' do + matcher = config.matcher_for('GetPost') + expect(matcher).to be_a(Set) + expect(matcher).to include('title') + expect(matcher).not_to include('id', 'name') + end + end + + context 'with unconfigured operation' do + it 'returns empty set for unknown operation' do + expect(config.matcher_for('UnknownOperation')).to be_empty + end + end + end + + describe '#empty?' do + context 'with no configuration' do + subject(:config) { described_class.new([]) } + + it { is_expected.to be_empty } + end + + context 'with configuration' do + subject(:config) { described_class.new('GetUser:id') } + + it { is_expected.not_to be_empty } + end + end +end diff --git a/spec/datadog/tracing/contrib/graphql/configuration/settings_spec.rb b/spec/datadog/tracing/contrib/graphql/configuration/settings_spec.rb index a1312d06e52..eb980331cd6 100644 --- a/spec/datadog/tracing/contrib/graphql/configuration/settings_spec.rb +++ b/spec/datadog/tracing/contrib/graphql/configuration/settings_spec.rb @@ -138,4 +138,52 @@ end end end + + shared_examples 'capture variables configuration' do |option_name, env_var| + subject(:config) { settings.public_send(option_name) } + let(:settings) { described_class.new } + + context 'when default' do + it { is_expected.to be_a(Datadog::Tracing::Contrib::GraphQL::Configuration::CaptureVariables) } + it { is_expected.to be_empty } + end + + context 'when given an array' do + let(:settings) { described_class.new(option_name => ['GetUser:id', 'GetPost:title']) } + + it 'configures the capture variables correctly' do + expect(config.matcher_for('GetUser')).to contain_exactly('id') + expect(config.matcher_for('GetPost')).to contain_exactly('title') + end + end + + context 'via the environment variable' do + it 'configures from environment variable' do + ClimateControl.modify(env_var => 'GetUser:id,GetPost:title') do + expect(config.matcher_for('GetUser')).to contain_exactly('id') + expect(config.matcher_for('GetPost')).to contain_exactly('title') + end + end + + context 'with empty string' do + it 'handles empty environment variable' do + ClimateControl.modify(env_var => '') do + expect(config.empty?).to be true + end + end + end + end + end + + describe 'capture_variables' do + include_examples 'capture variables configuration', + :capture_variables, + 'DD_TRACE_GRAPHQL_CAPTURE_VARIABLES' + end + + describe 'capture_variables_except' do + include_examples 'capture variables configuration', + :capture_variables_except, + 'DD_TRACE_GRAPHQL_CAPTURE_VARIABLES_EXCEPT' + end end diff --git a/spec/datadog/tracing/contrib/graphql/test_schema_examples.rb b/spec/datadog/tracing/contrib/graphql/test_schema_examples.rb index cbfe781af06..e0e52887f5f 100644 --- a/spec/datadog/tracing/contrib/graphql/test_schema_examples.rb +++ b/spec/datadog/tracing/contrib/graphql/test_schema_examples.rb @@ -2,11 +2,20 @@ require 'ostruct' require_relative 'test_helpers' +require 'datadog/tracing/contrib/support/spec_helper' +require 'datadog/tracing/contrib/graphql/unified_trace_patcher' +require 'datadog' def load_test_schema(prefix: '') # rubocop:disable Security/Eval # rubocop:disable Style/DocumentDynamicEvalDefinition eval <<-RUBY, binding, __FILE__, __LINE__ + 1 + class #{prefix}TestUserFilterInput < ::GraphQL::Schema::InputObject + argument :name, ::GraphQL::Types::String, required: false + argument :active, ::GraphQL::Types::Boolean, required: false + argument :min_age, ::GraphQL::Types::Int, required: false + end + class #{prefix}TestUserType < ::GraphQL::Schema::Object field :id, ::GraphQL::Types::ID, null: false field :name, ::GraphQL::Types::String, null: true @@ -28,6 +37,43 @@ def user(id:) def graphql_error raise 'GraphQL error' end + + field :user_with_org, #{prefix}TestUserType, null: false, description: 'Find user with org' do + argument :id, ::GraphQL::Types::ID, required: true + argument :org, ::GraphQL::Types::ID, required: true + end + + def user_with_org(id:, org:) + OpenStruct.new(id: id, name: 'Bits', org: org) + end + + field :user_with_filter, #{prefix}TestUserType, null: false, description: 'Find user with filter' do + argument :id, ::GraphQL::Types::ID, required: true + argument :active, ::GraphQL::Types::Boolean, required: true + end + + def user_with_filter(id:, active:) + OpenStruct.new(id: id, name: 'Bits', active: active) + end + + field :user_with_details, #{prefix}TestUserType, null: false, description: 'Find user with details' do + argument :id, ::GraphQL::Types::ID, required: true + argument :name, ::GraphQL::Types::String, required: false + argument :count, ::GraphQL::Types::Int, required: false + end + + def user_with_details(id:, name: nil, count: nil) + OpenStruct.new(id: id, name: name || 'Bits', count: count) + end + + field :user_with_input_filter, #{prefix}TestUserType, null: false, description: 'Find user with input filter' do + argument :id, ::GraphQL::Types::ID, required: true + argument :filter, #{prefix}TestUserFilterInput, required: true + end + + def user_with_input_filter(id:, filter:) + OpenStruct.new(id: id, name: 'Bits', filter: filter) + end end class #{prefix}TestGraphQLSchema < ::GraphQL::Schema @@ -51,6 +97,7 @@ class #{prefix}TestGraphQLSchema < ::GraphQL::Schema end def unload_test_schema(prefix: '') + Object.send(:remove_const, :"#{prefix}TestUserFilterInput") Object.send(:remove_const, :"#{prefix}TestUserType") Object.send(:remove_const, :"#{prefix}TestGraphQLQuery") Object.send(:remove_const, :"#{prefix}TestGraphQLSchema") @@ -98,7 +145,7 @@ def unload_test_schema(prefix: '') let(:service) { defined?(super) ? super() : tracer.default_service } describe 'query trace' do - subject(:result) { schema.execute(query: 'query Users($var: ID!){ user(id: $var) { name } }', variables: { var: 1 }) } + subject(:result) { schema.execute(query: 'query Users($var: ID!){ user(id: $var) { name } }', variables: {var: 1}) } matrix = [ ['graphql.analyze', 'query Users($var: ID!){ user(id: $var) { name } }'], @@ -124,7 +171,7 @@ def unload_test_schema(prefix: '') matrix.each_with_index do |(name, resource), index| it "creates #{name} span with #{resource} resource" do expect(result.to_h['errors']).to be nil - expect(result.to_h['data']).to eq({ 'user' => { 'name' => 'Bits' } }) + expect(result.to_h['data']).to eq({'user' => {'name' => 'Bits'}}) expect(spans).to have(matrix.length).items span = spans[index] @@ -141,15 +188,16 @@ def unload_test_schema(prefix: '') if name == 'graphql.execute' expect(span.get_tag('graphql.operation.type')).to eq('query') expect(span.get_tag('graphql.operation.name')).to eq('Users') - # graphql.variables.* in graphql.execute span are the ones defined outside the query - # (variables part in JSON for example) - expect(span.get_tag('graphql.variables.var')).to eq(1) + # Variables are now only captured when explicitly configured + # By default, no variables are captured + expect(span.get_tag('graphql.variables.var')).to be_nil expect(span.get_tag('span.kind')).to eq('server') end if name == 'graphql.resolve' && resource == 'TestGraphQLQuery.user' - # During graphql.resolve, it converts it to string (as it builds an SQL query for example) + # Field arguments are still captured with legacy graphql.variables.* tags + # This is different from operation variables which use graphql.operation.variable.* tags expect(span.get_tag('graphql.variables.id')).to eq('1') end end @@ -221,7 +269,7 @@ def unload_test_schema(prefix: '') 'extensions.bool' => true, 'extensions.str' => '1', 'extensions.array-1-2' => '[1, "2"]', - 'extensions.hash-a-b' => { a: 'b' }.to_s, # Hash#to_s changes per Ruby version: 3.3: '{:a=>1}', 3.4: '{a: 1}' + 'extensions.hash-a-b' => {a: 'b'}.to_s, # Hash#to_s changes per Ruby version: 3.3: '{:a=>1}', 3.4: '{a: 1}' 'extensions.object' => start_with('# 'Users:var,GetUser:id') do + # Reset configuration to pick up environment variable + Datadog.configuration.tracing[:graphql].reset! + ex.run + end + end + + it 'captures configured variables' do + schema.execute(query: 'query Users($var: ID!){ user(id: $var) { name } }', variables: {var: 1}) + + expect(graphql_execute.get_tag('graphql.operation.variable.var')).to eq(1) + end + + it 'does not capture unconfigured variables' do + schema.execute( + query: 'query GetUser($id: ID!, $org: ID!){ userWithOrg(id: $id, org: $org) { name } }', + variables: {id: 1, org: 2} + ) + + expect(graphql_execute.get_tag('graphql.operation.variable.id')).to eq(1) + expect(graphql_execute.get_tag('graphql.operation.variable.org')).to be_nil + end + + it 'does not capture variables for different operations' do + schema.execute(query: 'query DifferentOp($var: ID!){ user(id: $var) { name } }', variables: {var: 1}) + + expect(graphql_execute.get_tag('graphql.operation.variable.var')).to be_nil + end + end + + context 'with DD_TRACE_GRAPHQL_CAPTURE_VARIABLES_EXCEPT configured' do + around do |ex| + ClimateControl.modify( + 'DD_TRACE_GRAPHQL_CAPTURE_VARIABLES' => 'Users:var,Users:org', + 'DD_TRACE_GRAPHQL_CAPTURE_VARIABLES_EXCEPT' => 'Users:org' + ) do + Datadog.configuration.tracing[:graphql].reset! + ex.run + end + end + + it 'captures variables except those in the except list' do + schema.execute( + query: 'query Users($var: ID!, $org: ID!){ userWithOrg(id: $var, org: $org) { name } }', + variables: {var: 1, org: 2} + ) + + expect(graphql_execute.get_tag('graphql.operation.variable.var')).to eq(1) + expect(graphql_execute.get_tag('graphql.operation.variable.org')).to be_nil + end + end + + context 'with only DD_TRACE_GRAPHQL_CAPTURE_VARIABLES_EXCEPT configured' do + around do |ex| + ClimateControl.modify('DD_TRACE_GRAPHQL_CAPTURE_VARIABLES_EXCEPT' => 'Users:org') do + Datadog.configuration.tracing[:graphql].reset! + ex.run + end + end + + it 'captures all variables except those in the except list' do + schema.execute( + query: 'query Users($var: ID!, $org: ID!){ userWithOrg(id: $var, org: $org) { name } }', + variables: {var: 1, org: 2} + ) + + expect(graphql_execute.get_tag('graphql.operation.variable.var')).to eq(1) + expect(graphql_execute.get_tag('graphql.operation.variable.org')).to be_nil + end + end + + context 'with anonymous operations' do + around do |ex| + ClimateControl.modify('DD_TRACE_GRAPHQL_CAPTURE_VARIABLES_EXCEPT' => '') do + Datadog.configuration.tracing[:graphql].reset! + ex.run + end + end + + it 'never captures variables for anonymous operations' do + schema.execute(query: '{ user(id: "1") { name } }') + + expect(graphql_execute.resource).to eq('anonymous') + end + end + + context 'variable serialization' do + around do |ex| + ClimateControl.modify('DD_TRACE_GRAPHQL_CAPTURE_VARIABLES' => 'TestIntQuery:intVar,TestStringQuery:stringVar,TestBoolQuery:boolVar,TestIdQuery:idVar,TestInputQuery:inputVar') do + Datadog.configuration.tracing[:graphql].reset! + ex.run + end + end + + it 'serializes integer variables correctly' do + schema.execute( + query: 'query TestIntQuery($intVar: Int!){ userWithDetails(id: "1", count: $intVar) { name } }', + variables: {intVar: 42} + ) + + expect(graphql_execute.get_tag('graphql.operation.variable.intVar')).to eq(42) + end + + it 'serializes string variables correctly' do + schema.execute( + query: 'query TestStringQuery($stringVar: String!){ userWithDetails(id: "1", name: $stringVar) { name } }', + variables: {stringVar: 'hello'} + ) + + expect(graphql_execute.get_tag('graphql.operation.variable.stringVar')).to eq('hello') + end + + [ + {value: true, expected: 'true'}, + {value: false, expected: 'false'} + ].each do |test_case| + it "serializes #{test_case[:value]} boolean correctly" do + schema.execute( + query: 'query TestBoolQuery($boolVar: Boolean!){ userWithFilter(id: "1", active: $boolVar) { name } }', + variables: {boolVar: test_case[:value]} + ) + + expect(graphql_execute.get_tag('graphql.operation.variable.boolVar')).to eq(test_case[:expected]) + end + end + + it 'serializes ID variables correctly' do + schema.execute( + query: 'query TestIdQuery($idVar: ID!){ user(id: $idVar) { name } }', + variables: {idVar: 'user123'} + ) + + expect(graphql_execute.get_tag('graphql.operation.variable.idVar')).to eq('user123') + end + + it 'serializes custom input object variables correctly' do + # Create a Ruby hash that represents a GraphQL input object + # Use camelCase for GraphQL field names + input_object = {name: 'John', active: true, minAge: 18} + + # For schemas without prefix, use the base type name + input_type_name = if defined?(TraceWithTestUserFilterInput) + 'TraceWithTestUserFilterInput' + else + 'TestUserFilterInput' + end + + schema.execute( + query: "query TestInputQuery($inputVar: #{input_type_name}!){ userWithInputFilter(id: \"1\", filter: $inputVar) { name } }", + variables: {inputVar: input_object} + ) + + # Custom input objects should be serialized as strings using to_s + # GraphQL converts hash keys from symbols to strings, so we expect the string key version + expected_serialized = {'name' => 'John', 'active' => true, 'minAge' => 18}.to_s + expect(graphql_execute.get_tag('graphql.operation.variable.inputVar')).to eq(expected_serialized) + end + end + end end diff --git a/supported-configurations.json b/supported-configurations.json index fa5503ea345..c86a5265b7e 100644 --- a/supported-configurations.json +++ b/supported-configurations.json @@ -496,6 +496,12 @@ "DD_TRACE_GRAPHQL_ERROR_TRACKING": { "version": ["A"] }, + "DD_TRACE_GRAPHQL_CAPTURE_VARIABLES": { + "version": ["A"] + }, + "DD_TRACE_GRAPHQL_CAPTURE_VARIABLES_EXCEPT": { + "version": ["A"] + }, "DD_TRACE_GRAPHQL_WITH_UNIFIED_TRACER": { "version": ["A"] },