ddtrace 1.12.1 → 1.13.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 (264) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +109 -9
  3. data/ext/ddtrace_profiling_native_extension/collectors_thread_context.c +97 -14
  4. data/ext/ddtrace_profiling_native_extension/extconf.rb +6 -0
  5. data/ext/ddtrace_profiling_native_extension/http_transport.c +19 -6
  6. data/ext/ddtrace_profiling_native_extension/native_extension_helpers.rb +1 -1
  7. data/ext/ddtrace_profiling_native_extension/private_vm_api_access.c +41 -2
  8. data/ext/ddtrace_profiling_native_extension/private_vm_api_access.h +6 -0
  9. data/ext/ddtrace_profiling_native_extension/stack_recorder.c +6 -10
  10. data/ext/ddtrace_profiling_native_extension/time_helpers.c +40 -4
  11. data/ext/ddtrace_profiling_native_extension/time_helpers.h +14 -0
  12. data/lib/datadog/appsec/component.rb +9 -0
  13. data/lib/datadog/appsec/configuration/settings.rb +104 -195
  14. data/lib/datadog/appsec/configuration.rb +0 -79
  15. data/lib/datadog/appsec/contrib/auto_instrument.rb +2 -4
  16. data/lib/datadog/appsec/contrib/devise/event.rb +57 -0
  17. data/lib/datadog/appsec/contrib/devise/ext.rb +13 -0
  18. data/lib/datadog/appsec/contrib/devise/integration.rb +42 -0
  19. data/lib/datadog/appsec/contrib/devise/patcher/authenticatable_patch.rb +76 -0
  20. data/lib/datadog/appsec/contrib/devise/patcher/registration_controller_patch.rb +52 -0
  21. data/lib/datadog/appsec/contrib/devise/patcher.rb +45 -0
  22. data/lib/datadog/appsec/contrib/devise/resource.rb +35 -0
  23. data/lib/datadog/appsec/contrib/devise/tracking.rb +49 -0
  24. data/lib/datadog/appsec/contrib/rack/ext.rb +2 -1
  25. data/lib/datadog/appsec/contrib/rack/reactive/request.rb +1 -1
  26. data/lib/datadog/appsec/contrib/rack/reactive/request_body.rb +1 -1
  27. data/lib/datadog/appsec/contrib/rack/reactive/response.rb +1 -1
  28. data/lib/datadog/appsec/contrib/rack/request_middleware.rb +12 -7
  29. data/lib/datadog/appsec/contrib/rails/ext.rb +3 -2
  30. data/lib/datadog/appsec/contrib/rails/framework.rb +1 -3
  31. data/lib/datadog/appsec/contrib/rails/patcher.rb +8 -8
  32. data/lib/datadog/appsec/contrib/rails/reactive/action.rb +1 -1
  33. data/lib/datadog/appsec/contrib/sinatra/ext.rb +2 -1
  34. data/lib/datadog/appsec/contrib/sinatra/framework.rb +1 -3
  35. data/lib/datadog/appsec/contrib/sinatra/reactive/routed.rb +1 -1
  36. data/lib/datadog/appsec/event.rb +1 -1
  37. data/lib/datadog/appsec/extensions.rb +1 -130
  38. data/lib/datadog/appsec/monitor/reactive/set_user.rb +1 -1
  39. data/lib/datadog/appsec/processor.rb +1 -1
  40. data/lib/datadog/appsec/rate_limiter.rb +1 -1
  41. data/lib/datadog/appsec/remote.rb +1 -1
  42. data/lib/datadog/appsec.rb +1 -2
  43. data/lib/datadog/ci/configuration/settings.rb +6 -8
  44. data/lib/datadog/ci/contrib/cucumber/configuration/settings.rb +7 -5
  45. data/lib/datadog/ci/contrib/cucumber/ext.rb +10 -8
  46. data/lib/datadog/ci/contrib/minitest/configuration/settings.rb +35 -0
  47. data/lib/datadog/ci/contrib/minitest/ext.rb +21 -0
  48. data/lib/datadog/ci/contrib/minitest/integration.rb +49 -0
  49. data/lib/datadog/ci/contrib/minitest/patcher.rb +27 -0
  50. data/lib/datadog/ci/contrib/minitest/test_helper.rb +68 -0
  51. data/lib/datadog/ci/contrib/rspec/configuration/settings.rb +7 -5
  52. data/lib/datadog/ci/contrib/rspec/ext.rb +9 -7
  53. data/lib/datadog/ci.rb +1 -0
  54. data/lib/datadog/core/backport.rb +51 -0
  55. data/lib/datadog/core/configuration/base.rb +5 -5
  56. data/lib/datadog/core/configuration/components.rb +6 -1
  57. data/lib/datadog/core/configuration/ext.rb +7 -5
  58. data/lib/datadog/core/configuration/option.rb +269 -19
  59. data/lib/datadog/core/configuration/option_definition.rb +76 -11
  60. data/lib/datadog/core/configuration/options.rb +22 -10
  61. data/lib/datadog/core/configuration/settings.rb +116 -61
  62. data/lib/datadog/core/environment/ext.rb +13 -11
  63. data/lib/datadog/core/environment/yjit.rb +58 -0
  64. data/lib/datadog/core/git/ext.rb +24 -22
  65. data/lib/datadog/core/logging/ext.rb +3 -1
  66. data/lib/datadog/core/metrics/ext.rb +7 -5
  67. data/lib/datadog/core/remote/client/capabilities.rb +5 -0
  68. data/lib/datadog/core/remote/client.rb +3 -0
  69. data/lib/datadog/core/remote/component.rb +25 -34
  70. data/lib/datadog/core/remote/configuration/content.rb +28 -1
  71. data/lib/datadog/core/remote/configuration/repository.rb +3 -1
  72. data/lib/datadog/core/remote/ext.rb +1 -1
  73. data/lib/datadog/core/remote/negotiation.rb +17 -4
  74. data/lib/datadog/core/runtime/ext.rb +22 -12
  75. data/lib/datadog/core/runtime/metrics.rb +43 -0
  76. data/lib/datadog/core/telemetry/client.rb +12 -2
  77. data/lib/datadog/core/telemetry/emitter.rb +4 -2
  78. data/lib/datadog/core/telemetry/event.rb +19 -4
  79. data/lib/datadog/core/telemetry/ext.rb +4 -1
  80. data/lib/datadog/core/telemetry/heartbeat.rb +2 -4
  81. data/lib/datadog/core/telemetry/http/ext.rb +10 -8
  82. data/lib/datadog/core/telemetry/http/transport.rb +1 -0
  83. data/lib/datadog/core/telemetry/v2/app_client_configuration_change.rb +41 -0
  84. data/lib/datadog/core/telemetry/v2/request.rb +29 -0
  85. data/lib/datadog/core/transport/http/client.rb +1 -1
  86. data/lib/datadog/core/transport/http/config.rb +10 -0
  87. data/lib/datadog/core/utils/duration.rb +52 -0
  88. data/lib/datadog/core/utils/hash.rb +47 -0
  89. data/lib/datadog/core/utils/network.rb +1 -1
  90. data/lib/datadog/core/utils/safe_dup.rb +27 -20
  91. data/lib/datadog/core/utils.rb +1 -1
  92. data/lib/datadog/core/workers/async.rb +2 -2
  93. data/lib/datadog/kit/appsec/events.rb +139 -89
  94. data/lib/datadog/kit/identity.rb +80 -65
  95. data/lib/datadog/profiling/collectors/cpu_and_wall_time_worker.rb +3 -0
  96. data/lib/datadog/profiling/collectors/idle_sampling_helper.rb +1 -0
  97. data/lib/datadog/profiling/collectors/thread_context.rb +9 -2
  98. data/lib/datadog/profiling/component.rb +41 -9
  99. data/lib/datadog/profiling/exporter.rb +5 -1
  100. data/lib/datadog/profiling/flush.rb +9 -2
  101. data/lib/datadog/profiling/http_transport.rb +4 -1
  102. data/lib/datadog/profiling/load_native_extension.rb +7 -1
  103. data/lib/datadog/profiling.rb +11 -1
  104. data/lib/datadog/tracing/component.rb +58 -6
  105. data/lib/datadog/tracing/configuration/dynamic/option.rb +71 -0
  106. data/lib/datadog/tracing/configuration/dynamic.rb +64 -0
  107. data/lib/datadog/tracing/configuration/ext.rb +35 -32
  108. data/lib/datadog/tracing/configuration/http.rb +74 -0
  109. data/lib/datadog/tracing/configuration/settings.rb +106 -92
  110. data/lib/datadog/tracing/contrib/action_cable/configuration/settings.rb +9 -6
  111. data/lib/datadog/tracing/contrib/action_cable/ext.rb +20 -18
  112. data/lib/datadog/tracing/contrib/action_mailer/configuration/settings.rb +9 -6
  113. data/lib/datadog/tracing/contrib/action_mailer/ext.rb +20 -18
  114. data/lib/datadog/tracing/contrib/action_pack/configuration/settings.rb +8 -6
  115. data/lib/datadog/tracing/contrib/action_pack/ext.rb +10 -8
  116. data/lib/datadog/tracing/contrib/action_view/configuration/settings.rb +9 -6
  117. data/lib/datadog/tracing/contrib/action_view/ext.rb +12 -10
  118. data/lib/datadog/tracing/contrib/active_job/configuration/settings.rb +13 -7
  119. data/lib/datadog/tracing/contrib/active_job/ext.rb +25 -23
  120. data/lib/datadog/tracing/contrib/active_job/log_injection.rb +1 -1
  121. data/lib/datadog/tracing/contrib/active_job/patcher.rb +1 -1
  122. data/lib/datadog/tracing/contrib/active_model_serializers/configuration/settings.rb +9 -6
  123. data/lib/datadog/tracing/contrib/active_model_serializers/ext.rb +12 -10
  124. data/lib/datadog/tracing/contrib/active_record/configuration/settings.rb +9 -7
  125. data/lib/datadog/tracing/contrib/active_record/events/sql.rb +0 -8
  126. data/lib/datadog/tracing/contrib/active_record/ext.rb +17 -15
  127. data/lib/datadog/tracing/contrib/active_support/cache/instrumentation.rb +0 -5
  128. data/lib/datadog/tracing/contrib/active_support/configuration/settings.rb +9 -7
  129. data/lib/datadog/tracing/contrib/active_support/ext.rb +18 -16
  130. data/lib/datadog/tracing/contrib/aws/configuration/settings.rb +14 -7
  131. data/lib/datadog/tracing/contrib/aws/ext.rb +37 -24
  132. data/lib/datadog/tracing/contrib/aws/instrumentation.rb +9 -5
  133. data/lib/datadog/tracing/contrib/concurrent_ruby/configuration/settings.rb +3 -2
  134. data/lib/datadog/tracing/contrib/concurrent_ruby/ext.rb +4 -2
  135. data/lib/datadog/tracing/contrib/dalli/configuration/settings.rb +14 -7
  136. data/lib/datadog/tracing/contrib/dalli/ext.rb +19 -11
  137. data/lib/datadog/tracing/contrib/dalli/instrumentation.rb +8 -6
  138. data/lib/datadog/tracing/contrib/delayed_job/configuration/settings.rb +13 -7
  139. data/lib/datadog/tracing/contrib/delayed_job/ext.rb +16 -14
  140. data/lib/datadog/tracing/contrib/elasticsearch/configuration/settings.rb +14 -7
  141. data/lib/datadog/tracing/contrib/elasticsearch/ext.rb +21 -15
  142. data/lib/datadog/tracing/contrib/elasticsearch/patcher.rb +8 -5
  143. data/lib/datadog/tracing/contrib/ethon/configuration/settings.rb +16 -9
  144. data/lib/datadog/tracing/contrib/ethon/easy_patch.rb +43 -3
  145. data/lib/datadog/tracing/contrib/ethon/ext.rb +19 -11
  146. data/lib/datadog/tracing/contrib/ethon/multi_patch.rb +0 -5
  147. data/lib/datadog/tracing/contrib/excon/configuration/settings.rb +19 -10
  148. data/lib/datadog/tracing/contrib/excon/ext.rb +16 -8
  149. data/lib/datadog/tracing/contrib/excon/middleware.rb +20 -5
  150. data/lib/datadog/tracing/contrib/ext.rb +23 -1
  151. data/lib/datadog/tracing/contrib/extensions.rb +32 -0
  152. data/lib/datadog/tracing/contrib/faraday/configuration/settings.rb +20 -10
  153. data/lib/datadog/tracing/contrib/faraday/ext.rb +16 -8
  154. data/lib/datadog/tracing/contrib/faraday/middleware.rb +16 -5
  155. data/lib/datadog/tracing/contrib/grape/configuration/settings.rb +8 -6
  156. data/lib/datadog/tracing/contrib/grape/ext.rb +16 -14
  157. data/lib/datadog/tracing/contrib/graphql/configuration/settings.rb +8 -6
  158. data/lib/datadog/tracing/contrib/graphql/ext.rb +7 -5
  159. data/lib/datadog/tracing/contrib/grpc/configuration/settings.rb +19 -9
  160. data/lib/datadog/tracing/contrib/grpc/datadog_interceptor/client.rb +29 -20
  161. data/lib/datadog/tracing/contrib/grpc/datadog_interceptor/server.rb +21 -20
  162. data/lib/datadog/tracing/contrib/grpc/ext.rb +16 -13
  163. data/lib/datadog/tracing/contrib/grpc/formatting.rb +127 -0
  164. data/lib/datadog/tracing/contrib/hanami/configuration/settings.rb +3 -2
  165. data/lib/datadog/tracing/contrib/hanami/ext.rb +10 -8
  166. data/lib/datadog/tracing/contrib/http/circuit_breaker.rb +4 -7
  167. data/lib/datadog/tracing/contrib/http/configuration/settings.rb +33 -11
  168. data/lib/datadog/tracing/contrib/http/ext.rb +16 -9
  169. data/lib/datadog/tracing/contrib/http/instrumentation.rb +17 -5
  170. data/lib/datadog/tracing/contrib/httpclient/configuration/settings.rb +33 -11
  171. data/lib/datadog/tracing/contrib/httpclient/ext.rb +17 -9
  172. data/lib/datadog/tracing/contrib/httpclient/instrumentation.rb +17 -5
  173. data/lib/datadog/tracing/contrib/httprb/configuration/settings.rb +33 -11
  174. data/lib/datadog/tracing/contrib/httprb/ext.rb +16 -9
  175. data/lib/datadog/tracing/contrib/httprb/instrumentation.rb +17 -5
  176. data/lib/datadog/tracing/contrib/kafka/configuration/settings.rb +9 -6
  177. data/lib/datadog/tracing/contrib/kafka/ext.rb +42 -39
  178. data/lib/datadog/tracing/contrib/lograge/configuration/settings.rb +3 -2
  179. data/lib/datadog/tracing/contrib/lograge/ext.rb +3 -1
  180. data/lib/datadog/tracing/contrib/lograge/instrumentation.rb +1 -0
  181. data/lib/datadog/tracing/contrib/mongodb/configuration/settings.rb +14 -7
  182. data/lib/datadog/tracing/contrib/mongodb/ext.rb +20 -16
  183. data/lib/datadog/tracing/contrib/mongodb/subscribers.rb +9 -5
  184. data/lib/datadog/tracing/contrib/mysql2/configuration/settings.rb +17 -14
  185. data/lib/datadog/tracing/contrib/mysql2/ext.rb +15 -10
  186. data/lib/datadog/tracing/contrib/mysql2/instrumentation.rb +9 -5
  187. data/lib/datadog/tracing/contrib/opensearch/configuration/settings.rb +52 -0
  188. data/lib/datadog/tracing/contrib/opensearch/ext.rb +37 -0
  189. data/lib/datadog/tracing/contrib/opensearch/integration.rb +44 -0
  190. data/lib/datadog/tracing/contrib/opensearch/patcher.rb +128 -0
  191. data/lib/datadog/tracing/contrib/opensearch/quantize.rb +81 -0
  192. data/lib/datadog/tracing/contrib/pg/configuration/settings.rb +17 -14
  193. data/lib/datadog/tracing/contrib/pg/ext.rb +22 -19
  194. data/lib/datadog/tracing/contrib/pg/instrumentation.rb +9 -5
  195. data/lib/datadog/tracing/contrib/presto/configuration/settings.rb +14 -7
  196. data/lib/datadog/tracing/contrib/presto/ext.rb +25 -20
  197. data/lib/datadog/tracing/contrib/presto/instrumentation.rb +9 -5
  198. data/lib/datadog/tracing/contrib/propagation/sql_comment/ext.rb +12 -10
  199. data/lib/datadog/tracing/contrib/qless/configuration/settings.rb +12 -8
  200. data/lib/datadog/tracing/contrib/qless/ext.rb +14 -12
  201. data/lib/datadog/tracing/contrib/que/configuration/settings.rb +21 -12
  202. data/lib/datadog/tracing/contrib/racecar/configuration/settings.rb +9 -7
  203. data/lib/datadog/tracing/contrib/racecar/event.rb +0 -5
  204. data/lib/datadog/tracing/contrib/racecar/ext.rb +20 -18
  205. data/lib/datadog/tracing/contrib/rack/configuration/settings.rb +16 -12
  206. data/lib/datadog/tracing/contrib/rack/ext.rb +18 -16
  207. data/lib/datadog/tracing/contrib/rack/header_collection.rb +3 -0
  208. data/lib/datadog/tracing/contrib/rack/header_tagging.rb +53 -0
  209. data/lib/datadog/tracing/contrib/rack/middlewares.rb +8 -49
  210. data/lib/datadog/tracing/contrib/rails/configuration/settings.rb +15 -11
  211. data/lib/datadog/tracing/contrib/rails/ext.rb +7 -5
  212. data/lib/datadog/tracing/contrib/rails/log_injection.rb +4 -10
  213. data/lib/datadog/tracing/contrib/rails/patcher.rb +10 -41
  214. data/lib/datadog/tracing/contrib/rails/railtie.rb +3 -3
  215. data/lib/datadog/tracing/contrib/rake/configuration/settings.rb +12 -9
  216. data/lib/datadog/tracing/contrib/rake/ext.rb +14 -12
  217. data/lib/datadog/tracing/contrib/redis/configuration/settings.rb +17 -9
  218. data/lib/datadog/tracing/contrib/redis/ext.rb +22 -15
  219. data/lib/datadog/tracing/contrib/redis/tags.rb +9 -5
  220. data/lib/datadog/tracing/contrib/resque/configuration/settings.rb +13 -7
  221. data/lib/datadog/tracing/contrib/resque/ext.rb +9 -7
  222. data/lib/datadog/tracing/contrib/rest_client/configuration/settings.rb +16 -9
  223. data/lib/datadog/tracing/contrib/rest_client/ext.rb +15 -8
  224. data/lib/datadog/tracing/contrib/rest_client/request_patch.rb +20 -5
  225. data/lib/datadog/tracing/contrib/roda/configuration/settings.rb +9 -6
  226. data/lib/datadog/tracing/contrib/semantic_logger/configuration/settings.rb +3 -2
  227. data/lib/datadog/tracing/contrib/semantic_logger/ext.rb +3 -1
  228. data/lib/datadog/tracing/contrib/semantic_logger/instrumentation.rb +1 -0
  229. data/lib/datadog/tracing/contrib/sequel/configuration/settings.rb +9 -6
  230. data/lib/datadog/tracing/contrib/sequel/ext.rb +10 -8
  231. data/lib/datadog/tracing/contrib/sequel/utils.rb +2 -7
  232. data/lib/datadog/tracing/contrib/shoryuken/configuration/settings.rb +14 -8
  233. data/lib/datadog/tracing/contrib/shoryuken/ext.rb +14 -12
  234. data/lib/datadog/tracing/contrib/sidekiq/configuration/settings.rb +18 -11
  235. data/lib/datadog/tracing/contrib/sidekiq/ext.rb +32 -30
  236. data/lib/datadog/tracing/contrib/sinatra/configuration/settings.rb +11 -9
  237. data/lib/datadog/tracing/contrib/sinatra/env.rb +0 -17
  238. data/lib/datadog/tracing/contrib/sinatra/ext.rb +21 -19
  239. data/lib/datadog/tracing/contrib/sinatra/tracer_middleware.rb +3 -14
  240. data/lib/datadog/tracing/contrib/sneakers/configuration/settings.rb +14 -8
  241. data/lib/datadog/tracing/contrib/sneakers/ext.rb +1 -0
  242. data/lib/datadog/tracing/contrib/sneakers/tracer.rb +1 -1
  243. data/lib/datadog/tracing/contrib/span_attribute_schema.rb +74 -10
  244. data/lib/datadog/tracing/contrib/stripe/configuration/settings.rb +9 -6
  245. data/lib/datadog/tracing/contrib/sucker_punch/configuration/settings.rb +9 -6
  246. data/lib/datadog/tracing/contrib/sucker_punch/ext.rb +15 -13
  247. data/lib/datadog/tracing/contrib/utils/database.rb +5 -3
  248. data/lib/datadog/tracing/correlation.rb +9 -12
  249. data/lib/datadog/tracing/diagnostics/ext.rb +21 -19
  250. data/lib/datadog/tracing/distributed/b3_multi.rb +2 -2
  251. data/lib/datadog/tracing/distributed/b3_single.rb +1 -1
  252. data/lib/datadog/tracing/distributed/trace_context.rb +52 -17
  253. data/lib/datadog/tracing/metadata/ext.rb +9 -6
  254. data/lib/datadog/tracing/remote.rb +78 -0
  255. data/lib/datadog/tracing/sampling/rule_sampler.rb +29 -0
  256. data/lib/datadog/tracing/span_operation.rb +3 -15
  257. data/lib/datadog/tracing/trace_operation.rb +16 -3
  258. data/lib/datadog/tracing/trace_segment.rb +5 -2
  259. data/lib/datadog/tracing/tracer.rb +10 -1
  260. data/lib/ddtrace/transport/ext.rb +15 -9
  261. data/lib/ddtrace/transport/trace_formatter.rb +9 -0
  262. data/lib/ddtrace/version.rb +9 -12
  263. metadata +38 -10
  264. data/lib/datadog/tracing/contrib/sinatra/headers.rb +0 -35
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7755d42a1b84dda8386f13ce2edc3854f09e1e227d5786546b19ea31a60cc03b
4
- data.tar.gz: 57ee6f72d29b72305c8272b98dc4b7d08a66f9463820d9963aa487723094d1f7
3
+ metadata.gz: 845f4614c8e20a84d26d9d14a22b5cddde0e1b27aeb7e093b5addf7a0cbd7490
4
+ data.tar.gz: 829de76d1ac7aa04f1eb9a1bd36ef3ff5fec7bfc5657015cea291fe8219ea162
5
5
  SHA512:
6
- metadata.gz: e9c5d234fb1261e202bf8d4ae00417f31f325dbcc9ceb9081277ac96a04114316456fed6d21f3de343dbe6192e4a0ceccb4504e5b1a59bbb44fe2666042a7890
7
- data.tar.gz: effa42b2181771676d69ea5efb946cd6bd4617853b36f75b9655a710d369f57a200dded1cdc8b86642eaf60174c20b44da3b3de29fbfddfd76c6845364927fe2
6
+ metadata.gz: 6a3ed99fb7b1ddf340fa2f343f70d0f2ba456f6f45f62cd6f1a3250b05dafa2f44f18784899bd898d213eab37ca4921b618581b8faf0134c2bed325febb20c30
7
+ data.tar.gz: 6ef24c9b3559eb34705a4b43d325d4582bef7279627563641cae3675e26978ce92e5f953c277991866389083e57540622d232b58a44d44e4ede4fb370ff93b68
data/CHANGELOG.md CHANGED
@@ -2,21 +2,70 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [1.13.0] - 2023-07-31
6
+
7
+ ### Added
8
+
9
+ * Core: Add support for `Option` precedence ([#2915][])
10
+ * Core: Add support for unsetting options ([#2972][])
11
+ * Core: Gauge primitive `RubyVM::YJIT.runtime_stats`, if `YJIT` is enabled ([#2711][], [#2959][])([@HeyNonster][])
12
+ * Core: Add Telemetry `app-client-configuration-change` event ([#2977][])
13
+ * Core: Improve our `SafeDup` module ([#2960][])
14
+ * Tracing: Add `OpenSearch` Integration ([#2940][])
15
+ * Tracing: Implement `peer.service` tag to integrations ([#2982][])
16
+ * Tracing: Add mandatory rpc and grpc tags for `grpc` integration ([#2620][], [#2962][])
17
+ * Tracing: Include `_dd.profiling.enabled` tag ([#2913][])
18
+ * Tracing: Support host injection ([#2941][], [#3007][])
19
+ * Tracing: Implement Dynamic Configuration for tracing ([#2848][], [#2973][])
20
+ * Tracing: Add for dynamic log injection configuration ([#2992][])
21
+ * Tracing: Add sampling configuration with `DD_TRACE_SAMPLING_RULES` ([#2968][])
22
+ * Tracing: Add HTTP header tagging with `DD_TRACE_HEADER_TAGS` for clients and servers ([#2946][], [#2935][])
23
+ * Profiling: Add fallback name/invoke location for unnamed threads started in native code ([#2993][])
24
+ * Profiling: Use invoke location as a fallback for nameless threads in the profiler ([#2950][])
25
+ * Profiling: Add fallback name for main thread in profiling data ([#2939][])
26
+ * Ci-app: Add `Minitest` CI integration ([#2932][]) ([@bravehager][])
27
+ * Appsec: `Devise` integration and automatic user events ([#2877][])
28
+ * Appsec: Handle disabled tracing and appsec events ([#2572][])
29
+ * Appsec: Automate user events check for UUID in safe mode ([#2952][])
30
+ * Docs: Add Ruby 3.2 support to compatibility matrix ([#2971][])
31
+
32
+ ### Changed
33
+
34
+ * Core: Set maximum supported Ruby version ([#2497][])
35
+ * Core: Prevent telemetry requests from being traced ([#2961][])
36
+ * Core: Add `env` and `type` to Core configuration option ([#2983][], [#2988][], [#2994][])
37
+ * Core: Remove `lazy` from Core configuration option ([#2931][], [#2999][])
38
+ * Profiling: Bump `libdatadog` dependency to version 3 ([#2948][])
39
+ * Profiling: Improve error message when `ddtrace_profiling_loader` fails to load ([#2957][])
40
+ * Tracing: Improve log injection runtime conditionals ([#2926][], [#2882][])
41
+
42
+ ### Fixed
43
+
44
+ * Core: Fix polynomial-time regular expressions ([#2814][])
45
+ * Core: Fix environment variable for dynamic configuration polling interval ([#2967][])
46
+ * Core: Reduce remote configuration error logging noise ([#3011][])
47
+ * Tracing: Fix manual log injection for 128 bit trace_id ([#2974][])
48
+ * Tracing: Ensure the GRPC client interceptor return the response ([#2928][]) ([@KJTsanaktsidis][])
49
+ * Tracing: Remove dynamic input used in regular expression ([#2867][])
50
+ * Tracing: Fix distributed tracing header formats ([#3005][] )
51
+ * Profiling: Fix profiler `libmysqlclient` version detection with `mysql2-aurora` gem ([#2956][])
52
+ * Profiling: Automatically enable profiler "no signals" workaround for `passenger` web server ([#2978][])
53
+
5
54
  ## [1.12.1] - 2023-06-14
6
55
 
7
56
  ### Added
8
- Appsec: Add `appsec.blocked` tag to span ([#2895][])
9
- Profiling: Add workaround for legacy profiler incompatibility with ruby-cloud-profiler gem ([#2891][])
10
- Core: Allow setting remote configuration service name ([#2853][])
57
+ * Appsec: Add `appsec.blocked` tag to span ([#2895][])
58
+ * Profiling: Add workaround for legacy profiler incompatibility with ruby-cloud-profiler gem ([#2891][])
59
+ * Core: Allow setting remote configuration service name ([#2853][])
11
60
 
12
61
  ### Changed
13
- Appsec: Change the value format for the WAF address `server.request.query` ([#2903][])
14
- Profiling: Log pkg-config command when building profiling native extension
62
+ * Appsec: Change the value format for the WAF address `server.request.query` ([#2903][])
63
+ * Profiling: Log pkg-config command when building profiling native extension
15
64
 
16
65
  ### Fixed
17
- Appsec: Update blocked response content_type resolution ([#2900][])
18
- Appsec: Ensure to use service entry span. ([#2898][])
19
- Tracing: Fix AWS integration constant loading ([#2896][])
66
+ * Appsec: Update blocked response content_type resolution ([#2900][])
67
+ * Appsec: Ensure to use service entry span. ([#2898][])
68
+ * Tracing: Fix AWS integration constant loading ([#2896][])
20
69
 
21
70
  ## [1.12.0] - 2023-06-02
22
71
 
@@ -2454,7 +2503,8 @@ Release notes: https://github.com/DataDog/dd-trace-rb/releases/tag/v0.3.1
2454
2503
 
2455
2504
  Git diff: https://github.com/DataDog/dd-trace-rb/compare/v0.3.0...v0.3.1
2456
2505
 
2457
- [Unreleased]: https://github.com/DataDog/dd-trace-rb/compare/v1.12.1...master
2506
+ [Unreleased]: https://github.com/DataDog/dd-trace-rb/compare/v1.13.0...master
2507
+ [1.13.0]: https://github.com/DataDog/dd-trace-rb/compare/v1.12.1...v1.13.0
2458
2508
  [1.12.1]: https://github.com/DataDog/dd-trace-rb/compare/v1.12.0...v1.12.1
2459
2509
  [1.12.0]: https://github.com/DataDog/dd-trace-rb/compare/v1.11.1...v1.12.0
2460
2510
  [1.11.1]: https://github.com/DataDog/dd-trace-rb/compare/v1.10.1...v1.11.1
@@ -3427,6 +3477,7 @@ Git diff: https://github.com/DataDog/dd-trace-rb/compare/v0.3.0...v0.3.1
3427
3477
  [#2489]: https://github.com/DataDog/dd-trace-rb/issues/2489
3428
3478
  [#2493]: https://github.com/DataDog/dd-trace-rb/issues/2493
3429
3479
  [#2496]: https://github.com/DataDog/dd-trace-rb/issues/2496
3480
+ [#2497]: https://github.com/DataDog/dd-trace-rb/issues/2497
3430
3481
  [#2501]: https://github.com/DataDog/dd-trace-rb/issues/2501
3431
3482
  [#2504]: https://github.com/DataDog/dd-trace-rb/issues/2504
3432
3483
  [#2512]: https://github.com/DataDog/dd-trace-rb/issues/2512
@@ -3439,6 +3490,7 @@ Git diff: https://github.com/DataDog/dd-trace-rb/compare/v0.3.0...v0.3.1
3439
3490
  [#2543]: https://github.com/DataDog/dd-trace-rb/issues/2543
3440
3491
  [#2557]: https://github.com/DataDog/dd-trace-rb/issues/2557
3441
3492
  [#2562]: https://github.com/DataDog/dd-trace-rb/issues/2562
3493
+ [#2572]: https://github.com/DataDog/dd-trace-rb/issues/2572
3442
3494
  [#2573]: https://github.com/DataDog/dd-trace-rb/issues/2573
3443
3495
  [#2576]: https://github.com/DataDog/dd-trace-rb/issues/2576
3444
3496
  [#2580]: https://github.com/DataDog/dd-trace-rb/issues/2580
@@ -3461,6 +3513,7 @@ Git diff: https://github.com/DataDog/dd-trace-rb/compare/v0.3.0...v0.3.1
3461
3513
  [#2614]: https://github.com/DataDog/dd-trace-rb/issues/2614
3462
3514
  [#2618]: https://github.com/DataDog/dd-trace-rb/issues/2618
3463
3515
  [#2619]: https://github.com/DataDog/dd-trace-rb/issues/2619
3516
+ [#2620]: https://github.com/DataDog/dd-trace-rb/issues/2620
3464
3517
  [#2634]: https://github.com/DataDog/dd-trace-rb/issues/2634
3465
3518
  [#2635]: https://github.com/DataDog/dd-trace-rb/issues/2635
3466
3519
  [#2642]: https://github.com/DataDog/dd-trace-rb/issues/2642
@@ -3488,6 +3541,7 @@ Git diff: https://github.com/DataDog/dd-trace-rb/compare/v0.3.0...v0.3.1
3488
3541
  [#2704]: https://github.com/DataDog/dd-trace-rb/issues/2704
3489
3542
  [#2705]: https://github.com/DataDog/dd-trace-rb/issues/2705
3490
3543
  [#2710]: https://github.com/DataDog/dd-trace-rb/issues/2710
3544
+ [#2711]: https://github.com/DataDog/dd-trace-rb/issues/2711
3491
3545
  [#2720]: https://github.com/DataDog/dd-trace-rb/issues/2720
3492
3546
  [#2726]: https://github.com/DataDog/dd-trace-rb/issues/2726
3493
3547
  [#2727]: https://github.com/DataDog/dd-trace-rb/issues/2727
@@ -3514,6 +3568,7 @@ Git diff: https://github.com/DataDog/dd-trace-rb/compare/v0.3.0...v0.3.1
3514
3568
  [#2805]: https://github.com/DataDog/dd-trace-rb/issues/2805
3515
3569
  [#2806]: https://github.com/DataDog/dd-trace-rb/issues/2806
3516
3570
  [#2810]: https://github.com/DataDog/dd-trace-rb/issues/2810
3571
+ [#2814]: https://github.com/DataDog/dd-trace-rb/issues/2814
3517
3572
  [#2815]: https://github.com/DataDog/dd-trace-rb/issues/2815
3518
3573
  [#2822]: https://github.com/DataDog/dd-trace-rb/issues/2822
3519
3574
  [#2824]: https://github.com/DataDog/dd-trace-rb/issues/2824
@@ -3521,6 +3576,7 @@ Git diff: https://github.com/DataDog/dd-trace-rb/compare/v0.3.0...v0.3.1
3521
3576
  [#2829]: https://github.com/DataDog/dd-trace-rb/issues/2829
3522
3577
  [#2836]: https://github.com/DataDog/dd-trace-rb/issues/2836
3523
3578
  [#2840]: https://github.com/DataDog/dd-trace-rb/issues/2840
3579
+ [#2848]: https://github.com/DataDog/dd-trace-rb/issues/2848
3524
3580
  [#2853]: https://github.com/DataDog/dd-trace-rb/issues/2853
3525
3581
  [#2854]: https://github.com/DataDog/dd-trace-rb/issues/2854
3526
3582
  [#2855]: https://github.com/DataDog/dd-trace-rb/issues/2855
@@ -3529,10 +3585,13 @@ Git diff: https://github.com/DataDog/dd-trace-rb/compare/v0.3.0...v0.3.1
3529
3585
  [#2860]: https://github.com/DataDog/dd-trace-rb/issues/2860
3530
3586
  [#2864]: https://github.com/DataDog/dd-trace-rb/issues/2864
3531
3587
  [#2866]: https://github.com/DataDog/dd-trace-rb/issues/2866
3588
+ [#2867]: https://github.com/DataDog/dd-trace-rb/issues/2867
3532
3589
  [#2869]: https://github.com/DataDog/dd-trace-rb/issues/2869
3533
3590
  [#2873]: https://github.com/DataDog/dd-trace-rb/issues/2873
3534
3591
  [#2874]: https://github.com/DataDog/dd-trace-rb/issues/2874
3535
3592
  [#2875]: https://github.com/DataDog/dd-trace-rb/issues/2875
3593
+ [#2877]: https://github.com/DataDog/dd-trace-rb/issues/2877
3594
+ [#2882]: https://github.com/DataDog/dd-trace-rb/issues/2882
3536
3595
  [#2883]: https://github.com/DataDog/dd-trace-rb/issues/2883
3537
3596
  [#2890]: https://github.com/DataDog/dd-trace-rb/issues/2890
3538
3597
  [#2891]: https://github.com/DataDog/dd-trace-rb/issues/2891
@@ -3541,6 +3600,44 @@ Git diff: https://github.com/DataDog/dd-trace-rb/compare/v0.3.0...v0.3.1
3541
3600
  [#2898]: https://github.com/DataDog/dd-trace-rb/issues/2898
3542
3601
  [#2900]: https://github.com/DataDog/dd-trace-rb/issues/2900
3543
3602
  [#2903]: https://github.com/DataDog/dd-trace-rb/issues/2903
3603
+ [#2913]: https://github.com/DataDog/dd-trace-rb/issues/2913
3604
+ [#2915]: https://github.com/DataDog/dd-trace-rb/issues/2915
3605
+ [#2926]: https://github.com/DataDog/dd-trace-rb/issues/2926
3606
+ [#2928]: https://github.com/DataDog/dd-trace-rb/issues/2928
3607
+ [#2931]: https://github.com/DataDog/dd-trace-rb/issues/2931
3608
+ [#2932]: https://github.com/DataDog/dd-trace-rb/issues/2932
3609
+ [#2935]: https://github.com/DataDog/dd-trace-rb/issues/2935
3610
+ [#2939]: https://github.com/DataDog/dd-trace-rb/issues/2939
3611
+ [#2940]: https://github.com/DataDog/dd-trace-rb/issues/2940
3612
+ [#2941]: https://github.com/DataDog/dd-trace-rb/issues/2941
3613
+ [#2946]: https://github.com/DataDog/dd-trace-rb/issues/2946
3614
+ [#2948]: https://github.com/DataDog/dd-trace-rb/issues/2948
3615
+ [#2950]: https://github.com/DataDog/dd-trace-rb/issues/2950
3616
+ [#2952]: https://github.com/DataDog/dd-trace-rb/issues/2952
3617
+ [#2956]: https://github.com/DataDog/dd-trace-rb/issues/2956
3618
+ [#2957]: https://github.com/DataDog/dd-trace-rb/issues/2957
3619
+ [#2959]: https://github.com/DataDog/dd-trace-rb/issues/2959
3620
+ [#2960]: https://github.com/DataDog/dd-trace-rb/issues/2960
3621
+ [#2961]: https://github.com/DataDog/dd-trace-rb/issues/2961
3622
+ [#2962]: https://github.com/DataDog/dd-trace-rb/issues/2962
3623
+ [#2967]: https://github.com/DataDog/dd-trace-rb/issues/2967
3624
+ [#2968]: https://github.com/DataDog/dd-trace-rb/issues/2968
3625
+ [#2971]: https://github.com/DataDog/dd-trace-rb/issues/2971
3626
+ [#2972]: https://github.com/DataDog/dd-trace-rb/issues/2972
3627
+ [#2973]: https://github.com/DataDog/dd-trace-rb/issues/2973
3628
+ [#2974]: https://github.com/DataDog/dd-trace-rb/issues/2974
3629
+ [#2977]: https://github.com/DataDog/dd-trace-rb/issues/2977
3630
+ [#2978]: https://github.com/DataDog/dd-trace-rb/issues/2978
3631
+ [#2982]: https://github.com/DataDog/dd-trace-rb/issues/2982
3632
+ [#2983]: https://github.com/DataDog/dd-trace-rb/issues/2983
3633
+ [#2988]: https://github.com/DataDog/dd-trace-rb/issues/2988
3634
+ [#2992]: https://github.com/DataDog/dd-trace-rb/issues/2992
3635
+ [#2993]: https://github.com/DataDog/dd-trace-rb/issues/2993
3636
+ [#2994]: https://github.com/DataDog/dd-trace-rb/issues/2994
3637
+ [#2999]: https://github.com/DataDog/dd-trace-rb/issues/2999
3638
+ [#3005]: https://github.com/DataDog/dd-trace-rb/issues/3005
3639
+ [#3007]: https://github.com/DataDog/dd-trace-rb/issues/3007
3640
+ [#3011]: https://github.com/DataDog/dd-trace-rb/issues/3011
3544
3641
  [@AdrianLC]: https://github.com/AdrianLC
3545
3642
  [@Azure7111]: https://github.com/Azure7111
3546
3643
  [@BabyGroot]: https://github.com/BabyGroot
@@ -3548,11 +3645,13 @@ Git diff: https://github.com/DataDog/dd-trace-rb/compare/v0.3.0...v0.3.1
3548
3645
  [@Drowze]: https://github.com/Drowze
3549
3646
  [@EpiFouloux]: https://github.com/EpiFouloux
3550
3647
  [@EvNomad]: https://github.com/EvNomad
3648
+ [@HeyNonster]: https://github.com/HeyNonster
3551
3649
  [@HoneyryderChuck]: https://github.com/HoneyryderChuck
3552
3650
  [@JamesHarker]: https://github.com/JamesHarker
3553
3651
  [@Jared-Prime]: https://github.com/Jared-Prime
3554
3652
  [@Joas1988]: https://github.com/Joas1988
3555
3653
  [@JustSnow]: https://github.com/JustSnow
3654
+ [@KJTsanaktsidis]: https://github.com/KJTsanaktsidis
3556
3655
  [@KieranP]: https://github.com/KieranP
3557
3656
  [@MMartyn]: https://github.com/MMartyn
3558
3657
  [@NobodysNightmare]: https://github.com/NobodysNightmare
@@ -3577,6 +3676,7 @@ Git diff: https://github.com/DataDog/dd-trace-rb/compare/v0.3.0...v0.3.1
3577
3676
  [@bheemreddy181]: https://github.com/bheemreddy181
3578
3677
  [@blaines]: https://github.com/blaines
3579
3678
  [@brafales]: https://github.com/brafales
3679
+ [@bravehager]: https://github.com/bravehager
3580
3680
  [@bzf]: https://github.com/bzf
3581
3681
  [@callumj]: https://github.com/callumj
3582
3682
  [@caramcc]: https://github.com/caramcc
@@ -63,8 +63,8 @@
63
63
  // allowed to happen during Ruby's garbage collection start/finish hooks.
64
64
  // ---
65
65
 
66
- #define INVALID_TIME -1
67
66
  #define THREAD_ID_LIMIT_CHARS 44 // Why 44? "#{2**64} (#{2**64})".size + 1 for \0
67
+ #define THREAD_INVOKE_LOCATION_LIMIT_CHARS 512
68
68
  #define IS_WALL_TIME true
69
69
  #define IS_NOT_WALL_TIME false
70
70
  #define MISSING_TRACER_CONTEXT_KEY 0
@@ -99,6 +99,12 @@ struct thread_context_collector_state {
99
99
  VALUE thread_list_buffer;
100
100
  // Used to omit endpoint names (retrieved from tracer) from collected data
101
101
  bool endpoint_collection_enabled;
102
+ // Used to omit timestamps / timeline events from collected data
103
+ bool timeline_enabled;
104
+ // Used when calling monotonic_to_system_epoch_ns
105
+ monotonic_to_system_epoch_state time_converter_state;
106
+ // Used to identify the main thread, to give it a fallback name
107
+ VALUE main_thread;
102
108
 
103
109
  struct stats {
104
110
  // Track how many garbage collection samples we've taken.
@@ -112,6 +118,8 @@ struct thread_context_collector_state {
112
118
  struct per_thread_context {
113
119
  char thread_id[THREAD_ID_LIMIT_CHARS];
114
120
  ddog_CharSlice thread_id_char_slice;
121
+ char thread_invoke_location[THREAD_INVOKE_LOCATION_LIMIT_CHARS];
122
+ ddog_CharSlice thread_invoke_location_char_slice;
115
123
  thread_cpu_time_id thread_cpu_time_id;
116
124
  long cpu_time_at_previous_sample_ns; // Can be INVALID_TIME until initialized or if getting it fails for another reason
117
125
  long wall_time_at_previous_sample_ns; // Can be INVALID_TIME until initialized
@@ -148,7 +156,8 @@ static VALUE _native_initialize(
148
156
  VALUE recorder_instance,
149
157
  VALUE max_frames,
150
158
  VALUE tracer_context_key,
151
- VALUE endpoint_collection_enabled
159
+ VALUE endpoint_collection_enabled,
160
+ VALUE timeline_enabled
152
161
  );
153
162
  static VALUE _native_sample(VALUE self, VALUE collector_instance, VALUE profiler_overhead_stack_thread);
154
163
  static VALUE _native_on_gc_start(VALUE self, VALUE collector_instance);
@@ -168,12 +177,13 @@ static void trigger_sample_for_thread(
168
177
  VALUE stack_from_thread,
169
178
  struct per_thread_context *thread_context,
170
179
  sample_values values,
171
- sample_type type
180
+ sample_type type,
181
+ long current_monotonic_wall_time_ns
172
182
  );
173
183
  static VALUE _native_thread_list(VALUE self);
174
184
  static struct per_thread_context *get_or_create_context_for(VALUE thread, struct thread_context_collector_state *state);
175
185
  static struct per_thread_context *get_context_for(VALUE thread, struct thread_context_collector_state *state);
176
- static void initialize_context(VALUE thread, struct per_thread_context *thread_context);
186
+ static void initialize_context(VALUE thread, struct per_thread_context *thread_context, struct thread_context_collector_state *state);
177
187
  static VALUE _native_inspect(VALUE self, VALUE collector_instance);
178
188
  static VALUE per_thread_context_st_table_as_ruby_hash(struct thread_context_collector_state *state);
179
189
  static int per_thread_context_as_ruby_hash(st_data_t key_thread, st_data_t value_context, st_data_t result_hash);
@@ -190,6 +200,7 @@ static bool is_type_web(VALUE root_span_type);
190
200
  static VALUE _native_reset_after_fork(DDTRACE_UNUSED VALUE self, VALUE collector_instance);
191
201
  static VALUE thread_list(struct thread_context_collector_state *state);
192
202
  static VALUE _native_sample_allocation(VALUE self, VALUE collector_instance, VALUE sample_weight);
203
+ static VALUE _native_new_empty_thread(VALUE self);
193
204
 
194
205
  void collectors_thread_context_init(VALUE profiling_module) {
195
206
  VALUE collectors_module = rb_define_module_under(profiling_module, "Collectors");
@@ -207,7 +218,7 @@ void collectors_thread_context_init(VALUE profiling_module) {
207
218
  // https://bugs.ruby-lang.org/issues/18007 for a discussion around this.
208
219
  rb_define_alloc_func(collectors_thread_context_class, _native_new);
209
220
 
210
- rb_define_singleton_method(collectors_thread_context_class, "_native_initialize", _native_initialize, 5);
221
+ rb_define_singleton_method(collectors_thread_context_class, "_native_initialize", _native_initialize, 6);
211
222
  rb_define_singleton_method(collectors_thread_context_class, "_native_inspect", _native_inspect, 1);
212
223
  rb_define_singleton_method(collectors_thread_context_class, "_native_reset_after_fork", _native_reset_after_fork, 1);
213
224
  rb_define_singleton_method(testing_module, "_native_sample", _native_sample, 2);
@@ -218,6 +229,7 @@ void collectors_thread_context_init(VALUE profiling_module) {
218
229
  rb_define_singleton_method(testing_module, "_native_thread_list", _native_thread_list, 0);
219
230
  rb_define_singleton_method(testing_module, "_native_per_thread_context", _native_per_thread_context, 1);
220
231
  rb_define_singleton_method(testing_module, "_native_stats", _native_stats, 1);
232
+ rb_define_singleton_method(testing_module, "_native_new_empty_thread", _native_new_empty_thread, 0);
221
233
 
222
234
  at_active_span_id = rb_intern_const("@active_span");
223
235
  at_active_trace_id = rb_intern_const("@active_trace");
@@ -249,6 +261,7 @@ static void thread_context_collector_typed_data_mark(void *state_ptr) {
249
261
  rb_gc_mark(state->recorder_instance);
250
262
  st_foreach(state->hash_map_per_thread_context, hash_map_per_thread_context_mark, 0 /* unused */);
251
263
  rb_gc_mark(state->thread_list_buffer);
264
+ rb_gc_mark(state->main_thread);
252
265
  }
253
266
 
254
267
  static void thread_context_collector_typed_data_free(void *state_ptr) {
@@ -294,6 +307,9 @@ static VALUE _native_new(VALUE klass) {
294
307
  state->tracer_context_key = MISSING_TRACER_CONTEXT_KEY;
295
308
  state->thread_list_buffer = rb_ary_new();
296
309
  state->endpoint_collection_enabled = true;
310
+ state->timeline_enabled = true;
311
+ state->time_converter_state = (monotonic_to_system_epoch_state) MONOTONIC_TO_SYSTEM_EPOCH_INITIALIZER;
312
+ state->main_thread = rb_thread_main();
297
313
 
298
314
  return TypedData_Wrap_Struct(klass, &thread_context_collector_typed_data, state);
299
315
  }
@@ -304,9 +320,11 @@ static VALUE _native_initialize(
304
320
  VALUE recorder_instance,
305
321
  VALUE max_frames,
306
322
  VALUE tracer_context_key,
307
- VALUE endpoint_collection_enabled
323
+ VALUE endpoint_collection_enabled,
324
+ VALUE timeline_enabled
308
325
  ) {
309
326
  ENFORCE_BOOLEAN(endpoint_collection_enabled);
327
+ ENFORCE_BOOLEAN(timeline_enabled);
310
328
 
311
329
  struct thread_context_collector_state *state;
312
330
  TypedData_Get_Struct(collector_instance, struct thread_context_collector_state, &thread_context_collector_typed_data, state);
@@ -319,6 +337,7 @@ static VALUE _native_initialize(
319
337
  // hash_map_per_thread_context is already initialized, nothing to do here
320
338
  state->recorder_instance = enforce_recorder_instance(recorder_instance);
321
339
  state->endpoint_collection_enabled = (endpoint_collection_enabled == Qtrue);
340
+ state->timeline_enabled = (timeline_enabled == Qtrue);
322
341
 
323
342
  if (RTEST(tracer_context_key)) {
324
343
  ENFORCE_TYPE(tracer_context_key, T_SYMBOL);
@@ -443,7 +462,8 @@ void update_metrics_and_sample(
443
462
  stack_from_thread,
444
463
  thread_context,
445
464
  (sample_values) {.cpu_time_ns = cpu_time_elapsed_ns, .cpu_samples = 1, .wall_time_ns = wall_time_elapsed_ns},
446
- SAMPLE_REGULAR
465
+ SAMPLE_REGULAR,
466
+ current_monotonic_wall_time_ns
447
467
  );
448
468
  }
449
469
 
@@ -585,7 +605,8 @@ VALUE thread_context_collector_sample_after_gc(VALUE self_instance) {
585
605
  /* stack_from_thread: */ thread,
586
606
  thread_context,
587
607
  (sample_values) {.cpu_time_ns = gc_cpu_time_elapsed_ns, .cpu_samples = 1, .wall_time_ns = gc_wall_time_elapsed_ns},
588
- SAMPLE_IN_GC
608
+ SAMPLE_IN_GC,
609
+ INVALID_TIME // For now we're not collecting timestamps for these events
589
610
  );
590
611
 
591
612
  // Mark thread as no longer in GC
@@ -615,12 +636,14 @@ static void trigger_sample_for_thread(
615
636
  VALUE stack_from_thread, // This can be different when attributing profiler overhead using a different stack
616
637
  struct per_thread_context *thread_context,
617
638
  sample_values values,
618
- sample_type type
639
+ sample_type type,
640
+ long current_monotonic_wall_time_ns
619
641
  ) {
620
642
  int max_label_count =
621
643
  1 + // thread id
622
644
  1 + // thread name
623
645
  1 + // profiler overhead
646
+ 1 + // end_timestamp_ns
624
647
  2; // local root span id and span id
625
648
  ddog_prof_Label labels[max_label_count];
626
649
  int label_pos = 0;
@@ -636,6 +659,19 @@ static void trigger_sample_for_thread(
636
659
  .key = DDOG_CHARSLICE_C("thread name"),
637
660
  .str = char_slice_from_ruby_string(thread_name)
638
661
  };
662
+ } else if (thread == state->main_thread) { // Threads are often not named, but we can have a nice fallback for this special thread
663
+ ddog_CharSlice main_thread_name = DDOG_CHARSLICE_C("main");
664
+ labels[label_pos++] = (ddog_prof_Label) {
665
+ .key = DDOG_CHARSLICE_C("thread name"),
666
+ .str = main_thread_name
667
+ };
668
+ } else {
669
+ // For other threads without name, we use the "invoke location" (first file:line of the block used to start the thread), if any.
670
+ // This is what Ruby shows in `Thread#to_s`.
671
+ labels[label_pos++] = (ddog_prof_Label) {
672
+ .key = DDOG_CHARSLICE_C("thread name"),
673
+ .str = thread_context->thread_invoke_location_char_slice // This is an empty string if no invoke location was available
674
+ };
639
675
  }
640
676
 
641
677
  struct trace_identifiers trace_identifiers_result = {.valid = false, .trace_endpoint = Qnil};
@@ -670,10 +706,17 @@ static void trigger_sample_for_thread(
670
706
  };
671
707
  }
672
708
 
709
+ if (state->timeline_enabled && current_monotonic_wall_time_ns != INVALID_TIME) {
710
+ labels[label_pos++] = (ddog_prof_Label) {
711
+ .key = DDOG_CHARSLICE_C("end_timestamp_ns"),
712
+ .num = monotonic_to_system_epoch_ns(&state->time_converter_state, current_monotonic_wall_time_ns)
713
+ };
714
+ }
715
+
673
716
  // The number of times `label_pos++` shows up in this function needs to match `max_label_count`. To avoid "oops I
674
717
  // forgot to update max_label_count" in the future, we've also added this validation.
675
- // @ivoanjo: I wonder if C compilers are smart enough to statically prove when this check never triggers happens and
676
- // remove it entirely.
718
+ // @ivoanjo: I wonder if C compilers are smart enough to statically prove this check never triggers unless someone
719
+ // changes the code erroneously and remove it entirely?
677
720
  if (label_pos > max_label_count) {
678
721
  rb_raise(rb_eRuntimeError, "BUG: Unexpected label_pos (%d) > max_label_count (%d)", label_pos, max_label_count);
679
722
  }
@@ -704,7 +747,7 @@ static struct per_thread_context *get_or_create_context_for(VALUE thread, struct
704
747
  thread_context = (struct per_thread_context*) value_context;
705
748
  } else {
706
749
  thread_context = ruby_xcalloc(1, sizeof(struct per_thread_context));
707
- initialize_context(thread, thread_context);
750
+ initialize_context(thread, thread_context, state);
708
751
  st_insert(state->hash_map_per_thread_context, (st_data_t) thread, (st_data_t) thread_context);
709
752
  }
710
753
 
@@ -722,10 +765,32 @@ static struct per_thread_context *get_context_for(VALUE thread, struct thread_co
722
765
  return thread_context;
723
766
  }
724
767
 
725
- static void initialize_context(VALUE thread, struct per_thread_context *thread_context) {
768
+ static void initialize_context(VALUE thread, struct per_thread_context *thread_context, struct thread_context_collector_state *state) {
726
769
  snprintf(thread_context->thread_id, THREAD_ID_LIMIT_CHARS, "%"PRIu64" (%lu)", native_thread_id_for(thread), (unsigned long) thread_id_for(thread));
727
770
  thread_context->thread_id_char_slice = (ddog_CharSlice) {.ptr = thread_context->thread_id, .len = strlen(thread_context->thread_id)};
728
771
 
772
+ int invoke_line_location;
773
+ VALUE invoke_file_location = invoke_location_for(thread, &invoke_line_location);
774
+ if (invoke_file_location != Qnil) {
775
+ snprintf(
776
+ thread_context->thread_invoke_location,
777
+ THREAD_INVOKE_LOCATION_LIMIT_CHARS,
778
+ "%s:%d",
779
+ StringValueCStr(invoke_file_location),
780
+ invoke_line_location
781
+ );
782
+ } else if (thread != state->main_thread) {
783
+ // If the first function of a thread is native code, there won't be an invoke location, so we use this fallback.
784
+ // NOTE: In the future, I wonder if we could take the pointer to the native function, and try to see if there's a native
785
+ // symbol attached to it.
786
+ snprintf(thread_context->thread_invoke_location, THREAD_INVOKE_LOCATION_LIMIT_CHARS, "%s", "(Unnamed thread from native code)");
787
+ }
788
+
789
+ thread_context->thread_invoke_location_char_slice = (ddog_CharSlice) {
790
+ .ptr = thread_context->thread_invoke_location,
791
+ .len = strlen(thread_context->thread_invoke_location)
792
+ };
793
+
729
794
  thread_context->thread_cpu_time_id = thread_cpu_time_id_for(thread);
730
795
 
731
796
  // These will get initialized during actual sampling
@@ -753,6 +818,13 @@ static VALUE _native_inspect(DDTRACE_UNUSED VALUE _self, VALUE collector_instanc
753
818
  rb_str_concat(result, rb_sprintf(" sample_count=%u", state->sample_count));
754
819
  rb_str_concat(result, rb_sprintf(" stats=%"PRIsVALUE, stats_as_ruby_hash(state)));
755
820
  rb_str_concat(result, rb_sprintf(" endpoint_collection_enabled=%"PRIsVALUE, state->endpoint_collection_enabled ? Qtrue : Qfalse));
821
+ rb_str_concat(result, rb_sprintf(" timeline_enabled=%"PRIsVALUE, state->timeline_enabled ? Qtrue : Qfalse));
822
+ rb_str_concat(result, rb_sprintf(
823
+ " time_converter_state={.system_epoch_ns_reference=%ld, .delta_to_epoch_ns=%ld}",
824
+ state->time_converter_state.system_epoch_ns_reference,
825
+ state->time_converter_state.delta_to_epoch_ns
826
+ ));
827
+ rb_str_concat(result, rb_sprintf(" main_thread=%"PRIsVALUE, state->main_thread));
756
828
 
757
829
  return result;
758
830
  }
@@ -772,6 +844,7 @@ static int per_thread_context_as_ruby_hash(st_data_t key_thread, st_data_t value
772
844
 
773
845
  VALUE arguments[] = {
774
846
  ID2SYM(rb_intern("thread_id")), /* => */ rb_str_new2(thread_context->thread_id),
847
+ ID2SYM(rb_intern("thread_invoke_location")), /* => */ rb_str_new2(thread_context->thread_invoke_location),
775
848
  ID2SYM(rb_intern("thread_cpu_time_id_valid?")), /* => */ thread_context->thread_cpu_time_id.valid ? Qtrue : Qfalse,
776
849
  ID2SYM(rb_intern("thread_cpu_time_id")), /* => */ CLOCKID2NUM(thread_context->thread_cpu_time_id.clock_id),
777
850
  ID2SYM(rb_intern("cpu_time_at_previous_sample_ns")), /* => */ LONG2NUM(thread_context->cpu_time_at_previous_sample_ns),
@@ -989,7 +1062,8 @@ void thread_context_collector_sample_allocation(VALUE self_instance, unsigned in
989
1062
  /* stack_from_thread: */ current_thread,
990
1063
  get_or_create_context_for(current_thread, state),
991
1064
  (sample_values) {.alloc_samples = sample_weight},
992
- SAMPLE_REGULAR
1065
+ SAMPLE_REGULAR,
1066
+ INVALID_TIME // For now we're not collecting timestamps for allocation events, as per profiling team internal discussions
993
1067
  );
994
1068
  }
995
1069
 
@@ -999,3 +1073,12 @@ static VALUE _native_sample_allocation(DDTRACE_UNUSED VALUE self, VALUE collecto
999
1073
  thread_context_collector_sample_allocation(collector_instance, NUM2UINT(sample_weight));
1000
1074
  return Qtrue;
1001
1075
  }
1076
+
1077
+ static VALUE new_empty_thread_inner(DDTRACE_UNUSED void *arg) { return Qnil; }
1078
+
1079
+ // This method exists only to enable testing Datadog::Profiling::Collectors::ThreadContext behavior using RSpec.
1080
+ // It SHOULD NOT be used for other purposes.
1081
+ // (It creates an empty native thread, so we can test our native thread naming fallback)
1082
+ static VALUE _native_new_empty_thread(DDTRACE_UNUSED VALUE self) {
1083
+ return rb_thread_create(new_empty_thread_inner, NULL);
1084
+ }
@@ -143,6 +143,9 @@ $defs << '-DNO_RB_NATIVE_THREAD' if RUBY_VERSION < '3.2'
143
143
  # On older Rubies, there was no struct rb_thread_sched (it was struct rb_global_vm_lock_struct)
144
144
  $defs << '-DNO_RB_THREAD_SCHED' if RUBY_VERSION < '3.2'
145
145
 
146
+ # On older Rubies, the first_lineno inside a location was a VALUE and not a int (https://github.com/ruby/ruby/pull/6430)
147
+ $defs << '-DNO_INT_FIRST_LINENO' if RUBY_VERSION < '3.2'
148
+
146
149
  # On older Rubies, there was no tid member in the internal thread structure
147
150
  $defs << '-DNO_THREAD_TID' if RUBY_VERSION < '3.1'
148
151
 
@@ -155,6 +158,9 @@ $defs << '-DNO_RACTORS' if RUBY_VERSION < '3'
155
158
  # On older Rubies, rb_global_vm_lock_struct did not include the owner field
156
159
  $defs << '-DNO_GVL_OWNER' if RUBY_VERSION < '2.6'
157
160
 
161
+ # On older Rubies, there was no thread->invoke_arg
162
+ $defs << '-DNO_THREAD_INVOKE_ARG' if RUBY_VERSION < '2.6'
163
+
158
164
  # On older Rubies, we need to use rb_thread_t instead of rb_execution_context_t
159
165
  $defs << '-DUSE_THREAD_INSTEAD_OF_EXECUTION_CONTEXT' if RUBY_VERSION < '2.5'
160
166
 
@@ -46,7 +46,8 @@ static VALUE _native_do_export(
46
46
  VALUE pprof_data,
47
47
  VALUE code_provenance_file_name,
48
48
  VALUE code_provenance_data,
49
- VALUE tags_as_array
49
+ VALUE tags_as_array,
50
+ VALUE internal_metadata_json
50
51
  );
51
52
  static void *call_exporter_without_gvl(void *call_args);
52
53
  static void interrupt_exporter_call(void *cancel_token);
@@ -56,7 +57,7 @@ void http_transport_init(VALUE profiling_module) {
56
57
  http_transport_class = rb_define_class_under(profiling_module, "HttpTransport", rb_cObject);
57
58
 
58
59
  rb_define_singleton_method(http_transport_class, "_native_validate_exporter", _native_validate_exporter, 1);
59
- rb_define_singleton_method(http_transport_class, "_native_do_export", _native_do_export, 11);
60
+ rb_define_singleton_method(http_transport_class, "_native_do_export", _native_do_export, 12);
60
61
 
61
62
  ok_symbol = ID2SYM(rb_intern_const("ok"));
62
63
  error_symbol = ID2SYM(rb_intern_const("error"));
@@ -202,11 +203,20 @@ static VALUE perform_export(
202
203
  ddog_Timespec finish,
203
204
  ddog_prof_Exporter_Slice_File slice_files,
204
205
  ddog_Vec_Tag *additional_tags,
206
+ ddog_CharSlice internal_metadata,
205
207
  uint64_t timeout_milliseconds
206
208
  ) {
207
209
  ddog_prof_ProfiledEndpointsStats *endpoints_stats = NULL; // Not in use yet
208
- ddog_prof_Exporter_Request_BuildResult build_result =
209
- ddog_prof_Exporter_Request_build(exporter, start, finish, slice_files, additional_tags, endpoints_stats, timeout_milliseconds);
210
+ ddog_prof_Exporter_Request_BuildResult build_result = ddog_prof_Exporter_Request_build(
211
+ exporter,
212
+ start,
213
+ finish,
214
+ slice_files,
215
+ additional_tags,
216
+ endpoints_stats,
217
+ &internal_metadata,
218
+ timeout_milliseconds
219
+ );
210
220
 
211
221
  if (build_result.tag == DDOG_PROF_EXPORTER_REQUEST_BUILD_RESULT_ERR) {
212
222
  ddog_prof_Exporter_drop(exporter);
@@ -274,7 +284,8 @@ static VALUE _native_do_export(
274
284
  VALUE pprof_data,
275
285
  VALUE code_provenance_file_name,
276
286
  VALUE code_provenance_data,
277
- VALUE tags_as_array
287
+ VALUE tags_as_array,
288
+ VALUE internal_metadata_json
278
289
  ) {
279
290
  ENFORCE_TYPE(upload_timeout_milliseconds, T_FIXNUM);
280
291
  ENFORCE_TYPE(start_timespec_seconds, T_FIXNUM);
@@ -284,6 +295,7 @@ static VALUE _native_do_export(
284
295
  ENFORCE_TYPE(pprof_file_name, T_STRING);
285
296
  ENFORCE_TYPE(pprof_data, T_STRING);
286
297
  ENFORCE_TYPE(code_provenance_file_name, T_STRING);
298
+ ENFORCE_TYPE(internal_metadata_json, T_STRING);
287
299
 
288
300
  // Code provenance can be disabled and in that case will be set to nil
289
301
  bool have_code_provenance = !NIL_P(code_provenance_data);
@@ -312,6 +324,7 @@ static VALUE _native_do_export(
312
324
  }
313
325
 
314
326
  ddog_Vec_Tag *null_additional_tags = NULL;
327
+ ddog_CharSlice internal_metadata = char_slice_from_ruby_string(internal_metadata_json);
315
328
 
316
329
  ddog_prof_Exporter_NewResult exporter_result = create_exporter(exporter_configuration, tags_as_array);
317
330
  // Note: Do not add anything that can raise exceptions after this line, as otherwise the exporter memory will leak
@@ -319,7 +332,7 @@ static VALUE _native_do_export(
319
332
  VALUE failure_tuple = handle_exporter_failure(exporter_result);
320
333
  if (!NIL_P(failure_tuple)) return failure_tuple;
321
334
 
322
- return perform_export(exporter_result.ok, start, finish, slice_files, null_additional_tags, timeout_milliseconds);
335
+ return perform_export(exporter_result.ok, start, finish, slice_files, null_additional_tags, internal_metadata, timeout_milliseconds);
323
336
  }
324
337
 
325
338
  static void *call_exporter_without_gvl(void *call_args) {
@@ -15,7 +15,7 @@ module Datadog
15
15
  # The MJIT header was introduced on 2.6 and removed on 3.3; for other Rubies we rely on debase-ruby_core_source
16
16
  CAN_USE_MJIT_HEADER = RUBY_VERSION.start_with?('2.6', '2.7', '3.0.', '3.1.', '3.2.')
17
17
 
18
- LIBDATADOG_VERSION = '~> 2.0.0.1.0'
18
+ LIBDATADOG_VERSION = '~> 3.0.0.1.0'
19
19
 
20
20
  def self.fail_install_if_missing_extension?
21
21
  ENV[ENV_FAIL_INSTALL_IF_MISSING_EXTENSION].to_s.strip.downcase == 'true'