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
@@ -26,6 +26,53 @@ module Datadog
26
26
  end
27
27
  end
28
28
  end
29
+
30
+ # A minimal {Hash} wrapper that provides case-insensitive access
31
+ # to hash keys, without the overhead of copying the original hash.
32
+ #
33
+ # This class should be used when the original hash is short lived *and*
34
+ # each hash key is only accesses a few times.
35
+ # For other cases, create a copy of the original hash with the keys
36
+ # normalized adequate to your use case.
37
+ class CaseInsensitiveWrapper
38
+ def initialize(hash)
39
+ raise ArgumentError, "must be a hash, but was #{hash.class}: #{hash.inspect}" unless hash.is_a?(::Hash)
40
+
41
+ @hash = hash
42
+ end
43
+
44
+ def [](key)
45
+ return nil unless key.is_a?(::String)
46
+
47
+ @hash.each do |k, value|
48
+ return value if key.casecmp(k) == 0
49
+ end
50
+
51
+ nil
52
+ end
53
+
54
+ def key?(key)
55
+ return false unless key.is_a?(::String)
56
+
57
+ @hash.each_key do |k|
58
+ return true if key.casecmp(k) == 0
59
+ end
60
+
61
+ false
62
+ end
63
+
64
+ def empty?
65
+ @hash.empty?
66
+ end
67
+
68
+ def length
69
+ @hash.length
70
+ end
71
+
72
+ def original_hash
73
+ @hash
74
+ end
75
+ end
29
76
  end
30
77
  end
31
78
  end
@@ -101,7 +101,7 @@ module Datadog
101
101
  end
102
102
 
103
103
  def strip_ipv6_port(ip)
104
- if /\[(.*)\](?::\d+)?/ =~ ip
104
+ if /\[([^\]]*+)\](?::\d+)?/ =~ ip
105
105
  Regexp.last_match(1)
106
106
  else
107
107
  ip
@@ -1,40 +1,47 @@
1
+ require_relative '../backport'
2
+
1
3
  module Datadog
2
4
  module Core
3
5
  module Utils
4
6
  # Helper methods for safer dup
5
7
  module SafeDup
6
- if RUBY_VERSION < '2.2' # nil.dup only fails in Ruby 2.1
7
- # Ensures #initialize can call nil.dup safely
8
- module RefineNil
9
- refine NilClass do
10
- def dup
11
- self
12
- end
13
- end
14
- end
15
-
16
- using RefineNil
17
- end
18
-
19
8
  # String#+@ was introduced in Ruby 2.3
20
9
  if String.method_defined?(:+@) && String.method_defined?(:-@)
21
10
  def self.frozen_or_dup(v)
22
- # If the string is not frozen, the +(-v) will:
23
- # - first create a frozen deduplicated copy with -v
24
- # - then it will dup it more efficiently with +v
25
- v.frozen? ? v : +(-v)
11
+ # For the case of a String we use the methods +@ and -@.
12
+ # Those methods are only for String objects
13
+ # they are faster and chepaer on the memory side.
14
+ # Check the benchmark on
15
+ # https://github.com/DataDog/dd-trace-rb/pull/2704
16
+ if v.is_a?(String)
17
+ # If the string is not frozen, the +(-v) will:
18
+ # - first create a frozen deduplicated copy with -v
19
+ # - then it will dup it more efficiently with +v
20
+ v.frozen? ? v : +(-v)
21
+ else
22
+ v.frozen? ? v : Core::BackportFrom24.dup(v)
23
+ end
26
24
  end
27
25
 
28
26
  def self.frozen_dup(v)
29
- -v if v
27
+ # For the case of a String we use the methods -@
28
+ # That method are only for String objects
29
+ # they are faster and chepaer on the memory side.
30
+ # Check the benchmark on
31
+ # https://github.com/DataDog/dd-trace-rb/pull/2704
32
+ if v.is_a?(String)
33
+ -v if v
34
+ else
35
+ v.frozen? ? v : Core::BackportFrom24.dup(v).freeze
36
+ end
30
37
  end
31
38
  else
32
39
  def self.frozen_or_dup(v)
33
- v.frozen? ? v : v.dup
40
+ v.frozen? ? v : Core::BackportFrom24.dup(v)
34
41
  end
35
42
 
36
43
  def self.frozen_dup(v)
37
- v.frozen? ? v : v.dup.freeze
44
+ v.frozen? ? v : Core::BackportFrom24.dup(v).freeze
38
45
  end
39
46
  end
40
47
  end
@@ -67,7 +67,7 @@ module Datadog
67
67
  # @!visibility private
68
68
  def self.without_warnings
69
69
  # This is typically used when monkey patching functions such as
70
- # intialize, which Ruby advices you not to. Use cautiously.
70
+ # initialize, which Ruby advices you not to. Use cautiously.
71
71
  v = $VERBOSE
72
72
  $VERBOSE = nil
73
73
  begin
@@ -90,7 +90,7 @@ module Datadog
90
90
  :result
91
91
 
92
92
  def mutex
93
- @mutex || MUTEX_INIT.synchronize { @mutex ||= Mutex.new }
93
+ (defined?(@mutex) && @mutex) || MUTEX_INIT.synchronize { @mutex ||= Mutex.new }
94
94
  end
95
95
 
96
96
  def after_fork
@@ -103,7 +103,7 @@ module Datadog
103
103
  :pid
104
104
 
105
105
  def mutex_after_fork
106
- @mutex_after_fork || MUTEX_INIT.synchronize { @mutex_after_fork ||= Mutex.new }
106
+ (defined?(@mutex_after_fork) && @mutex_after_fork) || MUTEX_INIT.synchronize { @mutex_after_fork ||= Mutex.new }
107
107
  end
108
108
 
109
109
  def worker
@@ -9,109 +9,159 @@ module Datadog
9
9
  module Events
10
10
  LOGIN_SUCCESS_EVENT = 'users.login.success'
11
11
  LOGIN_FAILURE_EVENT = 'users.login.failure'
12
-
13
- # Attach login success event information to the trace
14
- #
15
- # This method is experimental and may change in the future.
16
- #
17
- # @param trace [TraceOperation] Trace to attach data to. Defaults to
18
- # active trace.
19
- # @param span [SpanOperation] Span to attach data to. Defaults to
20
- # active span on trace. Note that this should be a service entry span.
21
- # When AppSec is enabled, the expected span and trace are automatically
22
- # used as defaults.
23
- # @param user [Hash<Symbol, String>] User information to pass to
24
- # Datadog::Kit::Identity.set_user. Must contain at least :id as key.
25
- # @param others [Hash<String || Symbol, String>] Additional free-form
26
- # event information to attach to the trace.
27
- def self.track_login_success(trace = nil, span = nil, user:, **others)
28
- if (appsec_scope = Datadog::AppSec.active_scope)
29
- trace = appsec_scope.trace
30
- span = appsec_scope.service_entry_span
12
+ SIGNUP_EVENT = 'users.signup'
13
+
14
+ class << self
15
+ # Attach login success event information to the trace
16
+ #
17
+ # This method is experimental and may change in the future.
18
+ #
19
+ # @param trace [TraceOperation] Trace to attach data to. Defaults to
20
+ # active trace.
21
+ # @param span [SpanOperation] Span to attach data to. Defaults to
22
+ # active span on trace. Note that this should be a service entry span.
23
+ # When AppSec is enabled, the expected span and trace are automatically
24
+ # used as defaults.
25
+ # @param user [Hash<Symbol, String>] User information to pass to
26
+ # Datadog::Kit::Identity.set_user. Must contain at least :id as key.
27
+ # @param others [Hash<String || Symbol, String>] Additional free-form
28
+ # event information to attach to the trace.
29
+ def track_login_success(trace = nil, span = nil, user:, **others)
30
+ set_trace_and_span_context('track_login_success', trace, span) do |active_trace, active_span|
31
+ user_options = user.dup
32
+ user_id = user_options.delete(:id)
33
+
34
+ raise ArgumentError, 'missing required key: :user => { :id }' if user_id.nil?
35
+
36
+ track(LOGIN_SUCCESS_EVENT, active_trace, active_span, **others)
37
+
38
+ Kit::Identity.set_user(active_trace, active_span, id: user_id, **user_options)
39
+ end
31
40
  end
32
41
 
33
- trace ||= Datadog::Tracing.active_trace
34
- span ||= trace.active_span || Datadog::Tracing.active_span
35
-
36
- raise ArgumentError, "span #{span.span_id} does not belong to trace #{trace.id}" if trace.id != span.trace_id
37
-
38
- track(LOGIN_SUCCESS_EVENT, trace, span, **others)
39
-
40
- user_options = user.dup
41
- user_id = user_options.delete(:id)
42
-
43
- raise ArgumentError, 'missing required key: :user => { :id }' if user_id.nil?
42
+ # Attach login failure event information to the trace
43
+ #
44
+ # This method is experimental and may change in the future.
45
+ #
46
+ # @param trace [TraceOperation] Trace to attach data to. Defaults to
47
+ # active trace.
48
+ # @param span [SpanOperation] Span to attach data to. Defaults to
49
+ # active span on trace. Note that this should be a service entry span.
50
+ # When AppSec is enabled, the expected span and trace are automatically
51
+ # used as defaults.
52
+ # @param user_id [String] User id that attempted login
53
+ # @param user_exists [bool] Whether the user id that did a login attempt exists.
54
+ # @param others [Hash<String || Symbol, String>] Additional free-form
55
+ # event information to attach to the trace.
56
+ def track_login_failure(trace = nil, span = nil, user_id:, user_exists:, **others)
57
+ set_trace_and_span_context('track_login_failure', trace, span) do |active_trace, active_span|
58
+ raise ArgumentError, 'user_id cannot be nil' if user_id.nil?
59
+
60
+ track(LOGIN_FAILURE_EVENT, active_trace, active_span, **others)
61
+
62
+ active_span.set_tag('appsec.events.users.login.failure.usr.id', user_id)
63
+ active_span.set_tag('appsec.events.users.login.failure.usr.exists', user_exists)
64
+ end
65
+ end
44
66
 
45
- Kit::Identity.set_user(trace, span, id: user_id, **user_options)
46
- end
67
+ # Attach signup event information to the trace
68
+ #
69
+ # This method is experimental and may change in the future.
70
+ #
71
+ # @param trace [TraceOperation] Trace to attach data to. Defaults to
72
+ # active trace.
73
+ # @param span [SpanOperation] Span to attach data to. Defaults to
74
+ # active span on trace. Note that this should be a service entry span.
75
+ # When AppSec is enabled, the expected span and trace are automatically
76
+ # used as defaults.
77
+ # @param user [Hash<Symbol, String>] User information to pass to
78
+ # Datadog::Kit::Identity.set_user. Must contain at least :id as key.
79
+ # @param others [Hash<String || Symbol, String>] Additional free-form
80
+ # event information to attach to the trace.
81
+ def track_signup(trace = nil, span = nil, user:, **others)
82
+ set_trace_and_span_context('track_signup', trace, span) do |active_trace, active_span|
83
+ user_options = user.dup
84
+ user_id = user_options.delete(:id)
85
+
86
+ raise ArgumentError, 'missing required key: :user => { :id }' if user_id.nil?
87
+
88
+ track(SIGNUP_EVENT, active_trace, active_span, **others)
89
+
90
+ Kit::Identity.set_user(trace, id: user_id, **user_options)
91
+ end
92
+ end
47
93
 
48
- # Attach login failure event information to the trace
49
- #
50
- # This method is experimental and may change in the future.
51
- #
52
- # @param trace [TraceOperation] Trace to attach data to. Defaults to
53
- # active trace.
54
- # @param span [SpanOperation] Span to attach data to. Defaults to
55
- # active span on trace. Note that this should be a service entry span.
56
- # When AppSec is enabled, the expected span and trace are automatically
57
- # used as defaults.
58
- # @param user_id [String] User id that attempted login
59
- # @param user_exists [bool] Whether the user id that did a login attempt exists.
60
- # @param others [Hash<String || Symbol, String>] Additional free-form
61
- # event information to attach to the trace.
62
- def self.track_login_failure(trace = nil, span = nil, user_id:, user_exists:, **others)
63
- if (appsec_scope = Datadog::AppSec.active_scope)
64
- trace = appsec_scope.trace
65
- span = appsec_scope.service_entry_span
94
+ # Attach custom event information to the trace
95
+ #
96
+ # This method is experimental and may change in the future.
97
+ #
98
+ # @param event [String] Mandatory. Event code.
99
+ # @param trace [TraceOperation] Trace to attach data to. Defaults to
100
+ # active trace.
101
+ # @param span [SpanOperation] Span to attach data to. Defaults to
102
+ # active span on trace. Note that this should be a service entry span.
103
+ # When AppSec is enabled, the expected span and trace are automatically
104
+ # used as defaults.
105
+ # @param others [Hash<Symbol, String>] Additional free-form
106
+ # event information to attach to the trace. Key must not
107
+ # be :track.
108
+ def track(event, trace = nil, span = nil, **others)
109
+ if trace && span
110
+ check_trace_span_integrity(trace, span)
111
+
112
+ span.set_tag("appsec.events.#{event}.track", 'true')
113
+ span.set_tag("_dd.appsec.events.#{event}.sdk", 'true')
114
+
115
+ others.each do |k, v|
116
+ raise ArgumentError, 'key cannot be :track' if k.to_sym == :track
117
+
118
+ span.set_tag("appsec.events.#{event}.#{k}", v) unless v.nil?
119
+ end
120
+
121
+ trace.keep!
122
+ else
123
+ set_trace_and_span_context('track', trace, span) do |active_trace, active_span|
124
+ active_span.set_tag("appsec.events.#{event}.track", 'true')
125
+ active_span.set_tag("_dd.appsec.events.#{event}.sdk", 'true')
126
+
127
+ others.each do |k, v|
128
+ raise ArgumentError, 'key cannot be :track' if k.to_sym == :track
129
+
130
+ active_span.set_tag("appsec.events.#{event}.#{k}", v) unless v.nil?
131
+ end
132
+
133
+ active_trace.keep!
134
+ end
135
+ end
66
136
  end
67
137
 
68
- trace ||= Datadog::Tracing.active_trace
69
- span ||= trace.active_span || Datadog::Tracing.active_span
138
+ private
70
139
 
71
- raise ArgumentError, "span #{span.span_id} does not belong to trace #{trace.id}" if trace.id != span.trace_id
140
+ def set_trace_and_span_context(method, trace = nil, span = nil)
141
+ if (appsec_scope = Datadog::AppSec.active_scope)
142
+ trace = appsec_scope.trace
143
+ span = appsec_scope.service_entry_span
144
+ end
72
145
 
73
- track(LOGIN_FAILURE_EVENT, trace, span, **others)
146
+ trace ||= Datadog::Tracing.active_trace
147
+ span ||= trace && trace.active_span || Datadog::Tracing.active_span
74
148
 
75
- raise ArgumentError, 'user_id cannot be nil' if user_id.nil?
149
+ unless trace && span
150
+ Datadog.logger.debug(
151
+ "Tracing not enabled. Method ##{method} is a no-op. Please enable tracing if you want ##{method}"\
152
+ ' to track this events'
153
+ )
154
+ return
155
+ end
76
156
 
77
- span.set_tag('appsec.events.users.login.failure.usr.id', user_id)
78
- span.set_tag('appsec.events.users.login.failure.usr.exists', user_exists)
79
- end
157
+ check_trace_span_integrity(trace, span)
80
158
 
81
- # Attach custom event information to the trace
82
- #
83
- # This method is experimental and may change in the future.
84
- #
85
- # @param event [String] Mandatory. Event code.
86
- # @param trace [TraceOperation] Trace to attach data to. Defaults to
87
- # active trace.
88
- # @param span [SpanOperation] Span to attach data to. Defaults to
89
- # active span on trace. Note that this should be a service entry span.
90
- # When AppSec is enabled, the expected span and trace are automatically
91
- # used as defaults.
92
- # @param others [Hash<Symbol, String>] Additional free-form
93
- # event information to attach to the trace. Key must not
94
- # be :track.
95
- def self.track(event, trace = nil, span = nil, **others)
96
- if (appsec_scope = Datadog::AppSec.active_scope)
97
- trace = appsec_scope.trace
98
- span = appsec_scope.service_entry_span
159
+ yield(trace, span)
99
160
  end
100
161
 
101
- trace ||= Datadog::Tracing.active_trace
102
- span ||= trace.active_span || Datadog::Tracing.active_span
103
-
104
- raise ArgumentError, "span #{span.span_id} does not belong to trace #{trace.id}" if trace.id != span.trace_id
105
-
106
- span.set_tag("appsec.events.#{event}.track", 'true')
107
-
108
- others.each do |k, v|
109
- raise ArgumentError, 'key cannot be :track' if k.to_sym == :track
110
-
111
- span.set_tag("appsec.events.#{event}.#{k}", v) unless v.nil?
162
+ def check_trace_span_integrity(trace, span)
163
+ raise ArgumentError, "span #{span.span_id} does not belong to trace #{trace.id}" if trace.id != span.trace_id
112
164
  end
113
-
114
- trace.keep!
115
165
  end
116
166
  end
117
167
  end
@@ -6,84 +6,99 @@ module Datadog
6
6
  module Kit
7
7
  # Tracking identity via traces
8
8
  module Identity
9
- # Attach user information to the trace
10
- #
11
- # @param trace [TraceOperation] Trace to attach data to. Defaults to
12
- # active trace.
13
- # @param span [SpanOperation] Span to attach data to. Defaults to
14
- # active span on trace. Note that this should be a service entry span.
15
- # When AppSec is enabled, the expected span and trace are automatically
16
- # used as defaults.
17
- # @param id [String] Mandatory. Username or client id extracted
18
- # from the access token or Authorization header in the inbound request
19
- # from outside the system.
20
- # @param email [String] Email of the authenticated user associated
21
- # to the trace.
22
- # @param name [String] User-friendly name. To be displayed in the
23
- # UI if set.
24
- # @param session_id [String] Session ID of the authenticated user.
25
- # @param role [String] Actual/assumed role the client is making
26
- # the request under extracted from token or application security
27
- # context.
28
- # @param scope [String] Scopes or granted authorities the client
29
- # currently possesses extracted from token or application security
30
- # context. The value would come from the scope associated with an OAuth
31
- # 2.0 Access Token or an attribute value in a SAML 2.0 Assertion.
32
- # @param others [Hash<Symbol, String>] Additional free-form
33
- # user information to attach to the trace.
34
- #
35
- # rubocop:disable Metrics/CyclomaticComplexity
36
- # rubocop:disable Metrics/PerceivedComplexity
37
- # rubocop:disable Metrics/AbcSize
38
- def self.set_user(
39
- trace = nil, span = nil, id:, email: nil, name: nil, session_id: nil, role: nil, scope: nil, **others
40
- )
41
- raise ArgumentError, 'missing required key: :id' if id.nil?
9
+ class << self
10
+ # Attach user information to the trace
11
+ #
12
+ # @param trace [TraceOperation] Trace to attach data to. Defaults to
13
+ # active trace.
14
+ # @param span [SpanOperation] Span to attach data to. Defaults to
15
+ # active span on trace. Note that this should be a service entry span.
16
+ # When AppSec is enabled, the expected span and trace are automatically
17
+ # used as defaults.
18
+ # @param id [String] Mandatory. Username or client id extracted
19
+ # from the access token or Authorization header in the inbound request
20
+ # from outside the system.
21
+ # @param email [String] Email of the authenticated user associated
22
+ # to the trace.
23
+ # @param name [String] User-friendly name. To be displayed in the
24
+ # UI if set.
25
+ # @param session_id [String] Session ID of the authenticated user.
26
+ # @param role [String] Actual/assumed role the client is making
27
+ # the request under extracted from token or application security
28
+ # context.
29
+ # @param scope [String] Scopes or granted authorities the client
30
+ # currently possesses extracted from token or application security
31
+ # context. The value would come from the scope associated with an OAuth
32
+ # 2.0 Access Token or an attribute value in a SAML 2.0 Assertion.
33
+ # @param others [Hash<Symbol, String>] Additional free-form
34
+ # user information to attach to the trace.
35
+ #
36
+ # rubocop:disable Metrics/CyclomaticComplexity
37
+ # rubocop:disable Metrics/PerceivedComplexity
38
+ def set_user(
39
+ trace = nil, span = nil, id:, email: nil, name: nil, session_id: nil, role: nil, scope: nil, **others
40
+ )
41
+ raise ArgumentError, 'missing required key: :id' if id.nil?
42
42
 
43
- # enforce types
43
+ # enforce types
44
44
 
45
- raise TypeError, ':id must be a String' unless id.is_a?(String)
46
- raise TypeError, ':email must be a String' unless email.nil? || email.is_a?(String)
47
- raise TypeError, ':name must be a String' unless name.nil? || name.is_a?(String)
48
- raise TypeError, ':session_id must be a String' unless session_id.nil? || session_id.is_a?(String)
49
- raise TypeError, ':role must be a String' unless role.nil? || role.is_a?(String)
50
- raise TypeError, ':scope must be a String' unless scope.nil? || scope.is_a?(String)
45
+ raise TypeError, ':id must be a String' unless id.is_a?(String)
46
+ raise TypeError, ':email must be a String' unless email.nil? || email.is_a?(String)
47
+ raise TypeError, ':name must be a String' unless name.nil? || name.is_a?(String)
48
+ raise TypeError, ':session_id must be a String' unless session_id.nil? || session_id.is_a?(String)
49
+ raise TypeError, ':role must be a String' unless role.nil? || role.is_a?(String)
50
+ raise TypeError, ':scope must be a String' unless scope.nil? || scope.is_a?(String)
51
51
 
52
- others.each do |k, v|
53
- raise TypeError, "#{k.inspect} must be a String" unless v.nil? || v.is_a?(String)
54
- end
52
+ others.each do |k, v|
53
+ raise TypeError, "#{k.inspect} must be a String" unless v.nil? || v.is_a?(String)
54
+ end
55
+
56
+ set_trace_and_span_context('set_user', trace, span) do |_active_trace, active_span|
57
+ # set tags once data is known consistent
58
+ active_span.set_tag('usr.id', id)
59
+ active_span.set_tag('usr.email', email) unless email.nil?
60
+ active_span.set_tag('usr.name', name) unless name.nil?
61
+ active_span.set_tag('usr.session_id', session_id) unless session_id.nil?
62
+ active_span.set_tag('usr.role', role) unless role.nil?
63
+ active_span.set_tag('usr.scope', scope) unless scope.nil?
55
64
 
56
- if (appsec_scope = Datadog::AppSec.active_scope)
57
- trace = appsec_scope.trace
58
- span = appsec_scope.service_entry_span
65
+ others.each do |k, v|
66
+ active_span.set_tag("usr.#{k}", v) unless v.nil?
67
+ end
68
+
69
+ if Datadog::AppSec.active_scope
70
+ user = ::Datadog::AppSec::Instrumentation::Gateway::User.new(id)
71
+ ::Datadog::AppSec::Instrumentation.gateway.push('identity.set_user', user)
72
+ end
73
+ end
59
74
  end
75
+ # rubocop:enable Metrics/PerceivedComplexity
76
+ # rubocop:enable Metrics/CyclomaticComplexity
60
77
 
61
- trace ||= Datadog::Tracing.active_trace
62
- span ||= trace.active_span || Datadog::Tracing.active_span
78
+ private
63
79
 
64
- raise ArgumentError, "span #{span.span_id} does not belong to trace #{trace.id}" if trace.id != span.trace_id
80
+ def set_trace_and_span_context(method, trace = nil, span = nil)
81
+ if (appsec_scope = Datadog::AppSec.active_scope)
82
+ trace = appsec_scope.trace
83
+ span = appsec_scope.service_entry_span
84
+ end
65
85
 
66
- # set tags once data is known consistent
86
+ trace ||= Datadog::Tracing.active_trace
87
+ span ||= trace && trace.active_span || Datadog::Tracing.active_span
67
88
 
68
- span.set_tag('usr.id', id)
69
- span.set_tag('usr.email', email) unless email.nil?
70
- span.set_tag('usr.name', name) unless name.nil?
71
- span.set_tag('usr.session_id', session_id) unless session_id.nil?
72
- span.set_tag('usr.role', role) unless role.nil?
73
- span.set_tag('usr.scope', scope) unless scope.nil?
89
+ unless trace && span
90
+ Datadog.logger.debug(
91
+ "Tracing not enabled. Method ##{method} is a no-op. Please enable tracing if you want ##{method}"\
92
+ ' to track this events'
93
+ )
94
+ return
95
+ end
74
96
 
75
- others.each do |k, v|
76
- span.set_tag("usr.#{k}", v) unless v.nil?
77
- end
97
+ raise ArgumentError, "span #{span.span_id} does not belong to trace #{trace.id}" if trace.id != span.trace_id
78
98
 
79
- if appsec_scope
80
- user = ::Datadog::AppSec::Instrumentation::Gateway::User.new(id)
81
- ::Datadog::AppSec::Instrumentation.gateway.push('identity.set_user', user)
99
+ yield(trace, span)
82
100
  end
83
101
  end
84
- # rubocop:enable Metrics/AbcSize
85
- # rubocop:enable Metrics/PerceivedComplexity
86
- # rubocop:enable Metrics/CyclomaticComplexity
87
102
  end
88
103
  end
89
104
  end
@@ -21,11 +21,13 @@ module Datadog
21
21
  gc_profiling_enabled:,
22
22
  allocation_counting_enabled:,
23
23
  no_signals_workaround_enabled:,
24
+ timeline_enabled:,
24
25
  thread_context_collector: ThreadContext.new(
25
26
  recorder: recorder,
26
27
  max_frames: max_frames,
27
28
  tracer: tracer,
28
29
  endpoint_collection_enabled: endpoint_collection_enabled,
30
+ timeline_enabled: timeline_enabled,
29
31
  ),
30
32
  idle_sampling_helper: IdleSamplingHelper.new,
31
33
  # **NOTE**: This should only be used for testing; disabling the dynamic sampling rate will increase the
@@ -76,6 +78,7 @@ module Datadog
76
78
  )
77
79
  end
78
80
  end
81
+ @worker_thread.name = self.class.name # Repeated from above to make sure thread gets named asap
79
82
  end
80
83
 
81
84
  true
@@ -42,6 +42,7 @@ module Datadog
42
42
  )
43
43
  end
44
44
  end
45
+ @worker_thread.name = self.class.name # Repeated from above to make sure thread gets named asap
45
46
  end
46
47
 
47
48
  true
@@ -14,9 +14,16 @@ module Datadog
14
14
  #
15
15
  # Methods prefixed with _native_ are implemented in `collectors_thread_context.c`
16
16
  class ThreadContext
17
- def initialize(recorder:, max_frames:, tracer:, endpoint_collection_enabled:)
17
+ def initialize(recorder:, max_frames:, tracer:, endpoint_collection_enabled:, timeline_enabled:)
18
18
  tracer_context_key = safely_extract_context_key_from(tracer)
19
- self.class._native_initialize(self, recorder, max_frames, tracer_context_key, endpoint_collection_enabled)
19
+ self.class._native_initialize(
20
+ self,
21
+ recorder,
22
+ max_frames,
23
+ tracer_context_key,
24
+ endpoint_collection_enabled,
25
+ timeline_enabled,
26
+ )
20
27
  end
21
28
 
22
29
  def inspect