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
@@ -45,9 +45,17 @@ module Datadog
45
45
 
46
46
  option :error_status_codes do |o|
47
47
  o.env Ext::ENV_ERROR_STATUS_CODES
48
- o.default 400...600
49
- o.setter do |v|
50
- Tracing::Contrib::StatusRangeMatcher.new(v) if v
48
+ o.setter do |value|
49
+ if value.nil?
50
+ # Fallback to global config, which is defaulted to client (400..499) + server (500..599)
51
+ # DEV-3.0: `httpclient` is a client library, this should fall back to `http_error_statuses.client` only.
52
+ # We cannot change it without causing a breaking change.
53
+ client_global_error_statuses = Datadog.configuration.tracing.http_error_statuses.client
54
+ server_global_error_statuses = Datadog.configuration.tracing.http_error_statuses.server
55
+ client_global_error_statuses + server_global_error_statuses
56
+ else
57
+ Tracing::Contrib::StatusRangeMatcher.new(value)
58
+ end
51
59
  end
52
60
  o.env_parser do |v|
53
61
  Tracing::Contrib::StatusRangeEnvParser.call(v) if v
@@ -45,9 +45,17 @@ module Datadog
45
45
 
46
46
  option :error_status_codes do |o|
47
47
  o.env Ext::ENV_ERROR_STATUS_CODES
48
- o.default 400...600
49
- o.setter do |v|
50
- Tracing::Contrib::StatusRangeMatcher.new(v) if v
48
+ o.setter do |value|
49
+ if value.nil?
50
+ # Fallback to global config, which is defaulted to client (400..499) + server (500..599)
51
+ # DEV-3.0: `httprb` is a client library, this should fall back to `http_error_statuses.client` only.
52
+ # We cannot change it without causing a breaking change.
53
+ client_global_error_statuses = Datadog.configuration.tracing.http_error_statuses.client
54
+ server_global_error_statuses = Datadog.configuration.tracing.http_error_statuses.server
55
+ client_global_error_statuses + server_global_error_statuses
56
+ else
57
+ Tracing::Contrib::StatusRangeMatcher.new(value)
58
+ end
51
59
  end
52
60
  o.env_parser do |v|
53
61
  Tracing::Contrib::StatusRangeEnvParser.call(v) if v
@@ -0,0 +1,66 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Datadog
4
+ module Tracing
5
+ module Contrib
6
+ module Kafka
7
+ module Instrumentation
8
+ # Instrumentation for Kafka::Consumer
9
+ module Consumer
10
+ def self.prepended(base)
11
+ base.prepend(InstanceMethods)
12
+ end
13
+
14
+ # Instance methods for consumer instrumentation
15
+ module InstanceMethods
16
+ def each_message(**kwargs, &block)
17
+ return super unless Datadog::DataStreams.enabled?
18
+
19
+ wrapped_block = proc do |message|
20
+ Datadog.logger.debug { "Kafka each_message: DSM enabled for topic #{message.topic}" }
21
+
22
+ begin
23
+ headers = message.headers || {}
24
+ Datadog::DataStreams.set_consume_checkpoint(
25
+ type: 'kafka',
26
+ source: message.topic,
27
+ auto_instrumentation: true
28
+ ) { |key| headers[key] }
29
+ rescue => e
30
+ Datadog.logger.debug("Error setting DSM checkpoint: #{e.class}: #{e}")
31
+ end
32
+
33
+ yield(message) if block
34
+ end
35
+
36
+ super(**kwargs, &wrapped_block)
37
+ end
38
+
39
+ def each_batch(**kwargs, &block)
40
+ return super unless Datadog::DataStreams.enabled?
41
+
42
+ wrapped_block = proc do |batch|
43
+ Datadog.logger.debug { "Kafka each_batch: DSM enabled for topic #{batch.topic}" }
44
+
45
+ begin
46
+ Datadog::DataStreams.set_consume_checkpoint(
47
+ type: 'kafka',
48
+ source: batch.topic,
49
+ auto_instrumentation: true
50
+ )
51
+ rescue => e
52
+ Datadog.logger.debug("Error setting DSM checkpoint: #{e.class}: #{e}")
53
+ end
54
+
55
+ yield(batch) if block
56
+ end
57
+
58
+ super(**kwargs, &wrapped_block)
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,66 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Datadog
4
+ module Tracing
5
+ module Contrib
6
+ module Kafka
7
+ module Instrumentation
8
+ # Instrumentation for Kafka::Producer
9
+ module Producer
10
+ def self.prepended(base)
11
+ base.prepend(InstanceMethods)
12
+ end
13
+
14
+ module InstanceMethods
15
+ def deliver_messages(**kwargs)
16
+ if Datadog::DataStreams.enabled?
17
+ begin
18
+ pending_messages = instance_variable_get(:@pending_message_queue)
19
+
20
+ if pending_messages && !pending_messages.empty?
21
+ pending_messages.each do |message|
22
+ message.headers ||= {}
23
+ Datadog::DataStreams.set_produce_checkpoint(
24
+ type: 'kafka',
25
+ destination: message.topic,
26
+ auto_instrumentation: true
27
+ ) do |key, value|
28
+ message.headers[key] = value
29
+ end
30
+ end
31
+ end
32
+ rescue => e
33
+ Datadog.logger.debug("Error setting DSM checkpoint: #{e.class}: #{e}")
34
+ end
35
+ end
36
+
37
+ super
38
+ end
39
+
40
+ def send_messages(messages, **kwargs)
41
+ if Datadog::DataStreams.enabled?
42
+ begin
43
+ messages.each do |message|
44
+ message[:headers] ||= {}
45
+ Datadog::DataStreams.set_produce_checkpoint(
46
+ type: 'kafka',
47
+ destination: message[:topic],
48
+ auto_instrumentation: true
49
+ ) do |key, value|
50
+ message[:headers][key] = value
51
+ end
52
+ end
53
+ rescue => e
54
+ Datadog.logger.debug("Error setting DSM checkpoint: #{e.class}: #{e}")
55
+ end
56
+ end
57
+
58
+ super
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
66
+ end
@@ -21,6 +21,20 @@ module Datadog
21
21
  def patch
22
22
  # Subscribe to Kafka events
23
23
  Events.subscribe!
24
+
25
+ # Apply monkey patches for additional instrumentation (e.g., DSM)
26
+ patch_producer if defined?(::Kafka::Producer)
27
+ patch_consumer if defined?(::Kafka::Consumer)
28
+ end
29
+
30
+ def patch_producer
31
+ require_relative 'instrumentation/producer'
32
+ ::Kafka::Producer.prepend(Instrumentation::Producer)
33
+ end
34
+
35
+ def patch_consumer
36
+ require_relative 'instrumentation/consumer'
37
+ ::Kafka::Consumer.prepend(Instrumentation::Consumer)
24
38
  end
25
39
  end
26
40
  end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Datadog
4
+ module Tracing
5
+ module Contrib
6
+ module Karafka
7
+ # Karafka framework code, used to essentially:
8
+ # - handle configuration entries which are specific to Datadog tracing
9
+ # - instrument parts of the framework when needed
10
+ module Framework
11
+ def self.setup
12
+ Datadog.configure do |datadog_config|
13
+ karafka_config = datadog_config.tracing[:karafka]
14
+ activate_waterdrop!(datadog_config, karafka_config)
15
+ end
16
+ end
17
+
18
+ # Apply relevant configuration from Karafka to WaterDrop
19
+ def self.activate_waterdrop!(datadog_config, karafka_config)
20
+ datadog_config.tracing.instrument(
21
+ :waterdrop,
22
+ service_name: karafka_config[:service_name],
23
+ distributed_tracing: karafka_config[:distributed_tracing],
24
+ )
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -47,6 +47,17 @@ module Datadog
47
47
  span.set_tag(Ext::TAG_CONSUMER, consumer)
48
48
  span.set_tag(Contrib::Ext::Messaging::TAG_DESTINATION, job.executor.topic.name)
49
49
  span.set_tag(Contrib::Ext::Messaging::TAG_SYSTEM, Ext::TAG_SYSTEM)
50
+
51
+ # DSM: Track consumer offset stats for batch processing
52
+ if Datadog.configuration.data_streams.enabled
53
+ job.messages.each do |message|
54
+ Datadog::DataStreams.track_kafka_consume(
55
+ job.executor.topic.name,
56
+ job.executor.partition,
57
+ message.metadata.offset
58
+ )
59
+ end
60
+ end
50
61
  end
51
62
 
52
63
  super
@@ -25,17 +25,34 @@ module Datadog
25
25
  # @see https://github.com/karafka/karafka/blob/b06d1f7c17818e1605f80c2bb573454a33376b40/README.md?plain=1#L29-L35
26
26
  def each(&block)
27
27
  @messages_array.each do |message|
28
- if configuration[:distributed_tracing]
28
+ trace_digest = if configuration[:distributed_tracing]
29
29
  headers = if message.metadata.respond_to?(:raw_headers)
30
30
  message.metadata.raw_headers
31
31
  else
32
32
  message.metadata.headers
33
33
  end
34
- trace_digest = Karafka.extract(headers)
35
- Datadog::Tracing.continue_trace!(trace_digest) if trace_digest
34
+ Karafka.extract(headers)
36
35
  end
37
36
 
38
- Tracing.trace(Ext::SPAN_MESSAGE_CONSUME) do |span|
37
+ Tracing.trace(Ext::SPAN_MESSAGE_CONSUME, continue_from: trace_digest) do |span, trace|
38
+ if Datadog::DataStreams.enabled?
39
+ begin
40
+ headers = if message.metadata.respond_to?(:raw_headers)
41
+ message.metadata.raw_headers
42
+ else
43
+ message.metadata.headers
44
+ end
45
+
46
+ Datadog::DataStreams.set_consume_checkpoint(
47
+ type: 'kafka',
48
+ source: message.topic,
49
+ auto_instrumentation: true
50
+ ) { |key| headers[key] }
51
+ rescue => e
52
+ Datadog.logger.debug("Error setting DSM checkpoint: #{e.class}: #{e}")
53
+ end
54
+ end
55
+
39
56
  span.set_tag(Ext::TAG_OFFSET, message.metadata.offset)
40
57
  span.set_tag(Contrib::Ext::Messaging::TAG_DESTINATION, message.topic)
41
58
  span.set_tag(Contrib::Ext::Messaging::TAG_SYSTEM, Ext::TAG_SYSTEM)
@@ -52,6 +69,8 @@ module Datadog
52
69
  module Patcher
53
70
  include Contrib::Patcher
54
71
 
72
+ ACTIVATE_FRAMEWORK_ONLY_ONCE = Core::Utils::OnlyOnce.new
73
+
55
74
  module_function
56
75
 
57
76
  def target_version
@@ -60,9 +79,21 @@ module Datadog
60
79
 
61
80
  def patch
62
81
  require_relative 'monitor'
82
+ require_relative 'framework'
83
+ require_relative '../waterdrop'
63
84
 
64
85
  ::Karafka::Instrumentation::Monitor.prepend(Monitor)
65
86
  ::Karafka::Messages::Messages.prepend(MessagesPatch)
87
+
88
+ if Contrib::WaterDrop::Integration.compatible?
89
+ ::Karafka.monitor.subscribe('app.initialized') do |event|
90
+ ACTIVATE_FRAMEWORK_ONLY_ONCE.run do
91
+ Contrib::Karafka::Framework.setup
92
+ end
93
+
94
+ Contrib::WaterDrop::Patcher.add_middleware(::Karafka.producer)
95
+ end
96
+ end
66
97
  end
67
98
  end
68
99
  end
@@ -13,6 +13,7 @@ require_relative 'ext'
13
13
  require_relative 'header_collection'
14
14
  require_relative 'header_tagging'
15
15
  require_relative 'request_queue'
16
+ require_relative 'route_inference'
16
17
  require_relative 'trace_proxy_middleware'
17
18
 
18
19
  module Datadog
@@ -138,28 +139,7 @@ module Datadog
138
139
  request_span.set_tag(Tracing::Metadata::Ext::TAG_OPERATION, Ext::TAG_OPERATION_REQUEST)
139
140
  request_span.set_tag(Tracing::Metadata::Ext::TAG_KIND, Tracing::Metadata::Ext::SpanKind::TAG_SERVER)
140
141
 
141
- if status != 404 && (last_route = trace.get_tag(Tracing::Metadata::Ext::HTTP::TAG_ROUTE))
142
- last_script_name = trace.get_tag(Tracing::Metadata::Ext::HTTP::TAG_ROUTE_PATH) || ''
143
-
144
- # If the last_script_name is empty but the env['SCRIPT_NAME'] is NOT empty
145
- # then the current rack request was not routed and must be accounted for
146
- # which only happens in pure nested rack requests i.e /rack/rack/hello/world
147
- #
148
- # To account for the unaccounted nested rack requests of /rack/hello/world,
149
- # we use 'PATH_INFO knowing that rack cannot have named parameters
150
- if last_script_name == '' && env['SCRIPT_NAME'] && env['SCRIPT_NAME'] != ''
151
- last_script_name = last_route
152
- last_route = env['PATH_INFO']
153
- end
154
-
155
- # Clear the route and route path tags from the request trace to avoid possibility of misplacement
156
- trace.clear_tag(Tracing::Metadata::Ext::HTTP::TAG_ROUTE)
157
- trace.clear_tag(Tracing::Metadata::Ext::HTTP::TAG_ROUTE_PATH)
158
-
159
- # Ensure tags are placed in rack.request span as desired
160
- request_span.set_tag(Tracing::Metadata::Ext::HTTP::TAG_ROUTE, last_script_name + last_route)
161
- request_span.clear_tag(Tracing::Metadata::Ext::HTTP::TAG_ROUTE_PATH)
162
- end
142
+ set_route_and_endpoint_tags(trace: trace, request_span: request_span, status: status, env: env)
163
143
 
164
144
  # Set analytics sample rate
165
145
  if Contrib::Analytics.enabled?(configuration[:analytics_enabled])
@@ -218,16 +198,14 @@ module Datadog
218
198
  request_span.set_tag(Tracing::Metadata::Ext::HTTP::TAG_USER_AGENT, user_agent)
219
199
  end
220
200
 
221
- if request_span.get_tag(Tracing::Metadata::Ext::HTTP::TAG_ROUTE).nil? && status != 404
222
- request_span.set_tag(Tracing::Metadata::Ext::HTTP::TAG_ROUTE, env['PATH_INFO'])
223
- end
224
-
225
201
  HeaderTagging.tag_request_headers(request_span, request_header_collection, configuration)
226
202
  HeaderTagging.tag_response_headers(request_span, headers, configuration) if headers
227
203
 
228
204
  # detect if the status code is a 5xx and flag the request span as an error
229
205
  # unless it has been already set by the underlying framework
230
- request_span.status = 1 if status.to_s.start_with?('5') && request_span.status.zero?
206
+ if request_span.status.zero? && Datadog.configuration.tracing.http_error_statuses.server.include?(status)
207
+ request_span.status = Tracing::Metadata::Ext::Errors::STATUS
208
+ end
231
209
  end
232
210
  # rubocop:enable Metrics/AbcSize
233
211
  # rubocop:enable Metrics/CyclomaticComplexity
@@ -240,6 +218,60 @@ module Datadog
240
218
  Datadog.configuration.tracing[:rack]
241
219
  end
242
220
 
221
+ # rubocop:disable Metrics/AbcSize
222
+ # rubocop:disable Metrics/MethodLength
223
+ # rubocop:disable Metrics/CyclomaticComplexity
224
+ # rubocop:disable Metrics/PerceivedComplexity
225
+ def set_route_and_endpoint_tags(trace:, request_span:, status:, env:)
226
+ return if status == 404
227
+
228
+ if (last_route = trace.get_tag(Tracing::Metadata::Ext::HTTP::TAG_ROUTE))
229
+ last_script_name = trace.get_tag(Tracing::Metadata::Ext::HTTP::TAG_ROUTE_PATH) || ''
230
+
231
+ # This happens when processing requests to a nested rack application,
232
+ # when parent app is instrumented, and the nested app is not instrumented
233
+ #
234
+ # When resource_renaming.always_simplified_endpoint is set to true,
235
+ # we infer the route from the full request path.
236
+ if last_script_name == '' && env['SCRIPT_NAME'] != '' &&
237
+ !Datadog.configuration.tracing.resource_renaming.always_simplified_endpoint &&
238
+ (inferred_route = RouteInference.infer(env['PATH_INFO']))
239
+ set_endpoint_tag(request_span, last_route + inferred_route)
240
+ end
241
+
242
+ # Clear the route and route path tags from the request trace to avoid possibility of misplacement
243
+ trace.clear_tag(Tracing::Metadata::Ext::HTTP::TAG_ROUTE)
244
+ trace.clear_tag(Tracing::Metadata::Ext::HTTP::TAG_ROUTE_PATH)
245
+
246
+ # Ensure tags are placed in rack.request span as desired
247
+ request_span.set_tag(Tracing::Metadata::Ext::HTTP::TAG_ROUTE, last_script_name + last_route)
248
+ request_span.clear_tag(Tracing::Metadata::Ext::HTTP::TAG_ROUTE_PATH)
249
+ end
250
+
251
+ if Datadog.configuration.tracing.resource_renaming.always_simplified_endpoint ||
252
+ request_span.get_tag(Tracing::Metadata::Ext::HTTP::TAG_ROUTE).nil?
253
+ if (inferred_route = RouteInference.read_or_infer(env))
254
+ set_endpoint_tag(request_span, inferred_route) if inferred_route
255
+ end
256
+ elsif !request_span.get_tag(Tracing::Metadata::Ext::HTTP::TAG_ENDPOINT)
257
+ set_endpoint_tag(request_span, request_span.get_tag(Tracing::Metadata::Ext::HTTP::TAG_ROUTE))
258
+ end
259
+ end
260
+ # rubocop:enable Metrics/AbcSize
261
+ # rubocop:enable Metrics/MethodLength
262
+ # rubocop:enable Metrics/CyclomaticComplexity
263
+ # rubocop:enable Metrics/PerceivedComplexity
264
+
265
+ def set_endpoint_tag(request_span, value)
266
+ # In the first iteration, http.endpoint must be reported in 2 cases:
267
+ # 1. resource renaming is enabled
268
+ # 2. AppSec is enabled and resource renaming is disabled (by default, not explicitly)
269
+ if Datadog.configuration.tracing.resource_renaming.enabled ||
270
+ Datadog.configuration.appsec.enabled && Datadog.configuration.tracing.resource_renaming.options[:enabled].default_precedence?
271
+ request_span.set_tag(Tracing::Metadata::Ext::HTTP::TAG_ENDPOINT, value)
272
+ end
273
+ end
274
+
243
275
  # rubocop:disable Metrics/AbcSize
244
276
  # rubocop:disable Metrics/MethodLength
245
277
  def parse_url(env, original_env)
@@ -24,6 +24,7 @@ module Datadog
24
24
  # nginx header is seconds in the format "t=1512379167.574"
25
25
  # apache header is microseconds in the format "t=1570633834463123"
26
26
  # heroku header is milliseconds in the format "1570634024294"
27
+ # @see https://github.com/heroku/vegur/blob/65d168f757e0ddb448f41cfb9e4b0281c747378d/README.md?plain=1#L383-L384
27
28
  time_string = header.to_s.delete('^0-9')
28
29
  return if time_string.nil?
29
30
 
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Datadog
4
+ module Tracing
5
+ module Contrib
6
+ module Rack
7
+ # This module provides logic for inferring HTTP route pattern
8
+ # from an HTTP path.
9
+ module RouteInference
10
+ MAX_NUMBER_OF_SEGMENTS = 8
11
+
12
+ INT_PARAM_REGEX = /\A[0-9]+\z/.freeze
13
+ INT_ID_PARAM_REGEX = /\A(?=.*\d)[\d._-]{3,}\z/.freeze
14
+ HEX_PARAM_REGEX = /\A(?=.*\d)[A-Fa-f0-9]{6,}\z/.freeze
15
+ HEX_ID_PARAM_REGEX = /\A(?=.*\d)[A-Fa-f0-9._-]{6,}\z/.freeze
16
+ STRING_PARAM_REGEX = /\A.{20,}|.*[%&'()*+,:=@].*\z/.freeze
17
+
18
+ DATADOG_INFERRED_ROUTE_ENV_KEY = 'datadog.inferred_route'
19
+
20
+ module_function
21
+
22
+ def read_or_infer(request_env)
23
+ request_env[DATADOG_INFERRED_ROUTE_ENV_KEY] ||=
24
+ infer(request_env['SCRIPT_NAME'].to_s + request_env['PATH_INFO'].to_s)
25
+ end
26
+
27
+ def infer(path)
28
+ segments = path.delete_prefix('/').split('/', MAX_NUMBER_OF_SEGMENTS + 1).first(MAX_NUMBER_OF_SEGMENTS)
29
+
30
+ segments.map! do |segment| #: Array[String?]
31
+ next if segment.empty?
32
+
33
+ case segment
34
+ when INT_PARAM_REGEX then '{param:int}'
35
+ when INT_ID_PARAM_REGEX then '{param:int_id}'
36
+ when HEX_PARAM_REGEX then '{param:hex}'
37
+ when HEX_ID_PARAM_REGEX then '{param:hex_id}'
38
+ when STRING_PARAM_REGEX then '{param:str}'
39
+ else segment
40
+ end
41
+ end
42
+
43
+ segments.compact! #: Array[String]
44
+
45
+ "/#{segments.join("/")}"
46
+ rescue
47
+ nil
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
@@ -43,7 +43,13 @@ module Datadog
43
43
  # excluding the time spent processing the request itself
44
44
  queue_span.finish
45
45
 
46
- yield.tap { request_span.finish }
46
+ yield
47
+ ensure
48
+ # Ensure that the spans are finished even if an exception is raised.
49
+ # **This is very important** to prevent the trace from leaking between requests,
50
+ # especially because `queue_span` is normally a root span.
51
+ queue_span&.finish
52
+ request_span&.finish
47
53
  end
48
54
  end
49
55
  end
@@ -12,7 +12,8 @@ module Datadog
12
12
  # @!visibility private
13
13
  ENV_ANALYTICS_ENABLED = 'DD_TRACE_RAILS_ANALYTICS_ENABLED'
14
14
  ENV_ANALYTICS_SAMPLE_RATE = 'DD_TRACE_RAILS_ANALYTICS_SAMPLE_RATE'
15
- ENV_DISABLE = 'DISABLE_DATADOG_RAILS'
15
+ # Note: Alias (previous name DISABLE_DATADOG_RAILS) defined in supported-configurations.json
16
+ ENV_DISABLE = 'DD_DISABLE_DATADOG_RAILS'
16
17
 
17
18
  SPAN_RUNNER_FILE = 'rails.runner.file'
18
19
  SPAN_RUNNER_INLINE = 'rails.runner.inline'
@@ -35,7 +35,7 @@ module Datadog
35
35
  end
36
36
 
37
37
  def self.patchable?
38
- super && !ENV.key?(Ext::ENV_DISABLE)
38
+ super && !DATADOG_ENV.key?(Ext::ENV_DISABLE)
39
39
  end
40
40
 
41
41
  def new_configuration
@@ -26,8 +26,8 @@ module Datadog
26
26
  rescue Exception => e
27
27
  span = Tracing.active_span
28
28
  if !span.nil? && ActionPack::Utils.exception_is_error?(e)
29
- # Only set error if it's supposed to be flagged as such
30
- # e.g. we don't want to flag 404s.
29
+ # By default, only 5XX exceptions are actually errors (e.g. don't flag 404s).
30
+ # This can be changed by setting `DD_TRACE_HTTP_SERVER_ERROR_STATUSES` environment variable.
31
31
  # You can add custom errors via `config.action_dispatch.rescue_responses`
32
32
  span.set_error(e)
33
33
 
@@ -99,7 +99,10 @@ module Datadog
99
99
  end
100
100
  end
101
101
  rescue ::RestClient::ExceptionWithResponse => e
102
- span.set_error(e) if Tracing::Metadata::Ext::HTTP::ERROR_RANGE.cover?(e.http_code)
102
+ # DEV-3.0: This was previously checking against a 500..599 range.
103
+ # To not introduce breaking change, this was changed to use `http_error_statuses.server`,
104
+ # but `rest_client` is a client library, this check should use `http_error_statuses.client` instead.
105
+ span.set_error(e) if Datadog.configuration.tracing.http_error_statuses.server.include?(e.http_code)
103
106
  span.set_tag(Tracing::Metadata::Ext::HTTP::TAG_STATUS_CODE, e.http_code)
104
107
 
105
108
  raise e
@@ -61,7 +61,9 @@ module Datadog
61
61
  # Adds status code to the resource name once the resource comes back
62
62
  span.resource = "#{request_method} #{status_code}"
63
63
  span.set_tag(Tracing::Metadata::Ext::HTTP::TAG_STATUS_CODE, status_code)
64
- span.status = 1 if status_code.to_s.start_with?('5')
64
+ if Datadog.configuration.tracing.http_error_statuses.server.include?(status_code)
65
+ span.status = Tracing::Metadata::Ext::Errors::STATUS
66
+ end
65
67
  response
66
68
  end
67
69
  end
@@ -70,7 +70,9 @@ module Datadog
70
70
  sinatra_response = ::Sinatra::Response.new([], status) # Build object to use status code helpers
71
71
 
72
72
  span.set_tag(Tracing::Metadata::Ext::HTTP::TAG_STATUS_CODE, sinatra_response.status)
73
- span.set_error(env['sinatra.error']) if sinatra_response.server_error?
73
+ if Datadog.configuration.tracing.http_error_statuses.server.include?(sinatra_response.status)
74
+ span.set_error(env['sinatra.error'])
75
+ end
74
76
  end
75
77
 
76
78
  if (headers = response[1])
@@ -11,7 +11,7 @@ module Datadog
11
11
  NO_SOURCE = [].freeze
12
12
 
13
13
  def self.fetch_service_name(env, default)
14
- ENV.fetch(env) do
14
+ DATADOG_ENV.fetch(env) do
15
15
  if Datadog.configuration.tracing.contrib.global_default_service_name.enabled
16
16
  return Datadog.configuration.service
17
17
  end
@@ -5,9 +5,17 @@ module Datadog
5
5
  module Contrib
6
6
  # Useful checking whether the defined range covers status code
7
7
  class StatusRangeMatcher
8
+ attr_reader :ranges
9
+
8
10
  def initialize(ranges)
9
- @ranges = Array(ranges)
11
+ # Steep: https://github.com/ruby/rbs/issues/1874
12
+ @ranges = Array(ranges) # steep:ignore IncompatibleAssignment
13
+ end
14
+
15
+ def +(other)
16
+ StatusRangeMatcher.new(@ranges + other.ranges)
10
17
  end
18
+ alias_method :concat, :+
11
19
 
12
20
  def include?(status)
13
21
  @ranges.any? do |e|
@@ -10,7 +10,9 @@ module Datadog
10
10
  PLACEHOLDER = '?'
11
11
  EXCLUDE_KEYS = [].freeze
12
12
  SHOW_KEYS = [].freeze
13
- DEFAULT_OPTIONS = {
13
+
14
+ # Steep: https://github.com/soutaro/steep/issues/363
15
+ DEFAULT_OPTIONS = { # steep:ignore IncompatibleAssignment
14
16
  exclude: EXCLUDE_KEYS,
15
17
  show: SHOW_KEYS,
16
18
  placeholder: PLACEHOLDER
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../../configuration/settings'
4
+ require_relative '../ext'
5
+
6
+ module Datadog
7
+ module Tracing
8
+ module Contrib
9
+ module WaterDrop
10
+ module Configuration
11
+ # @public_api
12
+ class Settings < Contrib::Configuration::Settings
13
+ option :enabled do |o|
14
+ o.type :bool
15
+ o.env Ext::ENV_ENABLED
16
+ o.default true
17
+ end
18
+
19
+ option :service_name
20
+
21
+ option :distributed_tracing, default: false, type: :bool
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end