ddtrace 1.18.0 → 1.23.2

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 (229) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +228 -2
  3. data/LICENSE-3rdparty.csv +1 -1
  4. data/bin/ddprofrb +15 -0
  5. data/bin/ddtracerb +3 -1
  6. data/ext/{ddtrace_profiling_loader/ddtrace_profiling_loader.c → datadog_profiling_loader/datadog_profiling_loader.c} +2 -2
  7. data/ext/{ddtrace_profiling_loader → datadog_profiling_loader}/extconf.rb +3 -3
  8. data/ext/{ddtrace_profiling_native_extension → datadog_profiling_native_extension}/collectors_cpu_and_wall_time_worker.c +312 -117
  9. data/ext/datadog_profiling_native_extension/collectors_discrete_dynamic_sampler.c +422 -0
  10. data/ext/datadog_profiling_native_extension/collectors_discrete_dynamic_sampler.h +101 -0
  11. data/ext/{ddtrace_profiling_native_extension → datadog_profiling_native_extension}/collectors_dynamic_sampling_rate.c +22 -14
  12. data/ext/{ddtrace_profiling_native_extension → datadog_profiling_native_extension}/collectors_dynamic_sampling_rate.h +4 -0
  13. data/ext/datadog_profiling_native_extension/collectors_gc_profiling_helper.c +156 -0
  14. data/ext/datadog_profiling_native_extension/collectors_gc_profiling_helper.h +5 -0
  15. data/ext/{ddtrace_profiling_native_extension → datadog_profiling_native_extension}/collectors_stack.c +43 -102
  16. data/ext/{ddtrace_profiling_native_extension → datadog_profiling_native_extension}/collectors_stack.h +10 -3
  17. data/ext/{ddtrace_profiling_native_extension → datadog_profiling_native_extension}/collectors_thread_context.c +272 -136
  18. data/ext/{ddtrace_profiling_native_extension → datadog_profiling_native_extension}/collectors_thread_context.h +2 -1
  19. data/ext/{ddtrace_profiling_native_extension → datadog_profiling_native_extension}/extconf.rb +28 -7
  20. data/ext/datadog_profiling_native_extension/heap_recorder.c +1047 -0
  21. data/ext/datadog_profiling_native_extension/heap_recorder.h +166 -0
  22. data/ext/{ddtrace_profiling_native_extension → datadog_profiling_native_extension}/helpers.h +6 -0
  23. data/ext/{ddtrace_profiling_native_extension → datadog_profiling_native_extension}/http_transport.c +15 -19
  24. data/ext/{ddtrace_profiling_native_extension → datadog_profiling_native_extension}/libdatadog_helpers.c +20 -0
  25. data/ext/{ddtrace_profiling_native_extension → datadog_profiling_native_extension}/libdatadog_helpers.h +11 -0
  26. data/ext/{ddtrace_profiling_native_extension → datadog_profiling_native_extension}/native_extension_helpers.rb +50 -4
  27. data/ext/{ddtrace_profiling_native_extension → datadog_profiling_native_extension}/private_vm_api_access.c +19 -0
  28. data/ext/{ddtrace_profiling_native_extension → datadog_profiling_native_extension}/private_vm_api_access.h +4 -0
  29. data/ext/{ddtrace_profiling_native_extension → datadog_profiling_native_extension}/profiling.c +18 -1
  30. data/ext/datadog_profiling_native_extension/ruby_helpers.c +267 -0
  31. data/ext/{ddtrace_profiling_native_extension → datadog_profiling_native_extension}/ruby_helpers.h +33 -0
  32. data/ext/{ddtrace_profiling_native_extension → datadog_profiling_native_extension}/stack_recorder.c +476 -58
  33. data/ext/{ddtrace_profiling_native_extension → datadog_profiling_native_extension}/stack_recorder.h +3 -0
  34. data/ext/{ddtrace_profiling_native_extension → datadog_profiling_native_extension}/time_helpers.h +2 -0
  35. data/lib/datadog/appsec/contrib/devise/tracking.rb +8 -0
  36. data/lib/datadog/appsec/contrib/rack/request_middleware.rb +45 -14
  37. data/lib/datadog/appsec/event.rb +1 -1
  38. data/lib/datadog/auto_instrument.rb +3 -0
  39. data/lib/datadog/core/configuration/components.rb +7 -6
  40. data/lib/datadog/core/configuration/option.rb +8 -6
  41. data/lib/datadog/core/configuration/settings.rb +259 -60
  42. data/lib/datadog/core/configuration.rb +20 -4
  43. data/lib/datadog/core/diagnostics/environment_logger.rb +4 -3
  44. data/lib/datadog/core/environment/class_count.rb +6 -6
  45. data/lib/datadog/core/environment/git.rb +25 -0
  46. data/lib/datadog/core/environment/identity.rb +18 -48
  47. data/lib/datadog/core/environment/platform.rb +7 -1
  48. data/lib/datadog/core/git/ext.rb +2 -23
  49. data/lib/datadog/core/remote/client/capabilities.rb +1 -1
  50. data/lib/datadog/core/remote/component.rb +25 -12
  51. data/lib/datadog/core/remote/ext.rb +1 -0
  52. data/lib/datadog/core/remote/negotiation.rb +2 -2
  53. data/lib/datadog/core/remote/tie/tracing.rb +39 -0
  54. data/lib/datadog/core/remote/tie.rb +27 -0
  55. data/lib/datadog/core/remote/transport/http/config.rb +1 -1
  56. data/lib/datadog/core/remote/worker.rb +7 -4
  57. data/lib/datadog/core/telemetry/client.rb +18 -10
  58. data/lib/datadog/core/telemetry/emitter.rb +9 -13
  59. data/lib/datadog/core/telemetry/event.rb +247 -56
  60. data/lib/datadog/core/telemetry/ext.rb +4 -0
  61. data/lib/datadog/core/telemetry/heartbeat.rb +1 -3
  62. data/lib/datadog/core/telemetry/http/ext.rb +4 -1
  63. data/lib/datadog/core/telemetry/http/response.rb +4 -0
  64. data/lib/datadog/core/telemetry/http/transport.rb +9 -4
  65. data/lib/datadog/core/telemetry/request.rb +59 -0
  66. data/lib/datadog/core/transport/ext.rb +2 -0
  67. data/lib/datadog/core/utils/url.rb +25 -0
  68. data/lib/datadog/opentelemetry/sdk/propagator.rb +3 -2
  69. data/lib/datadog/opentelemetry.rb +3 -0
  70. data/lib/datadog/profiling/collectors/code_provenance.rb +10 -4
  71. data/lib/datadog/profiling/collectors/cpu_and_wall_time_worker.rb +36 -12
  72. data/lib/datadog/profiling/collectors/info.rb +101 -0
  73. data/lib/datadog/profiling/component.rb +210 -34
  74. data/lib/datadog/profiling/exporter.rb +23 -6
  75. data/lib/datadog/profiling/ext.rb +2 -0
  76. data/lib/datadog/profiling/flush.rb +6 -3
  77. data/lib/datadog/profiling/http_transport.rb +5 -1
  78. data/lib/datadog/profiling/load_native_extension.rb +19 -6
  79. data/lib/datadog/profiling/native_extension.rb +1 -1
  80. data/lib/datadog/profiling/scheduler.rb +4 -6
  81. data/lib/datadog/profiling/stack_recorder.rb +19 -4
  82. data/lib/datadog/profiling/tag_builder.rb +5 -0
  83. data/lib/datadog/profiling/tasks/exec.rb +3 -3
  84. data/lib/datadog/profiling/tasks/help.rb +3 -3
  85. data/lib/datadog/profiling.rb +13 -2
  86. data/lib/datadog/tracing/configuration/ext.rb +0 -1
  87. data/lib/datadog/tracing/configuration/settings.rb +2 -1
  88. data/lib/datadog/tracing/contrib/action_cable/configuration/settings.rb +1 -0
  89. data/lib/datadog/tracing/contrib/action_cable/ext.rb +1 -0
  90. data/lib/datadog/tracing/contrib/action_mailer/configuration/settings.rb +1 -0
  91. data/lib/datadog/tracing/contrib/action_mailer/events/deliver.rb +1 -1
  92. data/lib/datadog/tracing/contrib/action_mailer/ext.rb +1 -0
  93. data/lib/datadog/tracing/contrib/action_pack/configuration/settings.rb +1 -0
  94. data/lib/datadog/tracing/contrib/action_pack/ext.rb +1 -0
  95. data/lib/datadog/tracing/contrib/action_view/configuration/settings.rb +1 -0
  96. data/lib/datadog/tracing/contrib/action_view/ext.rb +1 -0
  97. data/lib/datadog/tracing/contrib/active_job/configuration/settings.rb +1 -0
  98. data/lib/datadog/tracing/contrib/active_job/ext.rb +1 -0
  99. data/lib/datadog/tracing/contrib/active_model_serializers/configuration/settings.rb +1 -0
  100. data/lib/datadog/tracing/contrib/active_model_serializers/ext.rb +1 -0
  101. data/lib/datadog/tracing/contrib/active_record/configuration/resolver.rb +11 -4
  102. data/lib/datadog/tracing/contrib/active_record/configuration/settings.rb +1 -0
  103. data/lib/datadog/tracing/contrib/active_record/ext.rb +1 -0
  104. data/lib/datadog/tracing/contrib/active_support/configuration/settings.rb +1 -0
  105. data/lib/datadog/tracing/contrib/active_support/ext.rb +1 -0
  106. data/lib/datadog/tracing/contrib/analytics.rb +0 -1
  107. data/lib/datadog/tracing/contrib/aws/configuration/settings.rb +1 -0
  108. data/lib/datadog/tracing/contrib/aws/ext.rb +1 -0
  109. data/lib/datadog/tracing/contrib/concurrent_ruby/async_patch.rb +20 -0
  110. data/lib/datadog/tracing/contrib/concurrent_ruby/patcher.rb +11 -1
  111. data/lib/datadog/tracing/contrib/configurable.rb +1 -1
  112. data/lib/datadog/tracing/contrib/dalli/configuration/settings.rb +1 -0
  113. data/lib/datadog/tracing/contrib/dalli/ext.rb +1 -0
  114. data/lib/datadog/tracing/contrib/delayed_job/configuration/settings.rb +1 -0
  115. data/lib/datadog/tracing/contrib/delayed_job/ext.rb +1 -0
  116. data/lib/datadog/tracing/contrib/elasticsearch/configuration/settings.rb +1 -0
  117. data/lib/datadog/tracing/contrib/elasticsearch/ext.rb +1 -0
  118. data/lib/datadog/tracing/contrib/ethon/configuration/settings.rb +1 -0
  119. data/lib/datadog/tracing/contrib/ethon/ext.rb +1 -0
  120. data/lib/datadog/tracing/contrib/excon/configuration/settings.rb +1 -0
  121. data/lib/datadog/tracing/contrib/excon/ext.rb +1 -0
  122. data/lib/datadog/tracing/contrib/extensions.rb +6 -2
  123. data/lib/datadog/tracing/contrib/faraday/configuration/settings.rb +7 -0
  124. data/lib/datadog/tracing/contrib/faraday/ext.rb +1 -0
  125. data/lib/datadog/tracing/contrib/faraday/middleware.rb +1 -1
  126. data/lib/datadog/tracing/contrib/grape/configuration/settings.rb +1 -0
  127. data/lib/datadog/tracing/contrib/grape/ext.rb +1 -0
  128. data/lib/datadog/tracing/contrib/graphql/configuration/settings.rb +1 -0
  129. data/lib/datadog/tracing/contrib/graphql/ext.rb +1 -0
  130. data/lib/datadog/tracing/contrib/grpc/configuration/settings.rb +1 -0
  131. data/lib/datadog/tracing/contrib/grpc/ext.rb +1 -0
  132. data/lib/datadog/tracing/contrib/http/configuration/settings.rb +1 -0
  133. data/lib/datadog/tracing/contrib/http/distributed/fetcher.rb +2 -2
  134. data/lib/datadog/tracing/contrib/http/ext.rb +1 -0
  135. data/lib/datadog/tracing/contrib/httpclient/configuration/settings.rb +1 -0
  136. data/lib/datadog/tracing/contrib/httpclient/ext.rb +1 -0
  137. data/lib/datadog/tracing/contrib/httprb/configuration/settings.rb +1 -0
  138. data/lib/datadog/tracing/contrib/httprb/ext.rb +1 -0
  139. data/lib/datadog/tracing/contrib/kafka/configuration/settings.rb +1 -0
  140. data/lib/datadog/tracing/contrib/kafka/ext.rb +1 -0
  141. data/lib/datadog/tracing/contrib/mongodb/configuration/settings.rb +1 -0
  142. data/lib/datadog/tracing/contrib/mongodb/ext.rb +1 -0
  143. data/lib/datadog/tracing/contrib/mysql2/configuration/settings.rb +5 -0
  144. data/lib/datadog/tracing/contrib/mysql2/ext.rb +1 -0
  145. data/lib/datadog/tracing/contrib/mysql2/instrumentation.rb +2 -1
  146. data/lib/datadog/tracing/contrib/opensearch/configuration/settings.rb +1 -0
  147. data/lib/datadog/tracing/contrib/opensearch/ext.rb +1 -0
  148. data/lib/datadog/tracing/contrib/pg/configuration/settings.rb +1 -0
  149. data/lib/datadog/tracing/contrib/pg/ext.rb +1 -0
  150. data/lib/datadog/tracing/contrib/pg/instrumentation.rb +11 -4
  151. data/lib/datadog/tracing/contrib/presto/configuration/settings.rb +1 -0
  152. data/lib/datadog/tracing/contrib/presto/ext.rb +1 -0
  153. data/lib/datadog/tracing/contrib/qless/configuration/settings.rb +1 -0
  154. data/lib/datadog/tracing/contrib/qless/ext.rb +1 -0
  155. data/lib/datadog/tracing/contrib/que/configuration/settings.rb +1 -0
  156. data/lib/datadog/tracing/contrib/que/ext.rb +1 -0
  157. data/lib/datadog/tracing/contrib/racecar/configuration/settings.rb +1 -0
  158. data/lib/datadog/tracing/contrib/racecar/ext.rb +1 -0
  159. data/lib/datadog/tracing/contrib/rack/configuration/settings.rb +1 -0
  160. data/lib/datadog/tracing/contrib/rack/ext.rb +1 -0
  161. data/lib/datadog/tracing/contrib/rack/middlewares.rb +9 -2
  162. data/lib/datadog/tracing/contrib/rails/auto_instrument_railtie.rb +0 -2
  163. data/lib/datadog/tracing/contrib/rails/configuration/settings.rb +1 -0
  164. data/lib/datadog/tracing/contrib/rails/ext.rb +1 -0
  165. data/lib/datadog/tracing/contrib/rake/configuration/settings.rb +1 -0
  166. data/lib/datadog/tracing/contrib/rake/ext.rb +1 -0
  167. data/lib/datadog/tracing/contrib/redis/configuration/settings.rb +1 -0
  168. data/lib/datadog/tracing/contrib/redis/ext.rb +1 -0
  169. data/lib/datadog/tracing/contrib/redis/instrumentation.rb +2 -2
  170. data/lib/datadog/tracing/contrib/redis/patcher.rb +34 -21
  171. data/lib/datadog/tracing/contrib/resque/configuration/settings.rb +1 -0
  172. data/lib/datadog/tracing/contrib/resque/ext.rb +1 -0
  173. data/lib/datadog/tracing/contrib/rest_client/configuration/settings.rb +1 -0
  174. data/lib/datadog/tracing/contrib/rest_client/ext.rb +1 -0
  175. data/lib/datadog/tracing/contrib/roda/configuration/settings.rb +1 -0
  176. data/lib/datadog/tracing/contrib/roda/ext.rb +1 -0
  177. data/lib/datadog/tracing/contrib/sequel/configuration/settings.rb +1 -0
  178. data/lib/datadog/tracing/contrib/sequel/ext.rb +1 -0
  179. data/lib/datadog/tracing/contrib/shoryuken/configuration/settings.rb +1 -0
  180. data/lib/datadog/tracing/contrib/shoryuken/ext.rb +1 -0
  181. data/lib/datadog/tracing/contrib/sidekiq/configuration/settings.rb +1 -0
  182. data/lib/datadog/tracing/contrib/sidekiq/ext.rb +1 -0
  183. data/lib/datadog/tracing/contrib/sinatra/configuration/settings.rb +1 -0
  184. data/lib/datadog/tracing/contrib/sinatra/ext.rb +1 -0
  185. data/lib/datadog/tracing/contrib/sneakers/configuration/settings.rb +1 -0
  186. data/lib/datadog/tracing/contrib/sneakers/ext.rb +1 -0
  187. data/lib/datadog/tracing/contrib/stripe/configuration/settings.rb +1 -0
  188. data/lib/datadog/tracing/contrib/stripe/ext.rb +1 -0
  189. data/lib/datadog/tracing/contrib/sucker_punch/configuration/settings.rb +1 -0
  190. data/lib/datadog/tracing/contrib/sucker_punch/ext.rb +1 -0
  191. data/lib/datadog/tracing/contrib/trilogy/configuration/settings.rb +58 -0
  192. data/lib/datadog/tracing/contrib/trilogy/ext.rb +27 -0
  193. data/lib/datadog/tracing/contrib/trilogy/instrumentation.rb +94 -0
  194. data/lib/datadog/tracing/contrib/trilogy/integration.rb +43 -0
  195. data/lib/datadog/tracing/contrib/trilogy/patcher.rb +31 -0
  196. data/lib/datadog/tracing/contrib.rb +1 -0
  197. data/lib/datadog/tracing/sampling/matcher.rb +23 -3
  198. data/lib/datadog/tracing/sampling/rule.rb +7 -2
  199. data/lib/datadog/tracing/sampling/rule_sampler.rb +2 -0
  200. data/lib/datadog/tracing/trace_operation.rb +1 -2
  201. data/lib/datadog/tracing/transport/http.rb +1 -0
  202. data/lib/datadog/tracing/transport/trace_formatter.rb +31 -0
  203. data/lib/datadog/tracing.rb +8 -2
  204. data/lib/ddtrace/version.rb +2 -2
  205. metadata +71 -61
  206. data/ext/ddtrace_profiling_native_extension/pid_controller.c +0 -57
  207. data/ext/ddtrace_profiling_native_extension/pid_controller.h +0 -45
  208. data/ext/ddtrace_profiling_native_extension/ruby_helpers.c +0 -110
  209. data/lib/datadog/core/telemetry/collector.rb +0 -240
  210. data/lib/datadog/core/telemetry/v1/app_event.rb +0 -52
  211. data/lib/datadog/core/telemetry/v1/application.rb +0 -92
  212. data/lib/datadog/core/telemetry/v1/configuration.rb +0 -25
  213. data/lib/datadog/core/telemetry/v1/dependency.rb +0 -43
  214. data/lib/datadog/core/telemetry/v1/host.rb +0 -59
  215. data/lib/datadog/core/telemetry/v1/integration.rb +0 -64
  216. data/lib/datadog/core/telemetry/v1/product.rb +0 -36
  217. data/lib/datadog/core/telemetry/v1/telemetry_request.rb +0 -106
  218. data/lib/datadog/core/telemetry/v2/app_client_configuration_change.rb +0 -41
  219. data/lib/datadog/core/telemetry/v2/request.rb +0 -29
  220. data/lib/datadog/profiling/diagnostics/environment_logger.rb +0 -39
  221. /data/ext/{ddtrace_profiling_native_extension → datadog_profiling_native_extension}/NativeExtensionDesign.md +0 -0
  222. /data/ext/{ddtrace_profiling_native_extension → datadog_profiling_native_extension}/clock_id.h +0 -0
  223. /data/ext/{ddtrace_profiling_native_extension → datadog_profiling_native_extension}/clock_id_from_pthread.c +0 -0
  224. /data/ext/{ddtrace_profiling_native_extension → datadog_profiling_native_extension}/clock_id_noop.c +0 -0
  225. /data/ext/{ddtrace_profiling_native_extension → datadog_profiling_native_extension}/collectors_idle_sampling_helper.c +0 -0
  226. /data/ext/{ddtrace_profiling_native_extension → datadog_profiling_native_extension}/collectors_idle_sampling_helper.h +0 -0
  227. /data/ext/{ddtrace_profiling_native_extension → datadog_profiling_native_extension}/setup_signal_handler.c +0 -0
  228. /data/ext/{ddtrace_profiling_native_extension → datadog_profiling_native_extension}/setup_signal_handler.h +0 -0
  229. /data/ext/{ddtrace_profiling_native_extension → datadog_profiling_native_extension}/time_helpers.c +0 -0
@@ -1,80 +1,271 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative 'collector'
4
- require_relative 'v1/app_event'
5
- require_relative 'v1/telemetry_request'
6
- require_relative 'v2/app_client_configuration_change'
7
-
8
3
  module Datadog
9
4
  module Core
10
5
  module Telemetry
11
- # Class defining methods to construct a Telemetry event
12
6
  class Event
13
- include Telemetry::Collector
7
+ # Base class for all Telemetry V2 events.
8
+ class Base
9
+ # The type of the event.
10
+ # It must be one of the stings defined in the Telemetry V2
11
+ # specification for event names.
12
+ def type; end
13
+
14
+ # The JSON payload for the event.
15
+ # @param seq_id [Integer] The sequence ID for the event.
16
+ def payload(seq_id)
17
+ {}
18
+ end
19
+ end
20
+
21
+ # Telemetry class for the 'app-started' event
22
+ class AppStarted < Base
23
+ def type
24
+ 'app-started'
25
+ end
26
+
27
+ def payload(seq_id)
28
+ @seq_id = seq_id
29
+ {
30
+ products: products,
31
+ configuration: configuration,
32
+ install_signature: install_signature,
33
+ # DEV: Not implemented yet
34
+ # error: error, # Start-up errors
35
+ }
36
+ end
37
+
38
+ private
39
+
40
+ def products
41
+ products = {
42
+ appsec: {
43
+ enabled: Datadog::AppSec.enabled?,
44
+ },
45
+ profiler: {
46
+ enabled: Datadog::Profiling.enabled?,
47
+ },
48
+ # DEV: Not implemented yet
49
+ # dynamic_instrumentation: {
50
+ # enabled: true,
51
+ # }
52
+ }
53
+
54
+ if (unsupported_reason = Datadog::Profiling.unsupported_reason)
55
+ products[:profiler][:error] = {
56
+ code: 1, # Error code. 0 if no error.
57
+ message: unsupported_reason,
58
+ }
59
+ end
60
+
61
+ products
62
+ end
63
+
64
+ TARGET_OPTIONS = %w[
65
+ logger.level
66
+ profiling.advanced.code_provenance_enabled
67
+ profiling.advanced.endpoint.collection.enabled
68
+ profiling.enabled
69
+ runtime_metrics.enabled
70
+ tracing.analytics.enabled
71
+ tracing.distributed_tracing.propagation_inject_style
72
+ tracing.distributed_tracing.propagation_extract_style
73
+ tracing.enabled
74
+ tracing.log_injection
75
+ tracing.partial_flush.enabled
76
+ tracing.partial_flush.min_spans_threshold
77
+ tracing.report_hostname
78
+ tracing.sampling.rate_limit
79
+ ].freeze
80
+
81
+ # rubocop:disable Metrics/AbcSize
82
+ def configuration
83
+ config = Datadog.configuration
84
+
85
+ list = [
86
+ conf_value('DD_AGENT_HOST', config.agent.host),
87
+ conf_value('DD_AGENT_TRANSPORT', agent_transport(config)),
88
+ conf_value('DD_TRACE_SAMPLE_RATE', to_value(config.tracing.sampling.default_rate)),
89
+ conf_value(
90
+ 'DD_TRACE_REMOVE_INTEGRATION_SERVICE_NAMES_ENABLED',
91
+ config.tracing.contrib.global_default_service_name.enabled
92
+ ),
93
+ ]
14
94
 
15
- API_VERSION = 'v1'
95
+ peer_service_mapping_str = ''
96
+ unless config.tracing.contrib.peer_service_mapping.empty?
97
+ peer_service_mapping = config.tracing.contrib.peer_service_mapping
98
+ peer_service_mapping_str = peer_service_mapping.map { |key, value| "#{key}:#{value}" }.join(',')
99
+ end
100
+ list << conf_value('DD_TRACE_PEER_SERVICE_MAPPING', peer_service_mapping_str)
16
101
 
17
- attr_reader \
18
- :api_version
102
+ # Whitelist of configuration options to send in additional payload object
103
+ TARGET_OPTIONS.each do |option|
104
+ split_option = option.split('.')
105
+ list << conf_value(option, to_value(config.dig(*split_option)))
106
+ end
107
+
108
+ # Add some more custom additional payload values here
109
+ list.push(
110
+ conf_value('tracing.auto_instrument.enabled', !defined?(Datadog::AutoInstrument::LOADED).nil?),
111
+ conf_value('tracing.writer_options.buffer_size', to_value(config.tracing.writer_options[:buffer_size])),
112
+ conf_value('tracing.writer_options.flush_interval', to_value(config.tracing.writer_options[:flush_interval])),
113
+ conf_value('tracing.opentelemetry.enabled', !defined?(Datadog::OpenTelemetry::LOADED).nil?),
114
+ )
115
+ list << conf_value('logger.instance', config.logger.instance.class.to_s) if config.logger.instance
116
+ list << conf_value('appsec.enabled', config.dig('appsec', 'enabled')) if config.respond_to?('appsec')
117
+ list << conf_value('ci.enabled', config.dig('ci', 'enabled')) if config.respond_to?('ci')
118
+
119
+ list.reject! { |entry| entry[:value].nil? }
120
+ list
121
+ end
122
+ # rubocop:enable Metrics/AbcSize
123
+
124
+ def agent_transport(config)
125
+ adapter = Core::Configuration::AgentSettingsResolver.call(config).adapter
126
+ if adapter == Datadog::Core::Transport::Ext::UnixSocket::ADAPTER
127
+ 'UDS'
128
+ else
129
+ 'TCP'
130
+ end
131
+ end
132
+
133
+ def conf_value(name, value, origin = 'code')
134
+ {
135
+ name: name,
136
+ value: value,
137
+ origin: origin,
138
+ seq_id: @seq_id,
139
+ }
140
+ end
141
+
142
+ def to_value(value)
143
+ # TODO: Add float if telemetry starts accepting it
144
+ case value
145
+ when Integer, String, true, false, nil
146
+ value
147
+ else
148
+ value.to_s
149
+ end
150
+ end
19
151
 
20
- def initialize
21
- @api_version = API_VERSION
152
+ def install_signature
153
+ config = Datadog.configuration
154
+ {
155
+ install_id: config.dig('telemetry', 'install_id'),
156
+ install_type: config.dig('telemetry', 'install_type'),
157
+ install_time: config.dig('telemetry', 'install_time'),
158
+ }
159
+ end
22
160
  end
23
161
 
24
- # Forms a TelemetryRequest object based on the event request_type
25
- # @param request_type [String] the type of telemetry request to collect data for
26
- # @param seq_id [Integer] the ID of the request; incremented each time a telemetry request is sent to the API
27
- # @param data [Object] arbitrary object to be passed to the respective `request_type` handler
28
- def telemetry_request(request_type:, seq_id:, data: nil)
29
- Telemetry::V1::TelemetryRequest.new(
30
- api_version: @api_version,
31
- application: application,
32
- host: host,
33
- payload: payload(request_type, data),
34
- request_type: request_type,
35
- runtime_id: runtime_id,
36
- seq_id: seq_id,
37
- tracer_time: tracer_time,
38
- )
162
+ # Telemetry class for the 'app-dependencies-loaded' event
163
+ class AppDependenciesLoaded < Base
164
+ def type
165
+ 'app-dependencies-loaded'
166
+ end
167
+
168
+ def payload(seq_id)
169
+ { dependencies: dependencies }
170
+ end
171
+
172
+ private
173
+
174
+ def dependencies
175
+ Gem.loaded_specs.collect do |name, gem|
176
+ {
177
+ name: name,
178
+ version: gem.version.to_s,
179
+ # hash: nil,
180
+ }
181
+ end
182
+ end
39
183
  end
40
184
 
41
- private
185
+ # Telemetry class for the 'app-integrations-change' event
186
+ class AppIntegrationsChange < Base
187
+ def type
188
+ 'app-integrations-change'
189
+ end
42
190
 
43
- def payload(request_type, data)
44
- case request_type
45
- when :'app-started'
46
- app_started
47
- when :'app-closing', :'app-heartbeat'
48
- {}
49
- when :'app-integrations-change'
50
- app_integrations_change
51
- when 'app-client-configuration-change'
52
- app_client_configuration_change(data)
53
- else
54
- raise ArgumentError, "Request type invalid, received request_type: #{@request_type}"
191
+ def payload(seq_id)
192
+ { integrations: integrations }
193
+ end
194
+
195
+ private
196
+
197
+ def integrations
198
+ instrumented_integrations = Datadog.configuration.tracing.instrumented_integrations
199
+ Datadog.registry.map do |integration|
200
+ is_instrumented = instrumented_integrations.include?(integration.name)
201
+
202
+ is_enabled = is_instrumented ? !!integration.klass.patcher.patch_successful : false
203
+
204
+ version = integration.klass.class.version ? integration.klass.class.version.to_s : nil
205
+
206
+ res = {
207
+ name: integration.name.to_s,
208
+ enabled: is_enabled,
209
+ version: version,
210
+ compatible: integration.klass.class.compatible?,
211
+ error: (patch_error(integration) if is_instrumented && !is_enabled),
212
+ # TODO: Track if integration is instrumented by manual configuration or by auto instrumentation
213
+ # auto_enabled: is_enabled && ???,
214
+ }
215
+ res.reject! { |_, v| v.nil? }
216
+ res
217
+ end
218
+ end
219
+
220
+ def patch_error(integration)
221
+ patch_error_result = integration.klass.patcher.patch_error_result
222
+ return patch_error_result.compact.to_s if patch_error_result
223
+
224
+ # If no error occurred during patching, but integration is still not instrumented
225
+ "Available?: #{integration.klass.class.available?}" \
226
+ ", Loaded? #{integration.klass.class.loaded?}" \
227
+ ", Compatible? #{integration.klass.class.compatible?}" \
228
+ ", Patchable? #{integration.klass.class.patchable?}"
55
229
  end
56
230
  end
57
231
 
58
- def app_started
59
- Telemetry::V1::AppEvent.new(
60
- dependencies: dependencies,
61
- integrations: integrations,
62
- configuration: configurations,
63
- additional_payload: additional_payload
64
- )
232
+ # Telemetry class for the 'app-client-configuration-change' event
233
+ class AppClientConfigurationChange < Base
234
+ def type
235
+ 'app-client-configuration-change'
236
+ end
237
+
238
+ def initialize(changes, origin)
239
+ super()
240
+ @changes = changes
241
+ @origin = origin
242
+ end
243
+
244
+ def payload(seq_id)
245
+ {
246
+ configuration: @changes.map do |name, value|
247
+ {
248
+ name: name,
249
+ value: value,
250
+ origin: @origin,
251
+ }
252
+ end
253
+ }
254
+ end
65
255
  end
66
256
 
67
- def app_integrations_change
68
- Telemetry::V1::AppEvent.new(integrations: integrations)
257
+ # Telemetry class for the 'app-heartbeat' event
258
+ class AppHeartbeat < Base
259
+ def type
260
+ 'app-heartbeat'
261
+ end
69
262
  end
70
263
 
71
- # DEV: During the transition from V1 to V2, the backend accepts many V2
72
- # DEV: payloads through the V1 transport protocol.
73
- # DEV: The `app-client-configuration-change` payload is one of them.
74
- # DEV: Once V2 is fully implemented, `Telemetry::V2::AppClientConfigurationChange`
75
- # DEV: should be reusable without major modifications.
76
- def app_client_configuration_change(data)
77
- Telemetry::V2::AppClientConfigurationChange.new(data[:changes], origin: data[:origin])
264
+ # Telemetry class for the 'app-closing' event
265
+ class AppClosing < Base
266
+ def type
267
+ 'app-closing'
268
+ end
78
269
  end
79
270
  end
80
271
  end
@@ -6,6 +6,10 @@ module Datadog
6
6
  module Ext
7
7
  ENV_ENABLED = 'DD_INSTRUMENTATION_TELEMETRY_ENABLED'
8
8
  ENV_HEARTBEAT_INTERVAL = 'DD_TELEMETRY_HEARTBEAT_INTERVAL'
9
+ ENV_DEPENDENCY_COLLECTION = 'DD_TELEMETRY_DEPENDENCY_COLLECTION_ENABLED'
10
+ ENV_INSTALL_ID = 'DD_INSTRUMENTATION_INSTALL_ID'
11
+ ENV_INSTALL_TYPE = 'DD_INSTRUMENTATION_INSTALL_TYPE'
12
+ ENV_INSTALL_TIME = 'DD_INSTRUMENTATION_INSTALL_TIME'
9
13
  end
10
14
  end
11
15
  end
@@ -20,9 +20,7 @@ module Datadog
20
20
  start
21
21
  end
22
22
 
23
- def loop_wait_before_first_iteration?
24
- true
25
- end
23
+ def loop_wait_before_first_iteration?; end
26
24
 
27
25
  private
28
26
 
@@ -10,9 +10,12 @@ module Datadog
10
10
  HEADER_CONTENT_LENGTH = 'Content-Length'
11
11
  HEADER_DD_TELEMETRY_API_VERSION = 'DD-Telemetry-API-Version'
12
12
  HEADER_DD_TELEMETRY_REQUEST_TYPE = 'DD-Telemetry-Request-Type'
13
+ HEADER_TELEMETRY_DEBUG_ENABLED = 'DD-Telemetry-Debug-Enabled'
14
+ HEADER_CLIENT_LIBRARY_LANGUAGE = 'DD-Client-Library-Language'
15
+ HEADER_CLIENT_LIBRARY_VERSION = 'DD-Client-Library-Version'
13
16
 
14
17
  CONTENT_TYPE_APPLICATION_JSON = 'application/json'
15
- API_VERSION = 'v1'
18
+ API_VERSION = 'v2'
16
19
 
17
20
  AGENT_ENDPOINT = '/telemetry/proxy/api/v2/apmtelemetry'
18
21
  end
@@ -32,6 +32,10 @@ module Datadog
32
32
  nil
33
33
  end
34
34
 
35
+ def code
36
+ nil
37
+ end
38
+
35
39
  def inspect
36
40
  "#{self.class} ok?:#{ok?} unsupported?:#{unsupported?}, " \
37
41
  "not_found?:#{not_found?}, client_error?:#{client_error?}, " \
@@ -39,10 +39,15 @@ module Datadog
39
39
 
40
40
  def headers(request_type:, api_version: Http::Ext::API_VERSION)
41
41
  {
42
- Datadog::Core::Transport::Ext::HTTP::HEADER_DD_INTERNAL_UNTRACED_REQUEST => '1',
43
- Http::Ext::HEADER_CONTENT_TYPE => Http::Ext::CONTENT_TYPE_APPLICATION_JSON,
44
- Http::Ext::HEADER_DD_TELEMETRY_API_VERSION => api_version,
45
- Http::Ext::HEADER_DD_TELEMETRY_REQUEST_TYPE => request_type,
42
+ Core::Transport::Ext::HTTP::HEADER_DD_INTERNAL_UNTRACED_REQUEST => '1',
43
+ Ext::HEADER_CONTENT_TYPE => Http::Ext::CONTENT_TYPE_APPLICATION_JSON,
44
+ Ext::HEADER_DD_TELEMETRY_API_VERSION => api_version,
45
+ Ext::HEADER_DD_TELEMETRY_REQUEST_TYPE => request_type,
46
+ Ext::HEADER_CLIENT_LIBRARY_LANGUAGE => Core::Environment::Ext::LANG,
47
+ Ext::HEADER_CLIENT_LIBRARY_VERSION => DDTrace::VERSION::STRING,
48
+
49
+ # Enable debug mode for telemetry
50
+ # HEADER_TELEMETRY_DEBUG_ENABLED => 'true',
46
51
  }
47
52
  end
48
53
 
@@ -0,0 +1,59 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../environment/platform'
4
+ require_relative '../utils/hash'
5
+
6
+ module Datadog
7
+ module Core
8
+ module Telemetry
9
+ # Module defining methods for collecting metadata for telemetry
10
+ module Request
11
+ class << self
12
+ using Core::Utils::Hash::Refinement
13
+
14
+ def build_payload(event, seq_id)
15
+ hash = {
16
+ api_version: Http::Ext::API_VERSION,
17
+ application: application,
18
+ debug: false,
19
+ host: host,
20
+ payload: event.payload(seq_id),
21
+ request_type: event.type,
22
+ runtime_id: Core::Environment::Identity.id,
23
+ seq_id: seq_id,
24
+ tracer_time: Time.now.to_i,
25
+ }
26
+ hash.compact!
27
+ hash
28
+ end
29
+
30
+ private
31
+
32
+ def application
33
+ config = Datadog.configuration
34
+ {
35
+ env: config.env,
36
+ language_name: Core::Environment::Ext::LANG,
37
+ language_version: Core::Environment::Ext::LANG_VERSION,
38
+ runtime_name: Core::Environment::Ext::RUBY_ENGINE,
39
+ runtime_version: Core::Environment::Ext::ENGINE_VERSION,
40
+ service_name: config.service,
41
+ service_version: config.version,
42
+ tracer_version: Core::Environment::Identity.tracer_version
43
+ }
44
+ end
45
+
46
+ def host
47
+ {
48
+ architecture: Core::Environment::Platform.architecture,
49
+ hostname: Core::Environment::Platform.hostname,
50
+ kernel_name: Core::Environment::Platform.kernel_name,
51
+ kernel_release: Core::Environment::Platform.kernel_release,
52
+ kernel_version: Core::Environment::Platform.kernel_version
53
+ }
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
@@ -25,6 +25,8 @@ module Datadog
25
25
  HEADER_META_LANG = 'Datadog-Meta-Lang'
26
26
  HEADER_META_LANG_VERSION = 'Datadog-Meta-Lang-Version'
27
27
  HEADER_META_LANG_INTERPRETER = 'Datadog-Meta-Lang-Interpreter'
28
+ # Use for distinguishing between CRuby, JRuby, and TruffleRuby.
29
+ HEADER_META_LANG_INTERPRETER_VENDOR = 'Datadog-Meta-Lang-Interpreter-Vendor'
28
30
  HEADER_META_TRACER_VERSION = 'Datadog-Meta-Tracer-Version'
29
31
 
30
32
  # Header that prevents the Net::HTTP integration from tracing internal trace requests.
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'uri'
4
+
5
+ module Datadog
6
+ module Core
7
+ module Utils
8
+ # Helpers class that provides methods to process URLs
9
+ # such as filtering sensitive information.
10
+ module Url
11
+ def self.filter_basic_auth(url)
12
+ return nil if url.nil?
13
+
14
+ URI(url).tap do |u|
15
+ u.user = nil
16
+ u.password = nil
17
+ end.to_s
18
+ # Git scheme: git@github.com:DataDog/dd-trace-rb.git
19
+ rescue URI::InvalidURIError
20
+ url
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -29,9 +29,10 @@ module Datadog
29
29
  carrier, context: ::OpenTelemetry::Context.current,
30
30
  getter: ::OpenTelemetry::Context::Propagation.text_map_getter
31
31
  )
32
- unless getter == ::OpenTelemetry::Context::Propagation.text_map_getter
32
+ if getter != ::OpenTelemetry::Context::Propagation.text_map_getter &&
33
+ getter != ::OpenTelemetry::Common::Propagation.rack_env_getter
33
34
  Datadog.logger.error(
34
- 'Custom getter is not supported. Please inform the `ddtrace` team at ' \
35
+ "Custom getter #{getter} is not supported. Please inform the `ddtrace` team at " \
35
36
  ' https://github.com/DataDog/dd-trace-rb of your use case so we can best support you. Using the default ' \
36
37
  'OpenTelemetry::Context::Propagation.text_map_getter as a fallback getter.'
37
38
  )
@@ -8,7 +8,10 @@
8
8
  # This file activates the integrations of all OpenTelemetry
9
9
  # components supported by Datadog.
10
10
 
11
+ # Load Tracing
11
12
  require_relative 'tracing'
13
+ require_relative 'tracing/contrib'
14
+
12
15
  require_relative 'opentelemetry/api/context'
13
16
 
14
17
  # DEV: Should this be a Contrib integration, that depends on the `opentelemetry-sdk`
@@ -97,14 +97,20 @@ module Datadog
97
97
  end
98
98
  end
99
99
 
100
- Library = Struct.new(:kind, :name, :version, :path) do
100
+ # Represents metadata we have for a ruby gem
101
+ class Library
102
+ attr_reader :kind, :name, :version, :path
103
+
101
104
  def initialize(kind:, name:, version:, path:)
102
- super(kind.freeze, name.dup.freeze, version.to_s.dup.freeze, path.dup.freeze)
105
+ @kind = kind.freeze
106
+ @name = name.dup.freeze
107
+ @version = version.to_s.dup.freeze
108
+ @path = path.dup.freeze
103
109
  freeze
104
110
  end
105
111
 
106
- def to_json(*args)
107
- { kind: kind, name: name, version: version, paths: [path] }.to_json(*args)
112
+ def to_json(arg = nil)
113
+ { kind: @kind, name: @name, version: @version, paths: [@path] }.to_json(arg)
108
114
  end
109
115
  end
110
116
  end
@@ -15,14 +15,15 @@ module Datadog
15
15
 
16
16
  def initialize(
17
17
  gc_profiling_enabled:,
18
- allocation_counting_enabled:,
19
18
  no_signals_workaround_enabled:,
20
19
  thread_context_collector:,
21
- idle_sampling_helper: IdleSamplingHelper.new,
20
+ dynamic_sampling_rate_overhead_target_percentage:,
21
+ allocation_profiling_enabled:,
22
22
  # **NOTE**: This should only be used for testing; disabling the dynamic sampling rate will increase the
23
23
  # profiler overhead!
24
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!
25
+ skip_idle_samples_for_testing: false,
26
+ idle_sampling_helper: IdleSamplingHelper.new
26
27
  )
27
28
  unless dynamic_sampling_rate_enabled
28
29
  Datadog.logger.warn(
@@ -30,27 +31,23 @@ module Datadog
30
31
  )
31
32
  end
32
33
 
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
-
40
34
  self.class._native_initialize(
41
35
  self,
42
36
  thread_context_collector,
43
37
  gc_profiling_enabled,
44
38
  idle_sampling_helper,
45
- allocation_counting_enabled,
46
39
  no_signals_workaround_enabled,
47
40
  dynamic_sampling_rate_enabled,
48
- allocation_sample_every,
41
+ dynamic_sampling_rate_overhead_target_percentage,
42
+ allocation_profiling_enabled,
43
+ skip_idle_samples_for_testing,
49
44
  )
50
45
  @worker_thread = nil
51
46
  @failure_exception = nil
52
47
  @start_stop_mutex = Mutex.new
53
48
  @idle_sampling_helper = idle_sampling_helper
49
+ @wait_until_running_mutex = Mutex.new
50
+ @wait_until_running_condition = ConditionVariable.new
54
51
  end
55
52
 
56
53
  def start(on_failure_proc: nil)
@@ -107,6 +104,33 @@ module Datadog
107
104
  def stats
108
105
  self.class._native_stats(self)
109
106
  end
107
+
108
+ def stats_and_reset_not_thread_safe
109
+ stats = self.stats
110
+ self.class._native_stats_reset_not_thread_safe(self)
111
+ stats
112
+ end
113
+
114
+ # Useful for testing, to e.g. make sure the profiler is running before we start running some code we want to observe
115
+ def wait_until_running(timeout_seconds: 5)
116
+ @wait_until_running_mutex.synchronize do
117
+ return true if self.class._native_is_running?(self)
118
+
119
+ @wait_until_running_condition.wait(@wait_until_running_mutex, timeout_seconds)
120
+
121
+ if self.class._native_is_running?(self)
122
+ true
123
+ else
124
+ raise "Timeout waiting for #{self.class.name} to start (waited for #{timeout_seconds} seconds)"
125
+ end
126
+ end
127
+ end
128
+
129
+ private
130
+
131
+ def signal_running
132
+ @wait_until_running_mutex.synchronize { @wait_until_running_condition.broadcast }
133
+ end
110
134
  end
111
135
  end
112
136
  end