ddtrace 1.13.1 → 1.15.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (279) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +207 -2
  3. data/ext/ddtrace_profiling_native_extension/NativeExtensionDesign.md +3 -5
  4. data/ext/ddtrace_profiling_native_extension/clock_id.h +0 -3
  5. data/ext/ddtrace_profiling_native_extension/clock_id_from_pthread.c +0 -22
  6. data/ext/ddtrace_profiling_native_extension/clock_id_noop.c +0 -1
  7. data/ext/ddtrace_profiling_native_extension/collectors_cpu_and_wall_time_worker.c +41 -6
  8. data/ext/ddtrace_profiling_native_extension/collectors_idle_sampling_helper.c +3 -0
  9. data/ext/ddtrace_profiling_native_extension/collectors_stack.c +76 -24
  10. data/ext/ddtrace_profiling_native_extension/collectors_stack.h +1 -1
  11. data/ext/ddtrace_profiling_native_extension/collectors_thread_context.c +207 -32
  12. data/ext/ddtrace_profiling_native_extension/collectors_thread_context.h +1 -1
  13. data/ext/ddtrace_profiling_native_extension/extconf.rb +8 -2
  14. data/ext/ddtrace_profiling_native_extension/http_transport.c +26 -10
  15. data/ext/ddtrace_profiling_native_extension/libdatadog_helpers.c +42 -0
  16. data/ext/ddtrace_profiling_native_extension/libdatadog_helpers.h +6 -0
  17. data/ext/ddtrace_profiling_native_extension/native_extension_helpers.rb +1 -1
  18. data/ext/ddtrace_profiling_native_extension/pid_controller.c +57 -0
  19. data/ext/ddtrace_profiling_native_extension/pid_controller.h +45 -0
  20. data/ext/ddtrace_profiling_native_extension/private_vm_api_access.c +17 -12
  21. data/ext/ddtrace_profiling_native_extension/profiling.c +0 -2
  22. data/ext/ddtrace_profiling_native_extension/stack_recorder.c +74 -37
  23. data/ext/ddtrace_profiling_native_extension/stack_recorder.h +13 -3
  24. data/lib/datadog/appsec/assets/waf_rules/processors.json +92 -0
  25. data/lib/datadog/appsec/assets/waf_rules/recommended.json +698 -75
  26. data/lib/datadog/appsec/assets/waf_rules/scanners.json +114 -0
  27. data/lib/datadog/appsec/assets/waf_rules/strict.json +98 -8
  28. data/lib/datadog/appsec/assets.rb +8 -0
  29. data/lib/datadog/appsec/component.rb +9 -2
  30. data/lib/datadog/appsec/configuration/settings.rb +68 -3
  31. data/lib/datadog/appsec/contrib/rack/gateway/watcher.rb +8 -6
  32. data/lib/datadog/appsec/contrib/rack/reactive/request.rb +2 -7
  33. data/lib/datadog/appsec/contrib/rack/reactive/request_body.rb +2 -5
  34. data/lib/datadog/appsec/contrib/rack/reactive/response.rb +2 -5
  35. data/lib/datadog/appsec/contrib/rack/request_body_middleware.rb +3 -2
  36. data/lib/datadog/appsec/contrib/rack/request_middleware.rb +23 -9
  37. data/lib/datadog/appsec/contrib/rails/gateway/watcher.rb +3 -2
  38. data/lib/datadog/appsec/contrib/rails/patcher.rb +9 -3
  39. data/lib/datadog/appsec/contrib/rails/reactive/action.rb +2 -5
  40. data/lib/datadog/appsec/contrib/sinatra/gateway/watcher.rb +6 -4
  41. data/lib/datadog/appsec/contrib/sinatra/patcher.rb +13 -7
  42. data/lib/datadog/appsec/contrib/sinatra/reactive/routed.rb +2 -5
  43. data/lib/datadog/appsec/event.rb +106 -50
  44. data/lib/datadog/appsec/monitor/gateway/watcher.rb +3 -3
  45. data/lib/datadog/appsec/monitor/reactive/set_user.rb +2 -5
  46. data/lib/datadog/appsec/processor/actions.rb +49 -0
  47. data/lib/datadog/appsec/processor/rule_merger.rb +22 -2
  48. data/lib/datadog/appsec/processor.rb +34 -6
  49. data/lib/datadog/appsec/remote.rb +4 -1
  50. data/lib/datadog/appsec/response.rb +82 -4
  51. data/lib/datadog/appsec/sample_rate.rb +21 -0
  52. data/lib/datadog/appsec.rb +2 -2
  53. data/lib/datadog/core/configuration/agent_settings_resolver.rb +29 -24
  54. data/lib/datadog/core/configuration/base.rb +1 -11
  55. data/lib/datadog/core/configuration/components.rb +9 -2
  56. data/lib/datadog/core/configuration/ext.rb +21 -0
  57. data/lib/datadog/core/configuration/option.rb +2 -4
  58. data/lib/datadog/core/configuration/option_definition.rb +17 -41
  59. data/lib/datadog/core/configuration/options.rb +5 -5
  60. data/lib/datadog/core/configuration/settings.rb +47 -45
  61. data/lib/datadog/core/diagnostics/environment_logger.rb +130 -234
  62. data/lib/datadog/core/environment/execution.rb +50 -2
  63. data/lib/datadog/core/environment/variable_helpers.rb +0 -69
  64. data/lib/datadog/core/error.rb +1 -0
  65. data/lib/datadog/core/git/ext.rb +2 -0
  66. data/lib/datadog/core/remote/client/capabilities.rb +1 -1
  67. data/lib/datadog/core/remote/component.rb +2 -2
  68. data/lib/datadog/core/remote/negotiation.rb +2 -2
  69. data/lib/datadog/core/remote/transport/config.rb +60 -0
  70. data/lib/datadog/core/remote/transport/http/api/instance.rb +39 -0
  71. data/lib/datadog/core/remote/transport/http/api/spec.rb +21 -0
  72. data/lib/datadog/core/remote/transport/http/api.rb +58 -0
  73. data/lib/datadog/core/remote/transport/http/builder.rb +219 -0
  74. data/lib/datadog/core/remote/transport/http/client.rb +48 -0
  75. data/lib/datadog/core/remote/transport/http/config.rb +280 -0
  76. data/lib/datadog/core/remote/transport/http/negotiation.rb +146 -0
  77. data/lib/datadog/core/remote/transport/http.rb +179 -0
  78. data/lib/datadog/core/{transport → remote/transport}/negotiation.rb +25 -23
  79. data/lib/datadog/core/telemetry/collector.rb +13 -4
  80. data/lib/datadog/core/telemetry/http/transport.rb +2 -1
  81. data/lib/datadog/core/transport/ext.rb +47 -0
  82. data/lib/datadog/core/transport/http/adapters/net.rb +168 -0
  83. data/lib/datadog/core/transport/http/adapters/registry.rb +29 -0
  84. data/lib/datadog/core/transport/http/adapters/test.rb +89 -0
  85. data/lib/datadog/core/transport/http/adapters/unix_socket.rb +83 -0
  86. data/lib/datadog/core/transport/http/api/endpoint.rb +31 -0
  87. data/lib/datadog/core/transport/http/api/fallbacks.rb +26 -0
  88. data/lib/datadog/core/transport/http/api/map.rb +18 -0
  89. data/lib/datadog/core/transport/http/env.rb +62 -0
  90. data/lib/datadog/core/transport/http/response.rb +60 -0
  91. data/lib/datadog/core/transport/parcel.rb +22 -0
  92. data/lib/datadog/core/transport/request.rb +17 -0
  93. data/lib/datadog/core/transport/response.rb +64 -0
  94. data/lib/datadog/core/workers/polling.rb +2 -2
  95. data/lib/datadog/opentelemetry/api/context.rb +10 -3
  96. data/lib/datadog/opentelemetry/sdk/propagator.rb +2 -1
  97. data/lib/datadog/opentelemetry/sdk/span_processor.rb +14 -2
  98. data/lib/datadog/opentelemetry/sdk/trace/span.rb +68 -0
  99. data/lib/datadog/opentelemetry/trace.rb +58 -0
  100. data/lib/datadog/opentelemetry.rb +1 -0
  101. data/lib/datadog/opentracer.rb +9 -0
  102. data/lib/datadog/profiling/collectors/cpu_and_wall_time_worker.rb +12 -18
  103. data/lib/datadog/profiling/collectors/idle_sampling_helper.rb +1 -1
  104. data/lib/datadog/profiling/collectors/thread_context.rb +9 -1
  105. data/lib/datadog/profiling/component.rb +34 -99
  106. data/lib/datadog/profiling/diagnostics/environment_logger.rb +39 -0
  107. data/lib/datadog/profiling/exporter.rb +4 -4
  108. data/lib/datadog/profiling/ext.rb +0 -12
  109. data/lib/datadog/profiling/flush.rb +2 -7
  110. data/lib/datadog/profiling/http_transport.rb +6 -3
  111. data/lib/datadog/profiling/native_extension.rb +0 -21
  112. data/lib/datadog/profiling/profiler.rb +11 -12
  113. data/lib/datadog/profiling.rb +9 -81
  114. data/lib/datadog/tracing/component.rb +12 -5
  115. data/lib/datadog/tracing/configuration/agent_settings_resolver.rb +13 -0
  116. data/lib/datadog/tracing/configuration/ext.rb +4 -2
  117. data/lib/datadog/tracing/configuration/settings.rb +14 -7
  118. data/lib/datadog/tracing/contrib/action_pack/configuration/settings.rb +1 -1
  119. data/lib/datadog/tracing/contrib/active_job/configuration/settings.rb +1 -1
  120. data/lib/datadog/tracing/contrib/active_record/configuration/resolver.rb +18 -11
  121. data/lib/datadog/tracing/contrib/active_record/events/sql.rb +4 -0
  122. data/lib/datadog/tracing/contrib/active_record/utils.rb +1 -1
  123. data/lib/datadog/tracing/contrib/active_support/cache/instrumentation.rb +104 -197
  124. data/lib/datadog/tracing/contrib/active_support/cache/patcher.rb +3 -0
  125. data/lib/datadog/tracing/contrib/aws/instrumentation.rb +7 -0
  126. data/lib/datadog/tracing/contrib/configuration/settings.rb +1 -1
  127. data/lib/datadog/tracing/contrib/dalli/configuration/settings.rb +6 -0
  128. data/lib/datadog/tracing/contrib/dalli/ext.rb +7 -0
  129. data/lib/datadog/tracing/contrib/dalli/instrumentation.rb +9 -2
  130. data/lib/datadog/tracing/contrib/delayed_job/configuration/settings.rb +1 -1
  131. data/lib/datadog/tracing/contrib/elasticsearch/patcher.rb +104 -102
  132. data/lib/datadog/tracing/contrib/ethon/easy_patch.rb +5 -0
  133. data/lib/datadog/tracing/contrib/ethon/multi_patch.rb +8 -0
  134. data/lib/datadog/tracing/contrib/excon/middleware.rb +5 -0
  135. data/lib/datadog/tracing/contrib/ext.rb +3 -0
  136. data/lib/datadog/tracing/contrib/faraday/configuration/settings.rb +1 -1
  137. data/lib/datadog/tracing/contrib/faraday/middleware.rb +5 -0
  138. data/lib/datadog/tracing/contrib/grpc/configuration/settings.rb +21 -1
  139. data/lib/datadog/tracing/contrib/grpc/datadog_interceptor/client.rb +11 -1
  140. data/lib/datadog/tracing/contrib/grpc/datadog_interceptor/server.rb +18 -0
  141. data/lib/datadog/tracing/contrib/grpc/datadog_interceptor.rb +0 -4
  142. data/lib/datadog/tracing/contrib/http/circuit_breaker.rb +3 -3
  143. data/lib/datadog/tracing/contrib/http/instrumentation.rb +5 -0
  144. data/lib/datadog/tracing/contrib/httpclient/instrumentation.rb +5 -0
  145. data/lib/datadog/tracing/contrib/httprb/instrumentation.rb +5 -0
  146. data/lib/datadog/tracing/contrib/lograge/instrumentation.rb +1 -17
  147. data/lib/datadog/tracing/contrib/mongodb/subscribers.rb +7 -0
  148. data/lib/datadog/tracing/contrib/mysql2/instrumentation.rb +13 -3
  149. data/lib/datadog/tracing/contrib/opensearch/integration.rb +2 -2
  150. data/lib/datadog/tracing/contrib/opensearch/patcher.rb +7 -0
  151. data/lib/datadog/tracing/contrib/pg/instrumentation.rb +5 -0
  152. data/lib/datadog/tracing/contrib/presto/instrumentation.rb +5 -0
  153. data/lib/datadog/tracing/contrib/propagation/sql_comment.rb +1 -1
  154. data/lib/datadog/tracing/contrib/que/configuration/settings.rb +1 -1
  155. data/lib/datadog/tracing/contrib/racecar/event.rb +5 -0
  156. data/lib/datadog/tracing/contrib/rack/header_tagging.rb +14 -4
  157. data/lib/datadog/tracing/contrib/rails/configuration/settings.rb +4 -4
  158. data/lib/datadog/tracing/contrib/rake/configuration/settings.rb +1 -1
  159. data/lib/datadog/tracing/contrib/redis/tags.rb +5 -0
  160. data/lib/datadog/tracing/contrib/resque/configuration/settings.rb +1 -1
  161. data/lib/datadog/tracing/contrib/rest_client/request_patch.rb +5 -0
  162. data/lib/datadog/tracing/contrib/semantic_logger/instrumentation.rb +3 -20
  163. data/lib/datadog/tracing/contrib/sequel/utils.rb +5 -0
  164. data/lib/datadog/tracing/contrib/shoryuken/configuration/settings.rb +1 -1
  165. data/lib/datadog/tracing/contrib/sidekiq/configuration/settings.rb +1 -1
  166. data/lib/datadog/tracing/contrib/sneakers/configuration/settings.rb +1 -1
  167. data/lib/datadog/tracing/contrib/utils/quantization/http.rb +11 -11
  168. data/lib/datadog/tracing/correlation.rb +20 -0
  169. data/lib/datadog/tracing/diagnostics/environment_logger.rb +159 -0
  170. data/lib/datadog/tracing/distributed/propagation.rb +13 -33
  171. data/lib/datadog/tracing/metadata/tagging.rb +3 -3
  172. data/lib/datadog/tracing/sync_writer.rb +3 -3
  173. data/lib/datadog/tracing/tracer.rb +2 -0
  174. data/lib/datadog/{core → tracing}/transport/http/api/instance.rb +1 -1
  175. data/lib/datadog/{core → tracing}/transport/http/api/spec.rb +1 -1
  176. data/lib/datadog/tracing/transport/http/api.rb +43 -0
  177. data/lib/datadog/{core → tracing}/transport/http/builder.rb +13 -68
  178. data/lib/datadog/tracing/transport/http/client.rb +57 -0
  179. data/lib/datadog/tracing/transport/http/statistics.rb +47 -0
  180. data/lib/datadog/tracing/transport/http/traces.rb +152 -0
  181. data/lib/datadog/tracing/transport/http.rb +124 -0
  182. data/lib/datadog/tracing/transport/io/client.rb +89 -0
  183. data/lib/datadog/tracing/transport/io/response.rb +27 -0
  184. data/lib/datadog/tracing/transport/io/traces.rb +101 -0
  185. data/lib/datadog/tracing/transport/io.rb +30 -0
  186. data/lib/datadog/tracing/transport/serializable_trace.rb +126 -0
  187. data/lib/datadog/tracing/transport/statistics.rb +77 -0
  188. data/lib/datadog/tracing/transport/trace_formatter.rb +209 -0
  189. data/lib/datadog/tracing/transport/traces.rb +224 -0
  190. data/lib/datadog/tracing/workers/trace_writer.rb +6 -4
  191. data/lib/datadog/tracing/workers.rb +3 -2
  192. data/lib/datadog/tracing/writer.rb +5 -2
  193. data/lib/ddtrace/transport/ext.rb +17 -15
  194. data/lib/ddtrace/version.rb +2 -2
  195. data/lib/ddtrace.rb +1 -1
  196. metadata +74 -96
  197. data/lib/datadog/ci/configuration/components.rb +0 -32
  198. data/lib/datadog/ci/configuration/settings.rb +0 -51
  199. data/lib/datadog/ci/contrib/cucumber/configuration/settings.rb +0 -35
  200. data/lib/datadog/ci/contrib/cucumber/ext.rb +0 -22
  201. data/lib/datadog/ci/contrib/cucumber/formatter.rb +0 -94
  202. data/lib/datadog/ci/contrib/cucumber/instrumentation.rb +0 -28
  203. data/lib/datadog/ci/contrib/cucumber/integration.rb +0 -47
  204. data/lib/datadog/ci/contrib/cucumber/patcher.rb +0 -27
  205. data/lib/datadog/ci/contrib/minitest/configuration/settings.rb +0 -35
  206. data/lib/datadog/ci/contrib/minitest/ext.rb +0 -21
  207. data/lib/datadog/ci/contrib/minitest/integration.rb +0 -49
  208. data/lib/datadog/ci/contrib/minitest/patcher.rb +0 -27
  209. data/lib/datadog/ci/contrib/minitest/test_helper.rb +0 -68
  210. data/lib/datadog/ci/contrib/rspec/configuration/settings.rb +0 -35
  211. data/lib/datadog/ci/contrib/rspec/example.rb +0 -68
  212. data/lib/datadog/ci/contrib/rspec/ext.rb +0 -21
  213. data/lib/datadog/ci/contrib/rspec/integration.rb +0 -48
  214. data/lib/datadog/ci/contrib/rspec/patcher.rb +0 -27
  215. data/lib/datadog/ci/ext/app_types.rb +0 -9
  216. data/lib/datadog/ci/ext/environment.rb +0 -575
  217. data/lib/datadog/ci/ext/settings.rb +0 -10
  218. data/lib/datadog/ci/ext/test.rb +0 -35
  219. data/lib/datadog/ci/extensions.rb +0 -19
  220. data/lib/datadog/ci/flush.rb +0 -38
  221. data/lib/datadog/ci/test.rb +0 -81
  222. data/lib/datadog/ci.rb +0 -21
  223. data/lib/datadog/core/configuration/dependency_resolver.rb +0 -28
  224. data/lib/datadog/core/configuration/option_definition_set.rb +0 -22
  225. data/lib/datadog/core/configuration/option_set.rb +0 -10
  226. data/lib/datadog/core/transport/config.rb +0 -58
  227. data/lib/datadog/core/transport/http/api.rb +0 -57
  228. data/lib/datadog/core/transport/http/client.rb +0 -45
  229. data/lib/datadog/core/transport/http/config.rb +0 -278
  230. data/lib/datadog/core/transport/http/negotiation.rb +0 -144
  231. data/lib/datadog/core/transport/http.rb +0 -169
  232. data/lib/datadog/core/utils/object_set.rb +0 -43
  233. data/lib/datadog/core/utils/string_table.rb +0 -47
  234. data/lib/datadog/profiling/backtrace_location.rb +0 -34
  235. data/lib/datadog/profiling/buffer.rb +0 -43
  236. data/lib/datadog/profiling/collectors/old_stack.rb +0 -301
  237. data/lib/datadog/profiling/encoding/profile.rb +0 -41
  238. data/lib/datadog/profiling/event.rb +0 -15
  239. data/lib/datadog/profiling/events/stack.rb +0 -82
  240. data/lib/datadog/profiling/old_recorder.rb +0 -107
  241. data/lib/datadog/profiling/pprof/builder.rb +0 -125
  242. data/lib/datadog/profiling/pprof/converter.rb +0 -102
  243. data/lib/datadog/profiling/pprof/message_set.rb +0 -16
  244. data/lib/datadog/profiling/pprof/payload.rb +0 -20
  245. data/lib/datadog/profiling/pprof/pprof.proto +0 -212
  246. data/lib/datadog/profiling/pprof/pprof_pb.rb +0 -81
  247. data/lib/datadog/profiling/pprof/stack_sample.rb +0 -139
  248. data/lib/datadog/profiling/pprof/string_table.rb +0 -12
  249. data/lib/datadog/profiling/pprof/template.rb +0 -118
  250. data/lib/datadog/profiling/trace_identifiers/ddtrace.rb +0 -43
  251. data/lib/datadog/profiling/trace_identifiers/helper.rb +0 -45
  252. data/lib/ddtrace/transport/http/adapters/net.rb +0 -168
  253. data/lib/ddtrace/transport/http/adapters/registry.rb +0 -27
  254. data/lib/ddtrace/transport/http/adapters/test.rb +0 -85
  255. data/lib/ddtrace/transport/http/adapters/unix_socket.rb +0 -77
  256. data/lib/ddtrace/transport/http/api/endpoint.rb +0 -29
  257. data/lib/ddtrace/transport/http/api/fallbacks.rb +0 -24
  258. data/lib/ddtrace/transport/http/api/instance.rb +0 -35
  259. data/lib/ddtrace/transport/http/api/map.rb +0 -16
  260. data/lib/ddtrace/transport/http/api/spec.rb +0 -17
  261. data/lib/ddtrace/transport/http/api.rb +0 -39
  262. data/lib/ddtrace/transport/http/builder.rb +0 -176
  263. data/lib/ddtrace/transport/http/client.rb +0 -52
  264. data/lib/ddtrace/transport/http/env.rb +0 -58
  265. data/lib/ddtrace/transport/http/response.rb +0 -58
  266. data/lib/ddtrace/transport/http/statistics.rb +0 -43
  267. data/lib/ddtrace/transport/http/traces.rb +0 -144
  268. data/lib/ddtrace/transport/http.rb +0 -117
  269. data/lib/ddtrace/transport/io/client.rb +0 -85
  270. data/lib/ddtrace/transport/io/response.rb +0 -25
  271. data/lib/ddtrace/transport/io/traces.rb +0 -99
  272. data/lib/ddtrace/transport/io.rb +0 -28
  273. data/lib/ddtrace/transport/parcel.rb +0 -20
  274. data/lib/ddtrace/transport/request.rb +0 -15
  275. data/lib/ddtrace/transport/response.rb +0 -60
  276. data/lib/ddtrace/transport/serializable_trace.rb +0 -122
  277. data/lib/ddtrace/transport/statistics.rb +0 -75
  278. data/lib/ddtrace/transport/trace_formatter.rb +0 -207
  279. data/lib/ddtrace/transport/traces.rb +0 -216
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Datadog
4
+ module Core
5
+ module Transport
6
+ # Data transfer object for generic data
7
+ # @abstract
8
+ module Parcel
9
+ attr_reader \
10
+ :data
11
+
12
+ def initialize(data)
13
+ @data = data
14
+ end
15
+
16
+ def encode_with(encoder)
17
+ raise NotImplementedError
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Datadog
4
+ module Core
5
+ module Transport
6
+ # Defines request for transport operations
7
+ class Request
8
+ attr_reader \
9
+ :parcel
10
+
11
+ def initialize(parcel = nil)
12
+ @parcel = parcel
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,64 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Datadog
4
+ module Core
5
+ module Transport
6
+ # Defines abstract response for transport operations
7
+ module Response
8
+ def payload
9
+ nil
10
+ end
11
+
12
+ def ok?
13
+ nil
14
+ end
15
+
16
+ def unsupported?
17
+ nil
18
+ end
19
+
20
+ def not_found?
21
+ nil
22
+ end
23
+
24
+ def client_error?
25
+ nil
26
+ end
27
+
28
+ def server_error?
29
+ nil
30
+ end
31
+
32
+ def internal_error?
33
+ nil
34
+ end
35
+
36
+ def inspect
37
+ "#{self.class} ok?:#{ok?} unsupported?:#{unsupported?}, " \
38
+ "not_found?:#{not_found?}, client_error?:#{client_error?}, " \
39
+ "server_error?:#{server_error?}, internal_error?:#{internal_error?}, " \
40
+ "payload:#{payload}"
41
+ end
42
+ end
43
+
44
+ # A generic error response for internal errors
45
+ class InternalErrorResponse
46
+ include Response
47
+
48
+ attr_reader :error
49
+
50
+ def initialize(error)
51
+ @error = error
52
+ end
53
+
54
+ def internal_error?
55
+ true
56
+ end
57
+
58
+ def inspect
59
+ "#{super}, error_type:#{error.class} error:#{error}"
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
@@ -6,7 +6,7 @@ module Datadog
6
6
  module Workers
7
7
  # Adds polling (async looping) behavior to workers
8
8
  module Polling
9
- SHUTDOWN_TIMEOUT = 1
9
+ DEFAULT_SHUTDOWN_TIMEOUT = 1
10
10
 
11
11
  def self.included(base)
12
12
  base.include(Workers::IntervalLoop)
@@ -21,7 +21,7 @@ module Datadog
21
21
  end
22
22
  end
23
23
 
24
- def stop(force_stop = false, timeout = SHUTDOWN_TIMEOUT)
24
+ def stop(force_stop = false, timeout = DEFAULT_SHUTDOWN_TIMEOUT)
25
25
  if running?
26
26
  # Attempt graceful stop and wait
27
27
  stop_loop
@@ -2,6 +2,7 @@
2
2
 
3
3
  require_relative 'trace/span'
4
4
  require_relative '../../tracing/trace_operation'
5
+ require_relative '../trace'
5
6
 
6
7
  module Datadog
7
8
  module OpenTelemetry
@@ -66,9 +67,15 @@ module Datadog
66
67
  # @param [Object] value Object to be stored under key
67
68
  # @return [Context]
68
69
  def set_values(values)
69
- trace = nil
70
- if (current_span = values[CURRENT_SPAN_KEY])
71
- trace = current_span.datadog_trace
70
+ if (current_span = values[CURRENT_SPAN_KEY]) && current_span.datadog_trace
71
+ # Because `#set_value` returns new context, we have to create
72
+ # a new copy of the active trace to ensure there's no conflict with
73
+ # other users of the active trace.
74
+ # It effectively becomes an internal trace propagation.
75
+ trace = Datadog::OpenTelemetry::Trace.start_trace_copy(
76
+ current_span.datadog_trace,
77
+ parent_span: current_span.datadog_span
78
+ )
72
79
  end
73
80
 
74
81
  existing_values = @trace && @trace.otel_values || {}
@@ -81,8 +81,9 @@ module Datadog
81
81
  private
82
82
 
83
83
  # Converts the {Numeric} Datadog id object to OpenTelemetry's byte array format.
84
+ # This method currently converts an unsigned 64-bit Integer to a binary String.
84
85
  def to_otel_id(dd_id)
85
- Array(dd_id).pack('S')
86
+ Array(dd_id).pack('Q')
86
87
  end
87
88
  end
88
89
  end
@@ -27,7 +27,7 @@ module Datadog
27
27
  #
28
28
  # @param [Span] span the {Span} that just ended.
29
29
  def on_finish(span)
30
- span.datadog_span.finish
30
+ span.datadog_span.finish(ns_to_time(span.end_timestamp))
31
31
  end
32
32
 
33
33
  # Export all ended spans to the configured `Exporter` that have not yet
@@ -81,10 +81,22 @@ module Datadog
81
81
  kind = span.kind || 'internal'
82
82
  tags[Tracing::Metadata::Ext::TAG_KIND] = kind
83
83
 
84
- datadog_span = Tracing.trace(span.name, tags: tags)
84
+ datadog_span = Tracing.trace(
85
+ span.name,
86
+ tags: tags,
87
+ start_time: ns_to_time(span.start_timestamp)
88
+ )
89
+
85
90
  datadog_span.set_error([nil, span.status.description]) unless span.status.ok?
91
+ datadog_span.set_tags(span.attributes)
92
+
86
93
  datadog_span
87
94
  end
95
+
96
+ # From nanoseconds, used by OpenTelemetry, to a {Time} object, used by the Datadog Tracer.
97
+ def ns_to_time(timestamp_ns)
98
+ Time.at(timestamp_ns / 1000000000.0)
99
+ end
88
100
  end
89
101
  end
90
102
  end
@@ -0,0 +1,68 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Datadog
4
+ module OpenTelemetry
5
+ module Trace
6
+ # Stores associated Datadog entities to the OpenTelemetry Span.
7
+ module Span
8
+ # Attributes are equivalent to span tags and metrics.
9
+ def set_attribute(key, value)
10
+ res = super
11
+ # Attributes can get dropped or their values truncated by `super`
12
+ datadog_set_attribute(key)
13
+ res
14
+ end
15
+
16
+ # `alias` performed to match {OpenTelemetry::SDK::Trace::Span} aliasing upstream
17
+ alias []= set_attribute
18
+
19
+ # Attributes are equivalent to span tags and metrics.
20
+ def add_attributes(attributes)
21
+ res = super
22
+ # Attributes can get dropped or their values truncated by `super`
23
+ attributes.each { |key, _| datadog_set_attribute(key) }
24
+ res
25
+ end
26
+
27
+ # Captures changes to span error state.
28
+ def status=(s)
29
+ super
30
+
31
+ return unless status # Return if status are currently disabled by OpenTelemetry.
32
+ return unless (span = datadog_span)
33
+
34
+ # Status code can only change into an error state.
35
+ # Other change operations should be ignored.
36
+ span.set_error(status.description) if status && status.code == ::OpenTelemetry::Trace::Status::ERROR
37
+ end
38
+
39
+ private
40
+
41
+ def datadog_set_attribute(key)
42
+ # Return if attributes are currently disabled by OpenTelemetry.
43
+ return unless defined?(@attributes) && @attributes
44
+ return unless (span = datadog_span)
45
+
46
+ # DEV: Accesses `@attributes` directly, since using `#attributes`
47
+ # DEV: clones the hash, causing unnecessary overhead.
48
+ if @attributes.key?(key)
49
+ value = @attributes[key]
50
+ span.set_tag(key, value)
51
+
52
+ span.service = value if key == 'service.name'
53
+ else
54
+ span.clear_tag(key)
55
+
56
+ if key == 'service.name'
57
+ # By removing the service name, we set it to the fallback default,
58
+ # effectively removing the `service` attribute from OpenTelemetry's perspective.
59
+ span.service = Datadog.send(:components).tracer.default_service
60
+ end
61
+ end
62
+ end
63
+
64
+ ::OpenTelemetry::SDK::Trace::Span.prepend(self)
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,58 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../tracing/trace_digest'
4
+
5
+ module Datadog
6
+ module OpenTelemetry
7
+ # OpenTelemetry utilities related to the respective Datadog trace.
8
+ module Trace
9
+ class << self
10
+ # Creates a new TraceOperation object that can be attached to a new
11
+ # OpenTelemetry span.
12
+ # If `parent_span` is provided, then that span is set as the currently
13
+ # active parent span.
14
+ #
15
+ # @return [TraceOperation]
16
+ def start_trace_copy(trace, parent_span: nil)
17
+ digest = if parent_span
18
+ digest_with_parent_span(trace, parent_span)
19
+ else
20
+ trace.to_digest
21
+ end
22
+
23
+ # Create a new TraceOperation, attached to the current Datadog Tracer.
24
+ Datadog::Tracing.continue_trace!(digest)
25
+ end
26
+
27
+ private
28
+
29
+ # Creates a TraceDigest with the active span modified.
30
+ # This supports the implementation of `OpenTelemetry::Trace.context_with_span`,
31
+ # which allows you to specific any span as the arbitrary parent of a new span.
32
+ def digest_with_parent_span(trace, parent_span)
33
+ digest = trace.to_digest
34
+
35
+ Tracing::TraceDigest.new(
36
+ span_id: parent_span.id,
37
+ span_name: parent_span.name,
38
+ span_resource: parent_span.resource,
39
+ span_service: parent_span.service,
40
+ span_type: parent_span.type,
41
+ trace_distributed_tags: digest.trace_distributed_tags,
42
+ trace_hostname: digest.trace_hostname,
43
+ trace_id: digest.trace_id,
44
+ trace_name: digest.trace_name,
45
+ trace_origin: digest.trace_origin,
46
+ trace_process_id: digest.trace_process_id,
47
+ trace_resource: digest.trace_resource,
48
+ trace_runtime_id: digest.trace_runtime_id,
49
+ trace_sampling_priority: digest.trace_sampling_priority,
50
+ trace_service: digest.trace_service,
51
+ trace_state: digest.trace_state,
52
+ trace_state_unknown_fields: digest.trace_state_unknown_fields,
53
+ ).freeze
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
@@ -16,6 +16,7 @@ require_relative 'opentelemetry/api/context'
16
16
  # DEV: This is different from our existing OpenTracer API, but there are many safety
17
17
  # DEV: features built into Contrib instrumentation today.
18
18
  require_relative 'opentelemetry/sdk/configurator' if defined?(OpenTelemetry::SDK)
19
+ require_relative 'opentelemetry/sdk/trace/span' if defined?(OpenTelemetry::SDK)
19
20
 
20
21
  module Datadog
21
22
  # Datadog OpenTelemetry integration.
@@ -22,3 +22,12 @@ require_relative 'opentracer/global_tracer'
22
22
 
23
23
  # Modify the OpenTracing module functions
24
24
  ::OpenTracing.singleton_class.prepend(Datadog::OpenTracer::GlobalTracer)
25
+
26
+ module Datadog
27
+ # Datadog OpenTracing integration.
28
+ # DEV: This module should be named `Datadog::OpenTracing` to match the gem (`opentracing`).
29
+ module OpenTracer
30
+ # Used by Telemetry to decide if OpenTracing instrumentation is enabled
31
+ LOADED = true
32
+ end
33
+ end
@@ -14,25 +14,15 @@ module Datadog
14
14
  public
15
15
 
16
16
  def initialize(
17
- recorder:,
18
- max_frames:,
19
- tracer:,
20
- endpoint_collection_enabled:,
21
17
  gc_profiling_enabled:,
22
18
  allocation_counting_enabled:,
23
19
  no_signals_workaround_enabled:,
24
- timeline_enabled:,
25
- thread_context_collector: ThreadContext.new(
26
- recorder: recorder,
27
- max_frames: max_frames,
28
- tracer: tracer,
29
- endpoint_collection_enabled: endpoint_collection_enabled,
30
- timeline_enabled: timeline_enabled,
31
- ),
20
+ thread_context_collector:,
32
21
  idle_sampling_helper: IdleSamplingHelper.new,
33
22
  # **NOTE**: This should only be used for testing; disabling the dynamic sampling rate will increase the
34
23
  # profiler overhead!
35
- dynamic_sampling_rate_enabled: true
24
+ dynamic_sampling_rate_enabled: true,
25
+ allocation_sample_every: 0 # Currently only for testing; Setting this to > 0 can add a lot of overhead!
36
26
  )
37
27
  unless dynamic_sampling_rate_enabled
38
28
  Datadog.logger.warn(
@@ -40,6 +30,13 @@ module Datadog
40
30
  )
41
31
  end
42
32
 
33
+ if allocation_counting_enabled && allocation_sample_every > 0
34
+ Datadog.logger.warn(
35
+ "Enabled experimental allocation profiling: allocation_sample_every=#{allocation_sample_every}. This is " \
36
+ 'experimental, not recommended, and will increase overhead!'
37
+ )
38
+ end
39
+
43
40
  self.class._native_initialize(
44
41
  self,
45
42
  thread_context_collector,
@@ -48,6 +45,7 @@ module Datadog
48
45
  allocation_counting_enabled,
49
46
  no_signals_workaround_enabled,
50
47
  dynamic_sampling_rate_enabled,
48
+ allocation_sample_every,
51
49
  )
52
50
  @worker_thread = nil
53
51
  @failure_exception = nil
@@ -84,11 +82,7 @@ module Datadog
84
82
  true
85
83
  end
86
84
 
87
- # TODO: Provided only for compatibility with the API for Collectors::OldStack used in the Profiler class.
88
- # Can be removed once we remove OldStack.
89
- def enabled=(_); end
90
-
91
- def stop(*_)
85
+ def stop
92
86
  @start_stop_mutex.synchronize do
93
87
  Datadog.logger.debug('Requesting CpuAndWallTimeWorker thread shut down')
94
88
 
@@ -48,7 +48,7 @@ module Datadog
48
48
  true
49
49
  end
50
50
 
51
- def stop(*_unused)
51
+ def stop
52
52
  @start_stop_mutex.synchronize do
53
53
  Datadog.logger.debug('Requesting IdleSamplingHelper thread shut down')
54
54
 
@@ -14,7 +14,14 @@ 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:, timeline_enabled:)
17
+ def initialize(
18
+ recorder:,
19
+ max_frames:,
20
+ tracer:,
21
+ endpoint_collection_enabled:,
22
+ timeline_enabled:,
23
+ allocation_type_enabled: true
24
+ )
18
25
  tracer_context_key = safely_extract_context_key_from(tracer)
19
26
  self.class._native_initialize(
20
27
  self,
@@ -23,6 +30,7 @@ module Datadog
23
30
  tracer_context_key,
24
31
  endpoint_collection_enabled,
25
32
  timeline_enabled,
33
+ allocation_type_enabled,
26
34
  )
27
35
  end
28
36
 
@@ -7,7 +7,11 @@ module Datadog
7
7
  # Passing in a `nil` tracer is supported and will disable the following profiling features:
8
8
  # * Code Hotspots panel in the trace viewer, as well as scoping a profile down to a span
9
9
  # * Endpoint aggregation in the profiler UX, including normalization (resource per endpoint call)
10
- def self.build_profiler_component(settings:, agent_settings:, optional_tracer:) # rubocop:disable Metrics/MethodLength
10
+ def self.build_profiler_component(settings:, agent_settings:, optional_tracer:)
11
+ require_relative '../profiling/diagnostics/environment_logger'
12
+
13
+ Profiling::Diagnostics::EnvironmentLogger.collect_and_log!
14
+
11
15
  return unless settings.profiling.enabled
12
16
 
13
17
  # Workaround for weird dependency direction: the Core::Configuration::Components class currently has a
@@ -30,98 +34,53 @@ module Datadog
30
34
  require_relative '../profiling'
31
35
  return unless Profiling.supported?
32
36
 
33
- unless defined?(Profiling::Tasks::Setup)
34
- # In #1545 a user reported a NameError due to this constant being uninitialized
35
- # I've documented my suspicion on why that happened in
36
- # https://github.com/DataDog/dd-trace-rb/issues/1545#issuecomment-856049025
37
- #
38
- # > Thanks for the info! It seems to feed into my theory: there's two moments in the code where we check if
39
- # > profiler is "supported": 1) when loading ddtrace (inside preload) and 2) when starting the profile
40
- # > after Datadog.configure gets run.
41
- # > The problem is that the code assumes that both checks 1) and 2) will always reach the same conclusion:
42
- # > either profiler is supported, or profiler is not supported.
43
- # > In the problematic case, it looks like in your case check 1 decides that profiler is not
44
- # > supported => doesn't load it, and then check 2 decides that it is => assumes it is loaded and tries to
45
- # > start it.
46
- #
47
- # I was never able to validate if this was the issue or why exactly .supported? would change its mind BUT
48
- # just in case it happens again, I've left this check which avoids breaking the user's application AND
49
- # would instead direct them to report it to us instead, so that we can investigate what's wrong.
50
- #
51
- # TODO: As of June 2021, most checks in .supported? are related to the google-protobuf gem; so it's
52
- # very likely that it was the origin of the issue we saw. Thus, if, as planned we end up moving away from
53
- # protobuf OR enough time has passed and no users saw the issue again, we can remove this check altogether.
54
- Datadog.logger.error(
55
- 'Profiling was marked as supported and enabled, but setup task was not loaded properly. ' \
56
- 'Please report this at https://github.com/DataDog/dd-trace-rb/blob/master/CONTRIBUTING.md#found-a-bug'
57
- )
58
-
59
- return
60
- end
61
-
62
- # Load extensions needed to support some of the Profiling features
37
+ # Activate forking extensions
63
38
  Profiling::Tasks::Setup.new.run
64
39
 
65
40
  # NOTE: Please update the Initialization section of ProfilingDevelopment.md with any changes to this method
66
41
 
67
- no_signals_workaround_enabled = false
42
+ no_signals_workaround_enabled = no_signals_workaround_enabled?(settings)
43
+ timeline_enabled = settings.profiling.advanced.experimental_timeline_enabled
68
44
 
69
- if enable_new_profiler?(settings)
70
- no_signals_workaround_enabled = no_signals_workaround_enabled?(settings)
71
-
72
- recorder = Datadog::Profiling::StackRecorder.new(
73
- cpu_time_enabled: RUBY_PLATFORM.include?('linux'), # Only supported on Linux currently
74
- alloc_samples_enabled: false, # Always disabled for now -- work in progress
75
- )
76
- collector = Datadog::Profiling::Collectors::CpuAndWallTimeWorker.new(
77
- recorder: recorder,
78
- max_frames: settings.profiling.advanced.max_frames,
79
- tracer: optional_tracer,
80
- endpoint_collection_enabled: settings.profiling.advanced.endpoint.collection.enabled,
81
- gc_profiling_enabled: enable_gc_profiling?(settings),
82
- allocation_counting_enabled: settings.profiling.advanced.allocation_counting_enabled,
83
- no_signals_workaround_enabled: no_signals_workaround_enabled,
84
- timeline_enabled: settings.profiling.advanced.experimental_timeline_enabled,
85
- )
86
- else
87
- load_pprof_support
45
+ recorder = Datadog::Profiling::StackRecorder.new(
46
+ cpu_time_enabled: RUBY_PLATFORM.include?('linux'), # Only supported on Linux currently
47
+ alloc_samples_enabled: false, # Always disabled for now -- work in progress
48
+ )
49
+ thread_context_collector = Datadog::Profiling::Collectors::ThreadContext.new(
50
+ recorder: recorder,
51
+ max_frames: settings.profiling.advanced.max_frames,
52
+ tracer: optional_tracer,
53
+ endpoint_collection_enabled: settings.profiling.advanced.endpoint.collection.enabled,
54
+ timeline_enabled: timeline_enabled,
55
+ )
56
+ worker = Datadog::Profiling::Collectors::CpuAndWallTimeWorker.new(
57
+ gc_profiling_enabled: enable_gc_profiling?(settings),
58
+ allocation_counting_enabled: settings.profiling.advanced.allocation_counting_enabled,
59
+ no_signals_workaround_enabled: no_signals_workaround_enabled,
60
+ thread_context_collector: thread_context_collector,
61
+ allocation_sample_every: 0,
62
+ )
88
63
 
89
- recorder = build_profiler_old_recorder(settings)
90
- collector = build_profiler_oldstack_collector(settings, recorder, optional_tracer)
91
- end
64
+ internal_metadata = {
65
+ no_signals_workaround_enabled: no_signals_workaround_enabled,
66
+ timeline_enabled: timeline_enabled,
67
+ }.freeze
92
68
 
93
- exporter = build_profiler_exporter(settings, recorder, no_signals_workaround_enabled: no_signals_workaround_enabled)
69
+ exporter = build_profiler_exporter(settings, recorder, internal_metadata: internal_metadata)
94
70
  transport = build_profiler_transport(settings, agent_settings)
95
71
  scheduler = Profiling::Scheduler.new(exporter: exporter, transport: transport)
96
72
 
97
- Profiling::Profiler.new([collector], scheduler)
73
+ Profiling::Profiler.new(worker: worker, scheduler: scheduler)
98
74
  end
99
75
 
100
- private_class_method def self.build_profiler_old_recorder(settings)
101
- Profiling::OldRecorder.new([Profiling::Events::StackSample], settings.profiling.advanced.max_events)
102
- end
103
-
104
- private_class_method def self.build_profiler_exporter(settings, recorder, no_signals_workaround_enabled:)
76
+ private_class_method def self.build_profiler_exporter(settings, recorder, internal_metadata:)
105
77
  code_provenance_collector =
106
78
  (Profiling::Collectors::CodeProvenance.new if settings.profiling.advanced.code_provenance_enabled)
107
79
 
108
80
  Profiling::Exporter.new(
109
81
  pprof_recorder: recorder,
110
82
  code_provenance_collector: code_provenance_collector,
111
- no_signals_workaround_enabled: no_signals_workaround_enabled,
112
- )
113
- end
114
-
115
- private_class_method def self.build_profiler_oldstack_collector(settings, old_recorder, tracer)
116
- trace_identifiers_helper = Profiling::TraceIdentifiers::Helper.new(
117
- tracer: tracer,
118
- endpoint_collection_enabled: settings.profiling.advanced.endpoint.collection.enabled
119
- )
120
-
121
- Profiling::Collectors::OldStack.new(
122
- old_recorder,
123
- trace_identifiers_helper: trace_identifiers_helper,
124
- max_frames: settings.profiling.advanced.max_frames
83
+ internal_metadata: internal_metadata,
125
84
  )
126
85
  end
127
86
 
@@ -151,17 +110,6 @@ module Datadog
151
110
  end
152
111
  end
153
112
 
154
- private_class_method def self.enable_new_profiler?(settings)
155
- if settings.profiling.advanced.force_enable_legacy_profiler
156
- Datadog.logger.warn(
157
- 'Legacy profiler has been force-enabled via configuration. Do not use unless instructed to by support.'
158
- )
159
- return false
160
- end
161
-
162
- true
163
- end
164
-
165
113
  private_class_method def self.no_signals_workaround_enabled?(settings) # rubocop:disable Metrics/MethodLength
166
114
  setting_value = settings.profiling.advanced.no_signals_workaround_enabled
167
115
  legacy_ruby_that_should_use_workaround = RUBY_VERSION.start_with?('2.3.', '2.4.', '2.5.')
@@ -289,19 +237,6 @@ module Datadog
289
237
  true
290
238
  end
291
239
  end
292
-
293
- # The old profiler's pprof support conflicts with the ruby-cloud-profiler gem.
294
- #
295
- # This is not a problem for almost all customers, since we now default everyone to use the new CPU Profiling 2.0
296
- # profiler. But the issue was still triggered, because currently we still _load_ both the old and new profiling
297
- # code paths.
298
- #
299
- # To work around this issue, and because we plan on deleting the old profiler soon, rather than poking at the
300
- # pprof support code, we only load the conflicting file when the old profiler is in use. This way customers using
301
- # the new profiler will not be affected by the issue any longer.
302
- private_class_method def self.load_pprof_support
303
- require_relative 'pprof/pprof_pb'
304
- end
305
240
  end
306
241
  end
307
242
  end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'date'
4
+ require 'json'
5
+ require 'rbconfig'
6
+ require_relative '../../core/diagnostics/environment_logger'
7
+
8
+ module Datadog
9
+ module Profiling
10
+ module Diagnostics
11
+ # Collects and logs Profiling diagnostic information
12
+ module EnvironmentLogger
13
+ extend Core::Diagnostics::EnvironmentLogging
14
+
15
+ def self.collect_and_log!
16
+ log_once! do
17
+ data = EnvironmentCollector.collect_config!
18
+ log_configuration!('PROFILING', data.to_json)
19
+ end
20
+ rescue => e
21
+ logger.warn("Failed to collect profiling environment information: #{e} Location: #{Array(e.backtrace).first}")
22
+ end
23
+ end
24
+
25
+ # Collects environment information for Profiling diagnostic logging
26
+ module EnvironmentCollector
27
+ def self.collect_config!(*args)
28
+ {
29
+ profiling_enabled: profiling_enabled
30
+ }
31
+ end
32
+
33
+ def self.profiling_enabled
34
+ !!Datadog.configuration.profiling.enabled
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end