ddtrace 1.11.0 → 1.12.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (118) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +85 -1
  3. data/ext/ddtrace_profiling_native_extension/NativeExtensionDesign.md +6 -4
  4. data/ext/ddtrace_profiling_native_extension/collectors_cpu_and_wall_time_worker.c +34 -16
  5. data/ext/ddtrace_profiling_native_extension/extconf.rb +19 -3
  6. data/ext/ddtrace_profiling_native_extension/native_extension_helpers.rb +2 -2
  7. data/ext/ddtrace_profiling_native_extension/private_vm_api_access.c +38 -4
  8. data/lib/datadog/appsec/assets/blocked.html +1 -1
  9. data/lib/datadog/appsec/assets/waf_rules/recommended.json +489 -133
  10. data/lib/datadog/appsec/assets/waf_rules/strict.json +2 -47
  11. data/lib/datadog/appsec/configuration/settings.rb +2 -10
  12. data/lib/datadog/appsec/configuration.rb +3 -9
  13. data/lib/datadog/appsec/contrib/rack/ext.rb +0 -1
  14. data/lib/datadog/appsec/contrib/rack/gateway/request.rb +17 -3
  15. data/lib/datadog/appsec/contrib/rack/gateway/response.rb +3 -3
  16. data/lib/datadog/appsec/contrib/rack/gateway/watcher.rb +27 -45
  17. data/lib/datadog/appsec/contrib/rack/integration.rb +0 -5
  18. data/lib/datadog/appsec/contrib/rack/reactive/request.rb +7 -1
  19. data/lib/datadog/appsec/contrib/rack/request_body_middleware.rb +1 -1
  20. data/lib/datadog/appsec/contrib/rack/request_middleware.rb +34 -26
  21. data/lib/datadog/appsec/contrib/rails/ext.rb +0 -1
  22. data/lib/datadog/appsec/contrib/rails/framework.rb +1 -13
  23. data/lib/datadog/appsec/contrib/rails/gateway/watcher.rb +9 -27
  24. data/lib/datadog/appsec/contrib/rails/integration.rb +0 -5
  25. data/lib/datadog/appsec/contrib/rails/patcher.rb +1 -1
  26. data/lib/datadog/appsec/contrib/sinatra/ext.rb +0 -1
  27. data/lib/datadog/appsec/contrib/sinatra/framework.rb +1 -13
  28. data/lib/datadog/appsec/contrib/sinatra/gateway/watcher.rb +18 -36
  29. data/lib/datadog/appsec/contrib/sinatra/integration.rb +0 -5
  30. data/lib/datadog/appsec/contrib/sinatra/patcher.rb +5 -4
  31. data/lib/datadog/appsec/event.rb +37 -37
  32. data/lib/datadog/appsec/ext.rb +1 -0
  33. data/lib/datadog/appsec/extensions.rb +2 -6
  34. data/lib/datadog/appsec/monitor/gateway/watcher.rb +9 -28
  35. data/lib/datadog/appsec/processor/rule_loader.rb +3 -3
  36. data/lib/datadog/appsec/processor/rule_merger.rb +15 -29
  37. data/lib/datadog/appsec/processor.rb +0 -45
  38. data/lib/datadog/appsec/remote.rb +10 -8
  39. data/lib/datadog/appsec/response.rb +23 -11
  40. data/lib/datadog/appsec/scope.rb +61 -0
  41. data/lib/datadog/appsec.rb +6 -0
  42. data/lib/datadog/ci/ext/environment.rb +40 -4
  43. data/lib/datadog/core/configuration/components.rb +9 -3
  44. data/lib/datadog/core/configuration/settings.rb +74 -14
  45. data/lib/datadog/core/configuration.rb +5 -1
  46. data/lib/datadog/core/remote/client/capabilities.rb +1 -1
  47. data/lib/datadog/core/remote/client.rb +5 -1
  48. data/lib/datadog/core/telemetry/client.rb +1 -1
  49. data/lib/datadog/core/telemetry/collector.rb +2 -1
  50. data/lib/datadog/core/telemetry/http/transport.rb +1 -0
  51. data/lib/datadog/core/telemetry/v1/dependency.rb +2 -1
  52. data/lib/datadog/kit/appsec/events.rb +58 -13
  53. data/lib/datadog/kit/identity.rb +29 -10
  54. data/lib/datadog/profiling/collectors/cpu_and_wall_time_worker.rb +2 -0
  55. data/lib/datadog/profiling/component.rb +69 -29
  56. data/lib/datadog/profiling.rb +2 -1
  57. data/lib/datadog/tracing/buffer.rb +0 -1
  58. data/lib/datadog/tracing/contrib/active_support/configuration/settings.rb +9 -1
  59. data/lib/datadog/tracing/contrib/aws/ext.rb +11 -1
  60. data/lib/datadog/tracing/contrib/aws/instrumentation.rb +7 -0
  61. data/lib/datadog/tracing/contrib/aws/parsed_context.rb +4 -0
  62. data/lib/datadog/tracing/contrib/aws/service/base.rb +16 -0
  63. data/lib/datadog/tracing/contrib/aws/service/dynamodb.rb +22 -0
  64. data/lib/datadog/tracing/contrib/aws/service/eventbridge.rb +22 -0
  65. data/lib/datadog/tracing/contrib/aws/service/kinesis.rb +32 -0
  66. data/lib/datadog/tracing/contrib/aws/service/s3.rb +22 -0
  67. data/lib/datadog/tracing/contrib/aws/service/sns.rb +30 -0
  68. data/lib/datadog/tracing/contrib/aws/service/sqs.rb +27 -0
  69. data/lib/datadog/tracing/contrib/aws/service/states.rb +40 -0
  70. data/lib/datadog/tracing/contrib/aws/services.rb +18 -0
  71. data/lib/datadog/tracing/contrib/httpclient/configuration/settings.rb +6 -1
  72. data/lib/datadog/tracing/contrib/httpclient/instrumentation.rb +5 -2
  73. data/lib/datadog/tracing/contrib/httprb/configuration/settings.rb +6 -1
  74. data/lib/datadog/tracing/contrib/httprb/instrumentation.rb +4 -2
  75. data/lib/datadog/tracing/contrib/mongodb/configuration/settings.rb +6 -1
  76. data/lib/datadog/tracing/contrib/mongodb/subscribers.rb +5 -2
  77. data/lib/datadog/tracing/contrib/mysql2/configuration/settings.rb +6 -1
  78. data/lib/datadog/tracing/contrib/mysql2/instrumentation.rb +5 -2
  79. data/lib/datadog/tracing/contrib/patcher.rb +0 -1
  80. data/lib/datadog/tracing/contrib/pg/configuration/settings.rb +6 -1
  81. data/lib/datadog/tracing/contrib/pg/instrumentation.rb +5 -2
  82. data/lib/datadog/tracing/contrib/presto/configuration/settings.rb +6 -1
  83. data/lib/datadog/tracing/contrib/presto/instrumentation.rb +4 -2
  84. data/lib/datadog/tracing/contrib/propagation/sql_comment.rb +10 -2
  85. data/lib/datadog/tracing/contrib/racecar/configuration/settings.rb +9 -1
  86. data/lib/datadog/tracing/contrib/racecar/event.rb +3 -1
  87. data/lib/datadog/tracing/contrib/rack/middlewares.rb +3 -1
  88. data/lib/datadog/tracing/contrib/redis/configuration/settings.rb +6 -1
  89. data/lib/datadog/tracing/contrib/redis/tags.rb +4 -1
  90. data/lib/datadog/tracing/contrib/rest_client/configuration/settings.rb +6 -1
  91. data/lib/datadog/tracing/contrib/rest_client/request_patch.rb +4 -1
  92. data/lib/datadog/tracing/contrib/roda/patcher.rb +1 -1
  93. data/lib/datadog/tracing/contrib/sequel/database.rb +4 -1
  94. data/lib/datadog/tracing/contrib/sequel/dataset.rb +4 -1
  95. data/lib/datadog/tracing/contrib/sequel/utils.rb +4 -1
  96. data/lib/datadog/tracing/contrib/status_code_matcher.rb +0 -1
  97. data/lib/datadog/tracing/correlation.rb +0 -1
  98. data/lib/datadog/tracing/distributed/headers/ext.rb +1 -1
  99. data/lib/datadog/tracing/event.rb +0 -2
  100. data/lib/datadog/tracing/pipeline.rb +0 -2
  101. data/lib/datadog/tracing/runtime/metrics.rb +0 -2
  102. data/lib/datadog/tracing/sampling/rate_by_service_sampler.rb +0 -1
  103. data/lib/datadog/tracing/sampling/rate_sampler.rb +0 -2
  104. data/lib/datadog/tracing/sampling/rule.rb +0 -2
  105. data/lib/datadog/tracing/sampling/rule_sampler.rb +0 -2
  106. data/lib/datadog/tracing/span_operation.rb +0 -1
  107. data/lib/datadog/tracing/sync_writer.rb +0 -2
  108. data/lib/datadog/tracing/trace_operation.rb +0 -1
  109. data/lib/datadog/tracing/tracer.rb +0 -1
  110. data/lib/datadog/tracing/workers/trace_writer.rb +0 -1
  111. data/lib/datadog/tracing/workers.rb +0 -2
  112. data/lib/datadog/tracing/writer.rb +0 -2
  113. data/lib/ddtrace/version.rb +2 -2
  114. metadata +17 -18
  115. data/lib/datadog/appsec/contrib/configuration/settings.rb +0 -20
  116. data/lib/datadog/appsec/contrib/rack/configuration/settings.rb +0 -22
  117. data/lib/datadog/appsec/contrib/rails/configuration/settings.rb +0 -22
  118. data/lib/datadog/appsec/contrib/sinatra/configuration/settings.rb +0 -22
@@ -14,38 +14,68 @@ module Datadog
14
14
  #
15
15
  # This method is experimental and may change in the future.
16
16
  #
17
- # @param trace [TraceOperation] Trace to attach data to.
17
+ # @param trace [TraceOperation] Trace to attach data to. Defaults to
18
+ # active trace.
19
+ # @param span [SpanOperation] Span to attach data to. Defaults to
20
+ # active span on trace. Note that this should be a service entry span.
21
+ # When AppSec is enabled, the expected span and trace are automatically
22
+ # used as defaults.
18
23
  # @param user [Hash<Symbol, String>] User information to pass to
19
24
  # Datadog::Kit::Identity.set_user. Must contain at least :id as key.
20
25
  # @param others [Hash<String || Symbol, String>] Additional free-form
21
26
  # event information to attach to the trace.
22
- def self.track_login_success(trace, user:, **others)
23
- track(LOGIN_SUCCESS_EVENT, trace, **others)
27
+ def self.track_login_success(trace = nil, span = nil, user:, **others)
28
+ if (appsec_scope = Datadog::AppSec.active_scope)
29
+ trace = appsec_scope.trace
30
+ span = appsec_scope.service_entry_span
31
+ end
32
+
33
+ trace ||= Datadog::Tracing.active_trace
34
+ span ||= trace.active_span || Datadog::Tracing.active_span
35
+
36
+ raise ArgumentError, "span #{span.span_id} does not belong to trace #{trace.id}" if trace.id != span.trace_id
37
+
38
+ track(LOGIN_SUCCESS_EVENT, trace, span, **others)
24
39
 
25
40
  user_options = user.dup
26
41
  user_id = user_options.delete(:id)
27
42
 
28
43
  raise ArgumentError, 'missing required key: :user => { :id }' if user_id.nil?
29
44
 
30
- Kit::Identity.set_user(trace, id: user_id, **user_options)
45
+ Kit::Identity.set_user(trace, span, id: user_id, **user_options)
31
46
  end
32
47
 
33
48
  # Attach login failure event information to the trace
34
49
  #
35
50
  # This method is experimental and may change in the future.
36
51
  #
37
- # @param trace [TraceOperation] Trace to attach data to.
52
+ # @param trace [TraceOperation] Trace to attach data to. Defaults to
53
+ # active trace.
54
+ # @param span [SpanOperation] Span to attach data to. Defaults to
55
+ # active span on trace. Note that this should be a service entry span.
56
+ # When AppSec is enabled, the expected span and trace are automatically
57
+ # used as defaults.
38
58
  # @param user_id [String] User id that attempted login
39
59
  # @param user_exists [bool] Whether the user id that did a login attempt exists.
40
60
  # @param others [Hash<String || Symbol, String>] Additional free-form
41
61
  # event information to attach to the trace.
42
- def self.track_login_failure(trace, user_id:, user_exists:, **others)
43
- track(LOGIN_FAILURE_EVENT, trace, **others)
62
+ def self.track_login_failure(trace = nil, span = nil, user_id:, user_exists:, **others)
63
+ if (appsec_scope = Datadog::AppSec.active_scope)
64
+ trace = appsec_scope.trace
65
+ span = appsec_scope.service_entry_span
66
+ end
67
+
68
+ trace ||= Datadog::Tracing.active_trace
69
+ span ||= trace.active_span || Datadog::Tracing.active_span
70
+
71
+ raise ArgumentError, "span #{span.span_id} does not belong to trace #{trace.id}" if trace.id != span.trace_id
72
+
73
+ track(LOGIN_FAILURE_EVENT, trace, span, **others)
44
74
 
45
75
  raise ArgumentError, 'user_id cannot be nil' if user_id.nil?
46
76
 
47
- trace.set_tag('appsec.events.users.login.failure.usr.id', user_id)
48
- trace.set_tag('appsec.events.users.login.failure.usr.exists', user_exists)
77
+ span.set_tag('appsec.events.users.login.failure.usr.id', user_id)
78
+ span.set_tag('appsec.events.users.login.failure.usr.exists', user_exists)
49
79
  end
50
80
 
51
81
  # Attach custom event information to the trace
@@ -53,17 +83,32 @@ module Datadog
53
83
  # This method is experimental and may change in the future.
54
84
  #
55
85
  # @param event [String] Mandatory. Event code.
56
- # @param trace [TraceOperation] Trace to attach data to.
86
+ # @param trace [TraceOperation] Trace to attach data to. Defaults to
87
+ # active trace.
88
+ # @param span [SpanOperation] Span to attach data to. Defaults to
89
+ # active span on trace. Note that this should be a service entry span.
90
+ # When AppSec is enabled, the expected span and trace are automatically
91
+ # used as defaults.
57
92
  # @param others [Hash<Symbol, String>] Additional free-form
58
93
  # event information to attach to the trace. Key must not
59
94
  # be :track.
60
- def self.track(event, trace, **others)
61
- trace.set_tag("appsec.events.#{event}.track", 'true')
95
+ def self.track(event, trace = nil, span = nil, **others)
96
+ if (appsec_scope = Datadog::AppSec.active_scope)
97
+ trace = appsec_scope.trace
98
+ span = appsec_scope.service_entry_span
99
+ end
100
+
101
+ trace ||= Datadog::Tracing.active_trace
102
+ span ||= trace.active_span || Datadog::Tracing.active_span
103
+
104
+ raise ArgumentError, "span #{span.span_id} does not belong to trace #{trace.id}" if trace.id != span.trace_id
105
+
106
+ span.set_tag("appsec.events.#{event}.track", 'true')
62
107
 
63
108
  others.each do |k, v|
64
109
  raise ArgumentError, 'key cannot be :track' if k.to_sym == :track
65
110
 
66
- trace.set_tag("appsec.events.#{event}.#{k}", v) unless v.nil?
111
+ span.set_tag("appsec.events.#{event}.#{k}", v) unless v.nil?
67
112
  end
68
113
 
69
114
  trace.keep!
@@ -8,7 +8,12 @@ module Datadog
8
8
  module Identity
9
9
  # Attach user information to the trace
10
10
  #
11
- # @param trace [TraceOperation] Trace to attach data to.
11
+ # @param trace [TraceOperation] Trace to attach data to. Defaults to
12
+ # active trace.
13
+ # @param span [SpanOperation] Span to attach data to. Defaults to
14
+ # active span on trace. Note that this should be a service entry span.
15
+ # When AppSec is enabled, the expected span and trace are automatically
16
+ # used as defaults.
12
17
  # @param id [String] Mandatory. Username or client id extracted
13
18
  # from the access token or Authorization header in the inbound request
14
19
  # from outside the system.
@@ -29,7 +34,10 @@ module Datadog
29
34
  #
30
35
  # rubocop:disable Metrics/CyclomaticComplexity
31
36
  # rubocop:disable Metrics/PerceivedComplexity
32
- def self.set_user(trace, id:, email: nil, name: nil, session_id: nil, role: nil, scope: nil, **others)
37
+ # rubocop:disable Metrics/AbcSize
38
+ def self.set_user(
39
+ trace = nil, span = nil, id:, email: nil, name: nil, session_id: nil, role: nil, scope: nil, **others
40
+ )
33
41
  raise ArgumentError, 'missing required key: :id' if id.nil?
34
42
 
35
43
  # enforce types
@@ -45,24 +53,35 @@ module Datadog
45
53
  raise TypeError, "#{k.inspect} must be a String" unless v.nil? || v.is_a?(String)
46
54
  end
47
55
 
56
+ if (appsec_scope = Datadog::AppSec.active_scope)
57
+ trace = appsec_scope.trace
58
+ span = appsec_scope.service_entry_span
59
+ end
60
+
61
+ trace ||= Datadog::Tracing.active_trace
62
+ span ||= trace.active_span || Datadog::Tracing.active_span
63
+
64
+ raise ArgumentError, "span #{span.span_id} does not belong to trace #{trace.id}" if trace.id != span.trace_id
65
+
48
66
  # set tags once data is known consistent
49
67
 
50
- trace.set_tag('usr.id', id)
51
- trace.set_tag('usr.email', email) unless email.nil?
52
- trace.set_tag('usr.name', name) unless name.nil?
53
- trace.set_tag('usr.session_id', session_id) unless session_id.nil?
54
- trace.set_tag('usr.role', role) unless role.nil?
55
- trace.set_tag('usr.scope', scope) unless scope.nil?
68
+ span.set_tag('usr.id', id)
69
+ span.set_tag('usr.email', email) unless email.nil?
70
+ span.set_tag('usr.name', name) unless name.nil?
71
+ span.set_tag('usr.session_id', session_id) unless session_id.nil?
72
+ span.set_tag('usr.role', role) unless role.nil?
73
+ span.set_tag('usr.scope', scope) unless scope.nil?
56
74
 
57
75
  others.each do |k, v|
58
- trace.set_tag("usr.#{k}", v) unless v.nil?
76
+ span.set_tag("usr.#{k}", v) unless v.nil?
59
77
  end
60
78
 
61
- if Datadog.configuration.appsec.enabled
79
+ if appsec_scope
62
80
  user = ::Datadog::AppSec::Instrumentation::Gateway::User.new(id)
63
81
  ::Datadog::AppSec::Instrumentation.gateway.push('identity.set_user', user)
64
82
  end
65
83
  end
84
+ # rubocop:enable Metrics/AbcSize
66
85
  # rubocop:enable Metrics/PerceivedComplexity
67
86
  # rubocop:enable Metrics/CyclomaticComplexity
68
87
  end
@@ -20,6 +20,7 @@ module Datadog
20
20
  endpoint_collection_enabled:,
21
21
  gc_profiling_enabled:,
22
22
  allocation_counting_enabled:,
23
+ no_signals_workaround_enabled:,
23
24
  thread_context_collector: ThreadContext.new(
24
25
  recorder: recorder,
25
26
  max_frames: max_frames,
@@ -43,6 +44,7 @@ module Datadog
43
44
  gc_profiling_enabled,
44
45
  idle_sampling_helper,
45
46
  allocation_counting_enabled,
47
+ no_signals_workaround_enabled,
46
48
  dynamic_sampling_rate_enabled,
47
49
  )
48
50
  @worker_thread = nil
@@ -65,8 +65,6 @@ module Datadog
65
65
  # NOTE: Please update the Initialization section of ProfilingDevelopment.md with any changes to this method
66
66
 
67
67
  if enable_new_profiler?(settings)
68
- print_new_profiler_warnings
69
-
70
68
  recorder = Datadog::Profiling::StackRecorder.new(
71
69
  cpu_time_enabled: RUBY_PLATFORM.include?('linux'), # Only supported on Linux currently
72
70
  alloc_samples_enabled: false, # Always disabled for now -- work in progress
@@ -78,8 +76,11 @@ module Datadog
78
76
  endpoint_collection_enabled: settings.profiling.advanced.endpoint.collection.enabled,
79
77
  gc_profiling_enabled: enable_gc_profiling?(settings),
80
78
  allocation_counting_enabled: settings.profiling.advanced.allocation_counting_enabled,
79
+ no_signals_workaround_enabled: no_signals_workaround_enabled?(settings),
81
80
  )
82
81
  else
82
+ load_pprof_support
83
+
83
84
  recorder = build_profiler_old_recorder(settings)
84
85
  collector = build_profiler_oldstack_collector(settings, recorder, optional_tracer)
85
86
  end
@@ -141,19 +142,6 @@ module Datadog
141
142
  end
142
143
  end
143
144
 
144
- private_class_method def self.print_new_profiler_warnings
145
- return if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('2.6')
146
-
147
- # For more details on the issue, see the "BIG Issue" comment on `gvl_owner` function in
148
- # `private_vm_api_access.c`.
149
- Datadog.logger.warn(
150
- 'The new CPU Profiling 2.0 profiler has been force-enabled on a legacy Ruby version (< 2.6). This is not ' \
151
- 'recommended in production environments, as due to limitations in Ruby APIs, we suspect it may lead to crashes ' \
152
- 'in very rare situations. Please report any issues you run into to Datadog support or ' \
153
- 'via <https://github.com/datadog/dd-trace-rb/issues/new>!'
154
- )
155
- end
156
-
157
145
  private_class_method def self.enable_new_profiler?(settings)
158
146
  if settings.profiling.advanced.force_enable_legacy_profiler
159
147
  Datadog.logger.warn(
@@ -162,32 +150,71 @@ module Datadog
162
150
  return false
163
151
  end
164
152
 
165
- return true if settings.profiling.advanced.force_enable_new_profiler
153
+ true
154
+ end
166
155
 
167
- return false if RUBY_VERSION.start_with?('2.3.', '2.4.', '2.5.')
156
+ private_class_method def self.no_signals_workaround_enabled?(settings) # rubocop:disable Metrics/MethodLength
157
+ setting_value = settings.profiling.advanced.no_signals_workaround_enabled
158
+ legacy_ruby_that_should_use_workaround = RUBY_VERSION.start_with?('2.3.', '2.4.', '2.5.')
159
+
160
+ unless [true, false, :auto].include?(setting_value)
161
+ Datadog.logger.error(
162
+ "Ignoring invalid value for profiling no_signals_workaround_enabled setting: #{setting_value.inspect}. " \
163
+ 'Valid options are `true`, `false` or (default) `:auto`.'
164
+ )
165
+
166
+ setting_value = :auto
167
+ end
168
+
169
+ if setting_value == false
170
+ if legacy_ruby_that_should_use_workaround
171
+ Datadog.logger.warn(
172
+ 'The profiling "no signals" workaround has been disabled via configuration on a legacy Ruby version ' \
173
+ '(< 2.6). This is not recommended ' \
174
+ 'in production environments, as due to limitations in Ruby APIs, we suspect it may lead to crashes ' \
175
+ 'in very rare situations. Please report any issues you run into to Datadog support or ' \
176
+ 'via <https://github.com/datadog/dd-trace-rb/issues/new>!'
177
+ )
178
+ else
179
+ Datadog.logger.warn('Profiling "no signals" workaround disabled via configuration')
180
+ end
181
+
182
+ return false
183
+ end
184
+
185
+ if setting_value == true
186
+ Datadog.logger.warn(
187
+ 'Profiling "no signals" workaround enabled via configuration. Profiling data will have lower quality.'
188
+ )
189
+
190
+ return true
191
+ end
192
+
193
+ # Setting is in auto mode. Let's probe to see if we should enable it:
194
+
195
+ # We don't warn users in this situation because "upgrade your Ruby" is not a great warning
196
+ return true if legacy_ruby_that_should_use_workaround
168
197
 
169
198
  if Gem.loaded_specs['mysql2'] && incompatible_libmysqlclient_version?(settings)
170
199
  Datadog.logger.warn(
171
- 'Falling back to legacy profiler because an incompatible version of the mysql2 gem is installed. ' \
172
- 'Older versions of libmysqlclient (the C ' \
173
- 'library used by the mysql2 gem) have a bug in their signal handling code that the new profiler can trigger. ' \
174
- 'This bug (https://bugs.mysql.com/bug.php?id=83109) is fixed in libmysqlclient versions 8.0.0 and above. '
200
+ 'Enabling the profiling "no signals" workaround because an incompatible version of the mysql2 gem is ' \
201
+ 'installed. Profiling data will have lower quality.' \
202
+ 'To fix this, upgrade the libmysqlclient in your OS image to version 8.0.0 or above.'
175
203
  )
176
- return false
204
+ return true
177
205
  end
178
206
 
179
207
  if Gem.loaded_specs['rugged']
180
208
  Datadog.logger.warn(
181
- 'Falling back to legacy profiler because rugged gem is installed. Some operations on this gem are ' \
182
- 'currently incompatible with the new CPU Profiling 2.0 profiler, as detailed in ' \
183
- '<https://github.com/datadog/dd-trace-rb/issues/2721>. If you still want to try out the new profiler, you ' \
184
- 'can force-enable it by using the `DD_PROFILING_FORCE_ENABLE_NEW` environment variable or the ' \
185
- '`c.profiling.advanced.force_enable_new_profiler` setting.'
209
+ 'Enabling the profiling "no signals" workaround because the rugged gem is installed. ' \
210
+ 'This is needed because some operations on this gem are currently incompatible with the normal working mode ' \
211
+ 'of the profiler, as detailed in <https://github.com/datadog/dd-trace-rb/issues/2721>. ' \
212
+ 'Profiling data will have lower quality.'
186
213
  )
187
- return false
214
+ return true
188
215
  end
189
216
 
190
- true
217
+ false
191
218
  end
192
219
 
193
220
  # Versions of libmysqlclient prior to 8.0.0 are known to have buggy handling of system call interruptions.
@@ -230,6 +257,19 @@ module Datadog
230
257
  true
231
258
  end
232
259
  end
260
+
261
+ # The old profiler's pprof support conflicts with the ruby-cloud-profiler gem.
262
+ #
263
+ # This is not a problem for almost all customers, since we now default everyone to use the new CPU Profiling 2.0
264
+ # profiler. But the issue was still triggered, because currently we still _load_ both the old and new profiling
265
+ # code paths.
266
+ #
267
+ # To work around this issue, and because we plan on deleting the old profiler soon, rather than poking at the
268
+ # pprof support code, we only load the conflicting file when the old profiler is in use. This way customers using
269
+ # the new profiler will not be affected by the issue any longer.
270
+ private_class_method def self.load_pprof_support
271
+ require_relative 'pprof/pprof_pb'
272
+ end
233
273
  end
234
274
  end
235
275
  end
@@ -197,7 +197,8 @@ module Datadog
197
197
  require_relative 'profiling/profiler'
198
198
  require_relative 'profiling/native_extension'
199
199
  require_relative 'profiling/trace_identifiers/helper'
200
- require_relative 'profiling/pprof/pprof_pb'
200
+ # This file is loaded in Profiling::Component#load_pprof_support; see notes there for why
201
+ # require_relative 'profiling/pprof/pprof_pb'
201
202
  require_relative 'profiling/tag_builder'
202
203
  require_relative 'profiling/http_transport'
203
204
 
@@ -1,4 +1,3 @@
1
- require_relative '../core'
2
1
  require_relative '../core/environment/ext'
3
2
  require_relative '../core/buffer/thread_safe'
4
3
  require_relative '../core/buffer/cruby'
@@ -26,7 +26,15 @@ module Datadog
26
26
  o.lazy
27
27
  end
28
28
 
29
- option :cache_service, default: Ext::SERVICE_CACHE
29
+ option :cache_service do |o|
30
+ o.default do
31
+ Contrib::SpanAttributeSchema.fetch_service_name(
32
+ '',
33
+ Ext::SERVICE_CACHE
34
+ )
35
+ end
36
+ o.lazy
37
+ end
30
38
  end
31
39
  end
32
40
  end
@@ -18,7 +18,17 @@ module Datadog
18
18
  TAG_OPERATION = 'aws.operation'.freeze
19
19
  TAG_OPERATION_COMMAND = 'command'.freeze
20
20
  TAG_PATH = 'path'.freeze
21
- TAG_REGION = 'aws.region'.freeze
21
+ TAG_AWS_REGION = 'aws.region'.freeze
22
+ TAG_REGION = 'region'.freeze
23
+ TAG_AWS_SERVICE = 'aws_service'.freeze
24
+ TAG_AWS_ACCOUNT = 'aws_account'.freeze
25
+ TAG_QUEUE_NAME = 'queuename'.freeze
26
+ TAG_TOPIC_NAME = 'topicname'.freeze
27
+ TAG_TABLE_NAME = 'tablename'.freeze
28
+ TAG_STREAM_NAME = 'streamname'.freeze
29
+ TAG_RULE_NAME = 'rulename'.freeze
30
+ TAG_STATE_MACHINE_NAME = 'statemachinename'.freeze
31
+ TAG_BUCKET_NAME = 'bucketname'.freeze
22
32
  end
23
33
  end
24
34
  end
@@ -33,6 +33,12 @@ module Datadog
33
33
  span.span_type = Tracing::Metadata::Ext::HTTP::TYPE_OUTBOUND
34
34
  span.name = Ext::SPAN_COMMAND
35
35
  span.resource = context.safely(:resource)
36
+ aws_service = span.resource.split('.')[0]
37
+ span.set_tag(Ext::TAG_AWS_SERVICE, aws_service)
38
+ params = context.safely(:params)
39
+ if (handler = Datadog::Tracing::Contrib::Aws::SERVICE_HANDLERS[aws_service])
40
+ handler.add_tags(span, params)
41
+ end
36
42
 
37
43
  span.set_tag(Tracing::Metadata::Ext::TAG_KIND, Tracing::Metadata::Ext::SpanKind::TAG_CLIENT)
38
44
 
@@ -55,6 +61,7 @@ module Datadog
55
61
  span.set_tag(Ext::TAG_AGENT, Ext::TAG_DEFAULT_AGENT)
56
62
  span.set_tag(Ext::TAG_OPERATION, context.safely(:operation))
57
63
  span.set_tag(Ext::TAG_REGION, context.safely(:region))
64
+ span.set_tag(Ext::TAG_AWS_REGION, context.safely(:region))
58
65
  span.set_tag(Ext::TAG_PATH, context.safely(:path))
59
66
  span.set_tag(Ext::TAG_HOST, context.safely(:host))
60
67
  span.set_tag(Tracing::Metadata::Ext::HTTP::TAG_METHOD, context.safely(:http_method))
@@ -20,6 +20,10 @@ module Datadog
20
20
  context.operation_name
21
21
  end
22
22
 
23
+ def params
24
+ context.params
25
+ end
26
+
23
27
  def status_code
24
28
  context.http_response.status_code
25
29
  end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Datadog
4
+ module Tracing
5
+ module Contrib
6
+ module Aws
7
+ module Service
8
+ # Base class for all AWS service-specific tag handlers.
9
+ class Base
10
+ def add_tags(span, params); end
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative './base'
4
+ require_relative '../ext'
5
+
6
+ module Datadog
7
+ module Tracing
8
+ module Contrib
9
+ module Aws
10
+ module Service
11
+ # DynamoDB tag handlers.
12
+ class DynamoDB < Base
13
+ def add_tags(span, params)
14
+ table_name = params[:table_name]
15
+ span.set_tag(Aws::Ext::TAG_TABLE_NAME, table_name)
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative './base'
4
+ require_relative '../ext'
5
+
6
+ module Datadog
7
+ module Tracing
8
+ module Contrib
9
+ module Aws
10
+ module Service
11
+ # EventBridge tag handlers.
12
+ class EventBridge < Base
13
+ def add_tags(span, params)
14
+ rule_name = params[:name] || params[:rule]
15
+ span.set_tag(Aws::Ext::TAG_RULE_NAME, rule_name)
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative './base'
4
+ require_relative '../ext'
5
+
6
+ module Datadog
7
+ module Tracing
8
+ module Contrib
9
+ module Aws
10
+ module Service
11
+ # Kinesis tag handlers.
12
+ class Kinesis < Base
13
+ def add_tags(span, params)
14
+ stream_arn = params[:stream_arn]
15
+ stream_name = params[:stream_name]
16
+
17
+ if stream_arn
18
+ # example stream_arn: arn:aws:kinesis:us-east-1:123456789012:stream/my-stream
19
+ parts = stream_arn.split(':')
20
+ stream_name = parts[-1].split('/')[-1]
21
+ aws_account = parts[-2]
22
+ span.set_tag(Aws::Ext::TAG_AWS_ACCOUNT, aws_account)
23
+ end
24
+
25
+ span.set_tag(Aws::Ext::TAG_STREAM_NAME, stream_name)
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative './base'
4
+ require_relative '../ext'
5
+
6
+ module Datadog
7
+ module Tracing
8
+ module Contrib
9
+ module Aws
10
+ module Service
11
+ # S3 tag handlers.
12
+ class S3 < Base
13
+ def add_tags(span, params)
14
+ bucket_name = params[:bucket]
15
+ span.set_tag(Aws::Ext::TAG_BUCKET_NAME, bucket_name)
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative './base'
4
+ require_relative '../ext'
5
+
6
+ module Datadog
7
+ module Tracing
8
+ module Contrib
9
+ module Aws
10
+ module Service
11
+ # SNS tag handlers.
12
+ class SNS < Base
13
+ def add_tags(span, params)
14
+ topic_arn = params[:topic_arn]
15
+ topic_name = params[:name]
16
+ if topic_arn
17
+ # example topic_arn: arn:aws:sns:us-west-2:123456789012:my-topic-name
18
+ parts = topic_arn.split(':')
19
+ topic_name = parts[-1]
20
+ aws_account = parts[-2]
21
+ span.set_tag(Aws::Ext::TAG_AWS_ACCOUNT, aws_account)
22
+ end
23
+ span.set_tag(Aws::Ext::TAG_TOPIC_NAME, topic_name)
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative './base'
4
+ require_relative '../ext'
5
+
6
+ module Datadog
7
+ module Tracing
8
+ module Contrib
9
+ module Aws
10
+ module Service
11
+ # SQS tag handlers.
12
+ class SQS < Base
13
+ def add_tags(span, params)
14
+ queue_url = params[:queue_url]
15
+ queue_name = params[:queue_name]
16
+ if queue_url
17
+ _, _, _, aws_account, queue_name = queue_url.split('/')
18
+ span.set_tag(Aws::Ext::TAG_AWS_ACCOUNT, aws_account)
19
+ end
20
+ span.set_tag(Aws::Ext::TAG_QUEUE_NAME, queue_name)
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative './base'
4
+ require_relative '../ext'
5
+
6
+ module Datadog
7
+ module Tracing
8
+ module Contrib
9
+ module Aws
10
+ module Service
11
+ # States tag handlers.
12
+ class States < Base
13
+ def add_tags(span, params)
14
+ state_machine_name = params[:name]
15
+ state_machine_arn = params[:state_machine_arn]
16
+ execution_arn = params[:execution_arn]
17
+ state_machine_account_id = ''
18
+
19
+ if execution_arn
20
+ # 'arn:aws:states:us-east-1:123456789012:execution:example-state-machine:example-execution'
21
+ parts = execution_arn.split(':')
22
+ state_machine_name = parts[-2]
23
+ state_machine_account_id = parts[4]
24
+ end
25
+
26
+ if state_machine_arn
27
+ # example statemachinearn: arn:aws:states:us-east-1:123456789012:stateMachine:MyStateMachine
28
+ parts = state_machine_arn.split(':')
29
+ state_machine_name ||= parts[-1]
30
+ state_machine_account_id = parts[-3]
31
+ end
32
+ span.set_tag(Aws::Ext::TAG_AWS_ACCOUNT, state_machine_account_id)
33
+ span.set_tag(Aws::Ext::TAG_STATE_MACHINE_NAME, state_machine_name)
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end