datadog 2.20.0 → 2.26.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (310) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +212 -1
  3. data/README.md +0 -1
  4. data/ext/LIBDATADOG_DEVELOPMENT.md +3 -0
  5. data/ext/datadog_profiling_native_extension/collectors_cpu_and_wall_time_worker.c +93 -23
  6. data/ext/datadog_profiling_native_extension/collectors_discrete_dynamic_sampler.c +1 -1
  7. data/ext/datadog_profiling_native_extension/collectors_stack.c +21 -5
  8. data/ext/datadog_profiling_native_extension/crashtracking_runtime_stacks.c +239 -0
  9. data/ext/datadog_profiling_native_extension/datadog_ruby_common.h +1 -1
  10. data/ext/datadog_profiling_native_extension/extconf.rb +9 -4
  11. data/ext/datadog_profiling_native_extension/heap_recorder.c +1 -1
  12. data/ext/datadog_profiling_native_extension/http_transport.c +1 -0
  13. data/ext/datadog_profiling_native_extension/private_vm_api_access.c +12 -0
  14. data/ext/datadog_profiling_native_extension/private_vm_api_access.h +4 -0
  15. data/ext/datadog_profiling_native_extension/profiling.c +2 -0
  16. data/ext/libdatadog_api/datadog_ruby_common.h +1 -1
  17. data/ext/libdatadog_api/ddsketch.c +106 -0
  18. data/ext/libdatadog_api/feature_flags.c +554 -0
  19. data/ext/libdatadog_api/feature_flags.h +5 -0
  20. data/ext/libdatadog_api/init.c +5 -0
  21. data/ext/libdatadog_api/library_config.c +34 -25
  22. data/ext/libdatadog_api/process_discovery.c +24 -18
  23. data/ext/libdatadog_extconf_helpers.rb +1 -1
  24. data/lib/datadog/ai_guard/api_client.rb +82 -0
  25. data/lib/datadog/ai_guard/component.rb +42 -0
  26. data/lib/datadog/ai_guard/configuration/ext.rb +17 -0
  27. data/lib/datadog/ai_guard/configuration/settings.rb +98 -0
  28. data/lib/datadog/ai_guard/configuration.rb +11 -0
  29. data/lib/datadog/ai_guard/evaluation/message.rb +25 -0
  30. data/lib/datadog/ai_guard/evaluation/no_op_result.rb +34 -0
  31. data/lib/datadog/ai_guard/evaluation/request.rb +81 -0
  32. data/lib/datadog/ai_guard/evaluation/result.rb +43 -0
  33. data/lib/datadog/ai_guard/evaluation/tool_call.rb +18 -0
  34. data/lib/datadog/ai_guard/evaluation.rb +72 -0
  35. data/lib/datadog/ai_guard/ext.rb +16 -0
  36. data/lib/datadog/ai_guard.rb +153 -0
  37. data/lib/datadog/appsec/api_security/endpoint_collection/grape_route_serializer.rb +26 -0
  38. data/lib/datadog/appsec/api_security/endpoint_collection/rails_collector.rb +59 -0
  39. data/lib/datadog/appsec/api_security/endpoint_collection/rails_route_serializer.rb +29 -0
  40. data/lib/datadog/appsec/api_security/endpoint_collection/sinatra_route_serializer.rb +26 -0
  41. data/lib/datadog/appsec/api_security/endpoint_collection.rb +10 -0
  42. data/lib/datadog/appsec/api_security/route_extractor.rb +26 -5
  43. data/lib/datadog/appsec/api_security/sampler.rb +7 -4
  44. data/lib/datadog/appsec/assets/blocked.html +8 -0
  45. data/lib/datadog/appsec/assets/blocked.json +1 -1
  46. data/lib/datadog/appsec/assets/blocked.text +3 -1
  47. data/lib/datadog/appsec/assets/waf_rules/README.md +30 -36
  48. data/lib/datadog/appsec/assets/waf_rules/recommended.json +359 -4
  49. data/lib/datadog/appsec/assets/waf_rules/strict.json +43 -2
  50. data/lib/datadog/appsec/assets.rb +1 -1
  51. data/lib/datadog/appsec/autoload.rb +1 -1
  52. data/lib/datadog/appsec/compressed_json.rb +1 -1
  53. data/lib/datadog/appsec/configuration/settings.rb +9 -0
  54. data/lib/datadog/appsec/context.rb +2 -1
  55. data/lib/datadog/appsec/contrib/active_record/instrumentation.rb +3 -1
  56. data/lib/datadog/appsec/contrib/excon/ssrf_detection_middleware.rb +3 -2
  57. data/lib/datadog/appsec/contrib/faraday/ssrf_detection_middleware.rb +3 -1
  58. data/lib/datadog/appsec/contrib/graphql/gateway/watcher.rb +3 -1
  59. data/lib/datadog/appsec/contrib/rack/gateway/watcher.rb +9 -4
  60. data/lib/datadog/appsec/contrib/rack/request_middleware.rb +5 -1
  61. data/lib/datadog/appsec/contrib/rails/gateway/watcher.rb +7 -2
  62. data/lib/datadog/appsec/contrib/rails/patcher.rb +30 -0
  63. data/lib/datadog/appsec/contrib/rest_client/request_ssrf_detection_patch.rb +3 -1
  64. data/lib/datadog/appsec/contrib/sinatra/gateway/watcher.rb +10 -4
  65. data/lib/datadog/appsec/event.rb +12 -14
  66. data/lib/datadog/appsec/metrics/collector.rb +19 -3
  67. data/lib/datadog/appsec/metrics/telemetry_exporter.rb +2 -1
  68. data/lib/datadog/appsec/monitor/gateway/watcher.rb +4 -4
  69. data/lib/datadog/appsec/remote.rb +34 -25
  70. data/lib/datadog/appsec/response.rb +18 -4
  71. data/lib/datadog/appsec/security_engine/engine.rb +3 -3
  72. data/lib/datadog/appsec/security_engine/result.rb +29 -9
  73. data/lib/datadog/appsec/security_engine/runner.rb +19 -9
  74. data/lib/datadog/appsec/security_event.rb +5 -7
  75. data/lib/datadog/core/configuration/agent_settings_resolver.rb +4 -4
  76. data/lib/datadog/core/configuration/components.rb +59 -11
  77. data/lib/datadog/core/configuration/config_helper.rb +100 -0
  78. data/lib/datadog/core/configuration/deprecations.rb +36 -0
  79. data/lib/datadog/core/configuration/ext.rb +0 -1
  80. data/lib/datadog/core/configuration/option.rb +38 -43
  81. data/lib/datadog/core/configuration/option_definition.rb +4 -11
  82. data/lib/datadog/core/configuration/options.rb +9 -10
  83. data/lib/datadog/core/configuration/settings.rb +38 -9
  84. data/lib/datadog/core/configuration/stable_config.rb +10 -0
  85. data/lib/datadog/core/configuration/supported_configurations.rb +373 -0
  86. data/lib/datadog/core/configuration.rb +2 -2
  87. data/lib/datadog/core/ddsketch.rb +19 -0
  88. data/lib/datadog/core/deprecations.rb +2 -2
  89. data/lib/datadog/core/environment/cgroup.rb +52 -25
  90. data/lib/datadog/core/environment/container.rb +140 -46
  91. data/lib/datadog/core/environment/ext.rb +7 -2
  92. data/lib/datadog/core/environment/git.rb +2 -2
  93. data/lib/datadog/core/environment/process.rb +87 -0
  94. data/lib/datadog/core/environment/variable_helpers.rb +3 -3
  95. data/lib/datadog/core/environment/yjit.rb +2 -1
  96. data/lib/datadog/core/error.rb +6 -6
  97. data/lib/datadog/core/feature_flags.rb +61 -0
  98. data/lib/datadog/core/metrics/client.rb +2 -2
  99. data/lib/datadog/core/pin.rb +8 -8
  100. data/lib/datadog/core/process_discovery/tracer_memfd.rb +2 -4
  101. data/lib/datadog/core/process_discovery.rb +48 -23
  102. data/lib/datadog/core/rate_limiter.rb +9 -1
  103. data/lib/datadog/core/remote/client/capabilities.rb +7 -0
  104. data/lib/datadog/core/remote/client.rb +14 -6
  105. data/lib/datadog/core/remote/component.rb +10 -10
  106. data/lib/datadog/core/remote/configuration/content.rb +15 -2
  107. data/lib/datadog/core/remote/configuration/digest.rb +14 -7
  108. data/lib/datadog/core/remote/configuration/repository.rb +1 -1
  109. data/lib/datadog/core/remote/configuration/target.rb +13 -6
  110. data/lib/datadog/core/remote/transport/config.rb +4 -25
  111. data/lib/datadog/core/remote/transport/http/config.rb +10 -50
  112. data/lib/datadog/core/remote/transport/http/negotiation.rb +14 -44
  113. data/lib/datadog/core/remote/transport/http.rb +15 -24
  114. data/lib/datadog/core/remote/transport/negotiation.rb +8 -33
  115. data/lib/datadog/core/remote/worker.rb +25 -37
  116. data/lib/datadog/core/runtime/ext.rb +0 -1
  117. data/lib/datadog/core/runtime/metrics.rb +11 -1
  118. data/lib/datadog/core/semaphore.rb +1 -4
  119. data/lib/datadog/core/tag_builder.rb +0 -4
  120. data/lib/datadog/core/tag_normalizer.rb +84 -0
  121. data/lib/datadog/core/telemetry/component.rb +69 -15
  122. data/lib/datadog/core/telemetry/emitter.rb +6 -6
  123. data/lib/datadog/core/telemetry/event/app_endpoints_loaded.rb +30 -0
  124. data/lib/datadog/core/telemetry/event/app_started.rb +89 -51
  125. data/lib/datadog/core/telemetry/event/synth_app_client_configuration_change.rb +27 -4
  126. data/lib/datadog/core/telemetry/event.rb +1 -0
  127. data/lib/datadog/core/telemetry/logger.rb +2 -2
  128. data/lib/datadog/core/telemetry/logging.rb +2 -8
  129. data/lib/datadog/core/telemetry/metrics_manager.rb +9 -0
  130. data/lib/datadog/core/telemetry/request.rb +17 -3
  131. data/lib/datadog/core/telemetry/transport/http/telemetry.rb +3 -34
  132. data/lib/datadog/core/telemetry/transport/http.rb +21 -16
  133. data/lib/datadog/core/telemetry/transport/telemetry.rb +3 -11
  134. data/lib/datadog/core/telemetry/worker.rb +88 -32
  135. data/lib/datadog/core/transport/ext.rb +2 -0
  136. data/lib/datadog/core/transport/http/api/endpoint.rb +9 -4
  137. data/lib/datadog/core/transport/http/api/instance.rb +4 -21
  138. data/lib/datadog/core/transport/http/builder.rb +9 -5
  139. data/lib/datadog/core/transport/http/client.rb +80 -0
  140. data/lib/datadog/core/transport/http.rb +22 -19
  141. data/lib/datadog/core/transport/response.rb +15 -1
  142. data/lib/datadog/core/transport/transport.rb +90 -0
  143. data/lib/datadog/core/utils/array.rb +29 -0
  144. data/lib/datadog/{appsec/api_security → core/utils}/lru_cache.rb +10 -21
  145. data/lib/datadog/core/utils/network.rb +22 -1
  146. data/lib/datadog/core/utils/only_once_successful.rb +8 -2
  147. data/lib/datadog/core/utils/safe_dup.rb +2 -2
  148. data/lib/datadog/core/utils/sequence.rb +2 -0
  149. data/lib/datadog/core/utils/time.rb +1 -1
  150. data/lib/datadog/core/utils.rb +2 -0
  151. data/lib/datadog/core/workers/async.rb +10 -1
  152. data/lib/datadog/core/workers/interval_loop.rb +44 -3
  153. data/lib/datadog/core/workers/polling.rb +2 -0
  154. data/lib/datadog/core/workers/queue.rb +100 -1
  155. data/lib/datadog/core.rb +2 -0
  156. data/lib/datadog/data_streams/configuration/settings.rb +49 -0
  157. data/lib/datadog/data_streams/configuration.rb +11 -0
  158. data/lib/datadog/data_streams/ext.rb +11 -0
  159. data/lib/datadog/data_streams/extensions.rb +16 -0
  160. data/lib/datadog/data_streams/pathway_context.rb +169 -0
  161. data/lib/datadog/data_streams/processor.rb +509 -0
  162. data/lib/datadog/data_streams/transport/http/stats.rb +52 -0
  163. data/lib/datadog/data_streams/transport/http.rb +40 -0
  164. data/lib/datadog/data_streams/transport/stats.rb +46 -0
  165. data/lib/datadog/data_streams.rb +100 -0
  166. data/lib/datadog/di/boot.rb +7 -3
  167. data/lib/datadog/di/component.rb +14 -16
  168. data/lib/datadog/di/context.rb +70 -0
  169. data/lib/datadog/di/contrib/active_record.rb +30 -5
  170. data/lib/datadog/di/el/compiler.rb +168 -0
  171. data/lib/datadog/di/el/evaluator.rb +159 -0
  172. data/lib/datadog/di/el/expression.rb +42 -0
  173. data/lib/datadog/di/el.rb +5 -0
  174. data/lib/datadog/di/error.rb +34 -0
  175. data/lib/datadog/di/instrumenter.rb +189 -55
  176. data/lib/datadog/di/logger.rb +2 -2
  177. data/lib/datadog/di/probe.rb +55 -15
  178. data/lib/datadog/di/probe_builder.rb +41 -2
  179. data/lib/datadog/di/probe_file_loader/railtie.rb +1 -1
  180. data/lib/datadog/di/probe_file_loader.rb +1 -1
  181. data/lib/datadog/di/probe_manager.rb +50 -35
  182. data/lib/datadog/di/probe_notification_builder.rb +121 -70
  183. data/lib/datadog/di/probe_notifier_worker.rb +5 -5
  184. data/lib/datadog/di/proc_responder.rb +32 -0
  185. data/lib/datadog/di/remote.rb +89 -84
  186. data/lib/datadog/di/serializer.rb +151 -7
  187. data/lib/datadog/di/transport/diagnostics.rb +8 -36
  188. data/lib/datadog/di/transport/http/diagnostics.rb +1 -33
  189. data/lib/datadog/di/transport/http/input.rb +1 -33
  190. data/lib/datadog/di/transport/http.rb +32 -17
  191. data/lib/datadog/di/transport/input.rb +67 -34
  192. data/lib/datadog/di.rb +61 -5
  193. data/lib/datadog/error_tracking/filters.rb +2 -2
  194. data/lib/datadog/kit/appsec/events/v2.rb +2 -3
  195. data/lib/datadog/open_feature/component.rb +60 -0
  196. data/lib/datadog/open_feature/configuration.rb +27 -0
  197. data/lib/datadog/open_feature/evaluation_engine.rb +70 -0
  198. data/lib/datadog/open_feature/exposures/batch_builder.rb +32 -0
  199. data/lib/datadog/open_feature/exposures/buffer.rb +43 -0
  200. data/lib/datadog/open_feature/exposures/deduplicator.rb +30 -0
  201. data/lib/datadog/open_feature/exposures/event.rb +60 -0
  202. data/lib/datadog/open_feature/exposures/reporter.rb +40 -0
  203. data/lib/datadog/open_feature/exposures/worker.rb +116 -0
  204. data/lib/datadog/open_feature/ext.rb +14 -0
  205. data/lib/datadog/open_feature/native_evaluator.rb +38 -0
  206. data/lib/datadog/open_feature/noop_evaluator.rb +26 -0
  207. data/lib/datadog/open_feature/provider.rb +141 -0
  208. data/lib/datadog/open_feature/remote.rb +67 -0
  209. data/lib/datadog/open_feature/resolution_details.rb +35 -0
  210. data/lib/datadog/open_feature/transport.rb +70 -0
  211. data/lib/datadog/open_feature.rb +19 -0
  212. data/lib/datadog/opentelemetry/api/baggage.rb +1 -1
  213. data/lib/datadog/opentelemetry/configuration/settings.rb +159 -0
  214. data/lib/datadog/opentelemetry/metrics.rb +117 -0
  215. data/lib/datadog/opentelemetry/sdk/configurator.rb +26 -2
  216. data/lib/datadog/opentelemetry/sdk/metrics_exporter.rb +35 -0
  217. data/lib/datadog/opentelemetry.rb +3 -0
  218. data/lib/datadog/profiling/collectors/code_provenance.rb +41 -7
  219. data/lib/datadog/profiling/collectors/cpu_and_wall_time_worker.rb +3 -2
  220. data/lib/datadog/profiling/collectors/idle_sampling_helper.rb +1 -1
  221. data/lib/datadog/profiling/collectors/info.rb +6 -5
  222. data/lib/datadog/profiling/component.rb +12 -11
  223. data/lib/datadog/profiling/ext/dir_monkey_patches.rb +18 -0
  224. data/lib/datadog/profiling/ext.rb +2 -1
  225. data/lib/datadog/profiling/http_transport.rb +5 -2
  226. data/lib/datadog/profiling/profiler.rb +4 -0
  227. data/lib/datadog/profiling/tag_builder.rb +36 -3
  228. data/lib/datadog/profiling/tasks/exec.rb +2 -2
  229. data/lib/datadog/profiling.rb +1 -2
  230. data/lib/datadog/single_step_instrument.rb +1 -1
  231. data/lib/datadog/tracing/component.rb +6 -17
  232. data/lib/datadog/tracing/configuration/dynamic.rb +2 -2
  233. data/lib/datadog/tracing/configuration/ext.rb +9 -3
  234. data/lib/datadog/tracing/configuration/settings.rb +89 -10
  235. data/lib/datadog/tracing/contrib/action_pack/action_controller/instrumentation.rb +4 -4
  236. data/lib/datadog/tracing/contrib/action_pack/utils.rb +1 -2
  237. data/lib/datadog/tracing/contrib/active_job/log_injection.rb +21 -7
  238. data/lib/datadog/tracing/contrib/active_job/patcher.rb +5 -1
  239. data/lib/datadog/tracing/contrib/aws/instrumentation.rb +4 -2
  240. data/lib/datadog/tracing/contrib/component.rb +2 -2
  241. data/lib/datadog/tracing/contrib/ethon/easy_patch.rb +4 -1
  242. data/lib/datadog/tracing/contrib/excon/configuration/settings.rb +11 -3
  243. data/lib/datadog/tracing/contrib/extensions.rb +10 -2
  244. data/lib/datadog/tracing/contrib/faraday/configuration/settings.rb +11 -7
  245. data/lib/datadog/tracing/contrib/grape/configuration/settings.rb +7 -3
  246. data/lib/datadog/tracing/contrib/graphql/configuration/settings.rb +7 -0
  247. data/lib/datadog/tracing/contrib/graphql/ext.rb +1 -0
  248. data/lib/datadog/tracing/contrib/graphql/unified_trace.rb +84 -43
  249. data/lib/datadog/tracing/contrib/http/configuration/settings.rb +11 -3
  250. data/lib/datadog/tracing/contrib/httpclient/configuration/settings.rb +11 -3
  251. data/lib/datadog/tracing/contrib/httprb/configuration/settings.rb +11 -3
  252. data/lib/datadog/tracing/contrib/kafka/instrumentation/consumer.rb +66 -0
  253. data/lib/datadog/tracing/contrib/kafka/instrumentation/producer.rb +66 -0
  254. data/lib/datadog/tracing/contrib/kafka/patcher.rb +14 -0
  255. data/lib/datadog/tracing/contrib/karafka/framework.rb +30 -0
  256. data/lib/datadog/tracing/contrib/karafka/monitor.rb +11 -0
  257. data/lib/datadog/tracing/contrib/karafka/patcher.rb +35 -4
  258. data/lib/datadog/tracing/contrib/rack/middlewares.rb +59 -27
  259. data/lib/datadog/tracing/contrib/rack/request_queue.rb +1 -0
  260. data/lib/datadog/tracing/contrib/rack/route_inference.rb +53 -0
  261. data/lib/datadog/tracing/contrib/rack/trace_proxy_middleware.rb +7 -1
  262. data/lib/datadog/tracing/contrib/rails/ext.rb +2 -1
  263. data/lib/datadog/tracing/contrib/rails/integration.rb +1 -1
  264. data/lib/datadog/tracing/contrib/rails/middlewares.rb +2 -2
  265. data/lib/datadog/tracing/contrib/rest_client/request_patch.rb +4 -1
  266. data/lib/datadog/tracing/contrib/roda/instrumentation.rb +3 -1
  267. data/lib/datadog/tracing/contrib/sinatra/tracer_middleware.rb +3 -1
  268. data/lib/datadog/tracing/contrib/span_attribute_schema.rb +1 -1
  269. data/lib/datadog/tracing/contrib/status_range_matcher.rb +9 -1
  270. data/lib/datadog/tracing/contrib/utils/quantization/hash.rb +3 -1
  271. data/lib/datadog/tracing/contrib/waterdrop/configuration/settings.rb +27 -0
  272. data/lib/datadog/tracing/contrib/waterdrop/distributed/propagation.rb +48 -0
  273. data/lib/datadog/tracing/contrib/waterdrop/ext.rb +17 -0
  274. data/lib/datadog/tracing/contrib/waterdrop/integration.rb +43 -0
  275. data/lib/datadog/tracing/contrib/waterdrop/middleware.rb +46 -0
  276. data/lib/datadog/tracing/contrib/waterdrop/patcher.rb +49 -0
  277. data/lib/datadog/tracing/contrib/waterdrop/producer.rb +50 -0
  278. data/lib/datadog/tracing/contrib/waterdrop.rb +41 -0
  279. data/lib/datadog/tracing/contrib.rb +1 -0
  280. data/lib/datadog/tracing/diagnostics/environment_logger.rb +1 -1
  281. data/lib/datadog/tracing/distributed/baggage.rb +3 -2
  282. data/lib/datadog/tracing/metadata/ext.rb +9 -1
  283. data/lib/datadog/tracing/remote.rb +1 -9
  284. data/lib/datadog/tracing/sampling/priority_sampler.rb +3 -1
  285. data/lib/datadog/tracing/span.rb +1 -1
  286. data/lib/datadog/tracing/span_event.rb +2 -2
  287. data/lib/datadog/tracing/span_operation.rb +20 -9
  288. data/lib/datadog/tracing/trace_operation.rb +44 -6
  289. data/lib/datadog/tracing/tracer.rb +42 -16
  290. data/lib/datadog/tracing/transport/http/client.rb +12 -26
  291. data/lib/datadog/tracing/transport/http/traces.rb +2 -50
  292. data/lib/datadog/tracing/transport/http.rb +15 -9
  293. data/lib/datadog/tracing/transport/io/client.rb +1 -1
  294. data/lib/datadog/tracing/transport/trace_formatter.rb +11 -0
  295. data/lib/datadog/tracing/transport/traces.rb +9 -71
  296. data/lib/datadog/tracing/workers/trace_writer.rb +5 -0
  297. data/lib/datadog/tracing/writer.rb +1 -0
  298. data/lib/datadog/version.rb +2 -2
  299. data/lib/datadog.rb +3 -0
  300. metadata +110 -24
  301. data/ext/libdatadog_api/macos_development.md +0 -26
  302. data/lib/datadog/core/remote/transport/http/api.rb +0 -53
  303. data/lib/datadog/core/remote/transport/http/client.rb +0 -49
  304. data/lib/datadog/core/telemetry/transport/http/api.rb +0 -43
  305. data/lib/datadog/core/telemetry/transport/http/client.rb +0 -49
  306. data/lib/datadog/core/transport/http/api/spec.rb +0 -36
  307. data/lib/datadog/di/transport/http/api.rb +0 -42
  308. data/lib/datadog/di/transport/http/client.rb +0 -47
  309. data/lib/datadog/opentelemetry/api/baggage.rbs +0 -26
  310. data/lib/datadog/tracing/transport/http/api.rb +0 -44
@@ -2,6 +2,8 @@
2
2
 
3
3
  require_relative '../../tracing/configuration/ext'
4
4
  require_relative '../../core/environment/variable_helpers'
5
+ require_relative '../contrib/status_range_matcher'
6
+ require_relative '../contrib/status_range_env_parser'
5
7
  require_relative 'http'
6
8
 
7
9
  module Datadog
@@ -93,9 +95,10 @@ module Datadog
93
95
  # @return [Array<String>]
94
96
  option :propagation_style do |o|
95
97
  o.type :array
96
- o.env [Configuration::Ext::Distributed::ENV_PROPAGATION_STYLE, Configuration::Ext::Distributed::ENV_OTEL_PROPAGATION_STYLE]
98
+ # Note: Alias (DD_TRACE_PROPAGATION_STYLE) defined in supported-configurations.json
99
+ o.env Configuration::Ext::Distributed::ENV_PROPAGATION_STYLE
97
100
  o.default []
98
- o.after_set do |styles|
101
+ o.after_set do |styles, _, precedence|
99
102
  next if styles.empty?
100
103
 
101
104
  # Make values case-insensitive
@@ -109,8 +112,8 @@ module Datadog
109
112
  false
110
113
  end
111
114
  end
112
- set_option(:propagation_style_extract, styles)
113
- set_option(:propagation_style_inject, styles)
115
+ set_option(:propagation_style_extract, styles, precedence: precedence)
116
+ set_option(:propagation_style_inject, styles, precedence: precedence)
114
117
  end
115
118
  end
116
119
 
@@ -133,13 +136,16 @@ module Datadog
133
136
  # @default `DD_TRACE_ENABLED` environment variable, otherwise `true`
134
137
  # @return [Boolean]
135
138
  option :enabled do |o|
136
- o.env [Tracing::Configuration::Ext::ENV_ENABLED, Tracing::Configuration::Ext::ENV_OTEL_TRACES_EXPORTER]
139
+ # Note: Alias (OTEL_TRACES_EXPORTER) defined in supported-configurations.json
140
+ o.env Tracing::Configuration::Ext::ENV_ENABLED
137
141
  o.default true
138
142
  o.type :bool
139
143
  o.env_parser do |value|
140
144
  value = value&.downcase
141
145
  # Tracing is disabled when OTEL_TRACES_EXPORTER is none or
142
146
  # DD_TRACE_ENABLED is 0 or false.
147
+ # DEV: The current implementation accepts all of the mentioned values
148
+ # for both environment variables, which is incorrect.
143
149
  if ['none', 'false', '0'].include?(value)
144
150
  false
145
151
  # Tracing is enabled when DD_TRACE_ENABLED is true or 1
@@ -268,6 +274,38 @@ module Datadog
268
274
  o.type :bool
269
275
  end
270
276
 
277
+ settings :resource_renaming do
278
+ # Whether resource renaming is enabled. When enabled, http.endpoint tag
279
+ # containing a route will be reported in traces. If AppSec is enabled,
280
+ # this feature will be enabled by default.
281
+ #
282
+ # For web applications built with instrumented frameworks, http.endpoint tag
283
+ # will contain the route as it is defined in the application.
284
+ # For basic Rack applications, or applications that are mounted and are not instrumented,
285
+ # the route will be inferred from the request path.
286
+ #
287
+ # @default `DD_TRACE_RESOURCE_RENAMING_ENABLED` environment variable, otherwise `false`.
288
+ # @return [Boolean]
289
+ option :enabled do |o|
290
+ o.type :bool, nilable: false
291
+ o.env Configuration::Ext::ENV_RESOURCE_RENAMING_ENABLED
292
+ o.default false
293
+ end
294
+
295
+ # When set to true, http.endoint is always inferred from path,
296
+ # instead of using http.route value when it is set.
297
+ #
298
+ # This is useful for testing purposes.
299
+ #
300
+ # @default false
301
+ # @return [Boolean]
302
+ option :always_simplified_endpoint do |o|
303
+ o.type :bool, nilable: false
304
+ o.env Configuration::Ext::ENV_RESOURCE_RENAMING_ALWAYS_SIMPLIFIED_ENDPOINT
305
+ o.default false
306
+ end
307
+ end
308
+
271
309
  # Forces the tracer to always send span events with the native span events format
272
310
  # regardless of the agent support. This is useful in agent-less setups.
273
311
  #
@@ -302,7 +340,8 @@ module Datadog
302
340
  # @return [Float, nil]
303
341
  option :default_rate do |o|
304
342
  o.type :float, nilable: true
305
- o.env [Tracing::Configuration::Ext::Sampling::ENV_SAMPLE_RATE, Tracing::Configuration::Ext::Sampling::ENV_OTEL_TRACES_SAMPLER]
343
+ # Note: Alias (OTEL_TRACES_SAMPLER) defined in supported-configurations.json
344
+ o.env Tracing::Configuration::Ext::Sampling::ENV_SAMPLE_RATE
306
345
  o.env_parser do |value|
307
346
  # Parse the value as a float
308
347
  next if value.nil?
@@ -321,7 +360,7 @@ module Datadog
321
360
  when 'parentbased_always_off'
322
361
  0.0
323
362
  when 'parentbased_traceidratio'
324
- ENV.fetch(Tracing::Configuration::Ext::Sampling::OTEL_TRACES_SAMPLER_ARG, 1.0).to_f
363
+ DATADOG_ENV.fetch(Configuration::Ext::Sampling::OTEL_TRACES_SAMPLER_ARG, 1.0).to_f
325
364
  else
326
365
  value.to_f
327
366
  end
@@ -355,7 +394,7 @@ module Datadog
355
394
  # @public_api
356
395
  option :rules do |o|
357
396
  o.type :string, nilable: true
358
- o.default { ENV.fetch(Configuration::Ext::Sampling::ENV_RULES, nil) }
397
+ o.default { DATADOG_ENV.fetch(Configuration::Ext::Sampling::ENV_RULES, nil) }
359
398
  end
360
399
 
361
400
  # Single span sampling rules.
@@ -372,8 +411,8 @@ module Datadog
372
411
  option :span_rules do |o|
373
412
  o.type :string, nilable: true
374
413
  o.default do
375
- rules = ENV[Tracing::Configuration::Ext::Sampling::Span::ENV_SPAN_SAMPLING_RULES]
376
- rules_file = ENV[Tracing::Configuration::Ext::Sampling::Span::ENV_SPAN_SAMPLING_RULES_FILE]
414
+ rules = DATADOG_ENV[Tracing::Configuration::Ext::Sampling::Span::ENV_SPAN_SAMPLING_RULES]
415
+ rules_file = DATADOG_ENV[Tracing::Configuration::Ext::Sampling::Span::ENV_SPAN_SAMPLING_RULES_FILE]
377
416
 
378
417
  if rules
379
418
  if rules_file
@@ -485,6 +524,46 @@ module Datadog
485
524
  o.env Tracing::Configuration::Ext::Distributed::ENV_X_DATADOG_TAGS_MAX_LENGTH
486
525
  o.default 512
487
526
  end
527
+
528
+ # HTTP error statuses configuration
529
+ # @public_api
530
+ settings :http_error_statuses do
531
+ # Defines the range of status codes to be considered errors on http.server span kinds.
532
+ # Once set, only the values within the specified range are considered errors.
533
+ #
534
+ # Format of env var: comma-separated list of values like 500,501,502 or ranges like 500-599 (e.g. `500,502,504-510`)
535
+ #
536
+ # @default `DD_TRACE_HTTP_SERVER_ERROR_STATUSES` environment variable, otherwise `500..599`.
537
+ # @return [Tracing::Contrib::StatusRangeMatcher]
538
+ option :server do |o|
539
+ o.env Tracing::Configuration::Ext::HTTPErrorStatuses::ENV_SERVER_ERROR_STATUSES
540
+ o.default 500..599
541
+ o.setter do |v|
542
+ Tracing::Contrib::StatusRangeMatcher.new(v) if v
543
+ end
544
+ o.env_parser do |values|
545
+ Tracing::Contrib::StatusRangeEnvParser.call(values)
546
+ end
547
+ end
548
+
549
+ # Defines the range of status codes to be considered errors on http.client span kinds.
550
+ # Once set, only the values within the specified range are considered errors.
551
+ #
552
+ # Format of env var: comma-separated list of values like 400,401,402 or ranges like 400-499 (e.g. `400,402,404-410`)
553
+ #
554
+ # @default `DD_TRACE_HTTP_CLIENT_ERROR_STATUSES` environment variable, otherwise `400..499`.
555
+ # @return [Tracing::Contrib::StatusRangeMatcher]
556
+ option :client do |o|
557
+ o.env Tracing::Configuration::Ext::HTTPErrorStatuses::ENV_CLIENT_ERROR_STATUSES
558
+ o.default 400..499
559
+ o.setter do |v|
560
+ Tracing::Contrib::StatusRangeMatcher.new(v) if v
561
+ end
562
+ o.env_parser do |values|
563
+ Tracing::Contrib::StatusRangeEnvParser.call(values)
564
+ end
565
+ end
566
+ end
488
567
  end
489
568
  end
490
569
  end
@@ -77,10 +77,10 @@ module Datadog
77
77
 
78
78
  exception = payload[:exception_object]
79
79
  if exception.nil?
80
- # [christian] in some cases :status is not defined,
81
- # rather than firing an error, simply acknowledge we don't know it.
82
- status = payload.fetch(:status, '?').to_s
83
- span.status = 1 if status.start_with?('5')
80
+ status = payload[:status]
81
+ if status && Datadog.configuration.tracing.http_error_statuses.server.include?(status)
82
+ span.status = Tracing::Metadata::Ext::Errors::STATUS
83
+ end
84
84
  elsif Utils.exception_is_error?(exception)
85
85
  span.set_error(exception)
86
86
  end
@@ -13,8 +13,7 @@ module Datadog
13
13
  # Gets the equivalent status code for the exception (not all are 5XX)
14
14
  # You can add custom errors via `config.action_dispatch.rescue_responses`
15
15
  status = ::ActionDispatch::ExceptionWrapper.status_code_for_exception(exception.class.name)
16
- # Only 5XX exceptions are actually errors (e.g. don't flag 404s)
17
- status.to_s.start_with?('5')
16
+ Datadog.configuration.tracing.http_error_statuses.server.include?(status)
18
17
  else
19
18
  true
20
19
  end
@@ -6,17 +6,31 @@ module Datadog
6
6
  module ActiveJob
7
7
  # Active Job log injection wrapped around job execution
8
8
  module LogInjection
9
- def self.included(base)
10
- base.class_eval do
11
- around_perform do |_, block|
12
- if Datadog.configuration.tracing.log_injection && logger.respond_to?(:tagged)
13
- logger.tagged(Tracing.log_correlation, &block)
14
- else
15
- block.call
9
+ # Active Job 4 / 5 don't execute `perform_now` at the right point, so we do best effort log correlation tagging
10
+ module AroundPerformPatch
11
+ def self.included(base)
12
+ base.class_eval do
13
+ around_perform do |_, block|
14
+ if Datadog.configuration.tracing.log_injection && logger.respond_to?(:tagged)
15
+ logger.tagged(Tracing.log_correlation, &block)
16
+ else
17
+ block.call
18
+ end
16
19
  end
17
20
  end
18
21
  end
19
22
  end
23
+
24
+ # Active Job 6+ executes `perform_now` at the right point, so we can provide better log correlation tagging
25
+ module PerformNowPatch
26
+ def perform_now
27
+ if Datadog.configuration.tracing.log_injection && logger.respond_to?(:tagged)
28
+ logger.tagged(Tracing.log_correlation) { super }
29
+ else
30
+ super
31
+ end
32
+ end
33
+ end
20
34
  end
21
35
  end
22
36
  end
@@ -26,7 +26,11 @@ module Datadog
26
26
 
27
27
  def inject_log_correlation
28
28
  ::ActiveSupport.on_load(:active_job) do
29
- include LogInjection
29
+ if ::ActiveJob.gem_version < Gem::Version.new('6.0.0')
30
+ include LogInjection::AroundPerformPatch
31
+ else
32
+ include LogInjection::PerformNowPatch
33
+ end
30
34
  end
31
35
  end
32
36
  end
@@ -36,8 +36,10 @@ module Datadog
36
36
  span.name = Ext::SPAN_COMMAND
37
37
  span.resource = context.safely(:resource)
38
38
 
39
- # Set error on the span if the Response Status Code is in error range
40
- if Tracing::Metadata::Ext::HTTP::ERROR_RANGE.cover?(context.safely(:status_code))
39
+ # DEV-3.0: This was previously checking against a 500..599 range.
40
+ # To not introduce breaking change, this was changed to use `http_error_statuses.server`,
41
+ # but `aws` is a client library, this check should use `http_error_statuses.client` instead.
42
+ if Datadog.configuration.tracing.http_error_statuses.server.include?(context.safely(:status_code))
41
43
  # At this point we do not have any additional diagnostics
42
44
  # besides the HTTP status code which is recorded in the span tags
43
45
  # later in this method.
@@ -9,13 +9,13 @@ module Datadog
9
9
  # Register a callback to be invoked when components are reconfigured.
10
10
  # @param name [String] the name of the integration
11
11
  # @param callback [Proc] the callback to invoke
12
- # @yieldparam config [Datadog::Configuration] the configuration to pass to callbacks
12
+ # @yieldparam config [Datadog::Core::Configuration::Settings] the configuration to pass to callbacks
13
13
  def register(name, &callback)
14
14
  @registry[name] = callback
15
15
  end
16
16
 
17
17
  # Invoke all registered callbacks with the given configuration.
18
- # @param config [Datadog::Configuration] the configuration to pass to callbacks
18
+ # @param config [Datadog::Core::Configuration::Settings] the configuration to pass to callbacks
19
19
  def configure(config)
20
20
  @registry.each do |name, callback|
21
21
  callback.call(config)
@@ -57,7 +57,10 @@ module Datadog
57
57
  set_span_error_message("Request has failed: #{message}")
58
58
  else
59
59
  @datadog_span.set_tag(Tracing::Metadata::Ext::HTTP::TAG_STATUS_CODE, response_code)
60
- if Tracing::Metadata::Ext::HTTP::ERROR_RANGE.cover?(response_code)
60
+ # DEV-3.0: This was previously checking against a 500..599 range.
61
+ # To not introduce breaking change, this was changed to use `http_error_statuses.server`,
62
+ # but `ethon` is a client library, this check should use `http_error_statuses.client` instead.
63
+ if Datadog.configuration.tracing.http_error_statuses.server.include?(response_code)
61
64
  set_span_error_message("Request has failed with HTTP error: #{response_code}")
62
65
  end
63
66
  end
@@ -41,9 +41,17 @@ module Datadog
41
41
 
42
42
  option :error_status_codes do |o|
43
43
  o.env Ext::ENV_ERROR_STATUS_CODES
44
- o.default 400...600
45
- o.setter do |v|
46
- Tracing::Contrib::StatusRangeMatcher.new(v) if v
44
+ o.setter do |value|
45
+ if value.nil?
46
+ # Fallback to global config, which is defaulted to client (400..499) + server (500..599)
47
+ # DEV-3.0: `excon` is a client library, this should fall back to `http_error_statuses.client` only.
48
+ # We cannot change it without causing a breaking change.
49
+ client_global_error_statuses = Datadog.configuration.tracing.http_error_statuses.client
50
+ server_global_error_statuses = Datadog.configuration.tracing.http_error_statuses.server
51
+ client_global_error_statuses + server_global_error_statuses
52
+ else
53
+ Tracing::Contrib::StatusRangeMatcher.new(value)
54
+ end
47
55
  end
48
56
  o.env_parser do |v|
49
57
  Tracing::Contrib::StatusRangeEnvParser.call(v) if v
@@ -220,12 +220,20 @@ module Datadog
220
220
  # `@instrumented_integrations` hash.
221
221
  # @!visibility private
222
222
  def instrumented_integrations
223
- INSTRUMENTED_INTEGRATIONS_LOCK.synchronize { (@instrumented_integrations&.dup || {}).freeze }
223
+ INSTRUMENTED_INTEGRATIONS_LOCK.synchronize do
224
+ (if defined?(@instrumented_integrations)
225
+ @instrumented_integrations&.dup
226
+ end || {}).freeze
227
+ end
224
228
  end
225
229
 
226
230
  # @!visibility private
227
231
  def reset!
228
- INSTRUMENTED_INTEGRATIONS_LOCK.synchronize { @instrumented_integrations&.clear }
232
+ INSTRUMENTED_INTEGRATIONS_LOCK.synchronize do
233
+ if defined?(@instrumented_integrations)
234
+ @instrumented_integrations&.clear
235
+ end
236
+ end
229
237
  super
230
238
  end
231
239
 
@@ -13,10 +13,6 @@ module Datadog
13
13
  # Custom settings for the Faraday integration
14
14
  # @public_api
15
15
  class Settings < Contrib::Configuration::Settings
16
- DEFAULT_ERROR_HANDLER = lambda do |env|
17
- Tracing::Metadata::Ext::HTTP::ERROR_RANGE.cover?(env[:status])
18
- end
19
-
20
16
  option :enabled do |o|
21
17
  o.type :bool
22
18
  o.env Ext::ENV_ENABLED
@@ -44,9 +40,17 @@ module Datadog
44
40
 
45
41
  option :error_status_codes do |o|
46
42
  o.env Ext::ENV_ERROR_STATUS_CODES
47
- o.default 400...600
48
- o.setter do |v|
49
- Tracing::Contrib::StatusRangeMatcher.new(v) if v
43
+ o.setter do |value|
44
+ if value.nil?
45
+ # Fallback to global config, which is defaulted to client (400..499) + server (500..599)
46
+ # DEV-3.0: `faraday` is a client library, this should fall back to `http_error_statuses.client` only.
47
+ # We cannot change it without causing a breaking change.
48
+ client_global_error_statuses = Datadog.configuration.tracing.http_error_statuses.client
49
+ server_global_error_statuses = Datadog.configuration.tracing.http_error_statuses.server
50
+ client_global_error_statuses + server_global_error_statuses
51
+ else
52
+ Tracing::Contrib::StatusRangeMatcher.new(value)
53
+ end
50
54
  end
51
55
  o.env_parser do |v|
52
56
  Tracing::Contrib::StatusRangeEnvParser.call(v) if v
@@ -39,9 +39,13 @@ module Datadog
39
39
 
40
40
  option :error_status_codes do |o|
41
41
  o.env Ext::ENV_ERROR_STATUS_CODES
42
- o.default 500...600
43
- o.setter do |v|
44
- Tracing::Contrib::StatusRangeMatcher.new(v) if v
42
+ o.setter do |value|
43
+ if value.nil?
44
+ # Fallback to global config, which is defaulted to server (500..599)
45
+ Datadog.configuration.tracing.http_error_statuses.server
46
+ else
47
+ Tracing::Contrib::StatusRangeMatcher.new(value)
48
+ end
45
49
  end
46
50
  o.env_parser do |v|
47
51
  Tracing::Contrib::StatusRangeEnvParser.call(v) if v
@@ -58,6 +58,13 @@ module Datadog
58
58
  o.default []
59
59
  o.env_parser { |v| ErrorExtensionEnvParser.call(v) }
60
60
  end
61
+
62
+ # Surface GraphQL errors in Error Tracking.
63
+ option :error_tracking do |o|
64
+ o.env Ext::ENV_ERROR_TRACKING
65
+ o.type :bool
66
+ o.default false
67
+ end
61
68
  end
62
69
  end
63
70
  end
@@ -13,6 +13,7 @@ module Datadog
13
13
  ENV_ANALYTICS_SAMPLE_RATE = 'DD_TRACE_GRAPHQL_ANALYTICS_SAMPLE_RATE'
14
14
  ENV_WITH_UNIFIED_TRACER = 'DD_TRACE_GRAPHQL_WITH_UNIFIED_TRACER'
15
15
  ENV_ERROR_EXTENSIONS = 'DD_TRACE_GRAPHQL_ERROR_EXTENSIONS'
16
+ ENV_ERROR_TRACKING = 'DD_TRACE_GRAPHQL_ERROR_TRACKING'
16
17
  SERVICE_NAME = 'graphql'
17
18
  TAG_COMPONENT = 'graphql'
18
19
 
@@ -11,11 +11,45 @@ module Datadog
11
11
  # which is required to use features such as API Catalog.
12
12
  # DEV-3.0: This tracer should be the default one in the next major version.
13
13
  module UnifiedTrace
14
+ include ::GraphQL::Tracing::PlatformTrace
15
+
14
16
  def initialize(*args, **kwargs)
15
17
  @has_prepare_span = respond_to?(:prepare_span)
18
+
19
+ # Cache configuration values to avoid repeated lookups
20
+ config = Datadog.configuration.tracing[:graphql]
21
+ @service_name = config[:service_name]
22
+ @analytics_enabled = config[:analytics_enabled]
23
+ @analytics_sample_rate = config[:analytics_sample_rate]
24
+ @error_extensions_config = config[:error_extensions]
25
+
26
+ load_error_event_attributes(config[:error_tracking])
27
+
16
28
  super
17
29
  end
18
30
 
31
+ def load_error_event_attributes(error_tracking)
32
+ if error_tracking
33
+ @event_name = Tracing::Metadata::Ext::Errors::EVENT_NAME
34
+ @message_key = Tracing::Metadata::Ext::Errors::ATTRIBUTE_MESSAGE
35
+ @type_key = Tracing::Metadata::Ext::Errors::ATTRIBUTE_TYPE
36
+ @stacktrace_key = Tracing::Metadata::Ext::Errors::ATTRIBUTE_STACKTRACE
37
+ @locations_key = 'graphql.error.locations'
38
+ @path_key = 'graphql.error.path'
39
+ @extensions_key = 'graphql.error.extensions.'
40
+ else
41
+ @event_name = Ext::EVENT_QUERY_ERROR
42
+ @message_key = 'message'
43
+ @type_key = 'type'
44
+ @stacktrace_key = 'stacktrace'
45
+ @locations_key = 'locations'
46
+ @path_key = 'path'
47
+ @extensions_key = 'extensions.'
48
+ end
49
+ end
50
+
51
+ private :load_error_event_attributes
52
+
19
53
  def lex(*args, query_string:, **kwargs)
20
54
  trace(proc { super }, 'lex', query_string, query_string: query_string)
21
55
  end
@@ -50,10 +84,13 @@ module Datadog
50
84
  trace(
51
85
  proc { super },
52
86
  'execute',
53
- query.selected_operation_name,
87
+ operation_resource(query.selected_operation),
54
88
  lambda { |span|
89
+ # Ensure this span can be aggregated by in the Datadog App, and generates RED metrics.
90
+ span.set_tag(Tracing::Metadata::Ext::TAG_KIND, Tracing::Metadata::Ext::SpanKind::TAG_SERVER)
91
+
55
92
  span.set_tag('graphql.source', query.query_string)
56
- span.set_tag('graphql.operation.type', query.selected_operation.operation_type)
93
+ span.set_tag('graphql.operation.type', query.selected_operation&.operation_type)
57
94
  if query.selected_operation_name
58
95
  span.set_tag(
59
96
  'graphql.operation.name',
@@ -127,8 +164,6 @@ module Datadog
127
164
  resolve_type_span(proc { super }, 'resolve_type_lazy', **kwargs)
128
165
  end
129
166
 
130
- include ::GraphQL::Tracing::PlatformTrace
131
-
132
167
  def platform_field_key(field, *args, **kwargs)
133
168
  field.path
134
169
  end
@@ -141,6 +176,26 @@ module Datadog
141
176
  "#{type.graphql_name}.resolve_type"
142
177
  end
143
178
 
179
+ # Serialize error's `locations` array as an array of Strings, given
180
+ # Span Events do not support hashes nested inside arrays.
181
+ #
182
+ # Here's an example in which `locations`:
183
+ # [
184
+ # {"line" => 3, "column" => 10},
185
+ # {"line" => 7, "column" => 8},
186
+ # ]
187
+ # is serialized as:
188
+ # ["3:10", "7:8"]
189
+ def self.serialize_error_locations(locations)
190
+ # locations are only provided by the `graphql` library when the error can
191
+ # be associated to a particular point in the query.
192
+ return [] if locations.nil?
193
+
194
+ locations.map do |location|
195
+ "#{location["line"]}:#{location["column"]}"
196
+ end
197
+ end
198
+
144
199
  private
145
200
 
146
201
  # Traces the given callable with the given trace key, resource, and kwargs.
@@ -153,16 +208,14 @@ module Datadog
153
208
  # @param kwargs [Hash] the arguments to pass to `prepare_span`
154
209
  # @yield [Span] the block to run before the trace, same as the `before` parameter
155
210
  def trace(callable, trace_key, resource, before = nil, after = nil, **kwargs, &before_block)
156
- config = Datadog.configuration.tracing[:graphql]
157
-
158
211
  Tracing.trace(
159
212
  "graphql.#{trace_key}",
160
213
  type: 'graphql',
161
214
  resource: resource,
162
- service: config[:service_name]
215
+ service: @service_name
163
216
  ) do |span|
164
- if Contrib::Analytics.enabled?(config[:analytics_enabled])
165
- Contrib::Analytics.set_sample_rate(span, config[:analytics_sample_rate])
217
+ if Contrib::Analytics.enabled?(@analytics_enabled)
218
+ Contrib::Analytics.set_sample_rate(span, @analytics_sample_rate)
166
219
  end
167
220
 
168
221
  # A sanity check for us.
@@ -194,27 +247,30 @@ module Datadog
194
247
  end
195
248
  end
196
249
 
250
+ def operation_resource(operation)
251
+ if operation&.name
252
+ "#{operation.operation_type} #{operation.name}"
253
+ else
254
+ 'anonymous'
255
+ end
256
+ end
257
+
197
258
  # Create a Span Event for each error that occurs at query level.
198
- #
199
- # These are represented in the Datadog App as special GraphQL errors,
200
- # given their event name `dd.graphql.query.error`.
201
259
  def add_query_error_events(span, errors)
202
- capture_extensions = Datadog.configuration.tracing[:graphql][:error_extensions]
203
260
  errors.each do |error|
204
- extensions = if !capture_extensions.empty? && (extensions = error.extensions)
261
+ attributes = if !@error_extensions_config.empty? && (extensions = error.extensions)
205
262
  # Capture extensions, ensuring all values are primitives
206
263
  extensions.each_with_object({}) do |(key, value), hash|
207
- next unless capture_extensions.include?(key.to_s)
264
+ next unless @error_extensions_config.include?(key.to_s)
208
265
 
209
266
  value = case value
210
267
  when TrueClass, FalseClass, Integer, Float
211
268
  value
212
269
  else
213
- # Stringify anything that is not a boolean or a number
214
270
  value.to_s
215
271
  end
216
272
 
217
- hash["extensions.#{key}"] = value
273
+ hash[@extensions_key + key.to_s] = value
218
274
  end
219
275
  else
220
276
  {}
@@ -224,36 +280,21 @@ module Datadog
224
280
  # This is an unwritten contract in the `graphql` library.
225
281
  # See for an example: https://github.com/rmosolgo/graphql-ruby/blob/0afa241775e5a113863766cce126214dee093464/lib/graphql/execution_error.rb#L32
226
282
  graphql_error = error.to_h
227
- error = Core::Error.build_from(error)
228
-
229
- span.span_events << Datadog::Tracing::SpanEvent.new(
230
- Ext::EVENT_QUERY_ERROR,
231
- attributes: extensions.merge!(
232
- message: graphql_error['message'],
233
- type: error.type,
234
- stacktrace: error.backtrace,
235
- locations: serialize_error_locations(graphql_error['locations']),
236
- path: graphql_error['path'],
283
+ parsed_error = Core::Error.build_from(error)
284
+
285
+ span.span_events << SpanEvent.new(
286
+ @event_name,
287
+ attributes: attributes.merge!(
288
+ @type_key => parsed_error.type,
289
+ @stacktrace_key => parsed_error.backtrace,
290
+ @message_key => graphql_error['message'],
291
+ @locations_key =>
292
+ Datadog::Tracing::Contrib::GraphQL::UnifiedTrace.serialize_error_locations(graphql_error['locations']),
293
+ @path_key => graphql_error['path'],
237
294
  )
238
295
  )
239
296
  end
240
297
  end
241
-
242
- # Serialize error's `locations` array as an array of Strings, given
243
- # Span Events do not support hashes nested inside arrays.
244
- #
245
- # Here's an example in which `locations`:
246
- # [
247
- # {"line" => 3, "column" => 10},
248
- # {"line" => 7, "column" => 8},
249
- # ]
250
- # is serialized as:
251
- # ["3:10", "7:8"]
252
- def serialize_error_locations(locations)
253
- locations.map do |location|
254
- "#{location["line"]}:#{location["column"]}"
255
- end
256
- end
257
298
  end
258
299
  end
259
300
  end
@@ -46,9 +46,17 @@ module Datadog
46
46
 
47
47
  option :error_status_codes do |o|
48
48
  o.env Ext::ENV_ERROR_STATUS_CODES
49
- o.default 400...600
50
- o.setter do |v|
51
- Tracing::Contrib::StatusRangeMatcher.new(v) if v
49
+ o.setter do |value|
50
+ if value.nil?
51
+ # Fallback to global config, which is defaulted to client (400..499) + server (500..599)
52
+ # DEV-3.0: `http` is a client library, this should fall back to `http_error_statuses.client` only.
53
+ # We cannot change it without causing a breaking change.
54
+ client_global_error_statuses = Datadog.configuration.tracing.http_error_statuses.client
55
+ server_global_error_statuses = Datadog.configuration.tracing.http_error_statuses.server
56
+ client_global_error_statuses + server_global_error_statuses
57
+ else
58
+ Tracing::Contrib::StatusRangeMatcher.new(value)
59
+ end
52
60
  end
53
61
  o.env_parser do |v|
54
62
  Tracing::Contrib::StatusRangeEnvParser.call(v) if v