datadog 2.21.0 → 2.23.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 (205) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +106 -2
  3. data/ext/LIBDATADOG_DEVELOPMENT.md +3 -0
  4. data/ext/datadog_profiling_native_extension/collectors_discrete_dynamic_sampler.c +1 -1
  5. data/ext/datadog_profiling_native_extension/collectors_stack.c +4 -0
  6. data/ext/datadog_profiling_native_extension/datadog_ruby_common.h +1 -1
  7. data/ext/datadog_profiling_native_extension/extconf.rb +6 -4
  8. data/ext/datadog_profiling_native_extension/heap_recorder.c +1 -1
  9. data/ext/libdatadog_api/datadog_ruby_common.h +1 -1
  10. data/ext/libdatadog_api/ddsketch.c +106 -0
  11. data/ext/libdatadog_api/feature_flags.c +554 -0
  12. data/ext/libdatadog_api/feature_flags.h +5 -0
  13. data/ext/libdatadog_api/init.c +5 -0
  14. data/ext/libdatadog_api/library_config.c +34 -25
  15. data/ext/libdatadog_api/process_discovery.c +19 -13
  16. data/ext/libdatadog_extconf_helpers.rb +1 -1
  17. data/lib/datadog/appsec/api_security/endpoint_collection/grape_route_serializer.rb +26 -0
  18. data/lib/datadog/appsec/api_security/endpoint_collection/rails_collector.rb +59 -0
  19. data/lib/datadog/appsec/api_security/endpoint_collection/rails_route_serializer.rb +29 -0
  20. data/lib/datadog/appsec/api_security/endpoint_collection/sinatra_route_serializer.rb +26 -0
  21. data/lib/datadog/appsec/api_security/endpoint_collection.rb +10 -0
  22. data/lib/datadog/appsec/api_security/route_extractor.rb +23 -6
  23. data/lib/datadog/appsec/api_security/sampler.rb +7 -4
  24. data/lib/datadog/appsec/assets/blocked.html +8 -0
  25. data/lib/datadog/appsec/assets/blocked.json +1 -1
  26. data/lib/datadog/appsec/assets/blocked.text +3 -1
  27. data/lib/datadog/appsec/assets/waf_rules/README.md +30 -36
  28. data/lib/datadog/appsec/assets/waf_rules/recommended.json +359 -4
  29. data/lib/datadog/appsec/assets/waf_rules/strict.json +43 -2
  30. data/lib/datadog/appsec/assets.rb +1 -1
  31. data/lib/datadog/appsec/compressed_json.rb +1 -1
  32. data/lib/datadog/appsec/configuration/settings.rb +9 -0
  33. data/lib/datadog/appsec/contrib/active_record/instrumentation.rb +3 -1
  34. data/lib/datadog/appsec/contrib/excon/ssrf_detection_middleware.rb +3 -2
  35. data/lib/datadog/appsec/contrib/faraday/ssrf_detection_middleware.rb +3 -1
  36. data/lib/datadog/appsec/contrib/graphql/gateway/watcher.rb +3 -1
  37. data/lib/datadog/appsec/contrib/rack/gateway/watcher.rb +9 -4
  38. data/lib/datadog/appsec/contrib/rack/request_middleware.rb +5 -1
  39. data/lib/datadog/appsec/contrib/rails/gateway/watcher.rb +7 -2
  40. data/lib/datadog/appsec/contrib/rails/patcher.rb +30 -0
  41. data/lib/datadog/appsec/contrib/rest_client/request_ssrf_detection_patch.rb +3 -1
  42. data/lib/datadog/appsec/contrib/sinatra/gateway/watcher.rb +10 -4
  43. data/lib/datadog/appsec/event.rb +12 -14
  44. data/lib/datadog/appsec/metrics/collector.rb +19 -3
  45. data/lib/datadog/appsec/metrics/telemetry_exporter.rb +2 -1
  46. data/lib/datadog/appsec/monitor/gateway/watcher.rb +4 -4
  47. data/lib/datadog/appsec/remote.rb +29 -13
  48. data/lib/datadog/appsec/response.rb +18 -4
  49. data/lib/datadog/appsec/security_engine/result.rb +28 -9
  50. data/lib/datadog/appsec/security_engine/runner.rb +17 -7
  51. data/lib/datadog/appsec/security_event.rb +5 -7
  52. data/lib/datadog/core/configuration/components.rb +44 -9
  53. data/lib/datadog/core/configuration/config_helper.rb +1 -1
  54. data/lib/datadog/core/configuration/settings.rb +14 -0
  55. data/lib/datadog/core/configuration/stable_config.rb +10 -0
  56. data/lib/datadog/core/configuration/supported_configurations.rb +330 -299
  57. data/lib/datadog/core/configuration.rb +1 -1
  58. data/lib/datadog/core/ddsketch.rb +19 -0
  59. data/lib/datadog/core/environment/ext.rb +6 -0
  60. data/lib/datadog/core/environment/process.rb +79 -0
  61. data/lib/datadog/core/environment/yjit.rb +2 -1
  62. data/lib/datadog/core/feature_flags.rb +61 -0
  63. data/lib/datadog/core/pin.rb +4 -8
  64. data/lib/datadog/core/process_discovery.rb +4 -2
  65. data/lib/datadog/core/remote/client/capabilities.rb +7 -0
  66. data/lib/datadog/core/remote/component.rb +4 -6
  67. data/lib/datadog/core/remote/transport/config.rb +2 -10
  68. data/lib/datadog/core/remote/transport/http/config.rb +9 -9
  69. data/lib/datadog/core/remote/transport/http/negotiation.rb +17 -8
  70. data/lib/datadog/core/remote/transport/http.rb +2 -0
  71. data/lib/datadog/core/remote/transport/negotiation.rb +2 -18
  72. data/lib/datadog/core/remote/worker.rb +25 -37
  73. data/lib/datadog/core/tag_builder.rb +0 -4
  74. data/lib/datadog/core/tag_normalizer.rb +84 -0
  75. data/lib/datadog/core/telemetry/component.rb +18 -3
  76. data/lib/datadog/core/telemetry/emitter.rb +6 -6
  77. data/lib/datadog/core/telemetry/event/app_endpoints_loaded.rb +30 -0
  78. data/lib/datadog/core/telemetry/event/app_started.rb +52 -49
  79. data/lib/datadog/core/telemetry/event/synth_app_client_configuration_change.rb +1 -1
  80. data/lib/datadog/core/telemetry/event.rb +1 -0
  81. data/lib/datadog/core/telemetry/logger.rb +2 -2
  82. data/lib/datadog/core/telemetry/logging.rb +2 -8
  83. data/lib/datadog/core/telemetry/transport/http/telemetry.rb +5 -6
  84. data/lib/datadog/core/telemetry/transport/telemetry.rb +1 -2
  85. data/lib/datadog/core/transport/http/client.rb +69 -0
  86. data/lib/datadog/core/transport/response.rb +4 -1
  87. data/lib/datadog/core/utils/array.rb +29 -0
  88. data/lib/datadog/{appsec/api_security → core/utils}/lru_cache.rb +10 -21
  89. data/lib/datadog/core/utils/network.rb +22 -1
  90. data/lib/datadog/core/utils/only_once_successful.rb +6 -2
  91. data/lib/datadog/core/utils.rb +2 -0
  92. data/lib/datadog/data_streams/configuration/settings.rb +49 -0
  93. data/lib/datadog/data_streams/configuration.rb +11 -0
  94. data/lib/datadog/data_streams/ext.rb +11 -0
  95. data/lib/datadog/data_streams/extensions.rb +16 -0
  96. data/lib/datadog/data_streams/pathway_context.rb +169 -0
  97. data/lib/datadog/data_streams/processor.rb +509 -0
  98. data/lib/datadog/data_streams/transport/http/api.rb +33 -0
  99. data/lib/datadog/data_streams/transport/http/client.rb +21 -0
  100. data/lib/datadog/data_streams/transport/http/stats.rb +87 -0
  101. data/lib/datadog/data_streams/transport/http.rb +41 -0
  102. data/lib/datadog/data_streams/transport/stats.rb +60 -0
  103. data/lib/datadog/data_streams.rb +100 -0
  104. data/lib/datadog/di/boot.rb +1 -0
  105. data/lib/datadog/di/component.rb +14 -16
  106. data/lib/datadog/di/context.rb +70 -0
  107. data/lib/datadog/di/el/compiler.rb +164 -0
  108. data/lib/datadog/di/el/evaluator.rb +159 -0
  109. data/lib/datadog/di/el/expression.rb +42 -0
  110. data/lib/datadog/di/el.rb +5 -0
  111. data/lib/datadog/di/error.rb +29 -0
  112. data/lib/datadog/di/instrumenter.rb +163 -48
  113. data/lib/datadog/di/probe.rb +55 -15
  114. data/lib/datadog/di/probe_builder.rb +39 -1
  115. data/lib/datadog/di/probe_manager.rb +13 -4
  116. data/lib/datadog/di/probe_notification_builder.rb +105 -67
  117. data/lib/datadog/di/proc_responder.rb +32 -0
  118. data/lib/datadog/di/serializer.rb +151 -7
  119. data/lib/datadog/di/transport/diagnostics.rb +2 -2
  120. data/lib/datadog/di/transport/http/diagnostics.rb +2 -4
  121. data/lib/datadog/di/transport/http/input.rb +2 -4
  122. data/lib/datadog/di/transport/http.rb +6 -2
  123. data/lib/datadog/di/transport/input.rb +64 -4
  124. data/lib/datadog/open_feature/component.rb +60 -0
  125. data/lib/datadog/open_feature/configuration.rb +27 -0
  126. data/lib/datadog/open_feature/evaluation_engine.rb +69 -0
  127. data/lib/datadog/open_feature/exposures/batch_builder.rb +32 -0
  128. data/lib/datadog/open_feature/exposures/buffer.rb +43 -0
  129. data/lib/datadog/open_feature/exposures/deduplicator.rb +30 -0
  130. data/lib/datadog/open_feature/exposures/event.rb +60 -0
  131. data/lib/datadog/open_feature/exposures/reporter.rb +40 -0
  132. data/lib/datadog/open_feature/exposures/worker.rb +116 -0
  133. data/lib/datadog/open_feature/ext.rb +14 -0
  134. data/lib/datadog/open_feature/native_evaluator.rb +38 -0
  135. data/lib/datadog/open_feature/noop_evaluator.rb +26 -0
  136. data/lib/datadog/open_feature/provider.rb +141 -0
  137. data/lib/datadog/open_feature/remote.rb +74 -0
  138. data/lib/datadog/open_feature/resolution_details.rb +35 -0
  139. data/lib/datadog/open_feature/transport.rb +72 -0
  140. data/lib/datadog/open_feature.rb +19 -0
  141. data/lib/datadog/opentelemetry/configuration/settings.rb +159 -0
  142. data/lib/datadog/opentelemetry/metrics.rb +110 -0
  143. data/lib/datadog/opentelemetry/sdk/configurator.rb +25 -1
  144. data/lib/datadog/opentelemetry/sdk/metrics_exporter.rb +38 -0
  145. data/lib/datadog/opentelemetry.rb +3 -0
  146. data/lib/datadog/profiling/collectors/code_provenance.rb +15 -6
  147. data/lib/datadog/profiling/collectors/cpu_and_wall_time_worker.rb +1 -1
  148. data/lib/datadog/profiling/collectors/idle_sampling_helper.rb +1 -1
  149. data/lib/datadog/profiling/profiler.rb +4 -0
  150. data/lib/datadog/profiling/tag_builder.rb +36 -3
  151. data/lib/datadog/profiling.rb +1 -2
  152. data/lib/datadog/single_step_instrument.rb +1 -1
  153. data/lib/datadog/tracing/component.rb +6 -17
  154. data/lib/datadog/tracing/configuration/dynamic.rb +2 -2
  155. data/lib/datadog/tracing/configuration/ext.rb +9 -0
  156. data/lib/datadog/tracing/configuration/settings.rb +77 -3
  157. data/lib/datadog/tracing/contrib/action_pack/action_controller/instrumentation.rb +4 -4
  158. data/lib/datadog/tracing/contrib/action_pack/utils.rb +1 -2
  159. data/lib/datadog/tracing/contrib/active_job/log_injection.rb +21 -7
  160. data/lib/datadog/tracing/contrib/active_job/patcher.rb +5 -1
  161. data/lib/datadog/tracing/contrib/aws/instrumentation.rb +4 -2
  162. data/lib/datadog/tracing/contrib/component.rb +2 -2
  163. data/lib/datadog/tracing/contrib/ethon/easy_patch.rb +4 -1
  164. data/lib/datadog/tracing/contrib/excon/configuration/settings.rb +11 -3
  165. data/lib/datadog/tracing/contrib/faraday/configuration/settings.rb +11 -7
  166. data/lib/datadog/tracing/contrib/grape/configuration/settings.rb +7 -3
  167. data/lib/datadog/tracing/contrib/graphql/configuration/settings.rb +7 -0
  168. data/lib/datadog/tracing/contrib/graphql/ext.rb +1 -0
  169. data/lib/datadog/tracing/contrib/graphql/unified_trace.rb +74 -44
  170. data/lib/datadog/tracing/contrib/http/configuration/settings.rb +11 -3
  171. data/lib/datadog/tracing/contrib/httpclient/configuration/settings.rb +11 -3
  172. data/lib/datadog/tracing/contrib/httprb/configuration/settings.rb +11 -3
  173. data/lib/datadog/tracing/contrib/kafka/instrumentation/consumer.rb +66 -0
  174. data/lib/datadog/tracing/contrib/kafka/instrumentation/producer.rb +66 -0
  175. data/lib/datadog/tracing/contrib/kafka/patcher.rb +14 -0
  176. data/lib/datadog/tracing/contrib/karafka/framework.rb +30 -0
  177. data/lib/datadog/tracing/contrib/karafka/monitor.rb +11 -0
  178. data/lib/datadog/tracing/contrib/karafka/patcher.rb +32 -0
  179. data/lib/datadog/tracing/contrib/rack/middlewares.rb +59 -27
  180. data/lib/datadog/tracing/contrib/rack/route_inference.rb +53 -0
  181. data/lib/datadog/tracing/contrib/rails/middlewares.rb +2 -2
  182. data/lib/datadog/tracing/contrib/rest_client/request_patch.rb +4 -1
  183. data/lib/datadog/tracing/contrib/roda/instrumentation.rb +3 -1
  184. data/lib/datadog/tracing/contrib/sinatra/tracer_middleware.rb +3 -1
  185. data/lib/datadog/tracing/contrib/status_range_matcher.rb +7 -0
  186. data/lib/datadog/tracing/contrib/waterdrop/configuration/settings.rb +27 -0
  187. data/lib/datadog/tracing/contrib/waterdrop/distributed/propagation.rb +48 -0
  188. data/lib/datadog/tracing/contrib/waterdrop/ext.rb +17 -0
  189. data/lib/datadog/tracing/contrib/waterdrop/integration.rb +43 -0
  190. data/lib/datadog/tracing/contrib/waterdrop/middleware.rb +46 -0
  191. data/lib/datadog/tracing/contrib/waterdrop/patcher.rb +46 -0
  192. data/lib/datadog/tracing/contrib/waterdrop/producer.rb +50 -0
  193. data/lib/datadog/tracing/contrib/waterdrop.rb +37 -0
  194. data/lib/datadog/tracing/contrib.rb +1 -0
  195. data/lib/datadog/tracing/metadata/ext.rb +9 -1
  196. data/lib/datadog/tracing/transport/http/client.rb +12 -26
  197. data/lib/datadog/tracing/transport/trace_formatter.rb +11 -0
  198. data/lib/datadog/tracing/transport/traces.rb +3 -5
  199. data/lib/datadog/version.rb +2 -2
  200. data/lib/datadog.rb +2 -0
  201. metadata +92 -16
  202. data/ext/libdatadog_api/macos_development.md +0 -26
  203. data/lib/datadog/core/remote/transport/http/client.rb +0 -49
  204. data/lib/datadog/core/telemetry/transport/http/client.rb +0 -49
  205. data/lib/datadog/di/transport/http/client.rb +0 -47
@@ -22,6 +22,8 @@ require_relative 'opentelemetry/api/baggage'
22
22
  require_relative 'opentelemetry/sdk/configurator' if defined?(OpenTelemetry::SDK)
23
23
  require_relative 'opentelemetry/sdk/trace/span' if defined?(OpenTelemetry::SDK)
24
24
 
25
+ require_relative 'opentelemetry/metrics' if defined?(OpenTelemetry::SDK::Metrics)
26
+
25
27
  module Datadog
26
28
  # Datadog OpenTelemetry integration.
27
29
  module OpenTelemetry
@@ -47,6 +49,7 @@ end
47
49
  # Currently, this closely translates to Datadog's partial flushing.
48
50
  #
49
51
  # @see OpenTelemetry::SDK::Trace::SpanProcessor#on_finish
52
+
50
53
  Datadog.configure do |c|
51
54
  c.tracing.partial_flush.enabled = true
52
55
  end
@@ -22,6 +22,7 @@ module Datadog
22
22
  @libraries_by_path = {}
23
23
  @seen_files = Set.new
24
24
  @seen_libraries = Set.new
25
+ @executable_paths = [Gem.bindir, (Bundler.bin_path.to_s if defined?(Bundler))].uniq.compact.freeze
25
26
 
26
27
  record_library(
27
28
  Library.new(
@@ -29,7 +30,7 @@ module Datadog
29
30
  name: "stdlib",
30
31
  version: RUBY_VERSION,
31
32
  path: standard_library_path,
32
- extra_path: ruby_native_filename,
33
+ extra_paths: [ruby_native_filename],
33
34
  )
34
35
  )
35
36
  end
@@ -51,7 +52,8 @@ module Datadog
51
52
  :libraries_by_name,
52
53
  :libraries_by_path,
53
54
  :seen_files,
54
- :seen_libraries
55
+ :seen_libraries,
56
+ :executable_paths
55
57
 
56
58
  def record_library(library)
57
59
  libraries_by_name[library.name] = library
@@ -79,13 +81,20 @@ module Datadog
79
81
  loaded_specs.each do |spec|
80
82
  next if libraries_by_name.key?(spec.name)
81
83
 
84
+ extra_paths = [(spec.extension_dir if spec.extensions.any?)]
85
+ spec.executables&.each do |executable|
86
+ executable_paths.each do |path|
87
+ extra_paths << File.join(path, executable)
88
+ end
89
+ end
90
+
82
91
  record_library(
83
92
  Library.new(
84
93
  kind: "library",
85
94
  name: spec.name,
86
95
  version: spec.version,
87
96
  path: spec.gem_dir,
88
- extra_path: (spec.extension_dir if spec.extensions.any?),
97
+ extra_paths: extra_paths,
89
98
  )
90
99
  )
91
100
  recorded_library = true
@@ -118,12 +127,12 @@ module Datadog
118
127
  class Library
119
128
  attr_reader :kind, :name, :version
120
129
 
121
- def initialize(kind:, name:, version:, path:, extra_path: nil)
122
- extra_path = nil if extra_path&.empty?
130
+ def initialize(kind:, name:, version:, path:, extra_paths:)
131
+ extra_paths = Array(extra_paths).compact.reject(&:empty?).map { |p| p.dup.freeze }
123
132
  @kind = kind.freeze
124
133
  @name = name.dup.freeze
125
134
  @version = version.to_s.dup.freeze
126
- @paths = [path.dup.freeze, extra_path.dup.freeze].compact.freeze
135
+ @paths = [path.dup.freeze, *extra_paths].freeze
127
136
  freeze
128
137
  end
129
138
 
@@ -82,7 +82,7 @@ module Datadog
82
82
  "Cause: #{e.class.name} #{e.message} Location: #{Array(e.backtrace).first}"
83
83
  )
84
84
  on_failure_proc&.call
85
- Datadog::Core::Telemetry::Logger.report(e, description: "CpuAndWallTimeWorker thread error", pii_safe: true)
85
+ Datadog::Core::Telemetry::Logger.report(e, description: "CpuAndWallTimeWorker thread error")
86
86
  end
87
87
  @worker_thread.name = self.class.name # Repeated from above to make sure thread gets named asap
88
88
  @worker_thread.thread_variable_set(:fork_safe, true)
@@ -41,7 +41,7 @@ module Datadog
41
41
  "IdleSamplingHelper thread error. " \
42
42
  "Cause: #{e.class.name} #{e.message} Location: #{Array(e.backtrace).first}"
43
43
  )
44
- Datadog::Core::Telemetry::Logger.report(e, description: "IdleSamplingHelper thread error", pii_safe: true)
44
+ Datadog::Core::Telemetry::Logger.report(e, description: "IdleSamplingHelper thread error")
45
45
  end
46
46
  @worker_thread.name = self.class.name # Repeated from above to make sure thread gets named asap
47
47
  @worker_thread.thread_variable_set(:fork_safe, true)
@@ -17,6 +17,10 @@ module Datadog
17
17
  @scheduler = scheduler
18
18
  end
19
19
 
20
+ def enabled?
21
+ scheduler.running?
22
+ end
23
+
20
24
  def start
21
25
  after_fork! do
22
26
  worker.reset_after_fork
@@ -1,17 +1,48 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "../core/tag_builder"
4
- require_relative "../core/utils"
3
+ require_relative '../core/tag_builder'
4
+ require_relative '../core/utils'
5
+
6
+ require 'set'
5
7
 
6
8
  module Datadog
7
9
  module Profiling
8
10
  # Builds a hash of default plus user tags to be included in a profile
11
+ #
12
+ # @api private
9
13
  module TagBuilder
10
14
  include Datadog::Profiling::Ext::Transport::HTTP # Tag name constants
11
15
 
16
+ # When changing or adding profiling-related tags, make sure they are
17
+ # kept in sync with
18
+ # https://docs.google.com/spreadsheets/d/1LOGMf4c4Avbtn36uZ2SWvhIGKRPLM1BoWkUP4JYj7hA/
19
+ # (Datadog internal link).
20
+ #
21
+ # For consistency between the different profilers, every tag should be
22
+ # vetted before it gets reported with a profile, as otherwise it's too
23
+ # easy to end up with different tags in different languages.
24
+ ALLOWED_TAGS = Set.new(
25
+ [
26
+ 'env',
27
+ 'service',
28
+ 'version',
29
+ 'git.commit.sha',
30
+ 'git.repository_url',
31
+ 'host',
32
+ 'language',
33
+ 'runtime',
34
+ 'runtime_engine',
35
+ 'runtime_platform',
36
+ 'runtime_version',
37
+ 'runtime-id',
38
+ 'process_id',
39
+ 'profiler_version',
40
+ 'profile_seq',
41
+ ]
42
+ ).freeze
43
+
12
44
  def self.call(
13
45
  settings:,
14
- # Other metadata
15
46
  profile_seq:,
16
47
  profiler_version: Core::Environment::Identity.gem_datadog_version
17
48
  )
@@ -19,6 +50,8 @@ module Datadog
19
50
  FORM_FIELD_TAG_PROFILER_VERSION => profiler_version,
20
51
  'profile_seq' => profile_seq.to_s,
21
52
  )
53
+ user_tag_keys = settings.tags.keys
54
+ hash.keep_if { |tag| user_tag_keys.include?(tag) || ALLOWED_TAGS.include?(tag) }
22
55
  Core::Utils.encode_tags(hash)
23
56
  end
24
57
  end
@@ -62,8 +62,7 @@ module Datadog
62
62
 
63
63
  def self.enabled?
64
64
  profiler = Datadog.send(:components).profiler
65
- # Use .send(...) to avoid exposing the attr_reader as an API to the outside
66
- !!profiler&.send(:scheduler)&.running?
65
+ !!profiler&.enabled?
67
66
  end
68
67
 
69
68
  def self.wait_until_running(timeout_seconds: 5)
@@ -15,7 +15,7 @@ end
15
15
 
16
16
  begin
17
17
  require_relative 'auto_instrument'
18
- Datadog::SingleStepInstrument::LOADED = true
18
+ Datadog::SingleStepInstrument.const_set(:LOADED, true)
19
19
  rescue StandardError, LoadError => e
20
20
  warn "Single step instrumentation failed: #{e.class}:#{e.message}\n\tSource:\n\t#{Array(e.backtrace).join("\n\t")}"
21
21
  end
@@ -12,16 +12,7 @@ module Datadog
12
12
  module Tracing
13
13
  # Tracing component
14
14
  module Component
15
- # Methods that interact with component instance fields.
16
- module InstanceMethods
17
- # Hot-swaps with a new sampler.
18
- # This operation acquires the Components lock to ensure
19
- # there is no concurrent modification of the sampler.
20
- def reconfigure_live_sampler
21
- sampler = self.class.build_sampler(Datadog.configuration)
22
- Datadog.send(:safely_synchronize) { tracer.sampler.sampler = sampler }
23
- end
24
- end
15
+ module_function
25
16
 
26
17
  def build_tracer(settings, agent_settings, logger:)
27
18
  # If a custom tracer has been provided, use it instead.
@@ -156,11 +147,6 @@ module Datadog
156
147
  Tracing::Sampling::Span::Sampler.new(rules || [])
157
148
  end
158
149
 
159
- # Configure non-privileged components.
160
- def configure_tracing(settings)
161
- Datadog::Tracing::Contrib::Component.configure(settings)
162
- end
163
-
164
150
  # Sampler wrapper component, to allow for hot-swapping
165
151
  # the sampler instance used by the tracer.
166
152
  # Swapping samplers happens during Dynamic Configuration.
@@ -182,8 +168,7 @@ module Datadog
182
168
  end
183
169
  end
184
170
 
185
- private
186
-
171
+ # @api private
187
172
  def build_tracer_tags(settings)
188
173
  settings.tags.dup.tap do |tags|
189
174
  tags[Core::Environment::Ext::TAG_ENV] = settings.env unless settings.env.nil?
@@ -193,6 +178,7 @@ module Datadog
193
178
 
194
179
  # Build a post-sampler that limits the rate of traces to one per `seconds`.
195
180
  # E.g.: `build_rate_limit_post_sampler(seconds: 60)` will limit the rate to one trace per minute.
181
+ # @api private
196
182
  def build_rate_limit_post_sampler(seconds:)
197
183
  Tracing::Sampling::RuleSampler.new(
198
184
  rate_limiter: Datadog::Core::TokenBucket.new(1.0 / seconds, 1.0),
@@ -200,11 +186,13 @@ module Datadog
200
186
  )
201
187
  end
202
188
 
189
+ # @api private
203
190
  def build_test_mode_trace_flush(settings)
204
191
  # If context flush behavior is provided, use it instead.
205
192
  settings.tracing.test_mode.trace_flush || build_trace_flush(settings)
206
193
  end
207
194
 
195
+ # @api private
208
196
  def build_test_mode_sampler
209
197
  # Do not sample any spans for tests; all must be preserved.
210
198
  # Set priority sampler to ensure the agent doesn't drop any traces.
@@ -214,6 +202,7 @@ module Datadog
214
202
  )
215
203
  end
216
204
 
205
+ # @api private
217
206
  def build_test_mode_writer(settings, agent_settings)
218
207
  writer_options = settings.tracing.test_mode.writer_options || {}
219
208
 
@@ -41,7 +41,7 @@ module Datadog
41
41
  # Ensures sampler is rebuilt and new configuration is applied
42
42
  def call(tracing_sampling_rate)
43
43
  super
44
- Datadog.send(:components).reconfigure_live_sampler
44
+ Datadog.send(:components).reconfigure_sampler
45
45
  end
46
46
 
47
47
  protected
@@ -79,7 +79,7 @@ module Datadog
79
79
  end
80
80
 
81
81
  super
82
- Datadog.send(:components).reconfigure_live_sampler
82
+ Datadog.send(:components).reconfigure_sampler
83
83
  end
84
84
 
85
85
  protected
@@ -13,6 +13,9 @@ module Datadog
13
13
  ENV_BAGGAGE_TAG_KEYS = 'DD_TRACE_BAGGAGE_TAG_KEYS'
14
14
  ENV_TRACE_ID_128_BIT_GENERATION_ENABLED = 'DD_TRACE_128_BIT_TRACEID_GENERATION_ENABLED'
15
15
  ENV_NATIVE_SPAN_EVENTS = 'DD_TRACE_NATIVE_SPAN_EVENTS'
16
+ ENV_RESOURCE_RENAMING_ENABLED = 'DD_TRACE_RESOURCE_RENAMING_ENABLED'
17
+ ENV_RESOURCE_RENAMING_ALWAYS_SIMPLIFIED_ENDPOINT = 'DD_TRACE_RESOURCE_RENAMING_ALWAYS_SIMPLIFIED_ENDPOINT'
18
+ ENV_EXPERIMENTAL_PROPAGATE_PROCESS_TAGS_ENABLED = 'DD_EXPERIMENTAL_PROPAGATE_PROCESS_TAGS_ENABLED'
16
19
 
17
20
  # @public_api
18
21
  module SpanAttributeSchema
@@ -104,6 +107,12 @@ module Datadog
104
107
  ENV_ENABLED = 'DD_TRACE_CLIENT_IP_ENABLED'
105
108
  ENV_HEADER_NAME = 'DD_TRACE_CLIENT_IP_HEADER'
106
109
  end
110
+
111
+ # @public_api
112
+ module HTTPErrorStatuses
113
+ ENV_SERVER_ERROR_STATUSES = 'DD_TRACE_HTTP_SERVER_ERROR_STATUSES'
114
+ ENV_CLIENT_ERROR_STATUSES = 'DD_TRACE_HTTP_CLIENT_ERROR_STATUSES'
115
+ end
107
116
  end
108
117
  end
109
118
  end
@@ -2,6 +2,8 @@
2
2
 
3
3
  require_relative '../../tracing/configuration/ext'
4
4
  require_relative '../../core/environment/variable_helpers'
5
+ require_relative '../contrib/status_range_matcher'
6
+ require_relative '../contrib/status_range_env_parser'
5
7
  require_relative 'http'
6
8
 
7
9
  module Datadog
@@ -96,7 +98,7 @@ module Datadog
96
98
  # Note: Alias (DD_TRACE_PROPAGATION_STYLE) defined in supported-configurations.json
97
99
  o.env Configuration::Ext::Distributed::ENV_PROPAGATION_STYLE
98
100
  o.default []
99
- o.after_set do |styles|
101
+ o.after_set do |styles, _, precedence|
100
102
  next if styles.empty?
101
103
 
102
104
  # Make values case-insensitive
@@ -110,8 +112,8 @@ module Datadog
110
112
  false
111
113
  end
112
114
  end
113
- set_option(:propagation_style_extract, styles)
114
- set_option(:propagation_style_inject, styles)
115
+ set_option(:propagation_style_extract, styles, precedence: precedence)
116
+ set_option(:propagation_style_inject, styles, precedence: precedence)
115
117
  end
116
118
  end
117
119
 
@@ -272,6 +274,38 @@ module Datadog
272
274
  o.type :bool
273
275
  end
274
276
 
277
+ settings :resource_renaming do
278
+ # Whether resource renaming is enabled. When enabled, http.endpoint tag
279
+ # containing a route will be reported in traces. If AppSec is enabled,
280
+ # this feature will be enabled by default.
281
+ #
282
+ # For web applications built with instrumented frameworks, http.endpoint tag
283
+ # will contain the route as it is defined in the application.
284
+ # For basic Rack applications, or applications that are mounted and are not instrumented,
285
+ # the route will be inferred from the request path.
286
+ #
287
+ # @default `DD_TRACE_RESOURCE_RENAMING_ENABLED` environment variable, otherwise `false`.
288
+ # @return [Boolean]
289
+ option :enabled do |o|
290
+ o.type :bool, nilable: false
291
+ o.env Configuration::Ext::ENV_RESOURCE_RENAMING_ENABLED
292
+ o.default false
293
+ end
294
+
295
+ # When set to true, http.endoint is always inferred from path,
296
+ # instead of using http.route value when it is set.
297
+ #
298
+ # This is useful for testing purposes.
299
+ #
300
+ # @default false
301
+ # @return [Boolean]
302
+ option :always_simplified_endpoint do |o|
303
+ o.type :bool, nilable: false
304
+ o.env Configuration::Ext::ENV_RESOURCE_RENAMING_ALWAYS_SIMPLIFIED_ENDPOINT
305
+ o.default false
306
+ end
307
+ end
308
+
275
309
  # Forces the tracer to always send span events with the native span events format
276
310
  # regardless of the agent support. This is useful in agent-less setups.
277
311
  #
@@ -490,6 +524,46 @@ module Datadog
490
524
  o.env Tracing::Configuration::Ext::Distributed::ENV_X_DATADOG_TAGS_MAX_LENGTH
491
525
  o.default 512
492
526
  end
527
+
528
+ # HTTP error statuses configuration
529
+ # @public_api
530
+ settings :http_error_statuses do
531
+ # Defines the range of status codes to be considered errors on http.server span kinds.
532
+ # Once set, only the values within the specified range are considered errors.
533
+ #
534
+ # Format of env var: comma-separated list of values like 500,501,502 or ranges like 500-599 (e.g. `500,502,504-510`)
535
+ #
536
+ # @default `DD_TRACE_HTTP_SERVER_ERROR_STATUSES` environment variable, otherwise `500..599`.
537
+ # @return [Tracing::Contrib::StatusRangeMatcher]
538
+ option :server do |o|
539
+ o.env Tracing::Configuration::Ext::HTTPErrorStatuses::ENV_SERVER_ERROR_STATUSES
540
+ o.default 500..599
541
+ o.setter do |v|
542
+ Tracing::Contrib::StatusRangeMatcher.new(v) if v
543
+ end
544
+ o.env_parser do |values|
545
+ Tracing::Contrib::StatusRangeEnvParser.call(values)
546
+ end
547
+ end
548
+
549
+ # Defines the range of status codes to be considered errors on http.client span kinds.
550
+ # Once set, only the values within the specified range are considered errors.
551
+ #
552
+ # Format of env var: comma-separated list of values like 400,401,402 or ranges like 400-499 (e.g. `400,402,404-410`)
553
+ #
554
+ # @default `DD_TRACE_HTTP_CLIENT_ERROR_STATUSES` environment variable, otherwise `400..499`.
555
+ # @return [Tracing::Contrib::StatusRangeMatcher]
556
+ option :client do |o|
557
+ o.env Tracing::Configuration::Ext::HTTPErrorStatuses::ENV_CLIENT_ERROR_STATUSES
558
+ o.default 400..499
559
+ o.setter do |v|
560
+ Tracing::Contrib::StatusRangeMatcher.new(v) if v
561
+ end
562
+ o.env_parser do |values|
563
+ Tracing::Contrib::StatusRangeEnvParser.call(values)
564
+ end
565
+ end
566
+ end
493
567
  end
494
568
  end
495
569
  end
@@ -77,10 +77,10 @@ module Datadog
77
77
 
78
78
  exception = payload[:exception_object]
79
79
  if exception.nil?
80
- # [christian] in some cases :status is not defined,
81
- # rather than firing an error, simply acknowledge we don't know it.
82
- status = payload.fetch(:status, '?').to_s
83
- span.status = 1 if status.start_with?('5')
80
+ status = payload[:status]
81
+ if status && Datadog.configuration.tracing.http_error_statuses.server.include?(status)
82
+ span.status = Tracing::Metadata::Ext::Errors::STATUS
83
+ end
84
84
  elsif Utils.exception_is_error?(exception)
85
85
  span.set_error(exception)
86
86
  end
@@ -13,8 +13,7 @@ module Datadog
13
13
  # Gets the equivalent status code for the exception (not all are 5XX)
14
14
  # You can add custom errors via `config.action_dispatch.rescue_responses`
15
15
  status = ::ActionDispatch::ExceptionWrapper.status_code_for_exception(exception.class.name)
16
- # Only 5XX exceptions are actually errors (e.g. don't flag 404s)
17
- status.to_s.start_with?('5')
16
+ Datadog.configuration.tracing.http_error_statuses.server.include?(status)
18
17
  else
19
18
  true
20
19
  end
@@ -6,17 +6,31 @@ module Datadog
6
6
  module ActiveJob
7
7
  # Active Job log injection wrapped around job execution
8
8
  module LogInjection
9
- def self.included(base)
10
- base.class_eval do
11
- around_perform do |_, block|
12
- if Datadog.configuration.tracing.log_injection && logger.respond_to?(:tagged)
13
- logger.tagged(Tracing.log_correlation, &block)
14
- else
15
- block.call
9
+ # Active Job 4 / 5 don't execute `perform_now` at the right point, so we do best effort log correlation tagging
10
+ module AroundPerformPatch
11
+ def self.included(base)
12
+ base.class_eval do
13
+ around_perform do |_, block|
14
+ if Datadog.configuration.tracing.log_injection && logger.respond_to?(:tagged)
15
+ logger.tagged(Tracing.log_correlation, &block)
16
+ else
17
+ block.call
18
+ end
16
19
  end
17
20
  end
18
21
  end
19
22
  end
23
+
24
+ # Active Job 6+ executes `perform_now` at the right point, so we can provide better log correlation tagging
25
+ module PerformNowPatch
26
+ def perform_now
27
+ if Datadog.configuration.tracing.log_injection && logger.respond_to?(:tagged)
28
+ logger.tagged(Tracing.log_correlation) { super }
29
+ else
30
+ super
31
+ end
32
+ end
33
+ end
20
34
  end
21
35
  end
22
36
  end
@@ -26,7 +26,11 @@ module Datadog
26
26
 
27
27
  def inject_log_correlation
28
28
  ::ActiveSupport.on_load(:active_job) do
29
- include LogInjection
29
+ if ::ActiveJob.gem_version < Gem::Version.new('6.0.0')
30
+ include LogInjection::AroundPerformPatch
31
+ else
32
+ include LogInjection::PerformNowPatch
33
+ end
30
34
  end
31
35
  end
32
36
  end
@@ -36,8 +36,10 @@ module Datadog
36
36
  span.name = Ext::SPAN_COMMAND
37
37
  span.resource = context.safely(:resource)
38
38
 
39
- # Set error on the span if the Response Status Code is in error range
40
- if Tracing::Metadata::Ext::HTTP::ERROR_RANGE.cover?(context.safely(:status_code))
39
+ # DEV-3.0: This was previously checking against a 500..599 range.
40
+ # To not introduce breaking change, this was changed to use `http_error_statuses.server`,
41
+ # but `aws` is a client library, this check should use `http_error_statuses.client` instead.
42
+ if Datadog.configuration.tracing.http_error_statuses.server.include?(context.safely(:status_code))
41
43
  # At this point we do not have any additional diagnostics
42
44
  # besides the HTTP status code which is recorded in the span tags
43
45
  # later in this method.
@@ -9,13 +9,13 @@ module Datadog
9
9
  # Register a callback to be invoked when components are reconfigured.
10
10
  # @param name [String] the name of the integration
11
11
  # @param callback [Proc] the callback to invoke
12
- # @yieldparam config [Datadog::Configuration] the configuration to pass to callbacks
12
+ # @yieldparam config [Datadog::Core::Configuration::Settings] the configuration to pass to callbacks
13
13
  def register(name, &callback)
14
14
  @registry[name] = callback
15
15
  end
16
16
 
17
17
  # Invoke all registered callbacks with the given configuration.
18
- # @param config [Datadog::Configuration] the configuration to pass to callbacks
18
+ # @param config [Datadog::Core::Configuration::Settings] the configuration to pass to callbacks
19
19
  def configure(config)
20
20
  @registry.each do |name, callback|
21
21
  callback.call(config)
@@ -57,7 +57,10 @@ module Datadog
57
57
  set_span_error_message("Request has failed: #{message}")
58
58
  else
59
59
  @datadog_span.set_tag(Tracing::Metadata::Ext::HTTP::TAG_STATUS_CODE, response_code)
60
- if Tracing::Metadata::Ext::HTTP::ERROR_RANGE.cover?(response_code)
60
+ # DEV-3.0: This was previously checking against a 500..599 range.
61
+ # To not introduce breaking change, this was changed to use `http_error_statuses.server`,
62
+ # but `ethon` is a client library, this check should use `http_error_statuses.client` instead.
63
+ if Datadog.configuration.tracing.http_error_statuses.server.include?(response_code)
61
64
  set_span_error_message("Request has failed with HTTP error: #{response_code}")
62
65
  end
63
66
  end
@@ -41,9 +41,17 @@ module Datadog
41
41
 
42
42
  option :error_status_codes do |o|
43
43
  o.env Ext::ENV_ERROR_STATUS_CODES
44
- o.default 400...600
45
- o.setter do |v|
46
- Tracing::Contrib::StatusRangeMatcher.new(v) if v
44
+ o.setter do |value|
45
+ if value.nil?
46
+ # Fallback to global config, which is defaulted to client (400..499) + server (500..599)
47
+ # DEV-3.0: `excon` is a client library, this should fall back to `http_error_statuses.client` only.
48
+ # We cannot change it without causing a breaking change.
49
+ client_global_error_statuses = Datadog.configuration.tracing.http_error_statuses.client
50
+ server_global_error_statuses = Datadog.configuration.tracing.http_error_statuses.server
51
+ client_global_error_statuses + server_global_error_statuses
52
+ else
53
+ Tracing::Contrib::StatusRangeMatcher.new(value)
54
+ end
47
55
  end
48
56
  o.env_parser do |v|
49
57
  Tracing::Contrib::StatusRangeEnvParser.call(v) if v
@@ -13,10 +13,6 @@ module Datadog
13
13
  # Custom settings for the Faraday integration
14
14
  # @public_api
15
15
  class Settings < Contrib::Configuration::Settings
16
- DEFAULT_ERROR_HANDLER = lambda do |env|
17
- Tracing::Metadata::Ext::HTTP::ERROR_RANGE.cover?(env[:status])
18
- end
19
-
20
16
  option :enabled do |o|
21
17
  o.type :bool
22
18
  o.env Ext::ENV_ENABLED
@@ -44,9 +40,17 @@ module Datadog
44
40
 
45
41
  option :error_status_codes do |o|
46
42
  o.env Ext::ENV_ERROR_STATUS_CODES
47
- o.default 400...600
48
- o.setter do |v|
49
- Tracing::Contrib::StatusRangeMatcher.new(v) if v
43
+ o.setter do |value|
44
+ if value.nil?
45
+ # Fallback to global config, which is defaulted to client (400..499) + server (500..599)
46
+ # DEV-3.0: `faraday` is a client library, this should fall back to `http_error_statuses.client` only.
47
+ # We cannot change it without causing a breaking change.
48
+ client_global_error_statuses = Datadog.configuration.tracing.http_error_statuses.client
49
+ server_global_error_statuses = Datadog.configuration.tracing.http_error_statuses.server
50
+ client_global_error_statuses + server_global_error_statuses
51
+ else
52
+ Tracing::Contrib::StatusRangeMatcher.new(value)
53
+ end
50
54
  end
51
55
  o.env_parser do |v|
52
56
  Tracing::Contrib::StatusRangeEnvParser.call(v) if v
@@ -39,9 +39,13 @@ module Datadog
39
39
 
40
40
  option :error_status_codes do |o|
41
41
  o.env Ext::ENV_ERROR_STATUS_CODES
42
- o.default 500...600
43
- o.setter do |v|
44
- Tracing::Contrib::StatusRangeMatcher.new(v) if v
42
+ o.setter do |value|
43
+ if value.nil?
44
+ # Fallback to global config, which is defaulted to server (500..599)
45
+ Datadog.configuration.tracing.http_error_statuses.server
46
+ else
47
+ Tracing::Contrib::StatusRangeMatcher.new(value)
48
+ end
45
49
  end
46
50
  o.env_parser do |v|
47
51
  Tracing::Contrib::StatusRangeEnvParser.call(v) if v
@@ -58,6 +58,13 @@ module Datadog
58
58
  o.default []
59
59
  o.env_parser { |v| ErrorExtensionEnvParser.call(v) }
60
60
  end
61
+
62
+ # Surface GraphQL errors in Error Tracking.
63
+ option :error_tracking do |o|
64
+ o.env Ext::ENV_ERROR_TRACKING
65
+ o.type :bool
66
+ o.default false
67
+ end
61
68
  end
62
69
  end
63
70
  end
@@ -13,6 +13,7 @@ module Datadog
13
13
  ENV_ANALYTICS_SAMPLE_RATE = 'DD_TRACE_GRAPHQL_ANALYTICS_SAMPLE_RATE'
14
14
  ENV_WITH_UNIFIED_TRACER = 'DD_TRACE_GRAPHQL_WITH_UNIFIED_TRACER'
15
15
  ENV_ERROR_EXTENSIONS = 'DD_TRACE_GRAPHQL_ERROR_EXTENSIONS'
16
+ ENV_ERROR_TRACKING = 'DD_TRACE_GRAPHQL_ERROR_TRACKING'
16
17
  SERVICE_NAME = 'graphql'
17
18
  TAG_COMPONENT = 'graphql'
18
19