datadog 2.31.0 → 2.32.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 (173) hide show
  1. checksums.yaml +4 -4
  2. data/ext/datadog_profiling_native_extension/collectors_cpu_and_wall_time_worker.c +17 -7
  3. data/ext/datadog_profiling_native_extension/collectors_thread_context.c +11 -4
  4. data/ext/datadog_profiling_native_extension/collectors_thread_context.h +6 -0
  5. data/ext/datadog_profiling_native_extension/extconf.rb +5 -4
  6. data/ext/datadog_profiling_native_extension/http_transport.c +10 -5
  7. data/ext/libdatadog_api/di.c +48 -0
  8. data/ext/libdatadog_api/extconf.rb +7 -4
  9. data/ext/libdatadog_extconf_helpers.rb +37 -0
  10. data/lib/datadog/ai_guard/configuration.rb +105 -2
  11. data/lib/datadog/ai_guard/evaluation.rb +1 -0
  12. data/lib/datadog/ai_guard/ext.rb +1 -0
  13. data/lib/datadog/appsec/autoload.rb +1 -1
  14. data/lib/datadog/appsec/component.rb +1 -1
  15. data/lib/datadog/appsec/configuration.rb +414 -1
  16. data/lib/datadog/appsec/contrib/devise/patches/signin_tracking_patch.rb +2 -1
  17. data/lib/datadog/appsec/contrib/rack/gateway/request.rb +1 -1
  18. data/lib/datadog/appsec/contrib/rails/patcher.rb +2 -2
  19. data/lib/datadog/appsec/metrics/telemetry.rb +13 -1
  20. data/lib/datadog/appsec/security_engine/runner.rb +1 -1
  21. data/lib/datadog/appsec/trace_keeper.rb +18 -6
  22. data/lib/datadog/appsec/utils/http/url_encoded.rb +2 -2
  23. data/lib/datadog/core/configuration/components.rb +1 -1
  24. data/lib/datadog/core/configuration/settings.rb +3 -0
  25. data/lib/datadog/core/configuration/supported_configurations.rb +2 -0
  26. data/lib/datadog/core/configuration.rb +1 -1
  27. data/lib/datadog/core/contrib/rails/utils.rb +1 -1
  28. data/lib/datadog/core/crashtracking/component.rb +3 -3
  29. data/lib/datadog/core/diagnostics/environment_logger.rb +3 -1
  30. data/lib/datadog/core/environment/container.rb +2 -2
  31. data/lib/datadog/core/feature_flags.rb +1 -1
  32. data/lib/datadog/core/metrics/client.rb +5 -5
  33. data/lib/datadog/core/remote/client.rb +1 -1
  34. data/lib/datadog/core/remote/component.rb +2 -2
  35. data/lib/datadog/core/runtime/metrics.rb +1 -1
  36. data/lib/datadog/core/telemetry/emitter.rb +1 -1
  37. data/lib/datadog/core/telemetry/event/app_started.rb +2 -2
  38. data/lib/datadog/core/transport/http.rb +2 -0
  39. data/lib/datadog/core/utils.rb +1 -1
  40. data/lib/datadog/core/workers/async.rb +1 -1
  41. data/lib/datadog/core.rb +1 -1
  42. data/lib/datadog/data_streams/configuration.rb +40 -1
  43. data/lib/datadog/data_streams/pathway_context.rb +1 -1
  44. data/lib/datadog/data_streams/processor.rb +1 -1
  45. data/lib/datadog/data_streams.rb +1 -1
  46. data/lib/datadog/di/base.rb +8 -5
  47. data/lib/datadog/di/code_tracker.rb +179 -1
  48. data/lib/datadog/di/component.rb +1 -1
  49. data/lib/datadog/di/configuration.rb +235 -2
  50. data/lib/datadog/di/instrumenter.rb +46 -26
  51. data/lib/datadog/di/probe_builder.rb +1 -1
  52. data/lib/datadog/di/probe_file_loader.rb +2 -2
  53. data/lib/datadog/di/probe_manager.rb +6 -6
  54. data/lib/datadog/di/probe_notification_builder.rb +1 -1
  55. data/lib/datadog/di/probe_notifier_worker.rb +2 -2
  56. data/lib/datadog/di/remote.rb +6 -6
  57. data/lib/datadog/di/serializer.rb +1 -1
  58. data/lib/datadog/di/transport/input.rb +3 -3
  59. data/lib/datadog/error_tracking/configuration.rb +55 -2
  60. data/lib/datadog/kit/enable_core_dumps.rb +1 -1
  61. data/lib/datadog/open_feature/component.rb +18 -1
  62. data/lib/datadog/open_feature/evaluation_engine.rb +3 -3
  63. data/lib/datadog/open_feature/exposures/reporter.rb +1 -1
  64. data/lib/datadog/open_feature/exposures/worker.rb +1 -1
  65. data/lib/datadog/open_feature/hooks/flag_eval_hook.rb +49 -0
  66. data/lib/datadog/open_feature/metrics/flag_eval_metrics.rb +149 -0
  67. data/lib/datadog/open_feature/provider.rb +19 -1
  68. data/lib/datadog/open_feature/remote.rb +1 -1
  69. data/lib/datadog/open_feature/transport.rb +1 -1
  70. data/lib/datadog/opentelemetry/metrics.rb +3 -3
  71. data/lib/datadog/opentelemetry/sdk/configurator.rb +1 -1
  72. data/lib/datadog/opentelemetry/sdk/metrics_exporter.rb +1 -1
  73. data/lib/datadog/profiling/collectors/code_provenance.rb +35 -9
  74. data/lib/datadog/profiling/collectors/cpu_and_wall_time_worker.rb +31 -2
  75. data/lib/datadog/profiling/collectors/idle_sampling_helper.rb +8 -2
  76. data/lib/datadog/profiling/collectors/info.rb +16 -3
  77. data/lib/datadog/profiling/component.rb +3 -5
  78. data/lib/datadog/profiling/exporter.rb +37 -12
  79. data/lib/datadog/profiling/ext.rb +0 -2
  80. data/lib/datadog/profiling/flush.rb +21 -12
  81. data/lib/datadog/profiling/http_transport.rb +12 -1
  82. data/lib/datadog/profiling/load_native_extension.rb +1 -1
  83. data/lib/datadog/profiling/profiler.rb +13 -1
  84. data/lib/datadog/profiling/scheduler.rb +2 -2
  85. data/lib/datadog/profiling/tasks/exec.rb +8 -3
  86. data/lib/datadog/profiling/tasks/help.rb +1 -0
  87. data/lib/datadog/profiling/tasks/setup.rb +2 -2
  88. data/lib/datadog/single_step_instrument.rb +1 -1
  89. data/lib/datadog/symbol_database/configuration.rb +65 -0
  90. data/lib/datadog/symbol_database/extractor.rb +915 -0
  91. data/lib/datadog/symbol_database/file_hash.rb +46 -0
  92. data/lib/datadog/symbol_database/logger.rb +43 -0
  93. data/lib/datadog/symbol_database/scope.rb +98 -0
  94. data/lib/datadog/symbol_database/service_version.rb +57 -0
  95. data/lib/datadog/symbol_database/symbol.rb +66 -0
  96. data/lib/datadog/symbol_database/transport/http/endpoint.rb +28 -0
  97. data/lib/datadog/symbol_database/transport/http.rb +45 -0
  98. data/lib/datadog/symbol_database/transport.rb +54 -0
  99. data/lib/datadog/symbol_database/uploader.rb +166 -0
  100. data/lib/datadog/symbol_database.rb +49 -0
  101. data/lib/datadog/tracing/buffer.rb +3 -3
  102. data/lib/datadog/tracing/configuration/settings.rb +1 -1
  103. data/lib/datadog/tracing/contrib/action_pack/action_controller/instrumentation.rb +5 -3
  104. data/lib/datadog/tracing/contrib/action_view/events/render_template.rb +1 -1
  105. data/lib/datadog/tracing/contrib/active_job/events/discard.rb +1 -1
  106. data/lib/datadog/tracing/contrib/active_job/events/enqueue.rb +1 -1
  107. data/lib/datadog/tracing/contrib/active_job/events/enqueue_at.rb +1 -1
  108. data/lib/datadog/tracing/contrib/active_job/events/enqueue_retry.rb +1 -1
  109. data/lib/datadog/tracing/contrib/active_job/events/perform.rb +1 -1
  110. data/lib/datadog/tracing/contrib/active_job/events/retry_stopped.rb +1 -1
  111. data/lib/datadog/tracing/contrib/active_model_serializers/events/render.rb +1 -1
  112. data/lib/datadog/tracing/contrib/active_model_serializers/events/serialize.rb +1 -1
  113. data/lib/datadog/tracing/contrib/active_record/configuration/resolver.rb +2 -2
  114. data/lib/datadog/tracing/contrib/active_record/events/instantiation.rb +1 -1
  115. data/lib/datadog/tracing/contrib/active_record/events/sql.rb +1 -1
  116. data/lib/datadog/tracing/contrib/active_record/utils.rb +1 -1
  117. data/lib/datadog/tracing/contrib/active_support/cache/events/cache.rb +1 -1
  118. data/lib/datadog/tracing/contrib/active_support/notifications/subscription.rb +2 -2
  119. data/lib/datadog/tracing/contrib/aws/instrumentation.rb +1 -1
  120. data/lib/datadog/tracing/contrib/component.rb +1 -1
  121. data/lib/datadog/tracing/contrib/configuration/resolver.rb +7 -4
  122. data/lib/datadog/tracing/contrib/dalli/quantize.rb +1 -1
  123. data/lib/datadog/tracing/contrib/elasticsearch/patcher.rb +1 -1
  124. data/lib/datadog/tracing/contrib/excon/middleware.rb +2 -2
  125. data/lib/datadog/tracing/contrib/extensions.rb +9 -0
  126. data/lib/datadog/tracing/contrib/faraday/middleware.rb +2 -2
  127. data/lib/datadog/tracing/contrib/grape/endpoint.rb +5 -5
  128. data/lib/datadog/tracing/contrib/grpc/datadog_interceptor/client.rb +2 -2
  129. data/lib/datadog/tracing/contrib/grpc/datadog_interceptor/server.rb +2 -2
  130. data/lib/datadog/tracing/contrib/http/instrumentation.rb +2 -2
  131. data/lib/datadog/tracing/contrib/httpclient/instrumentation.rb +6 -2
  132. data/lib/datadog/tracing/contrib/httprb/instrumentation.rb +2 -2
  133. data/lib/datadog/tracing/contrib/kafka/instrumentation/consumer.rb +2 -2
  134. data/lib/datadog/tracing/contrib/kafka/instrumentation/producer.rb +2 -2
  135. data/lib/datadog/tracing/contrib/karafka/patcher.rb +1 -1
  136. data/lib/datadog/tracing/contrib/mongodb/subscribers.rb +3 -3
  137. data/lib/datadog/tracing/contrib/opensearch/patcher.rb +1 -1
  138. data/lib/datadog/tracing/contrib/presto/instrumentation.rb +3 -3
  139. data/lib/datadog/tracing/contrib/rack/patcher.rb +1 -1
  140. data/lib/datadog/tracing/contrib/rack/request_queue.rb +1 -1
  141. data/lib/datadog/tracing/contrib/rails/log_injection.rb +1 -1
  142. data/lib/datadog/tracing/contrib/rails/runner.rb +1 -1
  143. data/lib/datadog/tracing/contrib/rake/instrumentation.rb +2 -2
  144. data/lib/datadog/tracing/contrib/redis/quantize.rb +1 -1
  145. data/lib/datadog/tracing/contrib/redis/tags.rb +1 -1
  146. data/lib/datadog/tracing/contrib/sidekiq/utils.rb +1 -1
  147. data/lib/datadog/tracing/contrib/stripe/request.rb +1 -1
  148. data/lib/datadog/tracing/contrib.rb +8 -0
  149. data/lib/datadog/tracing/diagnostics/environment_logger.rb +3 -1
  150. data/lib/datadog/tracing/distributed/baggage.rb +59 -5
  151. data/lib/datadog/tracing/distributed/datadog.rb +11 -11
  152. data/lib/datadog/tracing/distributed/datadog_tags_codec.rb +1 -1
  153. data/lib/datadog/tracing/distributed/propagation.rb +2 -2
  154. data/lib/datadog/tracing/distributed/trace_context.rb +74 -32
  155. data/lib/datadog/tracing/event.rb +1 -1
  156. data/lib/datadog/tracing/metadata/tagging.rb +2 -2
  157. data/lib/datadog/tracing/pipeline.rb +1 -1
  158. data/lib/datadog/tracing/remote.rb +1 -1
  159. data/lib/datadog/tracing/sampling/rule.rb +1 -1
  160. data/lib/datadog/tracing/sampling/rule_sampler.rb +2 -2
  161. data/lib/datadog/tracing/sampling/span/rule_parser.rb +2 -2
  162. data/lib/datadog/tracing/span_operation.rb +3 -3
  163. data/lib/datadog/tracing/trace_operation.rb +4 -4
  164. data/lib/datadog/tracing/tracer.rb +5 -5
  165. data/lib/datadog/tracing/transport/io/client.rb +1 -1
  166. data/lib/datadog/tracing/workers.rb +2 -1
  167. data/lib/datadog/version.rb +1 -1
  168. metadata +18 -9
  169. data/lib/datadog/ai_guard/configuration/settings.rb +0 -113
  170. data/lib/datadog/appsec/configuration/settings.rb +0 -423
  171. data/lib/datadog/data_streams/configuration/settings.rb +0 -49
  172. data/lib/datadog/di/configuration/settings.rb +0 -243
  173. data/lib/datadog/error_tracking/configuration/settings.rb +0 -63
@@ -14,11 +14,18 @@ module Datadog
14
14
  # could be seen as overkill for this case but it allows us to centralize information
15
15
  # gathering and easily support more flexible/dynamic info collection in the future.
16
16
  class Info
17
+ # @rbs @info: ::Hash[::Symbol, ::Hash[::Symbol, untyped]]
18
+ # @rbs @platform_info: ::Hash[::Symbol, untyped]
19
+ # @rbs @runtime_info: ::Hash[::Symbol, untyped]
20
+ # @rbs @application_info: ::Hash[::Symbol, untyped]
21
+ # @rbs @profiler_info: ::Hash[::Symbol, untyped]?
22
+ # @rbs @gc_tuning_info: ::Hash[::Symbol, ::String]
23
+
24
+ #: (untyped) -> void
17
25
  def initialize(settings)
18
26
  @profiler_info = nil
19
27
 
20
- # Steep: https://github.com/soutaro/steep/issues/363
21
- @info = { # steep:ignore IncompatibleAssignment
28
+ @info = {
22
29
  platform: collect_platform_info,
23
30
  runtime: collect_runtime_info,
24
31
  application: collect_application_info(settings),
@@ -26,7 +33,7 @@ module Datadog
26
33
  }.freeze
27
34
  end
28
35
 
29
- attr_reader :info
36
+ attr_reader :info #: ::Hash[::Symbol, ::Hash[::Symbol, untyped]]
30
37
 
31
38
  private
32
39
 
@@ -69,6 +76,7 @@ module Datadog
69
76
  # gets initialized before a user has a chance to configure the library.
70
77
  START_TIME = Time.now.utc.freeze
71
78
 
79
+ #: () -> ::Hash[::Symbol, untyped]
72
80
  def collect_platform_info
73
81
  @platform_info ||= {
74
82
  container_id: Datadog::Core::Environment::Container.container_id,
@@ -79,6 +87,7 @@ module Datadog
79
87
  }.freeze
80
88
  end
81
89
 
90
+ #: () -> ::Hash[::Symbol, untyped]
82
91
  def collect_runtime_info
83
92
  @runtime_info ||= {
84
93
  engine: Datadog::Core::Environment::Identity.lang_engine,
@@ -88,6 +97,7 @@ module Datadog
88
97
  }.freeze
89
98
  end
90
99
 
100
+ #: (untyped) -> ::Hash[::Symbol, untyped]
91
101
  def collect_application_info(settings)
92
102
  @application_info ||= {
93
103
  start_time: START_TIME.iso8601,
@@ -97,6 +107,7 @@ module Datadog
97
107
  }.freeze
98
108
  end
99
109
 
110
+ #: (untyped) -> ::Hash[::Symbol, untyped]
100
111
  def collect_profiler_info(settings)
101
112
  @profiler_info ||= begin
102
113
  lib_datadog_gem = ::Gem.loaded_specs["libdatadog"]
@@ -123,6 +134,7 @@ module Datadog
123
134
  # instances without proper serialization.
124
135
  # This method navigates a settings object recursively, converting
125
136
  # it into more basic types that are trivially convertible to JSON.
137
+ #: (untyped) -> untyped
126
138
  def collect_settings_recursively(v)
127
139
  v = v.options_hash if v.respond_to?(:options_hash)
128
140
 
@@ -143,6 +155,7 @@ module Datadog
143
155
  end
144
156
  end
145
157
 
158
+ #: () -> ::Hash[::Symbol, ::String]
146
159
  def collect_gc_tuning_info
147
160
  return @gc_tuning_info if defined?(@gc_tuning_info)
148
161
 
@@ -10,8 +10,6 @@ module Datadog
10
10
  # * Profiling in the trace viewer, as well as scoping a profile down to a span
11
11
  # * Endpoint aggregation in the profiler UX, including normalization (resource per endpoint call)
12
12
  def self.build_profiler_component(settings:, agent_settings:, optional_tracer:, logger:) # rubocop:disable Metrics/MethodLength
13
- return [nil, {profiling_enabled: false}] unless settings.profiling.enabled
14
-
15
13
  # Workaround for weird dependency direction: the Core::Configuration::Components class currently has a
16
14
  # dependency on individual products, in this case the Profiler.
17
15
  # (Note "currently": in the future we want to change this so core classes don't depend on specific products)
@@ -31,7 +29,7 @@ module Datadog
31
29
  # no-op if profiling is already loaded).
32
30
  require_relative "../profiling"
33
31
 
34
- return [nil, {profiling_enabled: false}] unless Profiling.supported?
32
+ return [nil, {profiling_enabled: false}] unless settings.profiling.enabled && Profiling.supported?
35
33
 
36
34
  # Activate forking extensions
37
35
  Profiling::Tasks::Setup.new.run
@@ -94,7 +92,7 @@ module Datadog
94
92
  [profiler, {profiling_enabled: true}]
95
93
  rescue Exception => e # rubocop:disable Lint/RescueException
96
94
  logger.warn do
97
- "Failed to initialize profiling: #{e.class}: #{e} " \
95
+ "Failed to initialize profiling: #{e.class}: #{e.message} " \
98
96
  "Location: #{Array(e.backtrace).first}"
99
97
  end
100
98
  Datadog::Core::Telemetry::Logger.report(e, description: "Failed to initialize profiling")
@@ -378,7 +376,7 @@ module Datadog
378
376
  rescue StandardError, LoadError => e
379
377
  logger.warn(
380
378
  "Failed to probe `mysql2` gem information. " \
381
- "Cause: #{e.class}: #{e} Location: #{Array(e.backtrace).first}"
379
+ "Cause: #{e.class}: #{e.message} Location: #{Array(e.backtrace).first}"
382
380
  )
383
381
 
384
382
  true
@@ -13,24 +13,35 @@ module Datadog
13
13
  # recorders, so I've decided to make it specific until we actually need to support more recorders.
14
14
  #
15
15
  class Exporter
16
+ # @rbs @worker: Datadog::Profiling::Collectors::CpuAndWallTimeWorker
17
+
16
18
  # Profiles with duration less than this will not be reported
17
19
  PROFILE_DURATION_THRESHOLD_SECONDS = 1
18
20
 
19
21
  private
20
22
 
21
- attr_reader \
22
- :pprof_recorder,
23
- :code_provenance_collector, # The code provenance collector acts both as collector and as a recorder
24
- :minimum_duration_seconds,
25
- :time_provider,
26
- :last_flush_finish_at,
27
- :created_at,
28
- :internal_metadata,
29
- :info_json,
30
- :sequence_tracker
23
+ attr_reader :pprof_recorder #: Datadog::Profiling::StackRecorder
24
+ # The code provenance collector acts both as collector and as a recorder
25
+ attr_reader :code_provenance_collector #: Datadog::Profiling::Collectors::CodeProvenance?
26
+ attr_reader :minimum_duration_seconds #: ::Integer
27
+ attr_reader :time_provider #: singleton(::Time)
28
+ attr_reader :last_flush_finish_at #: ::Time?
29
+ attr_reader :created_at #: ::Time
30
+ attr_reader :internal_metadata #: ::Hash[::Symbol, untyped]
31
+ attr_reader :info_json #: ::String
32
+ attr_reader :sequence_tracker #: singleton(Datadog::Profiling::SequenceTracker)
31
33
 
32
34
  public
33
35
 
36
+ # @rbs pprof_recorder: Datadog::Profiling::StackRecorder
37
+ # @rbs worker: Datadog::Profiling::Collectors::CpuAndWallTimeWorker
38
+ # @rbs info_collector: Datadog::Profiling::Collectors::Info
39
+ # @rbs code_provenance_collector: Datadog::Profiling::Collectors::CodeProvenance?
40
+ # @rbs internal_metadata: ::Hash[::Symbol, untyped]
41
+ # @rbs minimum_duration_seconds: ::Integer
42
+ # @rbs time_provider: singleton(::Time)
43
+ # @rbs sequence_tracker: singleton(Datadog::Profiling::SequenceTracker)
44
+ # @rbs return: void
34
45
  def initialize(
35
46
  pprof_recorder:,
36
47
  worker:,
@@ -55,6 +66,7 @@ module Datadog
55
66
  @sequence_tracker = sequence_tracker
56
67
  end
57
68
 
69
+ #: () -> Datadog::Profiling::Flush?
58
70
  def flush
59
71
  worker_stats = @worker.stats_and_reset_not_thread_safe
60
72
  serialization_result = pprof_recorder.serialize
@@ -68,7 +80,17 @@ module Datadog
68
80
  return
69
81
  end
70
82
 
71
- uncompressed_code_provenance = code_provenance_collector.refresh.generate_json if code_provenance_collector
83
+ uncompressed_code_provenance =
84
+ if (collector = code_provenance_collector)
85
+ collector.refresh.generate_json
86
+ end
87
+
88
+ metrics = [] #: Array[[::String, ::Numeric]]
89
+
90
+ # The key is always there, but the value might be nil if GVL profiling is disabled.
91
+ # We delete it to avoid reporting the same data point twice.
92
+ gvl_waiting_time_ns_total = worker_stats.delete(:gvl_waiting_time_ns_total)
93
+ metrics << ["ruby_global_lock_wait_time_total", gvl_waiting_time_ns_total] if gvl_waiting_time_ns_total
72
94
 
73
95
  process_tags = Datadog.configuration.experimental_propagate_process_tags_enabled ?
74
96
  Core::Environment::Process.serialized : ''
@@ -77,8 +99,8 @@ module Datadog
77
99
  start: start,
78
100
  finish: finish,
79
101
  encoded_profile: encoded_profile,
80
- code_provenance_file_name: Datadog::Profiling::Ext::Transport::HTTP::CODE_PROVENANCE_FILENAME,
81
102
  code_provenance_data: uncompressed_code_provenance,
103
+ metrics: metrics,
82
104
  tags_as_array: Datadog::Profiling::TagBuilder.call(
83
105
  settings: Datadog.configuration,
84
106
  profile_seq: sequence_tracker.get_next,
@@ -96,10 +118,12 @@ module Datadog
96
118
  )
97
119
  end
98
120
 
121
+ #: () -> bool
99
122
  def can_flush?
100
123
  !duration_below_threshold?(last_flush_finish_at || created_at, time_provider.now.utc)
101
124
  end
102
125
 
126
+ #: () -> void
103
127
  def reset_after_fork
104
128
  @last_flush_finish_at = time_provider.now.utc
105
129
  nil
@@ -107,6 +131,7 @@ module Datadog
107
131
 
108
132
  private
109
133
 
134
+ #: (::Time, ::Time) -> bool
110
135
  def duration_below_threshold?(start, finish)
111
136
  (finish - start) < minimum_duration_seconds
112
137
  end
@@ -13,8 +13,6 @@ module Datadog
13
13
  module Transport
14
14
  module HTTP
15
15
  FORM_FIELD_TAG_PROFILER_VERSION = "profiler_version"
16
-
17
- CODE_PROVENANCE_FILENAME = "code-provenance.json"
18
16
  end
19
17
  end
20
18
  end
@@ -6,23 +6,32 @@ module Datadog
6
6
  module Profiling
7
7
  # Entity class used to represent metadata for a given profile
8
8
  class Flush
9
- attr_reader \
10
- :start,
11
- :finish,
12
- :encoded_profile,
13
- :code_provenance_file_name,
14
- :code_provenance_data,
15
- :tags_as_array,
16
- :process_tags,
17
- :internal_metadata_json,
18
- :info_json
9
+ attr_reader :start #: ::Time
10
+ attr_reader :finish #: ::Time
11
+ attr_reader :encoded_profile #: Datadog::Profiling::EncodedProfile
12
+ attr_reader :code_provenance_data #: ::String?
13
+ attr_reader :metrics #: ::String
14
+ attr_reader :tags_as_array #: Array[[::String, ::String]]
15
+ attr_reader :process_tags #: ::String
16
+ attr_reader :internal_metadata_json #: ::String
17
+ attr_reader :info_json #: ::String
19
18
 
19
+ # @rbs start: ::Time
20
+ # @rbs finish: ::Time
21
+ # @rbs encoded_profile: Datadog::Profiling::EncodedProfile
22
+ # @rbs code_provenance_data: ::String?
23
+ # @rbs metrics: Array[[::String, ::Numeric]]
24
+ # @rbs tags_as_array: Array[[::String, ::String]]
25
+ # @rbs process_tags: ::String
26
+ # @rbs internal_metadata: ::Hash[::Symbol, ::String | bool | ::Numeric]
27
+ # @rbs info_json: ::String
28
+ # @rbs return: void
20
29
  def initialize(
21
30
  start:,
22
31
  finish:,
23
32
  encoded_profile:,
24
- code_provenance_file_name:,
25
33
  code_provenance_data:,
34
+ metrics:,
26
35
  tags_as_array:,
27
36
  process_tags:,
28
37
  internal_metadata:,
@@ -31,8 +40,8 @@ module Datadog
31
40
  @start = start
32
41
  @finish = finish
33
42
  @encoded_profile = encoded_profile
34
- @code_provenance_file_name = code_provenance_file_name
35
43
  @code_provenance_data = code_provenance_data
44
+ @metrics = JSON.generate(metrics)
36
45
  @tags_as_array = tags_as_array
37
46
  @process_tags = process_tags
38
47
  @internal_metadata_json = JSON.generate(internal_metadata)
@@ -8,8 +8,16 @@ module Datadog
8
8
  # Used to report profiling data to Datadog.
9
9
  # Methods prefixed with _native_ are implemented in `http_transport.c`
10
10
  class HttpTransport
11
- attr_reader :exporter_configuration
11
+ # @rbs @exporter_configuration: exporter_configuration_array
12
12
 
13
+ attr_reader :exporter_configuration #: exporter_configuration_array
14
+
15
+ # @rbs agent_settings: Datadog::Core::Configuration::AgentSettings
16
+ # @rbs site: ::String?
17
+ # @rbs api_key: ::String?
18
+ # @rbs upload_timeout_seconds: ::Integer
19
+ # @rbs use_system_dns: bool
20
+ # @rbs return: void
13
21
  def initialize(agent_settings:, site:, api_key:, upload_timeout_seconds:, use_system_dns:)
14
22
  timeout_milliseconds = (upload_timeout_seconds * 1_000).to_i
15
23
 
@@ -28,6 +36,7 @@ module Datadog
28
36
  raise(ArgumentError, "Failed to initialize transport: #{result}") if status == :error
29
37
  end
30
38
 
39
+ #: (Datadog::Profiling::Flush) -> bool
31
40
  def export(flush)
32
41
  status, result = self.class._native_do_export(
33
42
  exporter_configuration,
@@ -57,10 +66,12 @@ module Datadog
57
66
 
58
67
  private
59
68
 
69
+ #: (::String?, ::String?) -> bool?
60
70
  def agentless?(site, api_key)
61
71
  site && api_key && %w[1 true].include?(ENV[Profiling::Ext::ENV_AGENTLESS] || '') # rubocop:disable CustomCops/EnvUsageCop
62
72
  end
63
73
 
74
+ #: () -> ::String
64
75
  def config_without_api_key
65
76
  "#{exporter_configuration[0]}: #{exporter_configuration[3]}"
66
77
  end
@@ -5,5 +5,5 @@ begin
5
5
  rescue LoadError => e
6
6
  raise LoadError,
7
7
  "Failed to load the profiling native extension. To fix this, please remove and then reinstall datadog " \
8
- "(Details: #{e.message})"
8
+ "(Details: #{e.class}: #{e.message})"
9
9
  end
@@ -8,15 +8,20 @@ module Datadog
8
8
 
9
9
  private
10
10
 
11
- attr_reader :worker, :scheduler
11
+ attr_reader :worker #: Datadog::Profiling::Collectors::CpuAndWallTimeWorker
12
+ attr_reader :scheduler #: Datadog::Profiling::Scheduler
12
13
 
13
14
  public
14
15
 
16
+ # @rbs worker: Datadog::Profiling::Collectors::CpuAndWallTimeWorker
17
+ # @rbs scheduler: Datadog::Profiling::Scheduler
18
+ # @rbs return: void
15
19
  def initialize(worker:, scheduler:)
16
20
  @worker = worker
17
21
  @scheduler = scheduler
18
22
  end
19
23
 
24
+ #: () -> void
20
25
  def start
21
26
  after_fork! do
22
27
  worker.reset_after_fork
@@ -32,6 +37,8 @@ module Datadog
32
37
  scheduler.start(on_failure_proc: proc { component_failed(:scheduler) })
33
38
  end
34
39
 
40
+ # @rbs report_last_profile: bool
41
+ # @rbs return: void
35
42
  def shutdown!(report_last_profile: true)
36
43
  Datadog.logger.debug("Shutting down profiler")
37
44
 
@@ -42,15 +49,20 @@ module Datadog
42
49
 
43
50
  private
44
51
 
52
+ #: () -> void
45
53
  def stop_worker
46
54
  worker.stop
47
55
  end
48
56
 
57
+ #: () -> void
49
58
  def stop_scheduler
50
59
  scheduler.enabled = false
51
60
  scheduler.stop(true)
52
61
  end
53
62
 
63
+ # @rbs failed_component: :worker | :scheduler | ::Symbol
64
+ # @rbs log_failure: bool
65
+ # @rbs return: void
54
66
  def component_failed(failed_component, log_failure: true)
55
67
  if log_failure
56
68
  Datadog.logger.warn(
@@ -65,7 +65,7 @@ module Datadog
65
65
  rescue Exception => e # rubocop:disable Lint/RescueException
66
66
  Datadog.logger.warn(
67
67
  "Profiling::Scheduler thread error. " \
68
- "Cause: #{e.class}: #{e} Location: #{Array(e.backtrace).first}"
68
+ "Cause: #{e.class}: #{e.message} Location: #{Array(e.backtrace).first}"
69
69
  )
70
70
  on_failure_proc&.call
71
71
  Datadog::Core::Telemetry::Logger.report(e, description: "Profiling::Scheduler thread error")
@@ -136,7 +136,7 @@ module Datadog
136
136
  transport.export(flush)
137
137
  rescue => e
138
138
  Datadog.logger.warn(
139
- "Unable to report profile. Cause: #{e.class}: #{e} Location: #{Array(e.backtrace).first}"
139
+ "Unable to report profile. Cause: #{e.class}: #{e.message} Location: #{Array(e.backtrace).first}"
140
140
  )
141
141
  Datadog::Core::Telemetry::Logger.report(e, description: "Unable to report profile")
142
142
  end
@@ -5,17 +5,20 @@ module Datadog
5
5
  module Tasks
6
6
  # Wraps command with Datadog profiling
7
7
  class Exec
8
- attr_reader :args
8
+ attr_reader :args #: untyped
9
9
 
10
+ #: (untyped) -> void
10
11
  def initialize(args)
11
12
  @args = args
12
13
  end
13
14
 
15
+ #: () -> untyped
14
16
  def run
15
17
  set_rubyopt!
16
18
  exec_with_error_handling(args)
17
19
  end
18
20
 
21
+ #: () -> ::Array["-rdatadog/profiling/preload"]
19
22
  def rubyopts
20
23
  [
21
24
  "-rdatadog/profiling/preload"
@@ -24,6 +27,7 @@ module Datadog
24
27
 
25
28
  private
26
29
 
30
+ #: () -> untyped
27
31
  def set_rubyopt!
28
32
  existing_rubyopt = ENV["RUBYOPT"] # rubocop:disable CustomCops/EnvUsageCop
29
33
 
@@ -35,13 +39,14 @@ module Datadog
35
39
  # See also:
36
40
  # * https://www.gnu.org/software/bash/manual/html_node/Exit-Status.html
37
41
  # * https://github.com/rubygems/rubygems/blob/dd93966cac224532035deda533cba2685dfa30cc/bundler/lib/bundler/cli/exec.rb#L45
42
+ #: (untyped) -> untyped
38
43
  def exec_with_error_handling(args)
39
44
  Kernel.exec(*args)
40
45
  rescue Errno::ENOENT => e
41
- Kernel.warn "ddprofrb exec failed: #{e.class}: #{e} (command was '#{args.join(" ")}')"
46
+ Kernel.warn "ddprofrb exec failed: #{e.class}: #{e.message} (command was '#{args.join(" ")}')"
42
47
  Kernel.exit 127
43
48
  rescue Errno::EACCES, Errno::ENOEXEC => e
44
- Kernel.warn "ddprofrb exec failed: #{e.class}: #{e} (command was '#{args.join(" ")}')"
49
+ Kernel.warn "ddprofrb exec failed: #{e.class}: #{e.message} (command was '#{args.join(" ")}')"
45
50
  Kernel.exit 126
46
51
  end
47
52
  end
@@ -5,6 +5,7 @@ module Datadog
5
5
  module Tasks
6
6
  # Prints help message for usage of `ddprofrb`
7
7
  class Help
8
+ #: () -> untyped
8
9
  def run
9
10
  puts %(
10
11
  Usage: ddprofrb [command] [arguments]
@@ -16,7 +16,7 @@ module Datadog
16
16
  setup_at_fork_hooks
17
17
  rescue StandardError, ScriptError => e
18
18
  Datadog.logger.warn do
19
- "Profiler extensions unavailable. Cause: #{e.class}: #{e} " \
19
+ "Profiler extensions unavailable. Cause: #{e.class}: #{e.message} " \
20
20
  "Location: #{Array(e.backtrace).first}"
21
21
  end
22
22
  Datadog::Core::Telemetry::Logger.report(e, description: "Profiler extensions unavailable")
@@ -31,7 +31,7 @@ module Datadog
31
31
  Profiling.start_if_enabled
32
32
  rescue => e
33
33
  Datadog.logger.warn do
34
- "Error during post-fork hooks. Cause: #{e.class}: #{e} " \
34
+ "Error during post-fork hooks. Cause: #{e.class}: #{e.message} " \
35
35
  "Location: #{Array(e.backtrace).first}"
36
36
  end
37
37
  Datadog::Core::Telemetry::Logger.report(e, description: "Error during post-fork hooks")
@@ -17,5 +17,5 @@ begin
17
17
  require_relative 'auto_instrument'
18
18
  Datadog::SingleStepInstrument.const_set(:LOADED, true)
19
19
  rescue StandardError, LoadError => e
20
- warn "Single step instrumentation failed: #{e.class}: #{e}\n\tSource:\n\t#{Array(e.backtrace).join("\n\t")}"
20
+ warn "Single step instrumentation failed: #{e.class}: #{e.message}\n\tSource:\n\t#{Array(e.backtrace).join("\n\t")}"
21
21
  end
@@ -0,0 +1,65 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Datadog
4
+ module SymbolDatabase
5
+ # Configuration for symbol database
6
+ module Configuration
7
+ # Configuration settings for symbol database upload feature.
8
+ #
9
+ # Public environment variable:
10
+ # - DD_SYMBOL_DATABASE_UPLOAD_ENABLED (default: true) - Feature gate
11
+ #
12
+ # Extended into: Core::Configuration::Settings (via extend)
13
+ # Accessed as: Datadog.configuration.symbol_database.enabled
14
+ # Used by: Component.build (checks if feature enabled)
15
+ module Settings
16
+ # Hook called when this module is extended into a class.
17
+ # @param base [Class, Module] The class or module being extended
18
+ # @return [void]
19
+ def self.extended(base)
20
+ base = base.singleton_class unless base.is_a?(Class)
21
+ add_settings!(base)
22
+ end
23
+
24
+ # Add symbol_database settings block to base class.
25
+ # @param base [Class] Base class
26
+ # @return [void]
27
+ def self.add_settings!(base)
28
+ base.class_eval do
29
+ # steep:ignore:start
30
+ settings :symbol_database do
31
+ option :enabled do |o|
32
+ o.type :bool
33
+ o.env 'DD_SYMBOL_DATABASE_UPLOAD_ENABLED'
34
+ o.default true
35
+ end
36
+
37
+ # Settings in the 'internal' group are for internal Datadog
38
+ # use only, and are needed to test symbol database or
39
+ # experiment with features not released to customers.
40
+ settings :internal do
41
+ # Bypass remote config — start extraction immediately.
42
+ # Matches Java's DD_INTERNAL_FORCE_SYMBOL_DATABASE_UPLOAD
43
+ # and Python's private force_upload setting.
44
+ option :force_upload do |o|
45
+ o.type :bool
46
+ o.env 'DD_INTERNAL_FORCE_SYMBOL_DATABASE_UPLOAD'
47
+ o.default false
48
+ end
49
+
50
+ # Enable verbose trace-level logging for symdb operations.
51
+ # Activated by DD_TRACE_DEBUG (same trigger as DI trace logging).
52
+ option :trace_logging do |o|
53
+ o.type :bool
54
+ o.default false
55
+ o.env 'DD_TRACE_DEBUG'
56
+ end
57
+ end
58
+ end
59
+ # steep:ignore:end
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end