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
@@ -6,6 +6,7 @@
6
6
  #include "stack_recorder.h"
7
7
  #include "libdatadog_helpers.h"
8
8
  #include "ruby_helpers.h"
9
+ #include "time_helpers.h"
9
10
 
10
11
  // Used to wrap a ddog_prof_Profile in a Ruby object and expose Ruby-level serialization APIs
11
12
  // This file implements the native bits of the Datadog::Profiling::StackRecorder class
@@ -128,8 +129,6 @@
128
129
  static VALUE ok_symbol = Qnil; // :ok in Ruby
129
130
  static VALUE error_symbol = Qnil; // :error in Ruby
130
131
 
131
- static VALUE stack_recorder_class = Qnil;
132
-
133
132
  // Note: Please DO NOT use `VALUE_STRING` anywhere else, instead use `DDOG_CHARSLICE_C`.
134
133
  // `VALUE_STRING` is only needed because older versions of gcc (4.9.2, used in our Ruby 2.2 CI test images)
135
134
  // tripped when compiling `enabled_value_types` using `-std=gnu99` due to the extra cast that is included in
@@ -164,10 +163,10 @@ static const uint8_t all_value_types_positions[] = {CPU_TIME_VALUE_ID, CPU_SAMPL
164
163
  // Contains native state for each instance
165
164
  struct stack_recorder_state {
166
165
  pthread_mutex_t slot_one_mutex;
167
- ddog_prof_Profile *slot_one_profile;
166
+ ddog_prof_Profile slot_one_profile;
168
167
 
169
168
  pthread_mutex_t slot_two_mutex;
170
- ddog_prof_Profile *slot_two_profile;
169
+ ddog_prof_Profile slot_two_profile;
171
170
 
172
171
  short active_slot; // MUST NEVER BE ACCESSED FROM record_sample; this is NOT for the sampler thread to use.
173
172
 
@@ -196,6 +195,7 @@ struct call_serialize_without_gvl_arguments {
196
195
 
197
196
  static VALUE _native_new(VALUE klass);
198
197
  static void initialize_slot_concurrency_control(struct stack_recorder_state *state);
198
+ static void initialize_profiles(struct stack_recorder_state *state, ddog_prof_Slice_ValueType sample_types);
199
199
  static void stack_recorder_typed_data_free(void *data);
200
200
  static VALUE _native_initialize(DDTRACE_UNUSED VALUE _self, VALUE recorder_instance, VALUE cpu_time_enabled, VALUE alloc_samples_enabled);
201
201
  static VALUE _native_serialize(VALUE self, VALUE recorder_instance);
@@ -208,13 +208,14 @@ static VALUE _native_active_slot(DDTRACE_UNUSED VALUE _self, VALUE recorder_inst
208
208
  static VALUE _native_is_slot_one_mutex_locked(DDTRACE_UNUSED VALUE _self, VALUE recorder_instance);
209
209
  static VALUE _native_is_slot_two_mutex_locked(DDTRACE_UNUSED VALUE _self, VALUE recorder_instance);
210
210
  static VALUE test_slot_mutex_state(VALUE recorder_instance, int slot);
211
- static ddog_Timespec time_now(void);
211
+ static ddog_Timespec system_epoch_now_timespec(void);
212
212
  static VALUE _native_reset_after_fork(DDTRACE_UNUSED VALUE self, VALUE recorder_instance);
213
- static void serializer_set_start_timestamp_for_next_profile(struct stack_recorder_state *state, ddog_Timespec timestamp);
213
+ static void serializer_set_start_timestamp_for_next_profile(struct stack_recorder_state *state, ddog_Timespec start_time);
214
214
  static VALUE _native_record_endpoint(DDTRACE_UNUSED VALUE _self, VALUE recorder_instance, VALUE local_root_span_id, VALUE endpoint);
215
+ static void reset_profile(ddog_prof_Profile *profile, ddog_Timespec *start_time /* Can be null */);
215
216
 
216
217
  void stack_recorder_init(VALUE profiling_module) {
217
- stack_recorder_class = rb_define_class_under(profiling_module, "StackRecorder", rb_cObject);
218
+ VALUE stack_recorder_class = rb_define_class_under(profiling_module, "StackRecorder", rb_cObject);
218
219
  // Hosts methods used for testing the native code using RSpec
219
220
  VALUE testing_module = rb_define_module_under(stack_recorder_class, "Testing");
220
221
 
@@ -255,18 +256,25 @@ static const rb_data_type_t stack_recorder_typed_data = {
255
256
  static VALUE _native_new(VALUE klass) {
256
257
  struct stack_recorder_state *state = ruby_xcalloc(1, sizeof(struct stack_recorder_state));
257
258
 
259
+ // Note: Any exceptions raised from this note until the TypedData_Wrap_Struct call will lead to the state memory
260
+ // being leaked.
261
+
258
262
  ddog_prof_Slice_ValueType sample_types = {.ptr = all_value_types, .len = ALL_VALUE_TYPES_COUNT};
259
263
 
260
264
  initialize_slot_concurrency_control(state);
261
265
  for (uint8_t i = 0; i < ALL_VALUE_TYPES_COUNT; i++) { state->position_for[i] = all_value_types_positions[i]; }
262
266
  state->enabled_values_count = ALL_VALUE_TYPES_COUNT;
263
267
 
268
+ // Note: At this point, slot_one_profile and slot_two_profile contain null pointers. Libdatadog validates pointers
269
+ // before using them so it's ok for us to go ahead and create the StackRecorder object.
270
+
271
+ VALUE stack_recorder = TypedData_Wrap_Struct(klass, &stack_recorder_typed_data, state);
272
+
264
273
  // Note: Don't raise exceptions after this point, since it'll lead to libdatadog memory leaking!
265
274
 
266
- state->slot_one_profile = ddog_prof_Profile_new(sample_types, NULL /* period is optional */, NULL /* start_time is optional */);
267
- state->slot_two_profile = ddog_prof_Profile_new(sample_types, NULL /* period is optional */, NULL /* start_time is optional */);
275
+ initialize_profiles(state, sample_types);
268
276
 
269
- return TypedData_Wrap_Struct(klass, &stack_recorder_typed_data, state);
277
+ return stack_recorder;
270
278
  }
271
279
 
272
280
  static void initialize_slot_concurrency_control(struct stack_recorder_state *state) {
@@ -279,14 +287,36 @@ static void initialize_slot_concurrency_control(struct stack_recorder_state *sta
279
287
  state->active_slot = 1;
280
288
  }
281
289
 
290
+ static void initialize_profiles(struct stack_recorder_state *state, ddog_prof_Slice_ValueType sample_types) {
291
+ ddog_prof_Profile_NewResult slot_one_profile_result =
292
+ ddog_prof_Profile_new(sample_types, NULL /* period is optional */, NULL /* start_time is optional */);
293
+
294
+ if (slot_one_profile_result.tag == DDOG_PROF_PROFILE_NEW_RESULT_ERR) {
295
+ rb_raise(rb_eRuntimeError, "Failed to initialize slot one profile: %"PRIsVALUE, get_error_details_and_drop(&slot_one_profile_result.err));
296
+ }
297
+
298
+ ddog_prof_Profile_NewResult slot_two_profile_result =
299
+ ddog_prof_Profile_new(sample_types, NULL /* period is optional */, NULL /* start_time is optional */);
300
+
301
+ if (slot_two_profile_result.tag == DDOG_PROF_PROFILE_NEW_RESULT_ERR) {
302
+ // Uff! Though spot. We need to make sure to properly clean up the other profile as well first
303
+ ddog_prof_Profile_drop(&slot_one_profile_result.ok);
304
+ // And now we can raise...
305
+ rb_raise(rb_eRuntimeError, "Failed to initialize slot two profile: %"PRIsVALUE, get_error_details_and_drop(&slot_two_profile_result.err));
306
+ }
307
+
308
+ state->slot_one_profile = slot_one_profile_result.ok;
309
+ state->slot_two_profile = slot_two_profile_result.ok;
310
+ }
311
+
282
312
  static void stack_recorder_typed_data_free(void *state_ptr) {
283
313
  struct stack_recorder_state *state = (struct stack_recorder_state *) state_ptr;
284
314
 
285
315
  pthread_mutex_destroy(&state->slot_one_mutex);
286
- ddog_prof_Profile_drop(state->slot_one_profile);
316
+ ddog_prof_Profile_drop(&state->slot_one_profile);
287
317
 
288
318
  pthread_mutex_destroy(&state->slot_two_mutex);
289
- ddog_prof_Profile_drop(state->slot_two_profile);
319
+ ddog_prof_Profile_drop(&state->slot_two_profile);
290
320
 
291
321
  ruby_xfree(state);
292
322
  }
@@ -332,13 +362,11 @@ static VALUE _native_initialize(DDTRACE_UNUSED VALUE _self, VALUE recorder_insta
332
362
  state->position_for[ALLOC_SAMPLES_VALUE_ID] = next_disabled_pos++;
333
363
  }
334
364
 
335
- ddog_prof_Slice_ValueType sample_types = {.ptr = enabled_value_types, .len = state->enabled_values_count};
365
+ ddog_prof_Profile_drop(&state->slot_one_profile);
366
+ ddog_prof_Profile_drop(&state->slot_two_profile);
336
367
 
337
- ddog_prof_Profile_drop(state->slot_one_profile);
338
- ddog_prof_Profile_drop(state->slot_two_profile);
339
-
340
- state->slot_one_profile = ddog_prof_Profile_new(sample_types, NULL /* period is optional */, NULL /* start_time is optional */);
341
- state->slot_two_profile = ddog_prof_Profile_new(sample_types, NULL /* period is optional */, NULL /* start_time is optional */);
368
+ ddog_prof_Slice_ValueType sample_types = {.ptr = enabled_value_types, .len = state->enabled_values_count};
369
+ initialize_profiles(state, sample_types);
342
370
 
343
371
  return Qtrue;
344
372
  }
@@ -347,7 +375,7 @@ static VALUE _native_serialize(DDTRACE_UNUSED VALUE _self, VALUE recorder_instan
347
375
  struct stack_recorder_state *state;
348
376
  TypedData_Get_Struct(recorder_instance, struct stack_recorder_state, &stack_recorder_typed_data, state);
349
377
 
350
- ddog_Timespec finish_timestamp = time_now();
378
+ ddog_Timespec finish_timestamp = system_epoch_now_timespec();
351
379
  // Need to do this while still holding on to the Global VM Lock; see comments on method for why
352
380
  serializer_set_start_timestamp_for_next_profile(state, finish_timestamp);
353
381
 
@@ -385,10 +413,6 @@ static VALUE _native_serialize(DDTRACE_UNUSED VALUE _self, VALUE recorder_instan
385
413
  VALUE start = ruby_time_from(ddprof_start);
386
414
  VALUE finish = ruby_time_from(ddprof_finish);
387
415
 
388
- if (!ddog_prof_Profile_reset(args.profile, NULL /* start_time is optional */ )) {
389
- return rb_ary_new_from_args(2, error_symbol, rb_str_new_cstr("Failed to reset profile"));
390
- }
391
-
392
416
  return rb_ary_new_from_args(2, ok_symbol, rb_ary_new_from_args(3, start, finish, encoded_pprof));
393
417
  }
394
418
 
@@ -398,7 +422,7 @@ static VALUE ruby_time_from(ddog_Timespec ddprof_time) {
398
422
  return rb_time_timespec_new(&time, utc);
399
423
  }
400
424
 
401
- void record_sample(VALUE recorder_instance, ddog_prof_Slice_Location locations, sample_values values, ddog_prof_Slice_Label labels) {
425
+ void record_sample(VALUE recorder_instance, ddog_prof_Slice_Location locations, sample_values values, sample_labels labels) {
402
426
  struct stack_recorder_state *state;
403
427
  TypedData_Get_Struct(recorder_instance, struct stack_recorder_state, &stack_recorder_typed_data, state);
404
428
 
@@ -412,22 +436,23 @@ void record_sample(VALUE recorder_instance, ddog_prof_Slice_Location locations,
412
436
  uint8_t *position_for = state->position_for;
413
437
 
414
438
  metric_values[position_for[CPU_TIME_VALUE_ID]] = values.cpu_time_ns;
415
- metric_values[position_for[CPU_SAMPLES_VALUE_ID]] = values.cpu_samples;
439
+ metric_values[position_for[CPU_SAMPLES_VALUE_ID]] = values.cpu_or_wall_samples;
416
440
  metric_values[position_for[WALL_TIME_VALUE_ID]] = values.wall_time_ns;
417
441
  metric_values[position_for[ALLOC_SAMPLES_VALUE_ID]] = values.alloc_samples;
418
442
 
419
- ddog_prof_Profile_AddResult result = ddog_prof_Profile_add(
443
+ ddog_prof_Profile_Result result = ddog_prof_Profile_add(
420
444
  active_slot.profile,
421
445
  (ddog_prof_Sample) {
422
446
  .locations = locations,
423
447
  .values = (ddog_Slice_I64) {.ptr = metric_values, .len = state->enabled_values_count},
424
- .labels = labels
425
- }
448
+ .labels = labels.labels
449
+ },
450
+ labels.end_timestamp_ns
426
451
  );
427
452
 
428
453
  sampler_unlock_active_profile(active_slot);
429
454
 
430
- if (result.tag == DDOG_PROF_PROFILE_ADD_RESULT_ERR) {
455
+ if (result.tag == DDOG_PROF_PROFILE_RESULT_ERR) {
431
456
  rb_raise(rb_eArgError, "Failed to record sample: %"PRIsVALUE, get_error_details_and_drop(&result.err));
432
457
  }
433
458
  }
@@ -438,16 +463,21 @@ void record_endpoint(VALUE recorder_instance, uint64_t local_root_span_id, ddog_
438
463
 
439
464
  struct active_slot_pair active_slot = sampler_lock_active_profile(state);
440
465
 
441
- ddog_prof_Profile_set_endpoint(active_slot.profile, local_root_span_id, endpoint);
466
+ ddog_prof_Profile_Result result = ddog_prof_Profile_set_endpoint(active_slot.profile, local_root_span_id, endpoint);
442
467
 
443
468
  sampler_unlock_active_profile(active_slot);
469
+
470
+ if (result.tag == DDOG_PROF_PROFILE_RESULT_ERR) {
471
+ rb_raise(rb_eArgError, "Failed to record endpoint: %"PRIsVALUE, get_error_details_and_drop(&result.err));
472
+ }
444
473
  }
445
474
 
446
475
  static void *call_serialize_without_gvl(void *call_args) {
447
476
  struct call_serialize_without_gvl_arguments *args = (struct call_serialize_without_gvl_arguments *) call_args;
448
477
 
449
478
  args->profile = serializer_flip_active_and_inactive_slots(args->state);
450
- args->result = ddog_prof_Profile_serialize(args->profile, &args->finish_timestamp, NULL /* duration_nanos is optional */);
479
+ // Note: The profile gets reset by the serialize call
480
+ args->result = ddog_prof_Profile_serialize(args->profile, &args->finish_timestamp, NULL /* duration_nanos is optional */, NULL /* start_time is optional */);
451
481
  args->serialize_ran = true;
452
482
 
453
483
  return NULL; // Unused
@@ -466,7 +496,7 @@ static struct active_slot_pair sampler_lock_active_profile(struct stack_recorder
466
496
  if (error && error != EBUSY) ENFORCE_SUCCESS_GVL(error);
467
497
 
468
498
  // Slot one is active
469
- if (!error) return (struct active_slot_pair) {.mutex = &state->slot_one_mutex, .profile = state->slot_one_profile};
499
+ if (!error) return (struct active_slot_pair) {.mutex = &state->slot_one_mutex, .profile = &state->slot_one_profile};
470
500
 
471
501
  // If we got here, slot one was not active, let's try slot two
472
502
 
@@ -474,7 +504,7 @@ static struct active_slot_pair sampler_lock_active_profile(struct stack_recorder
474
504
  if (error && error != EBUSY) ENFORCE_SUCCESS_GVL(error);
475
505
 
476
506
  // Slot two is active
477
- if (!error) return (struct active_slot_pair) {.mutex = &state->slot_two_mutex, .profile = state->slot_two_profile};
507
+ if (!error) return (struct active_slot_pair) {.mutex = &state->slot_two_mutex, .profile = &state->slot_two_profile};
478
508
  }
479
509
 
480
510
  // We already tried both multiple times, and we did not succeed. This is not expected to happen. Let's stop sampling.
@@ -505,7 +535,7 @@ static ddog_prof_Profile *serializer_flip_active_and_inactive_slots(struct stack
505
535
  state->active_slot = (previously_active_slot == 1) ? 2 : 1;
506
536
 
507
537
  // Return profile for previously active slot (now inactive)
508
- return (previously_active_slot == 1) ? state->slot_one_profile : state->slot_two_profile;
538
+ return (previously_active_slot == 1) ? &state->slot_one_profile : &state->slot_two_profile;
509
539
  }
510
540
 
511
541
  // This method exists only to enable testing Datadog::Profiling::StackRecorder behavior using RSpec.
@@ -547,14 +577,9 @@ static VALUE test_slot_mutex_state(VALUE recorder_instance, int slot) {
547
577
  }
548
578
  }
549
579
 
550
- // Note that this is using CLOCK_REALTIME (e.g. actual time since unix epoch) and not the CLOCK_MONOTONIC as we use in
551
- // monotonic_wall_time_now_ns (used in other parts of the codebase)
552
- static ddog_Timespec time_now(void) {
553
- struct timespec current_time;
554
-
555
- if (clock_gettime(CLOCK_REALTIME, &current_time) != 0) ENFORCE_SUCCESS_GVL(errno);
556
-
557
- return (ddog_Timespec) {.seconds = current_time.tv_sec, .nanoseconds = (uint32_t) current_time.tv_nsec};
580
+ static ddog_Timespec system_epoch_now_timespec(void) {
581
+ long now_ns = system_epoch_time_now_ns(RAISE_ON_FAILURE);
582
+ return (ddog_Timespec) {.seconds = now_ns / SECONDS_AS_NS(1), .nanoseconds = now_ns % SECONDS_AS_NS(1)};
558
583
  }
559
584
 
560
585
  // After the Ruby VM forks, this method gets called in the child process to clean up any leftover state from the parent.
@@ -569,19 +594,18 @@ static VALUE _native_reset_after_fork(DDTRACE_UNUSED VALUE self, VALUE recorder_
569
594
  // resulting state is inconsistent, we make sure to reset it back to the initial state.
570
595
  initialize_slot_concurrency_control(state);
571
596
 
572
- ddog_prof_Profile_reset(state->slot_one_profile, /* start_time: */ NULL);
573
- ddog_prof_Profile_reset(state->slot_two_profile, /* start_time: */ NULL);
597
+ reset_profile(&state->slot_one_profile, /* start_time: */ NULL);
598
+ reset_profile(&state->slot_two_profile, /* start_time: */ NULL);
574
599
 
575
600
  return Qtrue;
576
601
  }
577
602
 
578
- // Assumption 1: This method is called with the GVL being held, because `ddog_prof_Profile_reset` mutates the profile and should
603
+ // Assumption 1: This method is called with the GVL being held, because `ddog_prof_Profile_reset` mutates the profile and must
579
604
  // not be interrupted part-way through by a VM fork.
580
- static void serializer_set_start_timestamp_for_next_profile(struct stack_recorder_state *state, ddog_Timespec timestamp) {
581
- // Before making this profile active, we reset it so that it uses the correct timestamp for its start
582
- ddog_prof_Profile *next_profile = (state->active_slot == 1) ? state->slot_two_profile : state->slot_one_profile;
583
-
584
- if (!ddog_prof_Profile_reset(next_profile, &timestamp)) rb_raise(rb_eRuntimeError, "Failed to reset profile");
605
+ static void serializer_set_start_timestamp_for_next_profile(struct stack_recorder_state *state, ddog_Timespec start_time) {
606
+ // Before making this profile active, we reset it so that it uses the correct start_time for its start
607
+ ddog_prof_Profile *next_profile = (state->active_slot == 1) ? &state->slot_two_profile : &state->slot_one_profile;
608
+ reset_profile(next_profile, &start_time);
585
609
  }
586
610
 
587
611
  static VALUE _native_record_endpoint(DDTRACE_UNUSED VALUE _self, VALUE recorder_instance, VALUE local_root_span_id, VALUE endpoint) {
@@ -589,3 +613,10 @@ static VALUE _native_record_endpoint(DDTRACE_UNUSED VALUE _self, VALUE recorder_
589
613
  record_endpoint(recorder_instance, NUM2ULL(local_root_span_id), char_slice_from_ruby_string(endpoint));
590
614
  return Qtrue;
591
615
  }
616
+
617
+ static void reset_profile(ddog_prof_Profile *profile, ddog_Timespec *start_time /* Can be null */) {
618
+ ddog_prof_Profile_Result reset_result = ddog_prof_Profile_reset(profile, start_time);
619
+ if (reset_result.tag == DDOG_PROF_PROFILE_RESULT_ERR) {
620
+ rb_raise(rb_eRuntimeError, "Failed to reset profile: %"PRIsVALUE, get_error_details_and_drop(&reset_result.err));
621
+ }
622
+ }
@@ -2,13 +2,23 @@
2
2
 
3
3
  #include <datadog/profiling.h>
4
4
 
5
- typedef struct sample_values {
5
+ typedef struct {
6
6
  int64_t cpu_time_ns;
7
7
  int64_t wall_time_ns;
8
- uint32_t cpu_samples;
8
+ uint32_t cpu_or_wall_samples;
9
9
  uint32_t alloc_samples;
10
10
  } sample_values;
11
11
 
12
- void record_sample(VALUE recorder_instance, ddog_prof_Slice_Location locations, sample_values values, ddog_prof_Slice_Label labels);
12
+ typedef struct sample_labels {
13
+ ddog_prof_Slice_Label labels;
14
+
15
+ // This is used to allow the `Collectors::Stack` to modify the existing label, if any. This MUST be NULL or point
16
+ // somewhere inside the labels slice above.
17
+ ddog_prof_Label *state_label;
18
+
19
+ int64_t end_timestamp_ns;
20
+ } sample_labels;
21
+
22
+ void record_sample(VALUE recorder_instance, ddog_prof_Slice_Location locations, sample_values values, sample_labels labels);
13
23
  void record_endpoint(VALUE recorder_instance, uint64_t local_root_span_id, ddog_CharSlice endpoint);
14
24
  VALUE enforce_recorder_instance(VALUE object);
@@ -5,13 +5,49 @@
5
5
  #include "time_helpers.h"
6
6
 
7
7
  // Safety: This function is assumed never to raise exceptions by callers when raise_on_failure == false
8
- long monotonic_wall_time_now_ns(bool raise_on_failure) {
9
- struct timespec current_monotonic;
8
+ long retrieve_clock_as_ns(clockid_t clock_id, bool raise_on_failure) {
9
+ struct timespec clock_value;
10
10
 
11
- if (clock_gettime(CLOCK_MONOTONIC, &current_monotonic) != 0) {
11
+ if (clock_gettime(clock_id, &clock_value) != 0) {
12
12
  if (raise_on_failure) ENFORCE_SUCCESS_GVL(errno);
13
13
  return 0;
14
14
  }
15
15
 
16
- return current_monotonic.tv_nsec + SECONDS_AS_NS(current_monotonic.tv_sec);
16
+ return clock_value.tv_nsec + SECONDS_AS_NS(clock_value.tv_sec);
17
+ }
18
+
19
+ long monotonic_wall_time_now_ns(bool raise_on_failure) { return retrieve_clock_as_ns(CLOCK_MONOTONIC, raise_on_failure); }
20
+ long system_epoch_time_now_ns(bool raise_on_failure) { return retrieve_clock_as_ns(CLOCK_REALTIME, raise_on_failure); }
21
+
22
+ // Design: The monotonic_to_system_epoch_state struct is kept somewhere by the caller, and MUST be initialized to
23
+ // MONOTONIC_TO_SYSTEM_EPOCH_INITIALIZER.
24
+ //
25
+ // This function is used by the ThreadContext collector to convert monotonic wall time timestamps which are used
26
+ // basically everywhere else in the codebase, into system epoch timestamps, which are needed by the timeline feature.
27
+ //
28
+ // There's a few ways we could have tackled this conversion, e.g. check the system clock on every call, or even
29
+ // use system clock timestamps elsewhere in the code.
30
+ // Using a system clock elsewhere has a few disadvantages (e.g. because it can move around if users adjust the system
31
+ // time). I also wanted to avoid calling system_epoch_time_now_ns(...) on every conversion.
32
+ //
33
+ // Thus I arrived at this solution: we calculate a delta between the monotonic clock and the system clock, and use
34
+ // that to convert the timestamps.
35
+ //
36
+ // To avoid the results of the system clock being off in cases where the system clock is adjusted while the profiler
37
+ // is running, every ~60 seconds of observed monotonic wall time we recalculate the delta. This means that worst case
38
+ // we'll have ~60 seconds of wrongly-timestamped data when the system clock jumps around, and in return we save the
39
+ // overhead of having to look up the system clock on every call to this function.
40
+ long monotonic_to_system_epoch_ns(monotonic_to_system_epoch_state *state, long monotonic_wall_time_ns) {
41
+ bool reference_needs_update =
42
+ (state->system_epoch_ns_reference == INVALID_TIME) ||
43
+ (state->delta_to_epoch_ns + monotonic_wall_time_ns > state->system_epoch_ns_reference + SECONDS_AS_NS(60));
44
+
45
+ if (reference_needs_update) {
46
+ state->system_epoch_ns_reference = system_epoch_time_now_ns(RAISE_ON_FAILURE);
47
+ long current_monotonic_wall_time_ns = monotonic_wall_time_now_ns(RAISE_ON_FAILURE);
48
+
49
+ state->delta_to_epoch_ns = state->system_epoch_ns_reference - current_monotonic_wall_time_ns;
50
+ }
51
+
52
+ return state->delta_to_epoch_ns + monotonic_wall_time_ns;
17
53
  }
@@ -6,5 +6,19 @@
6
6
  #define RAISE_ON_FAILURE true
7
7
  #define DO_NOT_RAISE_ON_FAILURE false
8
8
 
9
+ #define INVALID_TIME -1
10
+
11
+ typedef struct {
12
+ long system_epoch_ns_reference;
13
+ long delta_to_epoch_ns;
14
+ } monotonic_to_system_epoch_state;
15
+
16
+ #define MONOTONIC_TO_SYSTEM_EPOCH_INITIALIZER {.system_epoch_ns_reference = INVALID_TIME, .delta_to_epoch_ns = INVALID_TIME}
17
+
9
18
  // Safety: This function is assumed never to raise exceptions by callers when raise_on_failure == false
10
19
  long monotonic_wall_time_now_ns(bool raise_on_failure);
20
+
21
+ // Safety: This function is assumed never to raise exceptions by callers when raise_on_failure == false
22
+ long system_epoch_time_now_ns(bool raise_on_failure);
23
+
24
+ long monotonic_to_system_epoch_ns(monotonic_to_system_epoch_state *state, long monotonic_wall_time_ns);
@@ -0,0 +1,92 @@
1
+ [
2
+ {
3
+ "id": "processor-001",
4
+ "generator": "extract_schema",
5
+ "conditions": [
6
+ {
7
+ "operator": "equals",
8
+ "parameters": {
9
+ "inputs": [
10
+ {
11
+ "address": "waf.context.processor",
12
+ "key_path": [
13
+ "extract-schema"
14
+ ]
15
+ }
16
+ ],
17
+ "type": "boolean",
18
+ "value": true
19
+ }
20
+ }
21
+ ],
22
+ "parameters": {
23
+ "mappings": [
24
+ {
25
+ "inputs": [
26
+ {
27
+ "address": "server.request.body"
28
+ }
29
+ ],
30
+ "output": "_dd.appsec.s.req.body"
31
+ },
32
+ {
33
+ "inputs": [
34
+ {
35
+ "address": "server.request.headers.no_cookies"
36
+ }
37
+ ],
38
+ "output": "_dd.appsec.s.req.headers"
39
+ },
40
+ {
41
+ "inputs": [
42
+ {
43
+ "address": "server.request.query"
44
+ }
45
+ ],
46
+ "output": "_dd.appsec.s.req.query"
47
+ },
48
+ {
49
+ "inputs": [
50
+ {
51
+ "address": "server.request.path_params"
52
+ }
53
+ ],
54
+ "output": "_dd.appsec.s.req.params"
55
+ },
56
+ {
57
+ "inputs": [
58
+ {
59
+ "address": "server.request.cookies"
60
+ }
61
+ ],
62
+ "output": "_dd.appsec.s.req.cookies"
63
+ },
64
+ {
65
+ "inputs": [
66
+ {
67
+ "address": "server.response.headers.no_cookies"
68
+ }
69
+ ],
70
+ "output": "_dd.appsec.s.res.headers"
71
+ },
72
+ {
73
+ "inputs": [
74
+ {
75
+ "address": "server.response.body"
76
+ }
77
+ ],
78
+ "output": "_dd.appsec.s.res.body"
79
+ }
80
+ ],
81
+ "scanners": [
82
+ {
83
+ "tags": {
84
+ "category": "pii"
85
+ }
86
+ }
87
+ ]
88
+ },
89
+ "evaluate": false,
90
+ "output": true
91
+ }
92
+ ]