datadog 2.40.0 → 2.42.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 (170) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +120 -59
  3. data/ext/datadog_profiling_native_extension/NativeExtensionDesign.md +12 -24
  4. data/ext/datadog_profiling_native_extension/collectors_cpu_and_wall_time_worker.c +110 -61
  5. data/ext/datadog_profiling_native_extension/collectors_stack.c +13 -5
  6. data/ext/datadog_profiling_native_extension/collectors_thread_context.c +141 -103
  7. data/ext/datadog_profiling_native_extension/collectors_thread_context.h +7 -3
  8. data/ext/datadog_profiling_native_extension/datadog_ruby_common.h +0 -10
  9. data/ext/datadog_profiling_native_extension/extconf.rb +52 -93
  10. data/ext/datadog_profiling_native_extension/heap_recorder.c +338 -255
  11. data/ext/datadog_profiling_native_extension/heap_recorder.h +46 -31
  12. data/ext/datadog_profiling_native_extension/native_extension_helpers.rb +3 -27
  13. data/ext/datadog_profiling_native_extension/private_vm_api_access.c +526 -443
  14. data/ext/datadog_profiling_native_extension/private_vm_api_access.h +15 -3
  15. data/ext/datadog_profiling_native_extension/profiling.c +2 -0
  16. data/ext/datadog_profiling_native_extension/ruby_helpers.c +1 -79
  17. data/ext/datadog_profiling_native_extension/ruby_helpers.h +0 -7
  18. data/ext/datadog_profiling_native_extension/stack_recorder.c +93 -61
  19. data/ext/datadog_profiling_native_extension/stack_recorder.h +12 -4
  20. data/ext/libdatadog_api/datadog_ruby_common.h +0 -10
  21. data/ext/libdatadog_api/di.c +10 -0
  22. data/ext/libdatadog_api/extconf.rb +3 -0
  23. data/ext/libdatadog_api/init.c +2 -0
  24. data/ext/libdatadog_api/otel_thread_context.c +232 -0
  25. data/ext/libdatadog_api/otel_thread_context.h +5 -0
  26. data/ext/libdatadog_api/trace_exporter.c +409 -71
  27. data/ext/libdatadog_extconf_helpers.rb +1 -1
  28. data/lib/datadog/ai_guard/api_client.rb +1 -1
  29. data/lib/datadog/ai_guard/evaluation/request.rb +8 -8
  30. data/lib/datadog/ai_guard/evaluation.rb +10 -3
  31. data/lib/datadog/ai_guard/ext.rb +1 -1
  32. data/lib/datadog/appsec/actions_handler/serializable_backtrace.rb +21 -42
  33. data/lib/datadog/appsec/api_security/endpoint_collection/grape_route_serializer.rb +1 -1
  34. data/lib/datadog/appsec/api_security/endpoint_collection/rails_route_serializer.rb +1 -1
  35. data/lib/datadog/appsec/api_security/endpoint_collection/sinatra_route_serializer.rb +1 -1
  36. data/lib/datadog/appsec/assets/blocked.html +1 -108
  37. data/lib/datadog/appsec/configuration.rb +2 -2
  38. data/lib/datadog/appsec/context.rb +1 -1
  39. data/lib/datadog/appsec/contrib/active_record/instrumentation.rb +1 -1
  40. data/lib/datadog/appsec/contrib/aws_lambda/waf_addresses.rb +2 -2
  41. data/lib/datadog/appsec/contrib/devise/configuration.rb +1 -1
  42. data/lib/datadog/appsec/contrib/excon/ssrf_detection_middleware.rb +2 -2
  43. data/lib/datadog/appsec/contrib/faraday/ssrf_detection_middleware.rb +2 -2
  44. data/lib/datadog/appsec/contrib/graphql/gateway/watcher.rb +1 -1
  45. data/lib/datadog/appsec/contrib/rack/ext.rb +2 -2
  46. data/lib/datadog/appsec/contrib/rack/gateway/watcher.rb +2 -2
  47. data/lib/datadog/appsec/contrib/rails/gateway/watcher.rb +2 -2
  48. data/lib/datadog/appsec/contrib/rest_client/request_ssrf_detection_patch.rb +2 -2
  49. data/lib/datadog/appsec/contrib/sinatra/gateway/watcher.rb +2 -2
  50. data/lib/datadog/appsec/processor/rule_loader.rb +12 -12
  51. data/lib/datadog/appsec/response.rb +1 -1
  52. data/lib/datadog/appsec/route_normalizer/route_pattern.rb +3 -3
  53. data/lib/datadog/appsec/security_engine/engine.rb +3 -3
  54. data/lib/datadog/core/configuration/components.rb +3 -2
  55. data/lib/datadog/core/configuration/option_definition.rb +1 -1
  56. data/lib/datadog/core/configuration/options.rb +1 -1
  57. data/lib/datadog/core/crashtracking/component.rb +5 -1
  58. data/lib/datadog/core/diagnostics/environment_logger.rb +36 -1
  59. data/lib/datadog/core/metrics/helpers.rb +1 -1
  60. data/lib/datadog/core/metrics/options.rb +2 -2
  61. data/lib/datadog/core/process_discovery.rb +1 -1
  62. data/lib/datadog/core/remote/client.rb +1 -1
  63. data/lib/datadog/core/remote/configuration/repository.rb +2 -2
  64. data/lib/datadog/core/telemetry/configuration_value.rb +38 -0
  65. data/lib/datadog/core/telemetry/event/app_client_configuration_change.rb +3 -1
  66. data/lib/datadog/core/telemetry/event/app_endpoints_loaded.rb +1 -1
  67. data/lib/datadog/core/telemetry/event/app_started.rb +5 -24
  68. data/lib/datadog/core/telemetry/event/generate_metrics.rb +1 -1
  69. data/lib/datadog/core/telemetry/event/log.rb +2 -2
  70. data/lib/datadog/core/telemetry/metric.rb +2 -2
  71. data/lib/datadog/core/telemetry/request.rb +2 -2
  72. data/lib/datadog/core/transport/http.rb +1 -1
  73. data/lib/datadog/core/transport/transport.rb +1 -1
  74. data/lib/datadog/core/utils/at_fork_monkey_patch.rb +127 -43
  75. data/lib/datadog/data_streams/pathway_context.rb +20 -22
  76. data/lib/datadog/data_streams/processor.rb +45 -14
  77. data/lib/datadog/di/el/compiler.rb +23 -0
  78. data/lib/datadog/di/el/expression.rb +8 -5
  79. data/lib/datadog/di/instrumenter.rb +46 -5
  80. data/lib/datadog/di/logger.rb +2 -2
  81. data/lib/datadog/di/probe.rb +9 -1
  82. data/lib/datadog/di/probe_builder.rb +5 -4
  83. data/lib/datadog/di/probe_notification_builder.rb +3 -2
  84. data/lib/datadog/di/remote.rb +3 -3
  85. data/lib/datadog/di/serializer.rb +29 -4
  86. data/lib/datadog/error_tracking/component.rb +1 -1
  87. data/lib/datadog/kit/appsec/events/v2.rb +2 -2
  88. data/lib/datadog/open_feature/evaluation_engine.rb +29 -3
  89. data/lib/datadog/open_feature/exposures/batch_builder.rb +1 -1
  90. data/lib/datadog/open_feature/exposures/event.rb +15 -8
  91. data/lib/datadog/open_feature/ext.rb +19 -0
  92. data/lib/datadog/open_feature/flag_evaluation/aggregator.rb +236 -80
  93. data/lib/datadog/open_feature/flag_evaluation/writer.rb +179 -68
  94. data/lib/datadog/open_feature/hooks/flag_eval_evp_hook.rb +24 -21
  95. data/lib/datadog/open_feature/native_evaluator.rb +33 -6
  96. data/lib/datadog/open_feature/noop_evaluator.rb +5 -0
  97. data/lib/datadog/open_feature/provider.rb +11 -2
  98. data/lib/datadog/opentelemetry/sdk/propagator.rb +1 -1
  99. data/lib/datadog/opentelemetry/trace.rb +3 -0
  100. data/lib/datadog/profiling/collectors/cpu_and_wall_time_worker.rb +3 -0
  101. data/lib/datadog/profiling/collectors/info.rb +1 -1
  102. data/lib/datadog/profiling/collectors/thread_context.rb +0 -4
  103. data/lib/datadog/profiling/component.rb +8 -16
  104. data/lib/datadog/profiling/tasks/exec.rb +1 -1
  105. data/lib/datadog/symbol_database/extractor.rb +6 -6
  106. data/lib/datadog/tracing/configuration/dynamic/option.rb +4 -0
  107. data/lib/datadog/tracing/configuration/dynamic.rb +5 -3
  108. data/lib/datadog/tracing/contrib/action_cable/events.rb +1 -1
  109. data/lib/datadog/tracing/contrib/action_mailer/events.rb +1 -1
  110. data/lib/datadog/tracing/contrib/action_pack/action_controller/instrumentation.rb +2 -2
  111. data/lib/datadog/tracing/contrib/action_view/events.rb +1 -1
  112. data/lib/datadog/tracing/contrib/active_model_serializers/events.rb +1 -1
  113. data/lib/datadog/tracing/contrib/active_record/configuration/resolver.rb +1 -1
  114. data/lib/datadog/tracing/contrib/active_record/events/sql.rb +1 -0
  115. data/lib/datadog/tracing/contrib/active_record/events.rb +1 -1
  116. data/lib/datadog/tracing/contrib/active_support/cache/events/cache.rb +2 -2
  117. data/lib/datadog/tracing/contrib/aws/ext.rb +1 -1
  118. data/lib/datadog/tracing/contrib/aws/services.rb +1 -1
  119. data/lib/datadog/tracing/contrib/elasticsearch/quantize.rb +1 -1
  120. data/lib/datadog/tracing/contrib/ext.rb +3 -3
  121. data/lib/datadog/tracing/contrib/grpc/datadog_interceptor/client.rb +1 -1
  122. data/lib/datadog/tracing/contrib/grpc/datadog_interceptor/server.rb +1 -1
  123. data/lib/datadog/tracing/contrib/grpc/distributed/propagation.rb +1 -1
  124. data/lib/datadog/tracing/contrib/kafka/events.rb +1 -1
  125. data/lib/datadog/tracing/contrib/karafka/distributed/propagation.rb +1 -1
  126. data/lib/datadog/tracing/contrib/mongodb/parsers.rb +1 -1
  127. data/lib/datadog/tracing/contrib/opensearch/ext.rb +1 -1
  128. data/lib/datadog/tracing/contrib/opensearch/quantize.rb +1 -1
  129. data/lib/datadog/tracing/contrib/patchable.rb +1 -1
  130. data/lib/datadog/tracing/contrib/patcher.rb +1 -1
  131. data/lib/datadog/tracing/contrib/que/tracer.rb +1 -1
  132. data/lib/datadog/tracing/contrib/racecar/events.rb +1 -1
  133. data/lib/datadog/tracing/contrib/rack/configuration/settings.rb +1 -1
  134. data/lib/datadog/tracing/contrib/rack/header_tagging.rb +1 -1
  135. data/lib/datadog/tracing/contrib/rack/patcher.rb +1 -1
  136. data/lib/datadog/tracing/contrib/rack/trace_proxy_middleware.rb +1 -1
  137. data/lib/datadog/tracing/contrib/redis/configuration/resolver.rb +1 -1
  138. data/lib/datadog/tracing/contrib/redis/quantize.rb +36 -2
  139. data/lib/datadog/tracing/contrib/redis/trace_middleware.rb +9 -3
  140. data/lib/datadog/tracing/contrib/sequel/utils.rb +1 -1
  141. data/lib/datadog/tracing/contrib/sidekiq/distributed/propagation.rb +1 -1
  142. data/lib/datadog/tracing/contrib/sinatra/configuration/settings.rb +1 -1
  143. data/lib/datadog/tracing/contrib/sneakers/tracer.rb +1 -1
  144. data/lib/datadog/tracing/contrib/utils/quantization/hash_formatter.rb +1 -1
  145. data/lib/datadog/tracing/contrib/waterdrop/distributed/propagation.rb +1 -1
  146. data/lib/datadog/tracing/correlation.rb +2 -2
  147. data/lib/datadog/tracing/diagnostics/environment_logger.rb +2 -2
  148. data/lib/datadog/tracing/distributed/baggage.rb +1 -3
  149. data/lib/datadog/tracing/distributed/datadog.rb +3 -3
  150. data/lib/datadog/tracing/distributed/propagation.rb +3 -0
  151. data/lib/datadog/tracing/distributed/trace_context.rb +14 -271
  152. data/lib/datadog/tracing/distributed/trace_state/datadog.rb +233 -0
  153. data/lib/datadog/tracing/distributed/trace_state/ext.rb +44 -0
  154. data/lib/datadog/tracing/distributed/trace_state/open_telemetry.rb +156 -0
  155. data/lib/datadog/tracing/distributed/trace_state.rb +121 -0
  156. data/lib/datadog/tracing/metadata/tagging.rb +1 -1
  157. data/lib/datadog/tracing/otel_thread_context.rb +30 -0
  158. data/lib/datadog/tracing/remote.rb +197 -29
  159. data/lib/datadog/tracing/sampling/rule_sampler.rb +2 -0
  160. data/lib/datadog/tracing/span.rb +1 -1
  161. data/lib/datadog/tracing/span_operation.rb +1 -1
  162. data/lib/datadog/tracing/trace_digest.rb +22 -4
  163. data/lib/datadog/tracing/trace_operation.rb +22 -10
  164. data/lib/datadog/tracing/tracer.rb +5 -5
  165. data/lib/datadog/tracing/transport/io/traces.rb +1 -1
  166. data/lib/datadog/tracing/transport/native.rb +78 -54
  167. data/lib/datadog/tracing/writer.rb +1 -1
  168. data/lib/datadog/version.rb +1 -1
  169. metadata +15 -8
  170. data/lib/datadog/tracing/distributed/datadog_tags_codec.rb +0 -69
@@ -83,7 +83,7 @@ module Datadog
83
83
  hostname: Datadog::Core::Environment::Platform.hostname,
84
84
  kernel_name: Datadog::Core::Environment::Platform.kernel_name,
85
85
  kernel_release: Datadog::Core::Environment::Platform.kernel_release,
86
- kernel_version: Datadog::Core::Environment::Platform.kernel_version
86
+ kernel_version: Datadog::Core::Environment::Platform.kernel_version,
87
87
  }.freeze
88
88
  end
89
89
 
@@ -19,7 +19,6 @@ module Datadog
19
19
  max_frames:,
20
20
  tracer:,
21
21
  endpoint_collection_enabled:,
22
- waiting_for_gvl_threshold_ns:,
23
22
  otel_context_enabled:,
24
23
  native_filenames_enabled:,
25
24
  show_classes:
@@ -31,7 +30,6 @@ module Datadog
31
30
  max_frames: max_frames,
32
31
  tracer_context_key: tracer_context_key,
33
32
  endpoint_collection_enabled: endpoint_collection_enabled,
34
- waiting_for_gvl_threshold_ns: waiting_for_gvl_threshold_ns,
35
33
  otel_context_enabled: otel_context_enabled,
36
34
  native_filenames_enabled: native_filenames_enabled,
37
35
  show_classes: show_classes,
@@ -44,7 +42,6 @@ module Datadog
44
42
  max_frames: 400,
45
43
  tracer: nil,
46
44
  endpoint_collection_enabled: false,
47
- waiting_for_gvl_threshold_ns: 10_000_000,
48
45
  otel_context_enabled: false,
49
46
  native_filenames_enabled: true,
50
47
  show_classes: false,
@@ -56,7 +53,6 @@ module Datadog
56
53
  max_frames: max_frames,
57
54
  tracer: tracer,
58
55
  endpoint_collection_enabled: endpoint_collection_enabled,
59
- waiting_for_gvl_threshold_ns: waiting_for_gvl_threshold_ns,
60
56
  otel_context_enabled: otel_context_enabled,
61
57
  native_filenames_enabled: native_filenames_enabled,
62
58
  show_classes: show_classes,
@@ -65,6 +65,7 @@ module Datadog
65
65
  gvl_profiling_enabled: enable_gvl_profiling?(settings, logger),
66
66
  sighandler_sampling_enabled: settings.profiling.advanced.sighandler_sampling_enabled,
67
67
  cpu_sampling_interval_ms: cpu_sampling_interval_ms,
68
+ waiting_for_gvl_threshold_ns: settings.profiling.advanced.waiting_for_gvl_threshold_ns,
68
69
  )
69
70
 
70
71
  internal_metadata = {
@@ -102,7 +103,6 @@ module Datadog
102
103
  max_frames: settings.profiling.advanced.max_frames,
103
104
  tracer: optional_tracer,
104
105
  endpoint_collection_enabled: settings.profiling.advanced.endpoint.collection.enabled,
105
- waiting_for_gvl_threshold_ns: settings.profiling.advanced.waiting_for_gvl_threshold_ns,
106
106
  otel_context_enabled: settings.profiling.advanced.preview_otel_context_enabled,
107
107
  native_filenames_enabled: settings.profiling.advanced.native_filenames_enabled,
108
108
  show_classes: settings.profiling.advanced.experimental_show_classes_enabled,
@@ -227,11 +227,13 @@ module Datadog
227
227
  return false
228
228
  end
229
229
 
230
- # Heap profiling relies on `ObjectSpace._id2ref`, which was removed on Ruby 4.1
231
- # (https://bugs.ruby-lang.org/issues/22135).
232
- if RubyVersion.is?(">= 4.1")
230
+ # Heap profiling tracks live objects using an `ObjectSpace::WeakMap`, which could corrupt its internal
231
+ # state during compaction before these versions (https://bugs.ruby-lang.org/issues/19529).
232
+ if RubyVersion.is?("< 3.1.4") || RubyVersion.is?(">= 3.2", "< 3.2.3")
233
233
  logger.warn(
234
- "Heap profiling is currently incompatible with Ruby 4.1+ and has been disabled."
234
+ "Current Ruby version (#{RUBY_VERSION}) cannot support heap profiling due to a VM bug. " \
235
+ "Please upgrade to Ruby >= 3.1.4 or >= 3.2.3 in order to use this feature. " \
236
+ "Heap profiling has been disabled."
235
237
  )
236
238
  return false
237
239
  end
@@ -252,17 +254,7 @@ module Datadog
252
254
  private_class_method def self.enable_heap_size_profiling?(settings, heap_profiling_enabled, logger)
253
255
  heap_size_profiling_enabled = settings.profiling.advanced.experimental_heap_size_enabled
254
256
 
255
- return false unless heap_profiling_enabled && heap_size_profiling_enabled
256
-
257
- if RubyVersion.is?(">= 4")
258
- logger.info(
259
- "Heap live size profiling is currently incompatible with Ruby 4 and has been disabled. " \
260
- "Heap live objects is not affected and remains enabled."
261
- )
262
- return false
263
- end
264
-
265
- true
257
+ heap_profiling_enabled && heap_size_profiling_enabled
266
258
  end
267
259
 
268
260
  private_class_method def self.no_signals_workaround_enabled?(settings, logger) # rubocop:disable Metrics/MethodLength
@@ -21,7 +21,7 @@ module Datadog
21
21
  #: () -> ::Array["-rdatadog/profiling/preload"]
22
22
  def rubyopts
23
23
  [
24
- "-rdatadog/profiling/preload"
24
+ "-rdatadog/profiling/preload",
25
25
  ]
26
26
  end
27
27
 
@@ -616,7 +616,7 @@ module Datadog
616
616
  language_specifics: {
617
617
  visibility: method_visibility(klass, method_name),
618
618
  method_type: method_type.to_s,
619
- arity: method.arity
619
+ arity: method.arity,
620
620
  },
621
621
  symbols: extract_method_parameters(method)
622
622
  )
@@ -647,7 +647,7 @@ module Datadog
647
647
  # @param start_line [Integer] Fallback end_line if iseq unavailable
648
648
  # @return [Array(Array<Hash>, Integer), Array(nil, Integer)]
649
649
  def extract_targetable_lines(method, start_line)
650
- iseq = RubyVM::InstructionSequence.of(method) # steep:ignore
650
+ iseq = RubyVM::InstructionSequence.of(method)
651
651
  unless iseq
652
652
  @logger.debug { "symdb: no iseq for #{method.name} (C extension or native), skipping targetable lines" }
653
653
  return [nil, start_line]
@@ -801,7 +801,7 @@ module Datadog
801
801
  # objects allocated to read `source_location` are not retained between
802
802
  # passes, so they can be GC'd as soon as the inner loop ends.
803
803
  def collect_method_names_by_file(mod)
804
- result = Hash.new { |h, k| h[k] = [] } # steep:ignore
804
+ result = Hash.new { |h, k| h[k] = [] }
805
805
 
806
806
  # Module#instance_methods(false) already returns both public and protected
807
807
  # methods, so iterating it plus private_instance_methods covers all three
@@ -905,7 +905,7 @@ module Datadog
905
905
  current[:children][part] ||= {
906
906
  name: fqn, type: resolve_scope_type(fqn),
907
907
  children: {}, methods: [], mod: nil,
908
- source_file: file_path, fqn: fqn
908
+ source_file: file_path, fqn: fqn,
909
909
  }
910
910
  current = current[:children][part]
911
911
  end
@@ -924,7 +924,7 @@ module Datadog
924
924
  type: (Class === mod) ? "CLASS" : "MODULE",
925
925
  children: {}, methods: [],
926
926
  mod: mod, source_file: file_path,
927
- fqn: mod_name
927
+ fqn: mod_name,
928
928
  }
929
929
  current[:children][leaf_name] = leaf
930
930
  end
@@ -1043,7 +1043,7 @@ module Datadog
1043
1043
  language_specifics: {
1044
1044
  visibility: klass ? method_visibility(klass, method_name) : "public", # steep:ignore
1045
1045
  method_type: "instance",
1046
- arity: method.arity
1046
+ arity: method.arity,
1047
1047
  },
1048
1048
  symbols: extract_method_parameters(method)
1049
1049
  )
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative "../../../core/telemetry/configuration_value"
4
+
3
5
  module Datadog
4
6
  module Tracing
5
7
  module Configuration
@@ -56,6 +58,8 @@ module Datadog
56
58
  precedence: Core::Configuration::Option::Precedence::REMOTE_CONFIGURATION
57
59
  )
58
60
  end
61
+
62
+ Core::Telemetry::ConfigurationValue.convert(value)
59
63
  end
60
64
 
61
65
  protected
@@ -24,11 +24,11 @@ module Datadog
24
24
  def call(tracing_header_tags)
25
25
  # Modify the remote configuration value that it matches the
26
26
  # environment variable it configures.
27
- tracing_header_tags&.map! do |hash|
27
+ parsed_header_tags = tracing_header_tags&.map do |hash|
28
28
  "#{hash["header"]}:#{hash["tag_name"]}"
29
29
  end
30
30
 
31
- super
31
+ super(parsed_header_tags)
32
32
  end
33
33
  end
34
34
 
@@ -42,6 +42,7 @@ module Datadog
42
42
  def call(tracing_sampling_rate)
43
43
  super
44
44
  Datadog.send(:components).reconfigure_sampler
45
+ tracing_sampling_rate
45
46
  end
46
47
 
47
48
  protected
@@ -78,8 +79,9 @@ module Datadog
78
79
  tracing_sampling_rules = tracing_sampling_rules.to_json
79
80
  end
80
81
 
81
- super
82
+ telemetry_value = super
82
83
  Datadog.send(:components).reconfigure_sampler
84
+ telemetry_value
83
85
  end
84
86
 
85
87
  protected
@@ -14,7 +14,7 @@ module Datadog
14
14
  ALL = [
15
15
  Events::Broadcast,
16
16
  Events::PerformAction,
17
- Events::Transmit
17
+ Events::Transmit,
18
18
  ].freeze
19
19
 
20
20
  module_function
@@ -11,7 +11,7 @@ module Datadog
11
11
  module Events
12
12
  ALL = [
13
13
  Events::Process,
14
- Events::Deliver
14
+ Events::Deliver,
15
15
  ].freeze
16
16
 
17
17
  module_function
@@ -108,9 +108,9 @@ module Datadog
108
108
  headers: {
109
109
  # The exception this controller was given in the request,
110
110
  # which is typical if the controller is configured to handle exceptions.
111
- request_exception: request.headers["action_dispatch.exception"]
111
+ request_exception: request.headers["action_dispatch.exception"],
112
112
  },
113
- tracing_context: {}
113
+ tracing_context: {},
114
114
  }
115
115
 
116
116
  begin
@@ -11,7 +11,7 @@ module Datadog
11
11
  module Events
12
12
  ALL = [
13
13
  Events::RenderPartial,
14
- Events::RenderTemplate
14
+ Events::RenderTemplate,
15
15
  ].freeze
16
16
 
17
17
  module_function
@@ -11,7 +11,7 @@ module Datadog
11
11
  module Events
12
12
  ALL = [
13
13
  Events::Render,
14
- Events::Serialize
14
+ Events::Serialize,
15
15
  ].freeze
16
16
 
17
17
  module_function
@@ -138,7 +138,7 @@ module Datadog
138
138
  host: active_record_config[:host],
139
139
  port: active_record_config[:port],
140
140
  database: active_record_config[:database],
141
- username: active_record_config[:username]
141
+ username: active_record_config[:username],
142
142
  }
143
143
  end
144
144
 
@@ -46,6 +46,7 @@ module Datadog
46
46
  span.resource = payload.fetch(:sql)
47
47
  span.type = Tracing::Metadata::Ext::SQL::TYPE
48
48
 
49
+ span.set_tag(Tracing::Metadata::Ext::TAG_KIND, Tracing::Metadata::Ext::SpanKind::TAG_CLIENT)
49
50
  span.set_tag(Tracing::Metadata::Ext::TAG_COMPONENT, Ext::TAG_COMPONENT)
50
51
  span.set_tag(Tracing::Metadata::Ext::TAG_OPERATION, Ext::TAG_OPERATION_SQL)
51
52
 
@@ -11,7 +11,7 @@ module Datadog
11
11
  module Events
12
12
  ALL = [
13
13
  Events::Instantiation,
14
- Events::SQL
14
+ Events::SQL,
15
15
  ].freeze
16
16
 
17
17
  module_function
@@ -32,7 +32,7 @@ module Datadog
32
32
 
33
33
  def span_options
34
34
  {
35
- type: Ext::SPAN_TYPE_CACHE
35
+ type: Ext::SPAN_TYPE_CACHE,
36
36
  }
37
37
  end
38
38
 
@@ -42,7 +42,7 @@ module Datadog
42
42
  "cache_read.active_support" => {resource: Ext::RESOURCE_CACHE_GET},
43
43
  "cache_read_multi.active_support" => {resource: Ext::RESOURCE_CACHE_MGET, multi_key: true},
44
44
  "cache_write.active_support" => {resource: Ext::RESOURCE_CACHE_SET},
45
- "cache_write_multi.active_support" => {resource: Ext::RESOURCE_CACHE_MSET, multi_key: true}
45
+ "cache_write_multi.active_support" => {resource: Ext::RESOURCE_CACHE_MSET, multi_key: true},
46
46
  }.freeze
47
47
 
48
48
  def trace?(event, payload)
@@ -42,7 +42,7 @@ module Datadog
42
42
  TAG_STATE_MACHINE_NAME,
43
43
  Tracing::Metadata::Ext::TAG_PEER_HOSTNAME,
44
44
  Tracing::Metadata::Ext::NET::TAG_DESTINATION_NAME,
45
- Tracing::Metadata::Ext::NET::TAG_TARGET_HOST,].freeze
45
+ Tracing::Metadata::Ext::NET::TAG_TARGET_HOST].freeze
46
46
  end
47
47
  end
48
48
  end
@@ -131,7 +131,7 @@ module Datadog
131
131
  "kinesis" => Service::Kinesis.new,
132
132
  "eventbridge" => Service::EventBridge.new,
133
133
  "states" => Service::States.new,
134
- "s3" => Service::S3.new
134
+ "s3" => Service::S3.new,
135
135
  }.freeze
136
136
  end
137
137
  end
@@ -15,7 +15,7 @@ module Datadog
15
15
  DEFAULT_OPTIONS = {
16
16
  exclude: EXCLUDE_KEYS,
17
17
  show: SHOW_KEYS,
18
- placeholder: PLACEHOLDER
18
+ placeholder: PLACEHOLDER,
19
19
  }.freeze
20
20
 
21
21
  module_function
@@ -31,7 +31,7 @@ module Datadog
31
31
  PEER_SERVICE_SOURCES = [TAG_INSTANCE,
32
32
  Tracing::Metadata::Ext::NET::TAG_DESTINATION_NAME,
33
33
  Tracing::Metadata::Ext::TAG_PEER_HOSTNAME,
34
- Tracing::Metadata::Ext::NET::TAG_TARGET_HOST,].freeze
34
+ Tracing::Metadata::Ext::NET::TAG_TARGET_HOST].freeze
35
35
  end
36
36
 
37
37
  module RPC
@@ -41,7 +41,7 @@ module Datadog
41
41
  PEER_SERVICE_SOURCES = [TAG_SERVICE,
42
42
  Tracing::Metadata::Ext::NET::TAG_DESTINATION_NAME,
43
43
  Tracing::Metadata::Ext::TAG_PEER_HOSTNAME,
44
- Tracing::Metadata::Ext::NET::TAG_TARGET_HOST,].freeze
44
+ Tracing::Metadata::Ext::NET::TAG_TARGET_HOST].freeze
45
45
  module GRPC
46
46
  TAG_STATUS_CODE = "rpc.grpc.status_code"
47
47
  TAG_FULL_METHOD = "rpc.grpc.full_method"
@@ -53,7 +53,7 @@ module Datadog
53
53
  TAG_DESTINATION = "messaging.destination"
54
54
  PEER_SERVICE_SOURCES = [Tracing::Metadata::Ext::NET::TAG_DESTINATION_NAME,
55
55
  Tracing::Metadata::Ext::TAG_PEER_HOSTNAME,
56
- Tracing::Metadata::Ext::NET::TAG_TARGET_HOST,].freeze
56
+ Tracing::Metadata::Ext::NET::TAG_TARGET_HOST].freeze
57
57
  end
58
58
 
59
59
  module Metadata
@@ -25,7 +25,7 @@ module Datadog
25
25
  type: Tracing::Metadata::Ext::HTTP::TYPE_OUTBOUND,
26
26
  service: service_name, # Maintain client-side service name configuration
27
27
  resource: formatter.resource_name,
28
- on_error: on_error
28
+ on_error: on_error,
29
29
  }
30
30
 
31
31
  Tracing.trace(Ext::SPAN_CLIENT, **options) do |span, trace|
@@ -26,7 +26,7 @@ module Datadog
26
26
  type: Tracing::Metadata::Ext::HTTP::TYPE_INBOUND,
27
27
  service: service_name, # TODO: Remove server-side service name configuration
28
28
  resource: formatter.resource_name,
29
- on_error: on_error
29
+ on_error: on_error,
30
30
  }
31
31
  metadata = keywords[:call].metadata
32
32
 
@@ -35,7 +35,7 @@ module Datadog
35
35
  Tracing::Distributed::TraceContext.new(fetcher: Fetcher),
36
36
  Tracing::Configuration::Ext::Distributed::PROPAGATION_STYLE_BAGGAGE =>
37
37
  Tracing::Distributed::Baggage.new(fetcher: Fetcher),
38
- Tracing::Configuration::Ext::Distributed::PROPAGATION_STYLE_NONE => Tracing::Distributed::None.new
38
+ Tracing::Configuration::Ext::Distributed::PROPAGATION_STYLE_NONE => Tracing::Distributed::None.new,
39
39
  },
40
40
  propagation_style_inject: propagation_style_inject,
41
41
  propagation_style_extract: propagation_style_extract,
@@ -25,7 +25,7 @@ module Datadog
25
25
  Events::ConsumerGroup::LeaveGroup,
26
26
  Events::ConsumerGroup::SyncGroup,
27
27
  Events::ProduceOperation::SendMessages,
28
- Events::Producer::DeliverMessages
28
+ Events::Producer::DeliverMessages,
29
29
  ].freeze
30
30
 
31
31
  module_function
@@ -34,7 +34,7 @@ module Datadog
34
34
  Tracing::Distributed::TraceContext.new(fetcher: Tracing::Distributed::Fetcher),
35
35
  Tracing::Configuration::Ext::Distributed::PROPAGATION_STYLE_BAGGAGE =>
36
36
  Tracing::Distributed::Baggage.new(fetcher: Tracing::Distributed::Fetcher),
37
- Tracing::Configuration::Ext::Distributed::PROPAGATION_STYLE_NONE => Tracing::Distributed::None.new
37
+ Tracing::Configuration::Ext::Distributed::PROPAGATION_STYLE_NONE => Tracing::Distributed::None.new,
38
38
  },
39
39
  propagation_style_inject: propagation_style_inject,
40
40
  propagation_style_extract: propagation_style_extract,
@@ -28,7 +28,7 @@ module Datadog
28
28
  {
29
29
  "operation" => command_name,
30
30
  "database" => database_name,
31
- "collection" => command.values.first
31
+ "collection" => command.values.first,
32
32
  },
33
33
  options
34
34
  )
@@ -18,7 +18,7 @@ module Datadog
18
18
  RELATIVE_RESOURCE_PATTERN = "relative"
19
19
  VALID_RESOURCE_PATTERNS = [
20
20
  ABSOLUTE_RESOURCE_PATTERN,
21
- RELATIVE_RESOURCE_PATTERN
21
+ RELATIVE_RESOURCE_PATTERN,
22
22
  ].freeze
23
23
  # Default should be changed to RELATIVE in 3.0 to match the Elasticsearch integration
24
24
  DEFAULT_RESOURCE_PATTERN = ABSOLUTE_RESOURCE_PATTERN
@@ -15,7 +15,7 @@ module Datadog
15
15
  DEFAULT_OPTIONS = {
16
16
  exclude: EXCLUDE_KEYS,
17
17
  show: SHOW_KEYS,
18
- placeholder: PLACEHOLDER
18
+ placeholder: PLACEHOLDER,
19
19
  }.freeze
20
20
 
21
21
  module_function
@@ -84,7 +84,7 @@ module Datadog
84
84
  available: self.class.available?,
85
85
  loaded: self.class.loaded?,
86
86
  compatible: self.class.compatible?,
87
- patchable: self.class.patchable?
87
+ patchable: self.class.patchable?,
88
88
  }
89
89
  end
90
90
 
@@ -57,7 +57,7 @@ module Datadog
57
57
  @patch_error_result = {
58
58
  type: e.class.name,
59
59
  message: e.message,
60
- line: Array(e.backtrace).first
60
+ line: Array(e.backtrace).first,
61
61
  }
62
62
 
63
63
  # Emit a metric
@@ -12,7 +12,7 @@ module Datadog
12
12
  trace_options = {
13
13
  service: configuration[:service_name],
14
14
  type: Tracing::Metadata::Ext::AppTypes::TYPE_WORKER,
15
- on_error: configuration[:on_error]
15
+ on_error: configuration[:on_error],
16
16
  }
17
17
 
18
18
  Tracing.trace(Ext::SPAN_JOB, **trace_options) do |request_span|
@@ -13,7 +13,7 @@ module Datadog
13
13
  ALL = [
14
14
  Events::Consume,
15
15
  Events::Batch,
16
- Events::Message
16
+ Events::Message,
17
17
  ].freeze
18
18
 
19
19
  module_function
@@ -15,7 +15,7 @@ module Datadog
15
15
  response: %w[
16
16
  Content-Type
17
17
  X-Request-ID
18
- ]
18
+ ],
19
19
  }.freeze
20
20
 
21
21
  option :enabled do |o|
@@ -10,7 +10,7 @@ module Datadog
10
10
  module HeaderTagging
11
11
  DATADOG_REQUEST_ATTRIBUTION_HEADERS = [
12
12
  "x-datadog-endpoint-scan",
13
- "x-datadog-security-test"
13
+ "x-datadog-security-test",
14
14
  ].freeze
15
15
 
16
16
  def self.tag_request_headers(span, env, configuration)
@@ -70,7 +70,7 @@ module Datadog
70
70
  module Patcher
71
71
  PATCHERS = [
72
72
  MiddlewarePatcher,
73
- MiddlewareNamePatcher
73
+ MiddlewareNamePatcher,
74
74
  ].freeze
75
75
 
76
76
  module_function
@@ -27,7 +27,7 @@ module Datadog
27
27
  options = {
28
28
  service: configuration[:web_service_name],
29
29
  start_time: start_time,
30
- type: Tracing::Metadata::Ext::HTTP::TYPE_PROXY
30
+ type: Tracing::Metadata::Ext::HTTP::TYPE_PROXY,
31
31
  }
32
32
 
33
33
  request_span = Tracing.trace(Ext::SPAN_HTTP_PROXY_REQUEST, **options)
@@ -34,7 +34,7 @@ module Datadog
34
34
  host: hash[:host],
35
35
  port: hash[:port],
36
36
  db: hash[:db],
37
- scheme: hash[:scheme]
37
+ scheme: hash[:scheme],
38
38
  }
39
39
  end
40
40
 
@@ -15,6 +15,9 @@ module Datadog
15
15
 
16
16
  AUTH_COMMANDS = %w[AUTH auth].freeze
17
17
 
18
+ CONNECTION_SETUP_COMMANDS = Set.new(%w[HELLO]).freeze
19
+ CLIENT_CONNECTION_SETUP_SUBCOMMANDS = Set.new(%w[SETINFO SETNAME]).freeze
20
+
18
21
  MULTI_VERB_COMMANDS = Set.new(
19
22
  %w[
20
23
  ACL
@@ -40,7 +43,7 @@ module Datadog
40
43
 
41
44
  def format_command_args(command_args)
42
45
  command_args = resolve_command_args(command_args)
43
- return "AUTH ?" if auth_command?(command_args)
46
+ return "AUTH ?" if auth_command?(command_args) || hello_auth_command?(command_args)
44
47
 
45
48
  verb, *args = command_args.map { |x| format_arg(x) }
46
49
  Core::Utils.truncate("#{verb.upcase} #{args.join(" ")}", CMD_MAX_LEN, TOO_LONG_MARK)
@@ -51,6 +54,8 @@ module Datadog
51
54
 
52
55
  return get_verb(command_args.first) if command_args.first.is_a?(Array)
53
56
 
57
+ return "AUTH" if hello_auth_command?(command_args)
58
+
54
59
  verb = command_args.first.to_s.upcase
55
60
  return verb unless MULTI_VERB_COMMANDS.include?(verb) && command_args[1]
56
61
 
@@ -64,6 +69,35 @@ module Datadog
64
69
  AUTH_COMMANDS.include?(verb)
65
70
  end
66
71
 
72
+ # Identifies a RESP3 `HELLO ... AUTH user pass` handshake command, which embeds
73
+ # credentials the same way a standalone `AUTH` command does and must be redacted
74
+ # (and kept visible as its own span) rather than treated as a silent connection
75
+ # bootstrap command.
76
+ def hello_auth_command?(command_args)
77
+ return false unless command_args.is_a?(Array) && !command_args.empty?
78
+
79
+ # `redis-client` always emits this as `["HELLO", "3", "AUTH", username, password]` — check
80
+ # the fixed "AUTH" keyword position only, never the username/password values themselves,
81
+ # since those are untrusted, possibly-binary bulk strings that `#upcase` can raise on.
82
+ return false if command_args.length < 3
83
+ command_args[0].to_s.upcase == "HELLO" && command_args[2].to_s.upcase == "AUTH"
84
+ end
85
+
86
+ # Identifies protocol-level connection bootstrap commands (`HELLO`, `CLIENT SETINFO`,
87
+ # `CLIENT SETNAME`) that `redis-client` sends as part of its per-connection handshake,
88
+ # so they can be excluded from pipeline resource naming. A `HELLO` carrying `AUTH`
89
+ # credentials is excluded from this so authentication remains visible as its own span.
90
+ def connection_setup_command?(command_args)
91
+ command_args = resolve_command_args(command_args)
92
+ return false unless command_args.is_a?(Array) && !command_args.empty?
93
+ return false if hello_auth_command?(command_args)
94
+
95
+ verb = command_args.first.to_s.upcase
96
+ return true if CONNECTION_SETUP_COMMANDS.include?(verb)
97
+
98
+ verb == "CLIENT" && CLIENT_CONNECTION_SETUP_SUBCOMMANDS.include?(command_args[1].to_s.upcase)
99
+ end
100
+
67
101
  # Unwraps command array when Redis is called with the following syntax:
68
102
  # redis.call([:cmd, 'arg1', ...])
69
103
  def resolve_command_args(command_args)
@@ -72,7 +106,7 @@ module Datadog
72
106
  command_args
73
107
  end
74
108
 
75
- private_class_method :auth_command?, :resolve_command_args
109
+ private_class_method :auth_command?, :hello_auth_command?, :resolve_command_args
76
110
  end
77
111
  end
78
112
  end
@@ -37,12 +37,18 @@ module Datadog
37
37
  end
38
38
 
39
39
  def call_pipelined(client, commands, service_name, command_args)
40
+ # `redis-client` sends its per-connection handshake (`HELLO`, `CLIENT SETINFO`/`SETNAME`)
41
+ # as a pipeline through this same code path. Excluding those from resource naming keeps
42
+ # the resource focused on application-issued commands (e.g. a lone `SELECT` prelude).
43
+ traced_commands = commands.reject { |c| Contrib::Redis::Quantize.connection_setup_command?(c) }
44
+ return yield if traced_commands.empty? && !commands.empty?
45
+
40
46
  Tracing.trace(Redis::Ext::SPAN_COMMAND, type: Redis::Ext::TYPE, service: service_name) do |span|
41
47
  span.set_tag(Tracing::Metadata::Ext::TAG_SVC_SRC, Redis::Ext::TAG_COMPONENT)
42
- raw_command = get_pipeline_commands(commands, true)
43
- span.resource = command_args ? raw_command : get_pipeline_commands(commands, false)
48
+ raw_command = get_pipeline_commands(traced_commands, true)
49
+ span.resource = command_args ? raw_command : get_pipeline_commands(traced_commands, false)
44
50
 
45
- span.set_metric Contrib::Redis::Ext::METRIC_PIPELINE_LEN, commands.length
51
+ span.set_metric Contrib::Redis::Ext::METRIC_PIPELINE_LEN, traced_commands.length
46
52
 
47
53
  Contrib::Redis::Tags.set_common_tags(client, span, raw_command)
48
54
 
@@ -84,7 +84,7 @@ module Datadog
84
84
  query: sql,
85
85
  prepared_name: prepared_name,
86
86
  database: db_opts[:database],
87
- host: db_opts[:host]
87
+ host: db_opts[:host],
88
88
  }
89
89
  end
90
90