ddtrace 1.12.1 → 1.18.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 (448) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +388 -10
  3. data/ext/ddtrace_profiling_native_extension/NativeExtensionDesign.md +3 -5
  4. data/ext/ddtrace_profiling_native_extension/clock_id.h +0 -3
  5. data/ext/ddtrace_profiling_native_extension/clock_id_from_pthread.c +3 -22
  6. data/ext/ddtrace_profiling_native_extension/clock_id_noop.c +0 -1
  7. data/ext/ddtrace_profiling_native_extension/collectors_cpu_and_wall_time_worker.c +41 -6
  8. data/ext/ddtrace_profiling_native_extension/collectors_idle_sampling_helper.c +3 -0
  9. data/ext/ddtrace_profiling_native_extension/collectors_stack.c +76 -24
  10. data/ext/ddtrace_profiling_native_extension/collectors_stack.h +1 -1
  11. data/ext/ddtrace_profiling_native_extension/collectors_thread_context.c +292 -27
  12. data/ext/ddtrace_profiling_native_extension/collectors_thread_context.h +1 -1
  13. data/ext/ddtrace_profiling_native_extension/extconf.rb +40 -10
  14. data/ext/ddtrace_profiling_native_extension/http_transport.c +48 -16
  15. data/ext/ddtrace_profiling_native_extension/libdatadog_helpers.c +42 -0
  16. data/ext/ddtrace_profiling_native_extension/libdatadog_helpers.h +6 -0
  17. data/ext/ddtrace_profiling_native_extension/native_extension_helpers.rb +1 -1
  18. data/ext/ddtrace_profiling_native_extension/pid_controller.c +57 -0
  19. data/ext/ddtrace_profiling_native_extension/pid_controller.h +45 -0
  20. data/ext/ddtrace_profiling_native_extension/private_vm_api_access.c +136 -32
  21. data/ext/ddtrace_profiling_native_extension/private_vm_api_access.h +12 -0
  22. data/ext/ddtrace_profiling_native_extension/profiling.c +1 -2
  23. data/ext/ddtrace_profiling_native_extension/stack_recorder.c +81 -50
  24. data/ext/ddtrace_profiling_native_extension/stack_recorder.h +13 -3
  25. data/ext/ddtrace_profiling_native_extension/time_helpers.c +40 -4
  26. data/ext/ddtrace_profiling_native_extension/time_helpers.h +14 -0
  27. data/lib/datadog/appsec/assets/waf_rules/processors.json +92 -0
  28. data/lib/datadog/appsec/assets/waf_rules/recommended.json +698 -75
  29. data/lib/datadog/appsec/assets/waf_rules/scanners.json +114 -0
  30. data/lib/datadog/appsec/assets/waf_rules/strict.json +98 -8
  31. data/lib/datadog/appsec/assets.rb +8 -0
  32. data/lib/datadog/appsec/component.rb +21 -2
  33. data/lib/datadog/appsec/configuration/settings.rb +167 -189
  34. data/lib/datadog/appsec/configuration.rb +0 -79
  35. data/lib/datadog/appsec/contrib/auto_instrument.rb +2 -4
  36. data/lib/datadog/appsec/contrib/devise/event.rb +57 -0
  37. data/lib/datadog/appsec/contrib/devise/ext.rb +13 -0
  38. data/lib/datadog/appsec/contrib/devise/integration.rb +42 -0
  39. data/lib/datadog/appsec/contrib/devise/patcher/authenticatable_patch.rb +76 -0
  40. data/lib/datadog/appsec/contrib/devise/patcher/registration_controller_patch.rb +54 -0
  41. data/lib/datadog/appsec/contrib/devise/patcher.rb +45 -0
  42. data/lib/datadog/appsec/contrib/devise/resource.rb +35 -0
  43. data/lib/datadog/appsec/contrib/devise/tracking.rb +49 -0
  44. data/lib/datadog/appsec/contrib/rack/ext.rb +2 -1
  45. data/lib/datadog/appsec/contrib/rack/gateway/request.rb +6 -2
  46. data/lib/datadog/appsec/contrib/rack/gateway/watcher.rb +8 -6
  47. data/lib/datadog/appsec/contrib/rack/reactive/request.rb +3 -8
  48. data/lib/datadog/appsec/contrib/rack/reactive/request_body.rb +3 -6
  49. data/lib/datadog/appsec/contrib/rack/reactive/response.rb +3 -6
  50. data/lib/datadog/appsec/contrib/rack/request_body_middleware.rb +3 -2
  51. data/lib/datadog/appsec/contrib/rack/request_middleware.rb +36 -17
  52. data/lib/datadog/appsec/contrib/rails/ext.rb +3 -2
  53. data/lib/datadog/appsec/contrib/rails/framework.rb +1 -3
  54. data/lib/datadog/appsec/contrib/rails/gateway/watcher.rb +3 -2
  55. data/lib/datadog/appsec/contrib/rails/patcher.rb +17 -11
  56. data/lib/datadog/appsec/contrib/rails/reactive/action.rb +3 -6
  57. data/lib/datadog/appsec/contrib/sinatra/ext.rb +2 -1
  58. data/lib/datadog/appsec/contrib/sinatra/framework.rb +1 -3
  59. data/lib/datadog/appsec/contrib/sinatra/gateway/watcher.rb +6 -4
  60. data/lib/datadog/appsec/contrib/sinatra/patcher.rb +13 -7
  61. data/lib/datadog/appsec/contrib/sinatra/reactive/routed.rb +3 -6
  62. data/lib/datadog/appsec/event.rb +106 -50
  63. data/lib/datadog/appsec/extensions.rb +1 -130
  64. data/lib/datadog/appsec/monitor/gateway/watcher.rb +3 -3
  65. data/lib/datadog/appsec/monitor/reactive/set_user.rb +3 -6
  66. data/lib/datadog/appsec/processor/actions.rb +49 -0
  67. data/lib/datadog/appsec/processor/rule_loader.rb +60 -0
  68. data/lib/datadog/appsec/processor/rule_merger.rb +22 -2
  69. data/lib/datadog/appsec/processor.rb +35 -7
  70. data/lib/datadog/appsec/rate_limiter.rb +1 -1
  71. data/lib/datadog/appsec/remote.rb +17 -11
  72. data/lib/datadog/appsec/response.rb +82 -4
  73. data/lib/datadog/appsec/sample_rate.rb +21 -0
  74. data/lib/datadog/appsec.rb +3 -4
  75. data/lib/datadog/core/backport.rb +51 -0
  76. data/lib/datadog/core/configuration/agent_settings_resolver.rb +38 -29
  77. data/lib/datadog/core/configuration/base.rb +6 -16
  78. data/lib/datadog/core/configuration/components.rb +15 -3
  79. data/lib/datadog/core/configuration/ext.rb +28 -5
  80. data/lib/datadog/core/configuration/option.rb +269 -21
  81. data/lib/datadog/core/configuration/option_definition.rb +73 -32
  82. data/lib/datadog/core/configuration/options.rb +27 -15
  83. data/lib/datadog/core/configuration/settings.rb +182 -102
  84. data/lib/datadog/core/configuration.rb +4 -0
  85. data/lib/datadog/core/diagnostics/environment_logger.rb +130 -234
  86. data/lib/datadog/core/environment/execution.rb +103 -0
  87. data/lib/datadog/core/environment/ext.rb +13 -11
  88. data/lib/datadog/core/environment/variable_helpers.rb +0 -69
  89. data/lib/datadog/core/environment/yjit.rb +58 -0
  90. data/lib/datadog/core/error.rb +1 -0
  91. data/lib/datadog/core/git/ext.rb +26 -22
  92. data/lib/datadog/core/logging/ext.rb +3 -1
  93. data/lib/datadog/core/metrics/ext.rb +7 -5
  94. data/lib/datadog/core/remote/client/capabilities.rb +6 -1
  95. data/lib/datadog/core/remote/client.rb +3 -0
  96. data/lib/datadog/core/remote/component.rb +27 -36
  97. data/lib/datadog/core/remote/configuration/content.rb +28 -1
  98. data/lib/datadog/core/remote/configuration/repository.rb +3 -1
  99. data/lib/datadog/core/remote/ext.rb +1 -1
  100. data/lib/datadog/core/remote/negotiation.rb +19 -6
  101. data/lib/datadog/core/remote/transport/config.rb +60 -0
  102. data/lib/datadog/core/remote/transport/http/api/instance.rb +39 -0
  103. data/lib/datadog/core/remote/transport/http/api/spec.rb +21 -0
  104. data/lib/datadog/core/remote/transport/http/api.rb +58 -0
  105. data/lib/datadog/core/remote/transport/http/builder.rb +219 -0
  106. data/lib/datadog/core/remote/transport/http/client.rb +48 -0
  107. data/lib/datadog/core/remote/transport/http/config.rb +280 -0
  108. data/lib/datadog/core/remote/transport/http/negotiation.rb +146 -0
  109. data/lib/datadog/core/remote/transport/http.rb +179 -0
  110. data/lib/datadog/core/{transport → remote/transport}/negotiation.rb +25 -23
  111. data/lib/datadog/core/remote/worker.rb +4 -1
  112. data/lib/datadog/core/runtime/ext.rb +22 -12
  113. data/lib/datadog/core/runtime/metrics.rb +43 -0
  114. data/lib/datadog/core/telemetry/client.rb +12 -2
  115. data/lib/datadog/core/telemetry/collector.rb +13 -4
  116. data/lib/datadog/core/telemetry/emitter.rb +4 -2
  117. data/lib/datadog/core/telemetry/event.rb +19 -4
  118. data/lib/datadog/core/telemetry/ext.rb +4 -1
  119. data/lib/datadog/core/telemetry/heartbeat.rb +2 -4
  120. data/lib/datadog/core/telemetry/http/ext.rb +10 -8
  121. data/lib/datadog/core/telemetry/http/transport.rb +2 -0
  122. data/lib/datadog/core/telemetry/v2/app_client_configuration_change.rb +41 -0
  123. data/lib/datadog/core/telemetry/v2/request.rb +29 -0
  124. data/lib/datadog/core/transport/ext.rb +47 -0
  125. data/lib/datadog/core/transport/http/adapters/net.rb +168 -0
  126. data/lib/datadog/core/transport/http/adapters/registry.rb +29 -0
  127. data/lib/datadog/core/transport/http/adapters/test.rb +89 -0
  128. data/lib/datadog/core/transport/http/adapters/unix_socket.rb +83 -0
  129. data/lib/datadog/core/transport/http/api/endpoint.rb +31 -0
  130. data/lib/datadog/core/transport/http/api/fallbacks.rb +26 -0
  131. data/lib/datadog/core/transport/http/api/map.rb +18 -0
  132. data/lib/datadog/core/transport/http/env.rb +62 -0
  133. data/lib/datadog/core/transport/http/response.rb +60 -0
  134. data/lib/datadog/core/transport/parcel.rb +22 -0
  135. data/lib/datadog/core/transport/request.rb +17 -0
  136. data/lib/datadog/core/transport/response.rb +64 -0
  137. data/lib/datadog/core/utils/duration.rb +52 -0
  138. data/lib/datadog/core/utils/hash.rb +47 -0
  139. data/lib/datadog/core/utils/network.rb +1 -1
  140. data/lib/datadog/core/utils/safe_dup.rb +27 -20
  141. data/lib/datadog/core/utils.rb +1 -1
  142. data/lib/datadog/core/workers/async.rb +3 -2
  143. data/lib/datadog/core/workers/polling.rb +2 -2
  144. data/lib/datadog/kit/appsec/events.rb +139 -89
  145. data/lib/datadog/kit/enable_core_dumps.rb +5 -6
  146. data/lib/datadog/kit/identity.rb +80 -65
  147. data/lib/datadog/opentelemetry/api/context.rb +10 -3
  148. data/lib/datadog/opentelemetry/sdk/propagator.rb +2 -1
  149. data/lib/datadog/opentelemetry/sdk/span_processor.rb +48 -5
  150. data/lib/datadog/opentelemetry/sdk/trace/span.rb +167 -0
  151. data/lib/datadog/opentelemetry/trace.rb +58 -0
  152. data/lib/datadog/opentelemetry.rb +1 -0
  153. data/lib/datadog/opentracer/text_map_propagator.rb +2 -1
  154. data/lib/datadog/opentracer.rb +9 -0
  155. data/lib/datadog/profiling/collectors/cpu_and_wall_time_worker.rb +16 -17
  156. data/lib/datadog/profiling/collectors/idle_sampling_helper.rb +3 -1
  157. data/lib/datadog/profiling/collectors/thread_context.rb +17 -2
  158. data/lib/datadog/profiling/component.rb +69 -94
  159. data/lib/datadog/profiling/diagnostics/environment_logger.rb +39 -0
  160. data/lib/datadog/profiling/exporter.rb +5 -1
  161. data/lib/datadog/profiling/ext.rb +0 -12
  162. data/lib/datadog/profiling/flush.rb +7 -5
  163. data/lib/datadog/profiling/http_transport.rb +19 -6
  164. data/lib/datadog/profiling/load_native_extension.rb +7 -1
  165. data/lib/datadog/profiling/native_extension.rb +0 -21
  166. data/lib/datadog/profiling/profiler.rb +36 -13
  167. data/lib/datadog/profiling/scheduler.rb +16 -9
  168. data/lib/datadog/profiling.rb +16 -78
  169. data/lib/datadog/tracing/component.rb +70 -11
  170. data/lib/datadog/tracing/configuration/agent_settings_resolver.rb +13 -0
  171. data/lib/datadog/tracing/configuration/dynamic/option.rb +71 -0
  172. data/lib/datadog/tracing/configuration/dynamic.rb +64 -0
  173. data/lib/datadog/tracing/configuration/ext.rb +40 -32
  174. data/lib/datadog/tracing/configuration/http.rb +74 -0
  175. data/lib/datadog/tracing/configuration/settings.rb +134 -98
  176. data/lib/datadog/tracing/contrib/action_cable/configuration/settings.rb +9 -6
  177. data/lib/datadog/tracing/contrib/action_cable/ext.rb +20 -18
  178. data/lib/datadog/tracing/contrib/action_mailer/configuration/settings.rb +9 -6
  179. data/lib/datadog/tracing/contrib/action_mailer/ext.rb +20 -18
  180. data/lib/datadog/tracing/contrib/action_pack/configuration/settings.rb +9 -7
  181. data/lib/datadog/tracing/contrib/action_pack/ext.rb +10 -8
  182. data/lib/datadog/tracing/contrib/action_view/configuration/settings.rb +9 -6
  183. data/lib/datadog/tracing/contrib/action_view/ext.rb +12 -10
  184. data/lib/datadog/tracing/contrib/active_job/configuration/settings.rb +13 -7
  185. data/lib/datadog/tracing/contrib/active_job/ext.rb +25 -23
  186. data/lib/datadog/tracing/contrib/active_job/log_injection.rb +1 -1
  187. data/lib/datadog/tracing/contrib/active_job/patcher.rb +1 -1
  188. data/lib/datadog/tracing/contrib/active_model_serializers/configuration/settings.rb +9 -6
  189. data/lib/datadog/tracing/contrib/active_model_serializers/ext.rb +12 -10
  190. data/lib/datadog/tracing/contrib/active_record/configuration/resolver.rb +18 -11
  191. data/lib/datadog/tracing/contrib/active_record/configuration/settings.rb +9 -7
  192. data/lib/datadog/tracing/contrib/active_record/events/sql.rb +2 -6
  193. data/lib/datadog/tracing/contrib/active_record/ext.rb +17 -15
  194. data/lib/datadog/tracing/contrib/active_record/utils.rb +1 -1
  195. data/lib/datadog/tracing/contrib/active_support/cache/instrumentation.rb +106 -202
  196. data/lib/datadog/tracing/contrib/active_support/cache/patcher.rb +3 -0
  197. data/lib/datadog/tracing/contrib/active_support/configuration/settings.rb +9 -7
  198. data/lib/datadog/tracing/contrib/active_support/ext.rb +18 -16
  199. data/lib/datadog/tracing/contrib/aws/configuration/settings.rb +14 -7
  200. data/lib/datadog/tracing/contrib/aws/ext.rb +37 -24
  201. data/lib/datadog/tracing/contrib/aws/instrumentation.rb +16 -5
  202. data/lib/datadog/tracing/contrib/concurrent_ruby/configuration/settings.rb +3 -2
  203. data/lib/datadog/tracing/contrib/concurrent_ruby/context_composite_executor_service.rb +14 -14
  204. data/lib/datadog/tracing/contrib/concurrent_ruby/ext.rb +4 -2
  205. data/lib/datadog/tracing/contrib/concurrent_ruby/future_patch.rb +3 -10
  206. data/lib/datadog/tracing/contrib/concurrent_ruby/integration.rb +2 -1
  207. data/lib/datadog/tracing/contrib/concurrent_ruby/patcher.rb +8 -1
  208. data/lib/datadog/tracing/contrib/concurrent_ruby/promises_future_patch.rb +22 -0
  209. data/lib/datadog/tracing/contrib/configuration/settings.rb +1 -1
  210. data/lib/datadog/tracing/contrib/dalli/configuration/settings.rb +20 -7
  211. data/lib/datadog/tracing/contrib/dalli/ext.rb +26 -11
  212. data/lib/datadog/tracing/contrib/dalli/instrumentation.rb +17 -8
  213. data/lib/datadog/tracing/contrib/delayed_job/configuration/settings.rb +13 -7
  214. data/lib/datadog/tracing/contrib/delayed_job/ext.rb +16 -14
  215. data/lib/datadog/tracing/contrib/elasticsearch/configuration/settings.rb +14 -7
  216. data/lib/datadog/tracing/contrib/elasticsearch/ext.rb +21 -15
  217. data/lib/datadog/tracing/contrib/elasticsearch/patcher.rb +104 -99
  218. data/lib/datadog/tracing/contrib/ethon/configuration/settings.rb +16 -9
  219. data/lib/datadog/tracing/contrib/ethon/easy_patch.rb +48 -3
  220. data/lib/datadog/tracing/contrib/ethon/ext.rb +19 -11
  221. data/lib/datadog/tracing/contrib/ethon/multi_patch.rb +6 -3
  222. data/lib/datadog/tracing/contrib/excon/configuration/settings.rb +19 -10
  223. data/lib/datadog/tracing/contrib/excon/ext.rb +16 -8
  224. data/lib/datadog/tracing/contrib/excon/middleware.rb +25 -5
  225. data/lib/datadog/tracing/contrib/ext.rb +26 -1
  226. data/lib/datadog/tracing/contrib/extensions.rb +32 -0
  227. data/lib/datadog/tracing/contrib/faraday/configuration/settings.rb +20 -10
  228. data/lib/datadog/tracing/contrib/faraday/ext.rb +16 -8
  229. data/lib/datadog/tracing/contrib/faraday/middleware.rb +21 -5
  230. data/lib/datadog/tracing/contrib/grape/configuration/settings.rb +8 -6
  231. data/lib/datadog/tracing/contrib/grape/ext.rb +16 -14
  232. data/lib/datadog/tracing/contrib/graphql/configuration/settings.rb +8 -6
  233. data/lib/datadog/tracing/contrib/graphql/ext.rb +7 -5
  234. data/lib/datadog/tracing/contrib/grpc/configuration/settings.rb +39 -9
  235. data/lib/datadog/tracing/contrib/grpc/datadog_interceptor/client.rb +39 -20
  236. data/lib/datadog/tracing/contrib/grpc/datadog_interceptor/server.rb +37 -18
  237. data/lib/datadog/tracing/contrib/grpc/datadog_interceptor.rb +0 -4
  238. data/lib/datadog/tracing/contrib/grpc/ext.rb +16 -13
  239. data/lib/datadog/tracing/contrib/grpc/formatting.rb +127 -0
  240. data/lib/datadog/tracing/contrib/hanami/configuration/settings.rb +3 -2
  241. data/lib/datadog/tracing/contrib/hanami/ext.rb +10 -8
  242. data/lib/datadog/tracing/contrib/http/circuit_breaker.rb +5 -8
  243. data/lib/datadog/tracing/contrib/http/configuration/settings.rb +33 -11
  244. data/lib/datadog/tracing/contrib/http/ext.rb +16 -9
  245. data/lib/datadog/tracing/contrib/http/instrumentation.rb +27 -7
  246. data/lib/datadog/tracing/contrib/httpclient/configuration/settings.rb +33 -11
  247. data/lib/datadog/tracing/contrib/httpclient/ext.rb +17 -9
  248. data/lib/datadog/tracing/contrib/httpclient/instrumentation.rb +22 -5
  249. data/lib/datadog/tracing/contrib/httprb/configuration/settings.rb +33 -11
  250. data/lib/datadog/tracing/contrib/httprb/ext.rb +16 -9
  251. data/lib/datadog/tracing/contrib/httprb/instrumentation.rb +22 -5
  252. data/lib/datadog/tracing/contrib/kafka/configuration/settings.rb +9 -6
  253. data/lib/datadog/tracing/contrib/kafka/ext.rb +42 -39
  254. data/lib/datadog/tracing/contrib/lograge/configuration/settings.rb +3 -2
  255. data/lib/datadog/tracing/contrib/lograge/ext.rb +3 -1
  256. data/lib/datadog/tracing/contrib/lograge/instrumentation.rb +2 -17
  257. data/lib/datadog/tracing/contrib/mongodb/configuration/settings.rb +14 -7
  258. data/lib/datadog/tracing/contrib/mongodb/ext.rb +20 -16
  259. data/lib/datadog/tracing/contrib/mongodb/subscribers.rb +16 -5
  260. data/lib/datadog/tracing/contrib/mysql2/configuration/settings.rb +17 -14
  261. data/lib/datadog/tracing/contrib/mysql2/ext.rb +15 -10
  262. data/lib/datadog/tracing/contrib/mysql2/instrumentation.rb +20 -6
  263. data/lib/datadog/tracing/contrib/opensearch/configuration/settings.rb +52 -0
  264. data/lib/datadog/tracing/contrib/opensearch/ext.rb +37 -0
  265. data/lib/datadog/tracing/contrib/opensearch/integration.rb +44 -0
  266. data/lib/datadog/tracing/contrib/opensearch/patcher.rb +135 -0
  267. data/lib/datadog/tracing/contrib/opensearch/quantize.rb +81 -0
  268. data/lib/datadog/tracing/contrib/pg/configuration/settings.rb +22 -14
  269. data/lib/datadog/tracing/contrib/pg/ext.rb +22 -19
  270. data/lib/datadog/tracing/contrib/pg/instrumentation.rb +38 -5
  271. data/lib/datadog/tracing/contrib/presto/configuration/settings.rb +14 -7
  272. data/lib/datadog/tracing/contrib/presto/ext.rb +25 -20
  273. data/lib/datadog/tracing/contrib/presto/instrumentation.rb +14 -5
  274. data/lib/datadog/tracing/contrib/propagation/sql_comment/ext.rb +12 -10
  275. data/lib/datadog/tracing/contrib/propagation/sql_comment.rb +1 -1
  276. data/lib/datadog/tracing/contrib/qless/configuration/settings.rb +12 -8
  277. data/lib/datadog/tracing/contrib/qless/ext.rb +14 -12
  278. data/lib/datadog/tracing/contrib/que/configuration/settings.rb +21 -12
  279. data/lib/datadog/tracing/contrib/racecar/configuration/settings.rb +9 -7
  280. data/lib/datadog/tracing/contrib/racecar/event.rb +5 -5
  281. data/lib/datadog/tracing/contrib/racecar/ext.rb +20 -18
  282. data/lib/datadog/tracing/contrib/rack/configuration/settings.rb +16 -12
  283. data/lib/datadog/tracing/contrib/rack/ext.rb +18 -16
  284. data/lib/datadog/tracing/contrib/rack/header_collection.rb +3 -0
  285. data/lib/datadog/tracing/contrib/rack/header_tagging.rb +63 -0
  286. data/lib/datadog/tracing/contrib/rack/middlewares.rb +8 -49
  287. data/lib/datadog/tracing/contrib/rails/configuration/settings.rb +19 -15
  288. data/lib/datadog/tracing/contrib/rails/ext.rb +7 -5
  289. data/lib/datadog/tracing/contrib/rails/log_injection.rb +7 -10
  290. data/lib/datadog/tracing/contrib/rails/patcher.rb +10 -41
  291. data/lib/datadog/tracing/contrib/rails/railtie.rb +3 -3
  292. data/lib/datadog/tracing/contrib/rake/configuration/settings.rb +13 -10
  293. data/lib/datadog/tracing/contrib/rake/ext.rb +14 -12
  294. data/lib/datadog/tracing/contrib/redis/configuration/settings.rb +17 -9
  295. data/lib/datadog/tracing/contrib/redis/ext.rb +22 -15
  296. data/lib/datadog/tracing/contrib/redis/instrumentation.rb +3 -38
  297. data/lib/datadog/tracing/contrib/redis/tags.rb +16 -7
  298. data/lib/datadog/tracing/contrib/redis/trace_middleware.rb +46 -33
  299. data/lib/datadog/tracing/contrib/resque/configuration/settings.rb +13 -7
  300. data/lib/datadog/tracing/contrib/resque/ext.rb +9 -7
  301. data/lib/datadog/tracing/contrib/rest_client/configuration/settings.rb +16 -9
  302. data/lib/datadog/tracing/contrib/rest_client/ext.rb +15 -8
  303. data/lib/datadog/tracing/contrib/rest_client/request_patch.rb +25 -5
  304. data/lib/datadog/tracing/contrib/roda/configuration/settings.rb +9 -6
  305. data/lib/datadog/tracing/contrib/semantic_logger/configuration/settings.rb +3 -2
  306. data/lib/datadog/tracing/contrib/semantic_logger/ext.rb +3 -1
  307. data/lib/datadog/tracing/contrib/semantic_logger/instrumentation.rb +4 -20
  308. data/lib/datadog/tracing/contrib/sequel/configuration/settings.rb +9 -6
  309. data/lib/datadog/tracing/contrib/sequel/ext.rb +10 -8
  310. data/lib/datadog/tracing/contrib/sequel/utils.rb +7 -7
  311. data/lib/datadog/tracing/contrib/shoryuken/configuration/settings.rb +14 -8
  312. data/lib/datadog/tracing/contrib/shoryuken/ext.rb +14 -12
  313. data/lib/datadog/tracing/contrib/sidekiq/configuration/settings.rb +18 -11
  314. data/lib/datadog/tracing/contrib/sidekiq/ext.rb +32 -30
  315. data/lib/datadog/tracing/contrib/sinatra/configuration/settings.rb +11 -9
  316. data/lib/datadog/tracing/contrib/sinatra/env.rb +0 -17
  317. data/lib/datadog/tracing/contrib/sinatra/ext.rb +21 -19
  318. data/lib/datadog/tracing/contrib/sinatra/tracer_middleware.rb +3 -14
  319. data/lib/datadog/tracing/contrib/sneakers/configuration/settings.rb +14 -8
  320. data/lib/datadog/tracing/contrib/sneakers/ext.rb +1 -0
  321. data/lib/datadog/tracing/contrib/sneakers/tracer.rb +1 -1
  322. data/lib/datadog/tracing/contrib/span_attribute_schema.rb +74 -10
  323. data/lib/datadog/tracing/contrib/stripe/configuration/settings.rb +9 -6
  324. data/lib/datadog/tracing/contrib/sucker_punch/configuration/settings.rb +9 -6
  325. data/lib/datadog/tracing/contrib/sucker_punch/ext.rb +15 -13
  326. data/lib/datadog/tracing/contrib/utils/database.rb +5 -3
  327. data/lib/datadog/tracing/contrib/utils/quantization/http.rb +11 -11
  328. data/lib/datadog/tracing/contrib.rb +1 -0
  329. data/lib/datadog/tracing/correlation.rb +29 -12
  330. data/lib/datadog/tracing/diagnostics/environment_logger.rb +165 -0
  331. data/lib/datadog/tracing/diagnostics/ext.rb +21 -19
  332. data/lib/datadog/tracing/distributed/b3_multi.rb +2 -2
  333. data/lib/datadog/tracing/distributed/b3_single.rb +1 -1
  334. data/lib/datadog/tracing/distributed/datadog.rb +0 -1
  335. data/lib/datadog/tracing/distributed/propagation.rb +35 -34
  336. data/lib/datadog/tracing/distributed/trace_context.rb +52 -17
  337. data/lib/datadog/tracing/metadata/ext.rb +9 -6
  338. data/lib/datadog/tracing/metadata/tagging.rb +3 -3
  339. data/lib/datadog/tracing/remote.rb +78 -0
  340. data/lib/datadog/tracing/sampling/rule_sampler.rb +29 -0
  341. data/lib/datadog/tracing/span_operation.rb +3 -15
  342. data/lib/datadog/tracing/sync_writer.rb +3 -3
  343. data/lib/datadog/tracing/trace_digest.rb +31 -0
  344. data/lib/datadog/tracing/trace_operation.rb +16 -3
  345. data/lib/datadog/tracing/trace_segment.rb +5 -2
  346. data/lib/datadog/tracing/tracer.rb +12 -1
  347. data/lib/datadog/{core → tracing}/transport/http/api/instance.rb +1 -1
  348. data/lib/datadog/{core → tracing}/transport/http/api/spec.rb +1 -1
  349. data/lib/datadog/tracing/transport/http/api.rb +43 -0
  350. data/lib/datadog/{core → tracing}/transport/http/builder.rb +13 -68
  351. data/lib/datadog/tracing/transport/http/client.rb +57 -0
  352. data/lib/datadog/tracing/transport/http/statistics.rb +47 -0
  353. data/lib/datadog/tracing/transport/http/traces.rb +152 -0
  354. data/lib/datadog/tracing/transport/http.rb +124 -0
  355. data/lib/datadog/tracing/transport/io/client.rb +89 -0
  356. data/lib/datadog/tracing/transport/io/response.rb +27 -0
  357. data/lib/datadog/tracing/transport/io/traces.rb +101 -0
  358. data/lib/datadog/tracing/transport/io.rb +30 -0
  359. data/lib/datadog/tracing/transport/serializable_trace.rb +126 -0
  360. data/lib/datadog/tracing/transport/statistics.rb +77 -0
  361. data/lib/datadog/tracing/transport/trace_formatter.rb +209 -0
  362. data/lib/datadog/tracing/transport/traces.rb +224 -0
  363. data/lib/datadog/tracing/workers/trace_writer.rb +6 -4
  364. data/lib/datadog/tracing/workers.rb +4 -2
  365. data/lib/datadog/tracing/writer.rb +5 -2
  366. data/lib/ddtrace/transport/ext.rb +22 -14
  367. data/lib/ddtrace/version.rb +9 -12
  368. data/lib/ddtrace.rb +1 -1
  369. metadata +101 -93
  370. data/lib/datadog/ci/configuration/components.rb +0 -32
  371. data/lib/datadog/ci/configuration/settings.rb +0 -53
  372. data/lib/datadog/ci/contrib/cucumber/configuration/settings.rb +0 -33
  373. data/lib/datadog/ci/contrib/cucumber/ext.rb +0 -20
  374. data/lib/datadog/ci/contrib/cucumber/formatter.rb +0 -94
  375. data/lib/datadog/ci/contrib/cucumber/instrumentation.rb +0 -28
  376. data/lib/datadog/ci/contrib/cucumber/integration.rb +0 -47
  377. data/lib/datadog/ci/contrib/cucumber/patcher.rb +0 -27
  378. data/lib/datadog/ci/contrib/rspec/configuration/settings.rb +0 -33
  379. data/lib/datadog/ci/contrib/rspec/example.rb +0 -68
  380. data/lib/datadog/ci/contrib/rspec/ext.rb +0 -19
  381. data/lib/datadog/ci/contrib/rspec/integration.rb +0 -48
  382. data/lib/datadog/ci/contrib/rspec/patcher.rb +0 -27
  383. data/lib/datadog/ci/ext/app_types.rb +0 -9
  384. data/lib/datadog/ci/ext/environment.rb +0 -575
  385. data/lib/datadog/ci/ext/settings.rb +0 -10
  386. data/lib/datadog/ci/ext/test.rb +0 -35
  387. data/lib/datadog/ci/extensions.rb +0 -19
  388. data/lib/datadog/ci/flush.rb +0 -38
  389. data/lib/datadog/ci/test.rb +0 -81
  390. data/lib/datadog/ci.rb +0 -20
  391. data/lib/datadog/core/configuration/dependency_resolver.rb +0 -28
  392. data/lib/datadog/core/configuration/option_definition_set.rb +0 -22
  393. data/lib/datadog/core/configuration/option_set.rb +0 -10
  394. data/lib/datadog/core/transport/config.rb +0 -58
  395. data/lib/datadog/core/transport/http/api.rb +0 -57
  396. data/lib/datadog/core/transport/http/client.rb +0 -45
  397. data/lib/datadog/core/transport/http/config.rb +0 -268
  398. data/lib/datadog/core/transport/http/negotiation.rb +0 -144
  399. data/lib/datadog/core/transport/http.rb +0 -169
  400. data/lib/datadog/core/utils/object_set.rb +0 -43
  401. data/lib/datadog/core/utils/string_table.rb +0 -47
  402. data/lib/datadog/profiling/backtrace_location.rb +0 -34
  403. data/lib/datadog/profiling/buffer.rb +0 -43
  404. data/lib/datadog/profiling/collectors/old_stack.rb +0 -301
  405. data/lib/datadog/profiling/encoding/profile.rb +0 -41
  406. data/lib/datadog/profiling/event.rb +0 -15
  407. data/lib/datadog/profiling/events/stack.rb +0 -82
  408. data/lib/datadog/profiling/old_recorder.rb +0 -107
  409. data/lib/datadog/profiling/pprof/builder.rb +0 -125
  410. data/lib/datadog/profiling/pprof/converter.rb +0 -102
  411. data/lib/datadog/profiling/pprof/message_set.rb +0 -16
  412. data/lib/datadog/profiling/pprof/payload.rb +0 -20
  413. data/lib/datadog/profiling/pprof/pprof.proto +0 -212
  414. data/lib/datadog/profiling/pprof/pprof_pb.rb +0 -81
  415. data/lib/datadog/profiling/pprof/stack_sample.rb +0 -139
  416. data/lib/datadog/profiling/pprof/string_table.rb +0 -12
  417. data/lib/datadog/profiling/pprof/template.rb +0 -118
  418. data/lib/datadog/profiling/trace_identifiers/ddtrace.rb +0 -43
  419. data/lib/datadog/profiling/trace_identifiers/helper.rb +0 -45
  420. data/lib/datadog/tracing/contrib/sinatra/headers.rb +0 -35
  421. data/lib/ddtrace/transport/http/adapters/net.rb +0 -168
  422. data/lib/ddtrace/transport/http/adapters/registry.rb +0 -27
  423. data/lib/ddtrace/transport/http/adapters/test.rb +0 -85
  424. data/lib/ddtrace/transport/http/adapters/unix_socket.rb +0 -77
  425. data/lib/ddtrace/transport/http/api/endpoint.rb +0 -29
  426. data/lib/ddtrace/transport/http/api/fallbacks.rb +0 -24
  427. data/lib/ddtrace/transport/http/api/instance.rb +0 -35
  428. data/lib/ddtrace/transport/http/api/map.rb +0 -16
  429. data/lib/ddtrace/transport/http/api/spec.rb +0 -17
  430. data/lib/ddtrace/transport/http/api.rb +0 -39
  431. data/lib/ddtrace/transport/http/builder.rb +0 -176
  432. data/lib/ddtrace/transport/http/client.rb +0 -52
  433. data/lib/ddtrace/transport/http/env.rb +0 -58
  434. data/lib/ddtrace/transport/http/response.rb +0 -58
  435. data/lib/ddtrace/transport/http/statistics.rb +0 -43
  436. data/lib/ddtrace/transport/http/traces.rb +0 -144
  437. data/lib/ddtrace/transport/http.rb +0 -117
  438. data/lib/ddtrace/transport/io/client.rb +0 -85
  439. data/lib/ddtrace/transport/io/response.rb +0 -25
  440. data/lib/ddtrace/transport/io/traces.rb +0 -99
  441. data/lib/ddtrace/transport/io.rb +0 -28
  442. data/lib/ddtrace/transport/parcel.rb +0 -20
  443. data/lib/ddtrace/transport/request.rb +0 -15
  444. data/lib/ddtrace/transport/response.rb +0 -60
  445. data/lib/ddtrace/transport/serializable_trace.rb +0 -122
  446. data/lib/ddtrace/transport/statistics.rb +0 -75
  447. data/lib/ddtrace/transport/trace_formatter.rb +0 -198
  448. data/lib/ddtrace/transport/traces.rb +0 -216
@@ -1,4 +1,5 @@
1
1
  require_relative 'agent_settings_resolver'
2
+ require_relative 'ext'
2
3
  require_relative '../diagnostics/environment_logger'
3
4
  require_relative '../diagnostics/health'
4
5
  require_relative '../logger'
@@ -54,15 +55,20 @@ module Datadog
54
55
 
55
56
  def build_telemetry(settings, agent_settings, logger)
56
57
  enabled = settings.telemetry.enabled
57
- if agent_settings.adapter != Datadog::Transport::Ext::HTTP::ADAPTER
58
+ if agent_settings.adapter != Datadog::Core::Configuration::Ext::Agent::HTTP::ADAPTER
58
59
  enabled = false
59
60
  logger.debug { "Telemetry disabled. Agent network adapter not supported: #{agent_settings.adapter}" }
60
61
  end
61
62
 
62
- Telemetry::Client.new(enabled: enabled)
63
+ Telemetry::Client.new(
64
+ enabled: enabled,
65
+ heartbeat_interval_seconds: settings.telemetry.heartbeat_interval_seconds
66
+ )
63
67
  end
64
68
  end
65
69
 
70
+ include Datadog::Tracing::Component::InstanceMethods
71
+
66
72
  attr_reader \
67
73
  :health_metrics,
68
74
  :logger,
@@ -76,10 +82,14 @@ module Datadog
76
82
  def initialize(settings)
77
83
  @logger = self.class.build_logger(settings)
78
84
 
85
+ # This agent_settings is intended for use within Core. If you require
86
+ # agent_settings within a product outside of core you should extend
87
+ # the Core resolver from within your product/component's namespace.
79
88
  agent_settings = AgentSettingsResolver.call(settings, logger: @logger)
80
89
 
81
90
  @remote = Remote::Component.build(settings, agent_settings)
82
- @tracer = self.class.build_tracer(settings, agent_settings)
91
+ @tracer = self.class.build_tracer(settings, logger: @logger)
92
+
83
93
  @profiler = Datadog::Profiling::Component.build_profiler_component(
84
94
  settings: settings,
85
95
  agent_settings: agent_settings,
@@ -105,6 +115,8 @@ module Datadog
105
115
  else
106
116
  @logger.debug('Profiling is disabled')
107
117
  end
118
+
119
+ Core::Diagnostics::EnvironmentLogger.collect_and_log!
108
120
  end
109
121
 
110
122
  # Shuts down all the components in use.
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Datadog
2
4
  module Core
3
5
  module Configuration
@@ -6,17 +8,38 @@ module Datadog
6
8
  module Ext
7
9
  # @public_api
8
10
  module Diagnostics
9
- ENV_DEBUG_ENABLED = 'DD_TRACE_DEBUG'.freeze
10
- ENV_HEALTH_METRICS_ENABLED = 'DD_HEALTH_METRICS_ENABLED'.freeze
11
- ENV_STARTUP_LOGS_ENABLED = 'DD_TRACE_STARTUP_LOGS'.freeze
11
+ ENV_DEBUG_ENABLED = 'DD_TRACE_DEBUG'
12
+ ENV_HEALTH_METRICS_ENABLED = 'DD_HEALTH_METRICS_ENABLED'
13
+ ENV_STARTUP_LOGS_ENABLED = 'DD_TRACE_STARTUP_LOGS'
12
14
  end
13
15
 
14
16
  module Metrics
15
- ENV_DEFAULT_PORT = 'DD_METRIC_AGENT_PORT'.freeze
17
+ ENV_DEFAULT_PORT = 'DD_METRIC_AGENT_PORT'
16
18
  end
17
19
 
20
+ # DEV-2.0: This module only exists for backwards compatibility with the public API.
21
+ # It should be consolidated into the Agent module below.
18
22
  module Transport
19
- ENV_DEFAULT_HOST = 'DD_AGENT_HOST'.freeze
23
+ ENV_DEFAULT_HOST = 'DD_AGENT_HOST'
24
+ end
25
+
26
+ module Agent
27
+ # env var has "trace" in it, but it really applies to all products
28
+ ENV_DEFAULT_PORT = 'DD_TRACE_AGENT_PORT'
29
+ ENV_DEFAULT_URL = 'DD_TRACE_AGENT_URL'
30
+
31
+ module HTTP
32
+ ADAPTER = :net_http # DEV: Rename to simply `:http`, as Net::HTTP is an implementation detail.
33
+ DEFAULT_HOST = '127.0.0.1'
34
+ DEFAULT_PORT = 8126
35
+ end
36
+
37
+ # @public_api
38
+ module UnixSocket
39
+ ADAPTER = :unix
40
+ DEFAULT_PATH = '/var/run/datadog/apm.socket'
41
+ DEFAULT_TIMEOUT_SECONDS = 1
42
+ end
20
43
  end
21
44
  end
22
45
  end
@@ -1,61 +1,273 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative '../utils/safe_dup'
4
+
3
5
  module Datadog
4
6
  module Core
5
7
  module Configuration
6
8
  # Represents an instance of an integration configuration option
7
9
  # @public_api
8
10
  class Option
9
- attr_reader \
10
- :definition
11
+ attr_reader :definition
12
+
13
+ # Option setting precedence.
14
+ module Precedence
15
+ # Represents an Option precedence level.
16
+ # Each precedence has a `numeric` value; higher values means higher precedence.
17
+ # `name` is for inspection purposes only.
18
+ Value = Struct.new(:numeric, :name) do
19
+ include Comparable
20
+
21
+ def <=>(other)
22
+ return nil unless other.is_a?(Value)
23
+
24
+ numeric <=> other.numeric
25
+ end
26
+ end
27
+
28
+ # Remote configuration provided through the Datadog app.
29
+ REMOTE_CONFIGURATION = Value.new(2, :remote_configuration).freeze
30
+
31
+ # Configuration provided in Ruby code, in this same process
32
+ # or via Environment variable
33
+ PROGRAMMATIC = Value.new(1, :programmatic).freeze
34
+
35
+ # Configuration that comes from default values
36
+ DEFAULT = Value.new(0, :default).freeze
37
+
38
+ # All precedences, sorted from highest to lowest
39
+ LIST = [REMOTE_CONFIGURATION, PROGRAMMATIC, DEFAULT].sort.reverse.freeze
40
+ end
11
41
 
12
42
  def initialize(definition, context)
13
43
  @definition = definition
14
44
  @context = context
15
45
  @value = nil
16
46
  @is_set = false
47
+
48
+ # One value is stored per precedence, to allow unsetting a higher
49
+ # precedence value and falling back to a lower precedence one.
50
+ @value_per_precedence = Hash.new(UNSET)
51
+
52
+ # Lowest precedence, to allow for `#set` to always succeed for a brand new `Option` instance.
53
+ @precedence_set = Precedence::DEFAULT
17
54
  end
18
55
 
19
- def set(value)
20
- old_value = @value
21
- (@value = context_exec(value, old_value, &definition.setter)).tap do |v|
22
- @is_set = true
23
- context_exec(v, old_value, &definition.on_set) if definition.on_set
56
+ # Overrides the current value for this option if the `precedence` is equal or higher than
57
+ # the previously set value.
58
+ # The first call to `#set` will always store the value regardless of precedence.
59
+ #
60
+ # @param value [Object] the new value to be associated with this option
61
+ # @param precedence [Precedence] from what precedence order this new value comes from
62
+ def set(value, precedence: Precedence::PROGRAMMATIC)
63
+ # Is there a higher precedence value set?
64
+ if @precedence_set > precedence
65
+ # This should be uncommon, as higher precedence values tend to
66
+ # happen later in the application lifecycle.
67
+ Datadog.logger.info do
68
+ "Option '#{definition.name}' not changed to '#{value}' (precedence: #{precedence.name}) because the higher " \
69
+ "precedence value '#{@value}' (precedence: #{@precedence_set.name}) was already set."
70
+ end
71
+
72
+ # But if it happens, we have to store the lower precedence value `value`
73
+ # because it's possible to revert to it by `#unset`ting
74
+ # the existing, higher-precedence value.
75
+ # Effectively, we always store one value pre precedence.
76
+ @value_per_precedence[precedence] = value
77
+
78
+ return @value
79
+ end
80
+
81
+ internal_set(value, precedence)
82
+ end
83
+
84
+ def unset(precedence)
85
+ @value_per_precedence[precedence] = UNSET
86
+
87
+ # If we are unsetting the currently active value, we have to restore
88
+ # a lower precedence one...
89
+ if precedence == @precedence_set
90
+ # Find a lower precedence value that is already set.
91
+ Precedence::LIST.each do |p|
92
+ # DEV: This search can be optimized, but the list is small, and unset is
93
+ # DEV: only called from direct user interaction in the Datadog UI.
94
+ next unless p < precedence
95
+
96
+ # Look for value that is set.
97
+ # The hash `@value_per_precedence` has a custom default value of `UNSET`.
98
+ if (value = @value_per_precedence[p]) != UNSET
99
+ internal_set(value, p)
100
+ return nil
101
+ end
102
+ end
103
+
104
+ # If no value is left to fall back on, reset this option
105
+ reset
24
106
  end
107
+
108
+ # ... otherwise, we are either unsetting a higher precedence value that is not
109
+ # yet set, thus there's nothing to do; or we are unsetting a lower precedence
110
+ # value, which also does not change the current value.
25
111
  end
26
112
 
27
113
  def get
28
114
  if @is_set
29
115
  @value
30
- elsif definition.delegate_to
31
- context_eval(&definition.delegate_to)
32
116
  else
33
- set(default_value)
117
+ set_value_from_env_or_default
34
118
  end
35
119
  end
36
120
 
37
121
  def reset
38
- @value = if definition.resetter
39
- # Don't change @is_set to false; custom resetters are
40
- # responsible for changing @value back to a good state.
41
- # Setting @is_set = false would cause a default to be applied.
42
- context_exec(@value, &definition.resetter)
43
- else
44
- @is_set = false
45
- nil
46
- end
122
+ @value = if definition.resetter
123
+ # Don't change @is_set to false; custom resetters are
124
+ # responsible for changing @value back to a good state.
125
+ # Setting @is_set = false would cause a default to be applied.
126
+ context_exec(@value, &definition.resetter)
127
+ else
128
+ @is_set = false
129
+ nil
130
+ end
131
+
132
+ # Reset back to the lowest precedence, to allow all `set`s to succeed right after a reset.
133
+ @precedence_set = Precedence::DEFAULT
134
+ # Reset all stored values
135
+ @value_per_precedence = Hash.new(UNSET)
47
136
  end
48
137
 
49
138
  def default_value
50
- if definition.lazy
139
+ if definition.default.instance_of?(Proc)
51
140
  context_eval(&definition.default)
52
141
  else
53
- definition.default
142
+ definition.default_proc || Core::Utils::SafeDup.frozen_or_dup(definition.default)
54
143
  end
55
144
  end
56
145
 
146
+ def default_precedence?
147
+ precedence_set == Precedence::DEFAULT
148
+ end
149
+
57
150
  private
58
151
 
152
+ def coerce_env_variable(value)
153
+ return context_exec(value, &@definition.env_parser) if @definition.env_parser
154
+
155
+ case @definition.type
156
+ when :hash
157
+ values = value.split(',') # By default we only want to support comma separated strings
158
+
159
+ values.map! do |v|
160
+ v.gsub!(/\A[\s,]*|[\s,]*\Z/, '')
161
+
162
+ v.empty? ? nil : v
163
+ end
164
+
165
+ values.compact!
166
+ values.each.with_object({}) do |v, hash|
167
+ pair = v.split(':', 2)
168
+ hash[pair[0]] = pair[1]
169
+ end
170
+ when :int
171
+ # DEV-2.0: Change to a more strict coercion method. Integer(value).
172
+ value.to_i
173
+ when :float
174
+ # DEV-2.0: Change to a more strict coercion method. Float(value).
175
+ value.to_f
176
+ when :array
177
+ values = value.split(',')
178
+
179
+ values.map! do |v|
180
+ v.gsub!(/\A[\s,]*|[\s,]*\Z/, '')
181
+
182
+ v.empty? ? nil : v
183
+ end
184
+
185
+ values.compact!
186
+ values
187
+ when :bool
188
+ string_value = value.strip
189
+ string_value = string_value.downcase
190
+ string_value == 'true' || string_value == '1' # rubocop:disable Style/MultipleComparison
191
+ when :string, NilClass
192
+ value
193
+ else
194
+ raise ArgumentError,
195
+ "The option #{@definition.name} is using an unsupported type option for env coercion `#{@definition.type}`"
196
+ end
197
+ end
198
+
199
+ def validate_type(value)
200
+ return value if skip_validation?
201
+
202
+ raise_error = false
203
+
204
+ valid_type = validate(@definition.type, value)
205
+
206
+ unless valid_type
207
+ raise_error = if @definition.type_options[:nilable]
208
+ !value.is_a?(NilClass)
209
+ else
210
+ true
211
+ end
212
+ end
213
+
214
+ if raise_error
215
+ error_msg = if @definition.type_options[:nilable]
216
+ "The setting `#{@definition.name}` inside your app's `Datadog.configure` block expects a "\
217
+ "#{@definition.type} or `nil`, but a `#{value.class}` was provided (#{value.inspect})."\
218
+ else
219
+ "The setting `#{@definition.name}` inside your app's `Datadog.configure` block expects a "\
220
+ "#{@definition.type}, but a `#{value.class}` was provided (#{value.inspect})."\
221
+ end
222
+
223
+ error_msg = "#{error_msg} Please update your `configure` block. "\
224
+ 'Alternatively, you can disable this validation using the '\
225
+ '`DD_EXPERIMENTAL_SKIP_CONFIGURATION_VALIDATION=true`environment variable. '\
226
+ 'For help, please open an issue on <https://github.com/datadog/dd-trace-rb/issues/new/choose>.'
227
+
228
+ raise ArgumentError, error_msg
229
+ end
230
+
231
+ value
232
+ end
233
+
234
+ def validate(type, value)
235
+ case type
236
+ when :string
237
+ value.is_a?(String)
238
+ when :int, :float
239
+ value.is_a?(Numeric)
240
+ when :array
241
+ value.is_a?(Array)
242
+ when :hash
243
+ value.is_a?(Hash)
244
+ when :bool
245
+ value.is_a?(TrueClass) || value.is_a?(FalseClass)
246
+ when :proc
247
+ value.is_a?(Proc)
248
+ when :symbol
249
+ value.is_a?(Symbol)
250
+ when NilClass
251
+ true # No validation is performed when option is typeless
252
+ else
253
+ raise ArgumentError, "The option #{@definition.name} is using an unsupported type option `#{@definition.type}`"
254
+ end
255
+ end
256
+
257
+ # Directly manipulates the current value and currently set precedence.
258
+ def internal_set(value, precedence)
259
+ old_value = @value
260
+ (@value = context_exec(validate_type(value), old_value, &definition.setter)).tap do |v|
261
+ @is_set = true
262
+ @precedence_set = precedence
263
+ # Store original value to ensure we can always safely call `#internal_set`
264
+ # when restoring a value from `@value_per_precedence`, and we are only running `definition.setter`
265
+ # on the original value, not on a valud that has already been processed by `definition.setter`.
266
+ @value_per_precedence[precedence] = value
267
+ context_exec(v, old_value, &definition.after_set) if definition.after_set
268
+ end
269
+ end
270
+
59
271
  def context_exec(*args, &block)
60
272
  @context.instance_exec(*args, &block)
61
273
  end
@@ -63,6 +275,42 @@ module Datadog
63
275
  def context_eval(&block)
64
276
  @context.instance_eval(&block)
65
277
  end
278
+
279
+ def set_value_from_env_or_default
280
+ value = nil
281
+ precedence = nil
282
+
283
+ if definition.env && ENV[definition.env]
284
+ value = coerce_env_variable(ENV[definition.env])
285
+ precedence = Precedence::PROGRAMMATIC
286
+ end
287
+
288
+ if value.nil? && definition.deprecated_env && ENV[definition.deprecated_env]
289
+ value = coerce_env_variable(ENV[definition.deprecated_env])
290
+ precedence = Precedence::PROGRAMMATIC
291
+
292
+ Datadog::Core.log_deprecation do
293
+ "#{definition.deprecated_env} environment variable is deprecated, use #{definition.env} instead."
294
+ end
295
+ end
296
+
297
+ option_value = value.nil? ? default_value : value
298
+
299
+ set(option_value, precedence: precedence || Precedence::DEFAULT)
300
+ end
301
+
302
+ def skip_validation?
303
+ ['true', '1'].include?(ENV.fetch('DD_EXPERIMENTAL_SKIP_CONFIGURATION_VALIDATION', '').strip)
304
+ end
305
+
306
+ # Used for testing
307
+ attr_reader :precedence_set
308
+ private :precedence_set
309
+
310
+ # Anchor object that represents a value that is not set.
311
+ # This is necessary because `nil` is a valid value to be set.
312
+ UNSET = Object.new
313
+ private_constant :UNSET
66
314
  end
67
315
  end
68
316
  end
@@ -11,25 +11,29 @@ module Datadog
11
11
 
12
12
  attr_reader \
13
13
  :default,
14
- :delegate_to,
15
- :depends_on,
16
- :lazy,
14
+ :default_proc,
15
+ :env,
16
+ :deprecated_env,
17
+ :env_parser,
17
18
  :name,
18
- :on_set,
19
+ :after_set,
19
20
  :resetter,
20
21
  :setter,
21
- :type
22
+ :type,
23
+ :type_options
22
24
 
23
25
  def initialize(name, meta = {}, &block)
24
26
  @default = meta[:default]
25
- @delegate_to = meta[:delegate_to]
26
- @depends_on = meta[:depends_on] || []
27
- @lazy = meta[:lazy] || false
27
+ @default_proc = meta[:default_proc]
28
+ @env = meta[:env]
29
+ @deprecated_env = meta[:deprecated_env]
30
+ @env_parser = meta[:env_parser]
28
31
  @name = name.to_sym
29
- @on_set = meta[:on_set]
32
+ @after_set = meta[:after_set]
30
33
  @resetter = meta[:resetter]
31
34
  @setter = meta[:setter] || block || IDENTITY
32
35
  @type = meta[:type]
36
+ @type_options = meta[:type_options]
33
37
  end
34
38
 
35
39
  # Creates a new Option, bound to the context provided.
@@ -40,50 +44,69 @@ module Datadog
40
44
  # Acts as DSL for building OptionDefinitions
41
45
  # @public_api
42
46
  class Builder
47
+ class InvalidOptionError < StandardError; end
48
+
43
49
  attr_reader \
44
50
  :helpers
45
51
 
46
52
  def initialize(name, options = {})
53
+ @env = nil
54
+ @deprecated_env = nil
55
+ @env_parser = nil
47
56
  @default = nil
48
- @delegate_to = nil
49
- @depends_on = []
57
+ @default_proc = nil
50
58
  @helpers = {}
51
- @lazy = false
52
59
  @name = name.to_sym
53
- @on_set = nil
60
+ @after_set = nil
54
61
  @resetter = nil
55
62
  @setter = OptionDefinition::IDENTITY
56
63
  @type = nil
57
-
64
+ @type_options = {}
58
65
  # If options were supplied, apply them.
59
66
  apply_options!(options)
60
67
 
61
68
  # Apply block if given.
62
69
  yield(self) if block_given?
70
+
71
+ validate_options!
63
72
  end
64
73
 
65
- def depends_on(*values)
66
- @depends_on = values.flatten
74
+ def env(value)
75
+ @env = value
76
+ end
77
+
78
+ def deprecated_env(value)
79
+ @deprecated_env = value
80
+ end
81
+
82
+ def env_parser(&block)
83
+ @env_parser = block
67
84
  end
68
85
 
69
86
  def default(value = nil, &block)
70
87
  @default = block || value
71
88
  end
72
89
 
73
- def delegate_to(&block)
74
- @delegate_to = block
90
+ def default_proc(&block)
91
+ @default_proc = block
75
92
  end
76
93
 
77
94
  def helper(name, *_args, &block)
78
95
  @helpers[name] = block
79
96
  end
80
97
 
81
- def lazy(value = true)
82
- @lazy = value
98
+ def lazy(_value = true)
99
+ Datadog::Core.log_deprecation do
100
+ 'Defining an option as lazy is deprecated for removal. Options now always behave as lazy. '\
101
+ "Please remove all references to the lazy setting.\n"\
102
+ 'Non-lazy options that were previously stored as blocks are no longer supported. '\
103
+ 'If you used this feature, please let us know by opening an issue on: '\
104
+ 'https://github.com/datadog/dd-trace-rb/issues/new so we can better understand and support your use case.'
105
+ end
83
106
  end
84
107
 
85
- def on_set(&block)
86
- @on_set = block
108
+ def after_set(&block)
109
+ @after_set = block
87
110
  end
88
111
 
89
112
  def resetter(&block)
@@ -94,8 +117,11 @@ module Datadog
94
117
  @setter = block
95
118
  end
96
119
 
97
- def type(value = nil)
120
+ def type(value, nilable: false)
98
121
  @type = value
122
+ @type_options = { nilable: nilable }
123
+
124
+ value
99
125
  end
100
126
 
101
127
  # For applying options for OptionDefinition
@@ -103,13 +129,15 @@ module Datadog
103
129
  return if options.nil? || options.empty?
104
130
 
105
131
  default(options[:default]) if options.key?(:default)
106
- delegate_to(&options[:delegate_to]) if options.key?(:delegate_to)
107
- depends_on(*options[:depends_on]) if options.key?(:depends_on)
132
+ default_proc(&options[:default_proc]) if options.key?(:default_proc)
133
+ env(options[:env]) if options.key?(:env)
134
+ deprecated_env(options[:deprecated_env]) if options.key?(:deprecated_env)
135
+ env_parser(&options[:env_parser]) if options.key?(:env_parser)
108
136
  lazy(options[:lazy]) if options.key?(:lazy)
109
- on_set(&options[:on_set]) if options.key?(:on_set)
137
+ after_set(&options[:after_set]) if options.key?(:after_set)
110
138
  resetter(&options[:resetter]) if options.key?(:resetter)
111
139
  setter(&options[:setter]) if options.key?(:setter)
112
- type(&options[:type]) if options.key?(:type)
140
+ type(options[:type], **(options[:type_options] || {})) if options.key?(:type)
113
141
  end
114
142
 
115
143
  def to_definition
@@ -119,15 +147,28 @@ module Datadog
119
147
  def meta
120
148
  {
121
149
  default: @default,
122
- delegate_to: @delegate_to,
123
- depends_on: @depends_on,
124
- lazy: @lazy,
125
- on_set: @on_set,
150
+ default_proc: @default_proc,
151
+ env: @env,
152
+ deprecated_env: @deprecated_env,
153
+ env_parser: @env_parser,
154
+ after_set: @after_set,
126
155
  resetter: @resetter,
127
156
  setter: @setter,
128
- type: @type
157
+ type: @type,
158
+ type_options: @type_options
129
159
  }
130
160
  end
161
+
162
+ private
163
+
164
+ def validate_options!
165
+ if !@default.nil? && @default_proc
166
+ raise InvalidOptionError,
167
+ 'Using `default` and `default_proc` is not allowed. Please use one or the other.' \
168
+ 'If you want to store a block as the default value use `default_proc`'\
169
+ ' otherwise use `default`'
170
+ end
171
+ end
131
172
  end
132
173
  end
133
174
  end