datadog 2.3.0 → 2.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (129) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +37 -1
  3. data/ext/datadog_profiling_loader/datadog_profiling_loader.c +9 -1
  4. data/ext/datadog_profiling_loader/extconf.rb +10 -22
  5. data/ext/datadog_profiling_native_extension/collectors_cpu_and_wall_time_worker.c +148 -30
  6. data/ext/datadog_profiling_native_extension/collectors_discrete_dynamic_sampler.c +4 -2
  7. data/ext/datadog_profiling_native_extension/collectors_stack.c +89 -46
  8. data/ext/datadog_profiling_native_extension/collectors_thread_context.c +580 -29
  9. data/ext/datadog_profiling_native_extension/collectors_thread_context.h +9 -1
  10. data/ext/datadog_profiling_native_extension/datadog_ruby_common.c +0 -27
  11. data/ext/datadog_profiling_native_extension/datadog_ruby_common.h +0 -4
  12. data/ext/datadog_profiling_native_extension/extconf.rb +38 -21
  13. data/ext/datadog_profiling_native_extension/gvl_profiling_helper.c +50 -0
  14. data/ext/datadog_profiling_native_extension/gvl_profiling_helper.h +75 -0
  15. data/ext/datadog_profiling_native_extension/heap_recorder.c +20 -6
  16. data/ext/datadog_profiling_native_extension/http_transport.c +38 -6
  17. data/ext/datadog_profiling_native_extension/private_vm_api_access.c +52 -1
  18. data/ext/datadog_profiling_native_extension/private_vm_api_access.h +3 -0
  19. data/ext/datadog_profiling_native_extension/profiling.c +1 -1
  20. data/ext/datadog_profiling_native_extension/stack_recorder.h +1 -0
  21. data/ext/libdatadog_api/crashtracker.c +20 -18
  22. data/ext/libdatadog_api/datadog_ruby_common.c +0 -27
  23. data/ext/libdatadog_api/datadog_ruby_common.h +0 -4
  24. data/ext/libdatadog_extconf_helpers.rb +1 -1
  25. data/lib/datadog/appsec/assets/waf_rules/recommended.json +2184 -108
  26. data/lib/datadog/appsec/assets/waf_rules/strict.json +1430 -2
  27. data/lib/datadog/appsec/component.rb +29 -8
  28. data/lib/datadog/appsec/configuration/settings.rb +2 -2
  29. data/lib/datadog/appsec/contrib/devise/patcher/authenticatable_patch.rb +1 -0
  30. data/lib/datadog/appsec/contrib/devise/patcher/rememberable_patch.rb +21 -0
  31. data/lib/datadog/appsec/contrib/devise/patcher.rb +12 -2
  32. data/lib/datadog/appsec/contrib/graphql/appsec_trace.rb +0 -14
  33. data/lib/datadog/appsec/contrib/graphql/gateway/multiplex.rb +67 -31
  34. data/lib/datadog/appsec/contrib/graphql/gateway/watcher.rb +18 -15
  35. data/lib/datadog/appsec/contrib/graphql/integration.rb +14 -1
  36. data/lib/datadog/appsec/contrib/rack/gateway/request.rb +2 -5
  37. data/lib/datadog/appsec/event.rb +1 -1
  38. data/lib/datadog/appsec/processor/rule_loader.rb +3 -1
  39. data/lib/datadog/appsec/processor/rule_merger.rb +33 -15
  40. data/lib/datadog/appsec/processor.rb +36 -37
  41. data/lib/datadog/appsec/rate_limiter.rb +25 -40
  42. data/lib/datadog/appsec/remote.rb +7 -3
  43. data/lib/datadog/appsec.rb +2 -2
  44. data/lib/datadog/core/configuration/components.rb +4 -3
  45. data/lib/datadog/core/configuration/settings.rb +84 -5
  46. data/lib/datadog/core/crashtracking/component.rb +1 -1
  47. data/lib/datadog/core/environment/execution.rb +5 -5
  48. data/lib/datadog/core/metrics/client.rb +7 -0
  49. data/lib/datadog/core/rate_limiter.rb +183 -0
  50. data/lib/datadog/core/remote/client/capabilities.rb +4 -3
  51. data/lib/datadog/core/remote/component.rb +4 -2
  52. data/lib/datadog/core/remote/negotiation.rb +4 -4
  53. data/lib/datadog/core/remote/tie.rb +2 -0
  54. data/lib/datadog/core/runtime/metrics.rb +1 -1
  55. data/lib/datadog/core/telemetry/component.rb +2 -0
  56. data/lib/datadog/core/telemetry/event.rb +12 -7
  57. data/lib/datadog/core/telemetry/logger.rb +51 -0
  58. data/lib/datadog/core/telemetry/logging.rb +50 -14
  59. data/lib/datadog/core/telemetry/request.rb +13 -1
  60. data/lib/datadog/core/utils/time.rb +12 -0
  61. data/lib/datadog/di/code_tracker.rb +168 -0
  62. data/lib/datadog/di/configuration/settings.rb +163 -0
  63. data/lib/datadog/di/configuration.rb +11 -0
  64. data/lib/datadog/di/error.rb +31 -0
  65. data/lib/datadog/di/extensions.rb +16 -0
  66. data/lib/datadog/di/probe.rb +133 -0
  67. data/lib/datadog/di/probe_builder.rb +41 -0
  68. data/lib/datadog/di/redactor.rb +188 -0
  69. data/lib/datadog/di/serializer.rb +193 -0
  70. data/lib/datadog/di.rb +14 -0
  71. data/lib/datadog/opentelemetry/sdk/propagator.rb +2 -0
  72. data/lib/datadog/profiling/collectors/cpu_and_wall_time_worker.rb +12 -10
  73. data/lib/datadog/profiling/collectors/info.rb +12 -3
  74. data/lib/datadog/profiling/collectors/thread_context.rb +26 -0
  75. data/lib/datadog/profiling/component.rb +20 -4
  76. data/lib/datadog/profiling/http_transport.rb +6 -1
  77. data/lib/datadog/profiling/scheduler.rb +2 -0
  78. data/lib/datadog/profiling/stack_recorder.rb +3 -0
  79. data/lib/datadog/single_step_instrument.rb +12 -0
  80. data/lib/datadog/tracing/contrib/action_cable/instrumentation.rb +8 -12
  81. data/lib/datadog/tracing/contrib/action_pack/action_controller/instrumentation.rb +5 -0
  82. data/lib/datadog/tracing/contrib/action_pack/action_dispatch/instrumentation.rb +78 -0
  83. data/lib/datadog/tracing/contrib/action_pack/action_dispatch/patcher.rb +33 -0
  84. data/lib/datadog/tracing/contrib/action_pack/patcher.rb +2 -0
  85. data/lib/datadog/tracing/contrib/active_record/configuration/resolver.rb +4 -0
  86. data/lib/datadog/tracing/contrib/active_record/events/instantiation.rb +3 -1
  87. data/lib/datadog/tracing/contrib/active_record/events/sql.rb +3 -1
  88. data/lib/datadog/tracing/contrib/active_support/cache/events/cache.rb +5 -1
  89. data/lib/datadog/tracing/contrib/aws/instrumentation.rb +5 -0
  90. data/lib/datadog/tracing/contrib/elasticsearch/patcher.rb +6 -1
  91. data/lib/datadog/tracing/contrib/faraday/middleware.rb +9 -0
  92. data/lib/datadog/tracing/contrib/grape/endpoint.rb +19 -0
  93. data/lib/datadog/tracing/contrib/graphql/patcher.rb +9 -12
  94. data/lib/datadog/tracing/contrib/graphql/trace_patcher.rb +3 -3
  95. data/lib/datadog/tracing/contrib/graphql/tracing_patcher.rb +3 -3
  96. data/lib/datadog/tracing/contrib/graphql/unified_trace.rb +13 -9
  97. data/lib/datadog/tracing/contrib/graphql/unified_trace_patcher.rb +6 -3
  98. data/lib/datadog/tracing/contrib/http/instrumentation.rb +18 -15
  99. data/lib/datadog/tracing/contrib/httpclient/instrumentation.rb +6 -5
  100. data/lib/datadog/tracing/contrib/httpclient/patcher.rb +1 -14
  101. data/lib/datadog/tracing/contrib/httprb/instrumentation.rb +5 -0
  102. data/lib/datadog/tracing/contrib/httprb/patcher.rb +1 -14
  103. data/lib/datadog/tracing/contrib/lograge/patcher.rb +1 -2
  104. data/lib/datadog/tracing/contrib/mongodb/subscribers.rb +2 -0
  105. data/lib/datadog/tracing/contrib/opensearch/patcher.rb +13 -6
  106. data/lib/datadog/tracing/contrib/patcher.rb +2 -1
  107. data/lib/datadog/tracing/contrib/presto/patcher.rb +1 -13
  108. data/lib/datadog/tracing/contrib/rack/middlewares.rb +27 -0
  109. data/lib/datadog/tracing/contrib/redis/tags.rb +4 -0
  110. data/lib/datadog/tracing/contrib/sinatra/tracer.rb +4 -0
  111. data/lib/datadog/tracing/contrib/stripe/request.rb +3 -2
  112. data/lib/datadog/tracing/distributed/propagation.rb +7 -0
  113. data/lib/datadog/tracing/metadata/ext.rb +2 -0
  114. data/lib/datadog/tracing/remote.rb +5 -2
  115. data/lib/datadog/tracing/sampling/matcher.rb +6 -1
  116. data/lib/datadog/tracing/sampling/rate_sampler.rb +1 -1
  117. data/lib/datadog/tracing/sampling/rule.rb +2 -0
  118. data/lib/datadog/tracing/sampling/rule_sampler.rb +9 -5
  119. data/lib/datadog/tracing/sampling/span/ext.rb +1 -1
  120. data/lib/datadog/tracing/sampling/span/rule.rb +2 -2
  121. data/lib/datadog/tracing/trace_operation.rb +26 -2
  122. data/lib/datadog/tracing/tracer.rb +14 -12
  123. data/lib/datadog/tracing/transport/http/client.rb +1 -0
  124. data/lib/datadog/tracing/transport/io/client.rb +1 -0
  125. data/lib/datadog/tracing/workers/trace_writer.rb +1 -1
  126. data/lib/datadog/tracing/workers.rb +1 -1
  127. data/lib/datadog/version.rb +1 -1
  128. metadata +25 -8
  129. data/lib/datadog/tracing/sampling/rate_limiter.rb +0 -185
@@ -20,6 +20,8 @@ module Datadog
20
20
  tracer:,
21
21
  endpoint_collection_enabled:,
22
22
  timeline_enabled:,
23
+ waiting_for_gvl_threshold_ns:,
24
+ otel_context_enabled:,
23
25
  allocation_type_enabled: true
24
26
  )
25
27
  tracer_context_key = safely_extract_context_key_from(tracer)
@@ -30,10 +32,34 @@ module Datadog
30
32
  tracer_context_key,
31
33
  endpoint_collection_enabled,
32
34
  timeline_enabled,
35
+ waiting_for_gvl_threshold_ns,
36
+ otel_context_enabled,
33
37
  allocation_type_enabled,
34
38
  )
35
39
  end
36
40
 
41
+ def self.for_testing(
42
+ recorder:,
43
+ max_frames: 400,
44
+ tracer: nil,
45
+ endpoint_collection_enabled: false,
46
+ timeline_enabled: false,
47
+ waiting_for_gvl_threshold_ns: 10_000_000,
48
+ otel_context_enabled: false,
49
+ **options
50
+ )
51
+ new(
52
+ recorder: recorder,
53
+ max_frames: max_frames,
54
+ tracer: tracer,
55
+ endpoint_collection_enabled: endpoint_collection_enabled,
56
+ timeline_enabled: timeline_enabled,
57
+ waiting_for_gvl_threshold_ns: waiting_for_gvl_threshold_ns,
58
+ otel_context_enabled: otel_context_enabled,
59
+ **options,
60
+ )
61
+ end
62
+
37
63
  def inspect
38
64
  # Compose Ruby's default inspect with our custom inspect for the native parts
39
65
  result = super()
@@ -62,6 +62,7 @@ module Datadog
62
62
  dynamic_sampling_rate_overhead_target_percentage: overhead_target_percentage,
63
63
  allocation_profiling_enabled: allocation_profiling_enabled,
64
64
  allocation_counting_enabled: settings.profiling.advanced.allocation_counting_enabled,
65
+ gvl_profiling_enabled: enable_gvl_profiling?(settings),
65
66
  )
66
67
 
67
68
  internal_metadata = {
@@ -89,6 +90,8 @@ module Datadog
89
90
  tracer: optional_tracer,
90
91
  endpoint_collection_enabled: settings.profiling.advanced.endpoint.collection.enabled,
91
92
  timeline_enabled: timeline_enabled,
93
+ waiting_for_gvl_threshold_ns: settings.profiling.advanced.waiting_for_gvl_threshold_ns,
94
+ otel_context_enabled: settings.profiling.advanced.preview_otel_context_enabled,
92
95
  )
93
96
  end
94
97
 
@@ -252,6 +255,7 @@ module Datadog
252
255
  legacy_ruby_that_should_use_workaround = RUBY_VERSION.start_with?("2.5.")
253
256
 
254
257
  unless [true, false, :auto].include?(setting_value)
258
+ # TODO: Replace with a warning instead.
255
259
  Datadog.logger.error(
256
260
  "Ignoring invalid value for profiling no_signals_workaround_enabled setting: #{setting_value.inspect}. " \
257
261
  "Valid options are `true`, `false` or (default) `:auto`."
@@ -394,6 +398,7 @@ module Datadog
394
398
  if overhead_target_percentage > 0 && overhead_target_percentage <= 20
395
399
  overhead_target_percentage
396
400
  else
401
+ # TODO: Replace with a warning instead.
397
402
  Datadog.logger.error(
398
403
  "Ignoring invalid value for profiling overhead_target_percentage setting: " \
399
404
  "#{overhead_target_percentage.inspect}. Falling back to default value."
@@ -433,13 +438,24 @@ module Datadog
433
438
  end
434
439
 
435
440
  private_class_method def self.dir_interruption_workaround_enabled?(settings, no_signals_workaround_enabled)
436
- return false if no_signals_workaround_enabled
437
-
438
- # NOTE: In the future this method will evolve to check for Ruby versions affected and not apply the workaround
439
- # when it's not needed but currently all known Ruby versions are affected.
441
+ return false if no_signals_workaround_enabled || RUBY_VERSION >= "3.4"
440
442
 
441
443
  settings.profiling.advanced.dir_interruption_workaround_enabled
442
444
  end
445
+
446
+ private_class_method def self.enable_gvl_profiling?(settings)
447
+ if RUBY_VERSION < "3.2"
448
+ if settings.profiling.advanced.preview_gvl_enabled
449
+ Datadog.logger.warn("GVL profiling is currently not supported in Ruby < 3.2 and will not be enabled.")
450
+ end
451
+
452
+ return false
453
+ end
454
+
455
+ # GVL profiling only makes sense in the context of timeline. We could emit a warning here, but not sure how
456
+ # useful it is -- if a customer disables timeline, there's nowhere to look for GVL profiling anyway!
457
+ settings.profiling.advanced.timeline_enabled && settings.profiling.advanced.preview_gvl_enabled
458
+ end
443
459
  end
444
460
  end
445
461
  end
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative "../core/transport/ext"
4
+ require_relative "../core/telemetry/logger"
4
5
 
5
6
  module Datadog
6
7
  module Profiling
@@ -60,10 +61,14 @@ module Datadog
60
61
  "Failed to report profiling data (#{config_without_api_key}): " \
61
62
  "server returned unexpected HTTP #{result} status code"
62
63
  )
64
+ Datadog::Core::Telemetry::Logger.error(
65
+ "Failed to report profiling data: unexpected HTTP #{result} status code"
66
+ )
63
67
  false
64
68
  end
65
69
  else
66
70
  Datadog.logger.error("Failed to report profiling data (#{config_without_api_key}): #{result}")
71
+ Datadog::Core::Telemetry::Logger.error("Failed to report profiling data")
67
72
  false
68
73
  end
69
74
  end
@@ -134,7 +139,7 @@ module Datadog
134
139
  end
135
140
 
136
141
  def config_without_api_key
137
- [exporter_configuration[0..1]].to_h
142
+ "#{exporter_configuration[0]}: #{exporter_configuration[1]}"
138
143
  end
139
144
  end
140
145
  end
@@ -4,6 +4,7 @@ require_relative "../core/utils/time"
4
4
 
5
5
  require_relative "../core/worker"
6
6
  require_relative "../core/workers/polling"
7
+ require_relative "../core/telemetry/logger"
7
8
 
8
9
  module Datadog
9
10
  module Profiling
@@ -134,6 +135,7 @@ module Datadog
134
135
  Datadog.logger.error(
135
136
  "Unable to report profile. Cause: #{e.class.name} #{e.message} Location: #{Array(e.backtrace).first}"
136
137
  )
138
+ Datadog::Core::Telemetry::Logger.report(e, description: "Unable to report profile")
137
139
  end
138
140
 
139
141
  true
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative "../core/telemetry/logger"
4
+
3
5
  module Datadog
4
6
  module Profiling
5
7
  # Stores stack samples in a native libdatadog data structure and expose Ruby-level serialization APIs
@@ -42,6 +44,7 @@ module Datadog
42
44
  error_message = result
43
45
 
44
46
  Datadog.logger.error("Failed to serialize profiling data: #{error_message}")
47
+ Datadog::Core::Telemetry::Logger.error("Failed to serialize profiling data")
45
48
 
46
49
  nil
47
50
  end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ #
4
+ # Entrypoint file for single step instrumentation.
5
+ #
6
+ # This file's path is private. Do not reference this file.
7
+ #
8
+ begin
9
+ require_relative 'auto_instrument'
10
+ rescue StandardError, LoadError => e
11
+ warn "Single step instrumentation failed: #{e.class}:#{e.message}\n\tSource:\n\t#{Array(e.backtrace).join("\n\t")}"
12
+ end
@@ -14,21 +14,17 @@ module Datadog
14
14
  module ActionCableConnection
15
15
  def on_open
16
16
  Tracing.trace(Ext::SPAN_ON_OPEN) do |span, trace|
17
- begin
18
- span.resource = "#{self.class}#on_open"
19
- span.type = Tracing::Metadata::Ext::AppTypes::TYPE_WEB
17
+ span.resource = "#{self.class}#on_open"
18
+ span.type = Tracing::Metadata::Ext::AppTypes::TYPE_WEB
20
19
 
21
- span.set_tag(Ext::TAG_ACTION, 'on_open')
22
- span.set_tag(Ext::TAG_CONNECTION, self.class.to_s)
20
+ span.set_tag(Ext::TAG_ACTION, 'on_open')
21
+ span.set_tag(Ext::TAG_CONNECTION, self.class.to_s)
23
22
 
24
- span.set_tag(Tracing::Metadata::Ext::TAG_COMPONENT, Ext::TAG_COMPONENT)
25
- span.set_tag(Tracing::Metadata::Ext::TAG_OPERATION, Ext::TAG_OPERATION_ON_OPEN)
23
+ span.set_tag(Tracing::Metadata::Ext::TAG_COMPONENT, Ext::TAG_COMPONENT)
24
+ span.set_tag(Tracing::Metadata::Ext::TAG_OPERATION, Ext::TAG_OPERATION_ON_OPEN)
26
25
 
27
- # Set the resource name of the trace
28
- trace.resource = span.resource
29
- rescue StandardError => e
30
- Datadog.logger.error("Error preparing span for ActionCable::Connection: #{e}")
31
- end
26
+ # Set the resource name of the trace
27
+ trace.resource = span.resource
32
28
 
33
29
  super
34
30
  end
@@ -7,6 +7,7 @@ require_relative '../ext'
7
7
  require_relative '../utils'
8
8
  require_relative '../../rack/middlewares'
9
9
  require_relative '../../analytics'
10
+ require_relative '../../../../core/telemetry/logger'
10
11
 
11
12
  module Datadog
12
13
  module Tracing
@@ -43,6 +44,7 @@ module Datadog
43
44
  span.set_tag(Tracing::Metadata::Ext::TAG_OPERATION, Ext::TAG_OPERATION_CONTROLLER)
44
45
  rescue StandardError => e
45
46
  Datadog.logger.error(e.message)
47
+ Datadog::Core::Telemetry::Logger.report(e)
46
48
  end
47
49
 
48
50
  def finish_processing(payload)
@@ -81,10 +83,13 @@ module Datadog
81
83
  end
82
84
  rescue StandardError => e
83
85
  Datadog.logger.error(e.message)
86
+ Datadog::Core::Telemetry::Logger.report(e)
84
87
  end
85
88
 
86
89
  # Instrumentation for ActionController::Metal
87
90
  module Metal
91
+ # TODO: Refactor this method to avoid using async API that splits the logic
92
+ # into two different methods (`start_processing` and `finish_processing`)
88
93
  def process_action(*args)
89
94
  # mutable payload with a tracing context that is used in two different
90
95
  # signals; it propagates the request span so that it can be finished
@@ -0,0 +1,78 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../../../metadata/ext'
4
+
5
+ module Datadog
6
+ module Tracing
7
+ module Contrib
8
+ module ActionPack
9
+ module ActionDispatch
10
+ # Instrumentation for ActionDispatch components
11
+ module Instrumentation
12
+ module_function
13
+
14
+ def set_http_route_tags(route_spec, script_name)
15
+ return unless Tracing.enabled?
16
+
17
+ return unless route_spec
18
+
19
+ request_trace = Tracing.active_trace
20
+ return unless request_trace
21
+
22
+ request_trace.set_tag(Tracing::Metadata::Ext::HTTP::TAG_ROUTE, route_spec.to_s.gsub(/\(.:format\)\z/, ''))
23
+
24
+ if script_name && !script_name.empty?
25
+ request_trace.set_tag(Tracing::Metadata::Ext::HTTP::TAG_ROUTE_PATH, script_name)
26
+ end
27
+ end
28
+
29
+ def dispatcher_route?(route)
30
+ return true if route.dispatcher?
31
+
32
+ # in Rails 4 there is no #rack_app method on the app
33
+ return true if route.app.respond_to?(:rack_app) && !route.app.rack_app.nil?
34
+
35
+ false
36
+ end
37
+
38
+ # Instrumentation for ActionDispatch::Journey components
39
+ module Journey
40
+ # Instrumentation for ActionDispatch::Journey::Router for Rails versions older than 7.1
41
+ module Router
42
+ def find_routes(req)
43
+ result = super
44
+
45
+ # result is an array of [match, parameters, route] tuples
46
+ routes = result.map(&:last)
47
+
48
+ routes.each do |route|
49
+ if Instrumentation.dispatcher_route?(route)
50
+ Instrumentation.set_http_route_tags(route.path.spec, req.env['SCRIPT_NAME'])
51
+ break
52
+ end
53
+ end
54
+
55
+ result
56
+ end
57
+ end
58
+
59
+ # Since Rails 7.1 `Router#find_routes` makes the route computation lazy
60
+ # https://github.com/rails/rails/commit/35b280fcc2d5d474f9f2be3aca3ae7aa6bba66eb
61
+ module LazyRouter
62
+ def find_routes(req)
63
+ super do |match, parameters, route|
64
+ if Instrumentation.dispatcher_route?(route)
65
+ Instrumentation.set_http_route_tags(route.path.spec, req.env['SCRIPT_NAME'])
66
+ end
67
+
68
+ yield [match, parameters, route]
69
+ end
70
+ end
71
+ end
72
+ end
73
+ end
74
+ end
75
+ end
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../../patcher'
4
+ require_relative 'instrumentation'
5
+
6
+ module Datadog
7
+ module Tracing
8
+ module Contrib
9
+ module ActionPack
10
+ module ActionDispatch
11
+ # Patcher for ActionController components
12
+ module Patcher
13
+ include Contrib::Patcher
14
+
15
+ module_function
16
+
17
+ def target_version
18
+ Integration.version
19
+ end
20
+
21
+ def patch
22
+ if ::ActionPack.gem_version >= Gem::Version.new('7.1')
23
+ ::ActionDispatch::Journey::Router.prepend(ActionDispatch::Instrumentation::Journey::LazyRouter)
24
+ else
25
+ ::ActionDispatch::Journey::Router.prepend(ActionDispatch::Instrumentation::Journey::Router)
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -2,6 +2,7 @@
2
2
 
3
3
  require_relative '../patcher'
4
4
  require_relative 'action_controller/patcher'
5
+ require_relative 'action_dispatch/patcher'
5
6
 
6
7
  module Datadog
7
8
  module Tracing
@@ -19,6 +20,7 @@ module Datadog
19
20
 
20
21
  def patch
21
22
  ActionController::Patcher.patch
23
+ ActionDispatch::Patcher.patch
22
24
  end
23
25
  end
24
26
  end
@@ -2,6 +2,7 @@
2
2
 
3
3
  require_relative '../../configuration/resolver'
4
4
  require_relative 'makara_resolver'
5
+ require_relative '../../../../core/telemetry/logger'
5
6
 
6
7
  module Datadog
7
8
  module Tracing
@@ -72,10 +73,12 @@ module Datadog
72
73
  #
73
74
  # `db_config` input may contain sensitive information such as passwords,
74
75
  # hence provide a succinct summary for the error logging.
76
+ #
75
77
  Datadog.logger.error(
76
78
  'Failed to resolve ActiveRecord database configuration. '\
77
79
  "Cause: #{e.class.name} Source: #{Array(e.backtrace).first}"
78
80
  )
81
+ Core::Telemetry::Logger.report(e, description: 'Failed to resolve ActiveRecord database configuration')
79
82
 
80
83
  nil
81
84
  end
@@ -95,6 +98,7 @@ module Datadog
95
98
  "Failed to resolve key #{matcher.inspect}. " \
96
99
  "Cause: #{e.class.name} Source: #{Array(e.backtrace).first}"
97
100
  )
101
+ Core::Telemetry::Logger.report(e, description: 'Failed to resolve key')
98
102
 
99
103
  nil
100
104
  end
@@ -4,6 +4,7 @@ require_relative '../../../metadata/ext'
4
4
  require_relative '../../analytics'
5
5
  require_relative '../ext'
6
6
  require_relative '../event'
7
+ require_relative '../../../../core/telemetry/logger'
7
8
 
8
9
  module Datadog
9
10
  module Tracing
@@ -48,7 +49,8 @@ module Datadog
48
49
  span.set_tag(Ext::TAG_INSTANTIATION_CLASS_NAME, payload.fetch(:class_name))
49
50
  span.set_tag(Ext::TAG_INSTANTIATION_RECORD_COUNT, payload.fetch(:record_count))
50
51
  rescue StandardError => e
51
- Datadog.logger.debug(e.message)
52
+ Datadog.logger.error(e.message)
53
+ Datadog::Core::Telemetry::Logger.report(e)
52
54
  end
53
55
  end
54
56
  end
@@ -6,6 +6,7 @@ require_relative '../event'
6
6
  require_relative '../ext'
7
7
  require_relative '../../analytics'
8
8
  require_relative '../../utils/database'
9
+ require_relative '../../../../core/telemetry/logger'
9
10
 
10
11
  module Datadog
11
12
  module Tracing
@@ -68,7 +69,8 @@ module Datadog
68
69
  span.set_tag(Tracing::Metadata::Ext::NET::TAG_TARGET_HOST, config[:host]) if config[:host]
69
70
  span.set_tag(Tracing::Metadata::Ext::NET::TAG_TARGET_PORT, config[:port]) if config[:port]
70
71
  rescue StandardError => e
71
- Datadog.logger.debug(e.message)
72
+ Datadog.logger.error(e.message)
73
+ Datadog::Core::Telemetry::Logger.report(e)
72
74
  end
73
75
  end
74
76
  end
@@ -2,6 +2,7 @@
2
2
 
3
3
  require_relative '../../ext'
4
4
  require_relative '../event'
5
+ require_relative '../../../../../core/telemetry/logger'
5
6
 
6
7
  module Datadog
7
8
  module Tracing
@@ -64,7 +65,7 @@ module Datadog
64
65
  key = payload[:key]
65
66
  store = payload[:store]
66
67
 
67
- mapping = MAPPING[event]
68
+ mapping = MAPPING.fetch(event)
68
69
 
69
70
  span.service = configuration[:cache_service]
70
71
  span.resource = mapping[:resource]
@@ -81,6 +82,9 @@ module Datadog
81
82
  span.set_tag('EVENT', event)
82
83
 
83
84
  set_cache_key(span, key, mapping[:multi_key])
85
+ rescue StandardError => e
86
+ Datadog.logger.error(e.message)
87
+ Datadog::Core::Telemetry::Logger.report(e)
84
88
  end
85
89
 
86
90
  def set_cache_key(span, key, multi_key)
@@ -29,6 +29,7 @@ module Datadog
29
29
  private
30
30
 
31
31
  # rubocop:disable Metrics/AbcSize
32
+ # rubocop:disable Metrics/MethodLength
32
33
  def annotate!(span, context)
33
34
  span.service = configuration[:service_name]
34
35
  span.type = Tracing::Metadata::Ext::HTTP::TYPE_OUTBOUND
@@ -76,7 +77,11 @@ module Datadog
76
77
  span.set_tag(Tracing::Metadata::Ext::HTTP::TAG_STATUS_CODE, context.safely(:status_code))
77
78
 
78
79
  Contrib::SpanAttributeSchema.set_peer_service!(span, Ext::PEER_SERVICE_SOURCES)
80
+ rescue StandardError => e
81
+ Datadog.logger.error(e.message)
82
+ Datadog::Core::Telemetry::Logger.report(e)
79
83
  end
84
+ # rubocop:enable Metrics/MethodLength
80
85
  # rubocop:enable Metrics/AbcSize
81
86
 
82
87
  def configuration
@@ -93,11 +93,16 @@ module Datadog
93
93
  span.resource = "#{method} #{quantized_url}"
94
94
  Contrib::SpanAttributeSchema.set_peer_service!(span, Ext::PEER_SERVICE_SOURCES)
95
95
  rescue StandardError => e
96
+ # TODO: Refactor the code to streamline the execution without ensure
96
97
  Datadog.logger.error(e.message)
98
+ Datadog::Core::Telemetry::Logger.report(e)
97
99
  ensure
98
100
  # the call is still executed
99
101
  response = super
100
- span.set_tag(Tracing::Metadata::Ext::HTTP::TAG_STATUS_CODE, response.status)
102
+
103
+ if response && response.respond_to?(:status)
104
+ span.set_tag(Tracing::Metadata::Ext::HTTP::TAG_STATUS_CODE, response.status)
105
+ end
101
106
  end
102
107
  end
103
108
  response
@@ -7,6 +7,7 @@ require_relative '../http'
7
7
  require_relative '../analytics'
8
8
  require_relative 'ext'
9
9
  require_relative '../http_annotation_helper'
10
+ require_relative '../../../core/telemetry/logger'
10
11
 
11
12
  module Datadog
12
13
  module Tracing
@@ -37,6 +38,7 @@ module Datadog
37
38
 
38
39
  attr_reader :app
39
40
 
41
+ # rubocop:disable Metrics/AbcSize
40
42
  def annotate!(span, env, options)
41
43
  span.resource = resource_name(env)
42
44
  span.service = service_name(env[:url].host, options)
@@ -75,7 +77,11 @@ module Datadog
75
77
  )
76
78
 
77
79
  Contrib::SpanAttributeSchema.set_peer_service!(span, Ext::PEER_SERVICE_SOURCES)
80
+ rescue StandardError => e
81
+ Datadog.logger.error(e.message)
82
+ Datadog::Core::Telemetry::Logger.report(e)
78
83
  end
84
+ # rubocop:enable Metrics/AbcSize
79
85
 
80
86
  def handle_response(span, env, options)
81
87
  span.set_error(["Error #{env[:status]}", env[:body]]) if options[:error_status_codes].include? env[:status]
@@ -85,6 +91,9 @@ module Datadog
85
91
  span.set_tags(
86
92
  Datadog.configuration.tracing.header_tags.response_tags(env[:response_headers])
87
93
  )
94
+ rescue StandardError => e
95
+ Datadog.logger.error(e.message)
96
+ Datadog::Core::Telemetry::Logger.report(e)
88
97
  end
89
98
 
90
99
  def propagate!(trace, span, env)
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative '../../../core'
4
+ require_relative '../../../core/telemetry/logger'
4
5
  require_relative '../../metadata/ext'
5
6
  require_relative '../analytics'
6
7
  require_relative '../rack/ext'
@@ -41,6 +42,7 @@ module Datadog
41
42
 
42
43
  # collect endpoint details
43
44
  endpoint = payload.fetch(:endpoint)
45
+ env = payload.fetch(:env)
44
46
  api_view = api_view(endpoint.options[:for])
45
47
  request_method = endpoint.options.fetch(:method).first
46
48
  path = endpoint_expand_path(endpoint)
@@ -61,9 +63,22 @@ module Datadog
61
63
  span.set_tag(Tracing::Metadata::Ext::TAG_COMPONENT, Ext::TAG_COMPONENT)
62
64
  span.set_tag(Tracing::Metadata::Ext::TAG_OPERATION, Ext::TAG_OPERATION_ENDPOINT_RUN)
63
65
 
66
+ if (grape_route = env['grape.routing_args']) && grape_route[:route_info]
67
+ trace.set_tag(
68
+ Tracing::Metadata::Ext::HTTP::TAG_ROUTE,
69
+ # here we are removing the format from the path:
70
+ # e.g. /path/to/resource(.json) => /path/to/resource
71
+ # e.g. /path/to/resource(.:format) => /path/to/resource
72
+ grape_route[:route_info].path&.gsub(/\(\.:?\w+\)\z/, '')
73
+ )
74
+
75
+ trace.set_tag(Tracing::Metadata::Ext::HTTP::TAG_ROUTE_PATH, env['SCRIPT_NAME'])
76
+ end
77
+
64
78
  Thread.current[KEY_RUN] = true
65
79
  rescue StandardError => e
66
80
  Datadog.logger.error(e.message)
81
+ Datadog::Core::Telemetry::Logger.report(e)
67
82
  end
68
83
 
69
84
  def endpoint_run(name, start, finish, id, payload)
@@ -107,6 +122,7 @@ module Datadog
107
122
  end
108
123
  rescue StandardError => e
109
124
  Datadog.logger.error(e.message)
125
+ Datadog::Core::Telemetry::Logger.report(e)
110
126
  end
111
127
 
112
128
  # Status code resolution is tied to the exception handling
@@ -150,6 +166,7 @@ module Datadog
150
166
  Thread.current[KEY_RENDER] = true
151
167
  rescue StandardError => e
152
168
  Datadog.logger.error(e.message)
169
+ Datadog::Core::Telemetry::Logger.report(e)
153
170
  end
154
171
 
155
172
  def endpoint_render(name, start, finish, id, payload)
@@ -174,6 +191,7 @@ module Datadog
174
191
  end
175
192
  rescue StandardError => e
176
193
  Datadog.logger.error(e.message)
194
+ Datadog::Core::Telemetry::Logger.report(e)
177
195
  end
178
196
 
179
197
  def endpoint_run_filters(name, start, finish, id, payload)
@@ -212,6 +230,7 @@ module Datadog
212
230
  end
213
231
  rescue StandardError => e
214
232
  Datadog.logger.error(e.message)
233
+ Datadog::Core::Telemetry::Logger.report(e)
215
234
  end
216
235
 
217
236
  private
@@ -21,13 +21,18 @@ module Datadog
21
21
  end
22
22
 
23
23
  def patch
24
+ # DEV-3.0: We should remove as many patching options as possible, given the alternatives do not
25
+ # DEV-3.0: provide any benefit to the recommended `with_unified_tracer` patching method.
26
+ # DEV-3.0: `with_deprecated_tracer` is likely safe to remove.
27
+ # DEV-3.0: `with_unified_tracer: false` should be removed if possible.
28
+ # DEV-3.0: `with_unified_tracer: true` should be the default and hopefully not even necessary as an option.
24
29
  if configuration[:with_deprecated_tracer]
25
- TracingPatcher.patch!(schemas, trace_options)
30
+ TracingPatcher.patch!(schemas)
26
31
  elsif Integration.trace_supported?
27
32
  if configuration[:with_unified_tracer]
28
- UnifiedTracePatcher.patch!(schemas, trace_options)
33
+ UnifiedTracePatcher.patch!(schemas)
29
34
  else
30
- TracePatcher.patch!(schemas, trace_options)
35
+ TracePatcher.patch!(schemas)
31
36
  end
32
37
  else
33
38
  Datadog.logger.warn(
@@ -35,18 +40,10 @@ module Datadog
35
40
  'or Datadog::Tracing::Contrib::GraphQL::UnifiedTrace.'\
36
41
  'Falling back to GraphQL::Tracing::DataDogTracing.'
37
42
  )
38
- TracingPatcher.patch!(schemas, trace_options)
43
+ TracingPatcher.patch!(schemas)
39
44
  end
40
45
  end
41
46
 
42
- def trace_options
43
- {
44
- service: configuration[:service_name],
45
- analytics_enabled: Contrib::Analytics.enabled?(configuration[:analytics_enabled]),
46
- analytics_sample_rate: configuration[:analytics_sample_rate]
47
- }
48
- end
49
-
50
47
  def configuration
51
48
  Datadog.configuration.tracing[:graphql]
52
49
  end
@@ -8,12 +8,12 @@ module Datadog
8
8
  module TracePatcher
9
9
  module_function
10
10
 
11
- def patch!(schemas, options)
11
+ def patch!(schemas)
12
12
  if schemas.empty?
13
- ::GraphQL::Schema.trace_with(::GraphQL::Tracing::DataDogTrace, **options)
13
+ ::GraphQL::Schema.trace_with(::GraphQL::Tracing::DataDogTrace)
14
14
  else
15
15
  schemas.each do |schema|
16
- schema.trace_with(::GraphQL::Tracing::DataDogTrace, **options)
16
+ schema.trace_with(::GraphQL::Tracing::DataDogTrace)
17
17
  end
18
18
  end
19
19
  end