datadog 2.3.0 → 2.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (173) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +64 -2
  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/NativeExtensionDesign.md +3 -3
  6. data/ext/datadog_profiling_native_extension/collectors_cpu_and_wall_time_worker.c +198 -41
  7. data/ext/datadog_profiling_native_extension/collectors_discrete_dynamic_sampler.c +4 -2
  8. data/ext/datadog_profiling_native_extension/collectors_stack.c +89 -46
  9. data/ext/datadog_profiling_native_extension/collectors_thread_context.c +645 -107
  10. data/ext/datadog_profiling_native_extension/collectors_thread_context.h +15 -1
  11. data/ext/datadog_profiling_native_extension/datadog_ruby_common.c +0 -27
  12. data/ext/datadog_profiling_native_extension/datadog_ruby_common.h +0 -4
  13. data/ext/datadog_profiling_native_extension/extconf.rb +42 -25
  14. data/ext/datadog_profiling_native_extension/gvl_profiling_helper.c +50 -0
  15. data/ext/datadog_profiling_native_extension/gvl_profiling_helper.h +75 -0
  16. data/ext/datadog_profiling_native_extension/heap_recorder.c +194 -34
  17. data/ext/datadog_profiling_native_extension/heap_recorder.h +11 -0
  18. data/ext/datadog_profiling_native_extension/http_transport.c +38 -6
  19. data/ext/datadog_profiling_native_extension/native_extension_helpers.rb +1 -1
  20. data/ext/datadog_profiling_native_extension/private_vm_api_access.c +53 -2
  21. data/ext/datadog_profiling_native_extension/private_vm_api_access.h +3 -0
  22. data/ext/datadog_profiling_native_extension/profiling.c +1 -1
  23. data/ext/datadog_profiling_native_extension/ruby_helpers.c +14 -11
  24. data/ext/datadog_profiling_native_extension/stack_recorder.c +58 -22
  25. data/ext/datadog_profiling_native_extension/stack_recorder.h +2 -0
  26. data/ext/libdatadog_api/crashtracker.c +20 -18
  27. data/ext/libdatadog_api/datadog_ruby_common.c +0 -27
  28. data/ext/libdatadog_api/datadog_ruby_common.h +0 -4
  29. data/ext/libdatadog_extconf_helpers.rb +1 -1
  30. data/lib/datadog/appsec/assets/waf_rules/recommended.json +2184 -108
  31. data/lib/datadog/appsec/assets/waf_rules/strict.json +1430 -2
  32. data/lib/datadog/appsec/component.rb +29 -8
  33. data/lib/datadog/appsec/configuration/settings.rb +10 -2
  34. data/lib/datadog/appsec/contrib/devise/patcher/authenticatable_patch.rb +1 -0
  35. data/lib/datadog/appsec/contrib/devise/patcher/rememberable_patch.rb +21 -0
  36. data/lib/datadog/appsec/contrib/devise/patcher.rb +12 -2
  37. data/lib/datadog/appsec/contrib/graphql/appsec_trace.rb +0 -14
  38. data/lib/datadog/appsec/contrib/graphql/gateway/multiplex.rb +67 -31
  39. data/lib/datadog/appsec/contrib/graphql/gateway/watcher.rb +14 -15
  40. data/lib/datadog/appsec/contrib/graphql/integration.rb +14 -1
  41. data/lib/datadog/appsec/contrib/graphql/reactive/multiplex.rb +7 -20
  42. data/lib/datadog/appsec/contrib/rack/gateway/request.rb +2 -5
  43. data/lib/datadog/appsec/contrib/rack/gateway/watcher.rb +9 -15
  44. data/lib/datadog/appsec/contrib/rack/reactive/request.rb +6 -18
  45. data/lib/datadog/appsec/contrib/rack/reactive/request_body.rb +7 -20
  46. data/lib/datadog/appsec/contrib/rack/reactive/response.rb +5 -18
  47. data/lib/datadog/appsec/contrib/rack/request_middleware.rb +3 -1
  48. data/lib/datadog/appsec/contrib/rails/gateway/watcher.rb +3 -5
  49. data/lib/datadog/appsec/contrib/rails/reactive/action.rb +5 -18
  50. data/lib/datadog/appsec/contrib/sinatra/gateway/watcher.rb +6 -10
  51. data/lib/datadog/appsec/contrib/sinatra/reactive/routed.rb +7 -20
  52. data/lib/datadog/appsec/event.rb +25 -1
  53. data/lib/datadog/appsec/ext.rb +4 -0
  54. data/lib/datadog/appsec/monitor/gateway/watcher.rb +3 -5
  55. data/lib/datadog/appsec/monitor/reactive/set_user.rb +7 -20
  56. data/lib/datadog/appsec/processor/context.rb +109 -0
  57. data/lib/datadog/appsec/processor/rule_loader.rb +3 -1
  58. data/lib/datadog/appsec/processor/rule_merger.rb +33 -15
  59. data/lib/datadog/appsec/processor.rb +42 -107
  60. data/lib/datadog/appsec/rate_limiter.rb +25 -40
  61. data/lib/datadog/appsec/remote.rb +7 -3
  62. data/lib/datadog/appsec/scope.rb +1 -4
  63. data/lib/datadog/appsec/utils/trace_operation.rb +15 -0
  64. data/lib/datadog/appsec/utils.rb +2 -0
  65. data/lib/datadog/appsec.rb +3 -2
  66. data/lib/datadog/core/configuration/agent_settings_resolver.rb +26 -25
  67. data/lib/datadog/core/configuration/components.rb +4 -3
  68. data/lib/datadog/core/configuration/settings.rb +96 -5
  69. data/lib/datadog/core/configuration.rb +1 -3
  70. data/lib/datadog/core/crashtracking/component.rb +9 -6
  71. data/lib/datadog/core/environment/execution.rb +5 -5
  72. data/lib/datadog/core/environment/yjit.rb +5 -0
  73. data/lib/datadog/core/metrics/client.rb +7 -0
  74. data/lib/datadog/core/rate_limiter.rb +183 -0
  75. data/lib/datadog/core/remote/client/capabilities.rb +4 -3
  76. data/lib/datadog/core/remote/component.rb +4 -2
  77. data/lib/datadog/core/remote/negotiation.rb +4 -4
  78. data/lib/datadog/core/remote/tie.rb +2 -0
  79. data/lib/datadog/core/remote/transport/http.rb +5 -0
  80. data/lib/datadog/core/remote/worker.rb +1 -1
  81. data/lib/datadog/core/runtime/ext.rb +1 -0
  82. data/lib/datadog/core/runtime/metrics.rb +5 -1
  83. data/lib/datadog/core/semaphore.rb +35 -0
  84. data/lib/datadog/core/telemetry/component.rb +2 -0
  85. data/lib/datadog/core/telemetry/event.rb +12 -7
  86. data/lib/datadog/core/telemetry/logger.rb +51 -0
  87. data/lib/datadog/core/telemetry/logging.rb +50 -14
  88. data/lib/datadog/core/telemetry/request.rb +13 -1
  89. data/lib/datadog/core/transport/ext.rb +1 -0
  90. data/lib/datadog/core/utils/time.rb +12 -0
  91. data/lib/datadog/core/workers/async.rb +1 -1
  92. data/lib/datadog/di/code_tracker.rb +166 -0
  93. data/lib/datadog/di/configuration/settings.rb +163 -0
  94. data/lib/datadog/di/configuration.rb +11 -0
  95. data/lib/datadog/di/error.rb +31 -0
  96. data/lib/datadog/di/extensions.rb +16 -0
  97. data/lib/datadog/di/instrumenter.rb +301 -0
  98. data/lib/datadog/di/probe.rb +162 -0
  99. data/lib/datadog/di/probe_builder.rb +47 -0
  100. data/lib/datadog/di/probe_notification_builder.rb +207 -0
  101. data/lib/datadog/di/probe_notifier_worker.rb +244 -0
  102. data/lib/datadog/di/redactor.rb +188 -0
  103. data/lib/datadog/di/serializer.rb +215 -0
  104. data/lib/datadog/di/transport.rb +67 -0
  105. data/lib/datadog/di/utils.rb +39 -0
  106. data/lib/datadog/di.rb +57 -0
  107. data/lib/datadog/opentelemetry/sdk/propagator.rb +2 -0
  108. data/lib/datadog/profiling/collectors/cpu_and_wall_time_worker.rb +12 -10
  109. data/lib/datadog/profiling/collectors/info.rb +12 -3
  110. data/lib/datadog/profiling/collectors/thread_context.rb +32 -8
  111. data/lib/datadog/profiling/component.rb +21 -4
  112. data/lib/datadog/profiling/http_transport.rb +6 -1
  113. data/lib/datadog/profiling/scheduler.rb +2 -0
  114. data/lib/datadog/profiling/stack_recorder.rb +40 -9
  115. data/lib/datadog/single_step_instrument.rb +12 -0
  116. data/lib/datadog/tracing/component.rb +13 -0
  117. data/lib/datadog/tracing/contrib/action_cable/instrumentation.rb +8 -12
  118. data/lib/datadog/tracing/contrib/action_pack/action_controller/instrumentation.rb +5 -0
  119. data/lib/datadog/tracing/contrib/action_pack/action_dispatch/instrumentation.rb +78 -0
  120. data/lib/datadog/tracing/contrib/action_pack/action_dispatch/patcher.rb +33 -0
  121. data/lib/datadog/tracing/contrib/action_pack/patcher.rb +2 -0
  122. data/lib/datadog/tracing/contrib/active_record/configuration/resolver.rb +4 -0
  123. data/lib/datadog/tracing/contrib/active_record/events/instantiation.rb +3 -1
  124. data/lib/datadog/tracing/contrib/active_record/events/sql.rb +3 -1
  125. data/lib/datadog/tracing/contrib/active_support/cache/events/cache.rb +5 -1
  126. data/lib/datadog/tracing/contrib/aws/instrumentation.rb +5 -0
  127. data/lib/datadog/tracing/contrib/elasticsearch/patcher.rb +6 -1
  128. data/lib/datadog/tracing/contrib/ethon/easy_patch.rb +4 -0
  129. data/lib/datadog/tracing/contrib/excon/middleware.rb +3 -0
  130. data/lib/datadog/tracing/contrib/faraday/middleware.rb +12 -0
  131. data/lib/datadog/tracing/contrib/grape/endpoint.rb +24 -2
  132. data/lib/datadog/tracing/contrib/graphql/patcher.rb +9 -12
  133. data/lib/datadog/tracing/contrib/graphql/trace_patcher.rb +3 -3
  134. data/lib/datadog/tracing/contrib/graphql/tracing_patcher.rb +3 -3
  135. data/lib/datadog/tracing/contrib/graphql/unified_trace.rb +13 -9
  136. data/lib/datadog/tracing/contrib/graphql/unified_trace_patcher.rb +6 -3
  137. data/lib/datadog/tracing/contrib/http/circuit_breaker.rb +9 -0
  138. data/lib/datadog/tracing/contrib/http/instrumentation.rb +22 -15
  139. data/lib/datadog/tracing/contrib/httpclient/instrumentation.rb +10 -5
  140. data/lib/datadog/tracing/contrib/httpclient/patcher.rb +1 -14
  141. data/lib/datadog/tracing/contrib/httprb/instrumentation.rb +9 -0
  142. data/lib/datadog/tracing/contrib/httprb/patcher.rb +1 -14
  143. data/lib/datadog/tracing/contrib/lograge/patcher.rb +1 -2
  144. data/lib/datadog/tracing/contrib/mongodb/subscribers.rb +2 -0
  145. data/lib/datadog/tracing/contrib/opensearch/patcher.rb +13 -6
  146. data/lib/datadog/tracing/contrib/patcher.rb +2 -1
  147. data/lib/datadog/tracing/contrib/presto/patcher.rb +1 -13
  148. data/lib/datadog/tracing/contrib/rack/middlewares.rb +27 -0
  149. data/lib/datadog/tracing/contrib/rails/runner.rb +1 -1
  150. data/lib/datadog/tracing/contrib/redis/tags.rb +4 -0
  151. data/lib/datadog/tracing/contrib/rest_client/request_patch.rb +3 -0
  152. data/lib/datadog/tracing/contrib/sinatra/tracer.rb +4 -0
  153. data/lib/datadog/tracing/contrib/stripe/request.rb +3 -2
  154. data/lib/datadog/tracing/distributed/propagation.rb +7 -0
  155. data/lib/datadog/tracing/metadata/ext.rb +2 -0
  156. data/lib/datadog/tracing/remote.rb +5 -2
  157. data/lib/datadog/tracing/sampling/matcher.rb +6 -1
  158. data/lib/datadog/tracing/sampling/rate_sampler.rb +1 -1
  159. data/lib/datadog/tracing/sampling/rule.rb +2 -0
  160. data/lib/datadog/tracing/sampling/rule_sampler.rb +15 -9
  161. data/lib/datadog/tracing/sampling/span/ext.rb +1 -1
  162. data/lib/datadog/tracing/sampling/span/rule.rb +2 -2
  163. data/lib/datadog/tracing/trace_operation.rb +26 -2
  164. data/lib/datadog/tracing/tracer.rb +29 -22
  165. data/lib/datadog/tracing/transport/http/client.rb +1 -0
  166. data/lib/datadog/tracing/transport/http.rb +4 -0
  167. data/lib/datadog/tracing/transport/io/client.rb +1 -0
  168. data/lib/datadog/tracing/workers/trace_writer.rb +1 -1
  169. data/lib/datadog/tracing/workers.rb +2 -2
  170. data/lib/datadog/tracing/writer.rb +26 -28
  171. data/lib/datadog/version.rb +1 -1
  172. metadata +40 -15
  173. data/lib/datadog/tracing/sampling/rate_limiter.rb +0 -185
@@ -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
@@ -248,8 +267,11 @@ module Datadog
248
267
  route_path = endpoint.options[:path]
249
268
  namespace = endpoint.routes.first && endpoint.routes.first.namespace || ''
250
269
 
251
- parts = (namespace.split('/') + route_path).reject { |p| p.blank? || p.eql?('/') }
252
- parts.join('/').prepend('/')
270
+ path = (namespace.split('/') + route_path)
271
+ .reject { |p| p.blank? || p.eql?('/') }
272
+ .join('/')
273
+ path.prepend('/') if path[0] != '/'
274
+ path
253
275
  end
254
276
 
255
277
  def service_name
@@ -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
@@ -8,13 +8,13 @@ module Datadog
8
8
  module TracingPatcher
9
9
  module_function
10
10
 
11
- def patch!(schemas, options)
11
+ def patch!(schemas)
12
12
  if schemas.empty?
13
- ::GraphQL::Schema.tracer(::GraphQL::Tracing::DataDogTracing.new(**options))
13
+ ::GraphQL::Schema.tracer(::GraphQL::Tracing::DataDogTracing.new)
14
14
  else
15
15
  schemas.each do |schema|
16
16
  if schema.respond_to? :use
17
- schema.use(::GraphQL::Tracing::DataDogTracing, **options)
17
+ schema.use(::GraphQL::Tracing::DataDogTracing)
18
18
  else
19
19
  Datadog.logger.warn("Unable to patch #{schema}: Please migrate to class-based schema.")
20
20
  end
@@ -11,14 +11,7 @@ module Datadog
11
11
  # which is required to use features such as API Catalog.
12
12
  # DEV-3.0: This tracer should be the default one in the next major version.
13
13
  module UnifiedTrace
14
- # @param analytics_enabled [Boolean] Deprecated
15
- # @param analytics_sample_rate [Float] Deprecated
16
- # @param service [String|nil] The service name to be set on the spans
17
- def initialize(*args, analytics_enabled: false, analytics_sample_rate: 1.0, service: nil, **kwargs)
18
- @analytics_enabled = analytics_enabled
19
- @analytics_sample_rate = analytics_sample_rate
20
-
21
- @service_name = service
14
+ def initialize(*args, **kwargs)
22
15
  @has_prepare_span = respond_to?(:prepare_span)
23
16
  super
24
17
  end
@@ -139,7 +132,18 @@ module Datadog
139
132
  private
140
133
 
141
134
  def trace(callable, trace_key, resource, **kwargs)
142
- Tracing.trace("graphql.#{trace_key}", resource: resource, service: @service_name, type: 'graphql') do |span|
135
+ config = Datadog.configuration.tracing[:graphql]
136
+
137
+ Tracing.trace(
138
+ "graphql.#{trace_key}",
139
+ type: 'graphql',
140
+ resource: resource,
141
+ service: config[:service_name]
142
+ ) do |span|
143
+ if Contrib::Analytics.enabled?(config[:analytics_enabled])
144
+ Contrib::Analytics.set_sample_rate(span, config[:analytics_sample_rate])
145
+ end
146
+
143
147
  yield(span) if block_given?
144
148
 
145
149
  prepare_span(trace_key, kwargs, span) if @has_prepare_span
@@ -12,12 +12,15 @@ module Datadog
12
12
  module UnifiedTracePatcher
13
13
  module_function
14
14
 
15
- def patch!(schemas, options)
15
+ # TODO: `GraphQL::Schema.trace_with` and `YOUR_SCHEMA.trace_with` don't mix.
16
+ # TODO: They create duplicate spans when combined.
17
+ # TODO: We should measure how frequently users use `YOUR_SCHEMA.trace_with`, and hopefully we can remove it.
18
+ def patch!(schemas)
16
19
  if schemas.empty?
17
- ::GraphQL::Schema.trace_with(UnifiedTrace, **options)
20
+ ::GraphQL::Schema.trace_with(UnifiedTrace)
18
21
  else
19
22
  schemas.each do |schema|
20
- schema.trace_with(UnifiedTrace, **options)
23
+ schema.trace_with(UnifiedTrace)
21
24
  end
22
25
  end
23
26
  end
@@ -29,6 +29,15 @@ module Datadog
29
29
  end
30
30
 
31
31
  def should_skip_distributed_tracing?(client_config)
32
+ if Datadog.configuration.appsec.standalone.enabled
33
+ # Skip distributed tracing so that we don't bill distributed traces in case of absence of
34
+ # upstream ASM event (_dd.p.appsec:1) and no local security event (which sets _dd.p.appsec:1 locally).
35
+ # If there is an ASM event, we still have to check if distributed tracing is enabled or not
36
+ return true unless Tracing.active_trace
37
+
38
+ return true if Tracing.active_trace.get_tag(Datadog::AppSec::Ext::TAG_DISTRIBUTED_APPSEC_EVENT) != '1'
39
+ end
40
+
32
41
  return !client_config[:distributed_tracing] if client_config && client_config.key?(:distributed_tracing)
33
42
 
34
43
  !Datadog.configuration.tracing[:http][:distributed_tracing]
@@ -6,6 +6,7 @@ require_relative '../../metadata/ext'
6
6
  require_relative '../analytics'
7
7
  require_relative '../http_annotation_helper'
8
8
  require_relative '../utils/quantization/http'
9
+ require_relative '../../../core/telemetry/logger'
9
10
 
10
11
  module Datadog
11
12
  module Tracing
@@ -30,23 +31,23 @@ module Datadog
30
31
  return super(req, body, &block) if Contrib::HTTP.should_skip_tracing?(req)
31
32
 
32
33
  Tracing.trace(Ext::SPAN_REQUEST, on_error: method(:annotate_span_with_error!)) do |span, trace|
33
- begin
34
- span.service = service_name(host, request_options, client_config)
35
- span.type = Tracing::Metadata::Ext::HTTP::TYPE_OUTBOUND
36
- span.resource = req.method
37
-
38
- if Tracing.enabled? && !Contrib::HTTP.should_skip_distributed_tracing?(client_config)
39
- Contrib::HTTP.inject(trace, req)
40
- end
41
-
42
- # Add additional request specific tags to the span.
43
- annotate_span_with_request!(span, req, request_options)
44
- rescue StandardError => e
45
- Datadog.logger.error("error preparing span for http request: #{e}")
46
- ensure
47
- response = super(req, body, &block)
34
+ span.service = service_name(host, request_options, client_config)
35
+ span.type = Tracing::Metadata::Ext::HTTP::TYPE_OUTBOUND
36
+ span.resource = req.method
37
+
38
+ if Datadog::AppSec::Utils::TraceOperation.appsec_standalone_reject?(trace)
39
+ trace.sampling_priority = Tracing::Sampling::Ext::Priority::AUTO_REJECT
40
+ end
41
+
42
+ if Tracing.enabled? && !Contrib::HTTP.should_skip_distributed_tracing?(client_config)
43
+ Contrib::HTTP.inject(trace, req)
48
44
  end
49
45
 
46
+ # Add additional request specific tags to the span.
47
+ annotate_span_with_request!(span, req, request_options)
48
+
49
+ response = super(req, body, &block)
50
+
50
51
  # Add additional response specific tags to the span.
51
52
  annotate_span_with_response!(span, response, request_options)
52
53
 
@@ -91,6 +92,9 @@ module Datadog
91
92
  )
92
93
 
93
94
  Contrib::SpanAttributeSchema.set_peer_service!(span, Ext::PEER_SERVICE_SOURCES)
95
+ rescue StandardError => e
96
+ Datadog.logger.error("error preparing span from http request: #{e}")
97
+ Datadog::Core::Telemetry::Logger.report(e)
94
98
  end
95
99
 
96
100
  def annotate_span_with_response!(span, response, request_options)
@@ -103,6 +107,9 @@ module Datadog
103
107
  span.set_tags(
104
108
  Datadog.configuration.tracing.header_tags.response_tags(response)
105
109
  )
110
+ rescue StandardError => e
111
+ Datadog.logger.error("error preparing span from http response: #{e}")
112
+ Datadog::Core::Telemetry::Logger.report(e)
106
113
  end
107
114
 
108
115
  def annotate_span_with_error!(span, error)
@@ -4,6 +4,7 @@ require_relative '../../metadata/ext'
4
4
  require_relative '../http'
5
5
  require_relative '../analytics'
6
6
  require_relative '../http_annotation_helper'
7
+ require_relative '../../../core/telemetry/logger'
7
8
 
8
9
  module Datadog
9
10
  module Tracing
@@ -29,6 +30,10 @@ module Datadog
29
30
  span.service = service_name(host, request_options, client_config)
30
31
  span.type = Tracing::Metadata::Ext::HTTP::TYPE_OUTBOUND
31
32
 
33
+ if Datadog::AppSec::Utils::TraceOperation.appsec_standalone_reject?(trace)
34
+ trace.sampling_priority = Tracing::Sampling::Ext::Priority::AUTO_REJECT
35
+ end
36
+
32
37
  if Tracing.enabled? && !should_skip_distributed_tracing?(client_config)
33
38
  Contrib::HTTP.inject(trace, req.header)
34
39
  end
@@ -36,7 +41,8 @@ module Datadog
36
41
  # Add additional request specific tags to the span.
37
42
  annotate_span_with_request!(span, req, request_options)
38
43
  rescue StandardError => e
39
- logger.error("error preparing span for httpclient request: #{e}, Source: #{e.backtrace}")
44
+ Datadog.logger.error("error preparing span for httpclient request: #{e}, Source: #{e.backtrace}")
45
+ Datadog::Core::Telemetry::Logger.report(e)
40
46
  ensure
41
47
  res = super
42
48
  end
@@ -100,6 +106,9 @@ module Datadog
100
106
  span.set_tags(
101
107
  Datadog.configuration.tracing.header_tags.response_tags(response.header)
102
108
  )
109
+ rescue StandardError => e
110
+ Datadog.logger.error("error preparing span from httpclient response: #{e}, Source: #{e.backtrace}")
111
+ Datadog::Core::Telemetry::Logger.report(e)
103
112
  end
104
113
 
105
114
  def annotate_span_with_error!(span, error)
@@ -114,10 +123,6 @@ module Datadog
114
123
  Contrib::Analytics.enabled?(request_options[:analytics_enabled])
115
124
  end
116
125
 
117
- def logger
118
- Datadog.logger
119
- end
120
-
121
126
  def should_skip_distributed_tracing?(client_config)
122
127
  return !client_config[:distributed_tracing] if client_config && client_config.key?(:distributed_tracing)
123
128
 
@@ -13,27 +13,14 @@ module Datadog
13
13
  module Patcher
14
14
  include Contrib::Patcher
15
15
 
16
- PATCH_ONLY_ONCE = Core::Utils::OnlyOnce.new
17
-
18
16
  module_function
19
17
 
20
- def patched?
21
- PATCH_ONLY_ONCE.ran?
22
- end
23
-
24
18
  def target_version
25
19
  Integration.version
26
20
  end
27
21
 
28
- # patch applies our patch
29
22
  def patch
30
- PATCH_ONLY_ONCE.run do
31
- begin
32
- ::HTTPClient.include(Instrumentation)
33
- rescue StandardError => e
34
- Datadog.logger.error("Unable to apply httpclient integration: #{e}")
35
- end
36
- end
23
+ ::HTTPClient.include(Instrumentation)
37
24
  end
38
25
  end
39
26
  end
@@ -4,6 +4,7 @@ require_relative '../../metadata/ext'
4
4
  require_relative '../http'
5
5
  require_relative '../analytics'
6
6
  require_relative '../http_annotation_helper'
7
+ require_relative '../../../core/telemetry/logger'
7
8
 
8
9
  module Datadog
9
10
  module Tracing
@@ -29,12 +30,17 @@ module Datadog
29
30
  span.service = service_name(host, request_options, client_config)
30
31
  span.type = Tracing::Metadata::Ext::HTTP::TYPE_OUTBOUND
31
32
 
33
+ if Datadog::AppSec::Utils::TraceOperation.appsec_standalone_reject?(trace)
34
+ trace.sampling_priority = Tracing::Sampling::Ext::Priority::AUTO_REJECT
35
+ end
36
+
32
37
  Contrib::HTTP.inject(trace, req) if Tracing.enabled? && !should_skip_distributed_tracing?(client_config)
33
38
 
34
39
  # Add additional request specific tags to the span.
35
40
  annotate_span_with_request!(span, req, request_options)
36
41
  rescue StandardError => e
37
42
  logger.error("error preparing span for http.rb request: #{e}, Source: #{e.backtrace}")
43
+ Datadog::Core::Telemetry::Logger.report(e)
38
44
  ensure
39
45
  res = super(req, options)
40
46
  end
@@ -108,6 +114,9 @@ module Datadog
108
114
  span.set_tags(
109
115
  Datadog.configuration.tracing.header_tags.response_tags(response.headers)
110
116
  )
117
+ rescue StandardError => e
118
+ logger.error("error preparing span from http.rb response: #{e}, Source: #{e.backtrace}")
119
+ Datadog::Core::Telemetry::Logger.report(e)
111
120
  end
112
121
 
113
122
  def annotate_span_with_error!(span, error)
@@ -13,27 +13,14 @@ module Datadog
13
13
  module Patcher
14
14
  include Contrib::Patcher
15
15
 
16
- PATCH_ONLY_ONCE = Core::Utils::OnlyOnce.new
17
-
18
16
  module_function
19
17
 
20
- def patched?
21
- PATCH_ONLY_ONCE.ran?
22
- end
23
-
24
18
  def target_version
25
19
  Integration.version
26
20
  end
27
21
 
28
- # patch applies our patch
29
22
  def patch
30
- PATCH_ONLY_ONCE.run do
31
- begin
32
- ::HTTP::Client.include(Instrumentation)
33
- rescue StandardError => e
34
- Datadog.logger.error("Unable to apply httprb integration: #{e}")
35
- end
36
- end
23
+ ::HTTP::Client.include(Instrumentation)
37
24
  end
38
25
  end
39
26
  end
@@ -24,8 +24,7 @@ module Datadog
24
24
  if defined?(::ActiveSupport::TaggedLogging::Formatter) &&
25
25
  ::Lograge::LogSubscribers::ActionController
26
26
  .logger&.formatter.is_a?(::ActiveSupport::TaggedLogging::Formatter)
27
-
28
- Datadog.logger.error(
27
+ Datadog.logger.warn(
29
28
  'Lograge and ActiveSupport::TaggedLogging (the default Rails log formatter) are not compatible: ' \
30
29
  'Lograge does not account for Rails log tags, creating polluted logs and breaking log formatting. ' \
31
30
  'Traces and Logs correlation may not work. ' \
@@ -70,6 +70,8 @@ module Datadog
70
70
 
71
71
  # set the resource with the quantized query
72
72
  span.resource = serialized_query
73
+ rescue StandardError => e
74
+ Datadog.logger.debug("error when handling MongoDB 'started' event: #{e}")
73
75
  end
74
76
  # rubocop:enable Metrics/AbcSize
75
77
 
@@ -6,6 +6,7 @@ require_relative 'ext'
6
6
  require_relative '../ext'
7
7
  require_relative '../integration'
8
8
  require_relative '../patcher'
9
+ require_relative '../../../core/telemetry/logger'
9
10
 
10
11
  module Datadog
11
12
  module Tracing
@@ -81,6 +82,8 @@ module Datadog
81
82
  Contrib::SpanAttributeSchema.set_peer_service!(span, Ext::PEER_SERVICE_SOURCES)
82
83
  rescue StandardError => e
83
84
  Datadog.logger.error(e.message)
85
+ Datadog::Core::Telemetry::Logger.report(e)
86
+ # TODO: Refactor the code to streamline the execution without ensure
84
87
  ensure
85
88
  begin
86
89
  response = super
@@ -90,12 +93,16 @@ module Datadog
90
93
  raise
91
94
  end
92
95
  # Set post-response tags
93
- span.set_tag(Tracing::Metadata::Ext::HTTP::TAG_STATUS_CODE, response.status)
94
- if response.headers['content-length']
95
- span.set_tag(
96
- OpenSearch::Ext::TAG_RESPONSE_CONTENT_LENGTH,
97
- response.headers['content-length'].to_i
98
- )
96
+ if response
97
+ if response.respond_to?(:status)
98
+ span.set_tag(Tracing::Metadata::Ext::HTTP::TAG_STATUS_CODE, response.status)
99
+ end
100
+ if response.respond_to?(:headers) && (response.headers || {})['content-length']
101
+ span.set_tag(
102
+ OpenSearch::Ext::TAG_RESPONSE_CONTENT_LENGTH,
103
+ response.headers['content-length'].to_i
104
+ )
105
+ end
99
106
  end
100
107
  end
101
108
  end
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative '../../core/utils/only_once'
4
+ require_relative '../../core/telemetry/logger'
4
5
 
5
6
  module Datadog
6
7
  module Tracing
@@ -49,8 +50,8 @@ module Datadog
49
50
  # Processes patching errors. This default implementation logs the error and reports relevant metrics.
50
51
  # @param e [Exception]
51
52
  def on_patch_error(e)
52
- # Log the error
53
53
  Datadog.logger.error("Failed to apply #{patch_name} patch. Cause: #{e} Location: #{Array(e.backtrace).first}")
54
+ Datadog::Core::Telemetry::Logger.report(e, description: "Failed to apply #{patch_name} patch")
54
55
 
55
56
  @patch_error_result = {
56
57
  type: e.class.name,
@@ -13,22 +13,10 @@ module Datadog
13
13
  module Patcher
14
14
  include Contrib::Patcher
15
15
 
16
- PATCH_ONLY_ONCE = Core::Utils::OnlyOnce.new
17
-
18
16
  module_function
19
17
 
20
- def patched?
21
- PATCH_ONLY_ONCE.ran?
22
- end
23
-
24
18
  def patch
25
- PATCH_ONLY_ONCE.run do
26
- begin
27
- ::Presto::Client::Client.include(Instrumentation::Client)
28
- rescue StandardError => e
29
- Datadog.logger.error("Unable to apply Presto integration: #{e}")
30
- end
31
- end
19
+ ::Presto::Client::Client.include(Instrumentation::Client)
32
20
  end
33
21
  end
34
22
  end
@@ -138,6 +138,29 @@ module Datadog
138
138
  request_span.set_tag(Tracing::Metadata::Ext::TAG_OPERATION, Ext::TAG_OPERATION_REQUEST)
139
139
  request_span.set_tag(Tracing::Metadata::Ext::TAG_KIND, Tracing::Metadata::Ext::SpanKind::TAG_SERVER)
140
140
 
141
+ if status != 404 && (last_route = trace.get_tag(Tracing::Metadata::Ext::HTTP::TAG_ROUTE))
142
+ last_script_name = trace.get_tag(Tracing::Metadata::Ext::HTTP::TAG_ROUTE_PATH) || ''
143
+
144
+ # If the last_script_name is empty but the env['SCRIPT_NAME'] is NOT empty
145
+ # then the current rack request was not routed and must be accounted for
146
+ # which only happens in pure nested rack requests i.e /rack/rack/hello/world
147
+ #
148
+ # To account for the unaccounted nested rack requests of /rack/hello/world,
149
+ # we use 'PATH_INFO knowing that rack cannot have named parameters
150
+ if last_script_name == '' && env['SCRIPT_NAME'] && env['SCRIPT_NAME'] != ''
151
+ last_script_name = last_route
152
+ last_route = env['PATH_INFO']
153
+ end
154
+
155
+ # Clear the route and route path tags from the request trace to avoid possibility of misplacement
156
+ trace.clear_tag(Tracing::Metadata::Ext::HTTP::TAG_ROUTE)
157
+ trace.clear_tag(Tracing::Metadata::Ext::HTTP::TAG_ROUTE_PATH)
158
+
159
+ # Ensure tags are placed in rack.request span as desired
160
+ request_span.set_tag(Tracing::Metadata::Ext::HTTP::TAG_ROUTE, last_script_name + last_route)
161
+ request_span.clear_tag(Tracing::Metadata::Ext::HTTP::TAG_ROUTE_PATH)
162
+ end
163
+
141
164
  # Set analytics sample rate
142
165
  if Contrib::Analytics.enabled?(configuration[:analytics_enabled])
143
166
  Contrib::Analytics.set_sample_rate(request_span, configuration[:analytics_sample_rate])
@@ -195,6 +218,10 @@ module Datadog
195
218
  request_span.set_tag(Tracing::Metadata::Ext::HTTP::TAG_USER_AGENT, user_agent)
196
219
  end
197
220
 
221
+ if request_span.get_tag(Tracing::Metadata::Ext::HTTP::TAG_ROUTE).nil? && status != 404
222
+ request_span.set_tag(Tracing::Metadata::Ext::HTTP::TAG_ROUTE, env['PATH_INFO'])
223
+ end
224
+
198
225
  HeaderTagging.tag_request_headers(request_span, request_header_collection, configuration)
199
226
  HeaderTagging.tag_response_headers(request_span, headers, configuration) if headers
200
227
 
@@ -58,7 +58,7 @@ module Datadog
58
58
  # Capture the executed source code when provided from STDIN.
59
59
  def eval(*args)
60
60
  span = Datadog::Tracing.active_span
61
- if span.name == Ext::SPAN_RUNNER_STDIN
61
+ if span&.name == Ext::SPAN_RUNNER_STDIN
62
62
  source = args[0]
63
63
  span.set_tag(
64
64
  Ext::TAG_RUNNER_SOURCE,
@@ -4,6 +4,7 @@ require_relative '../../metadata/ext'
4
4
  require_relative '../analytics'
5
5
  require_relative 'ext'
6
6
  require_relative '../ext'
7
+ require_relative '../../../core/telemetry/logger'
7
8
 
8
9
  module Datadog
9
10
  module Tracing
@@ -45,6 +46,9 @@ module Datadog
45
46
  span.set_tag Ext::TAG_RAW_COMMAND, raw_command
46
47
 
47
48
  Contrib::SpanAttributeSchema.set_peer_service!(span, Ext::PEER_SERVICE_SOURCES)
49
+ rescue StandardError => e
50
+ Datadog.logger.error(e.message)
51
+ Datadog::Core::Telemetry::Logger.report(e)
48
52
  end
49
53
 
50
54
  private
@@ -25,6 +25,9 @@ module Datadog
25
25
  return super(&block) unless Tracing.enabled?
26
26
 
27
27
  datadog_trace_request(uri) do |_span, trace|
28
+ if Datadog::AppSec::Utils::TraceOperation.appsec_standalone_reject?(trace)
29
+ trace.sampling_priority = Tracing::Sampling::Ext::Priority::AUTO_REJECT
30
+ end
28
31
  Contrib::HTTP.inject(trace, processed_headers) if datadog_configuration[:distributed_tracing]
29
32
 
30
33
  super(&block)
@@ -69,6 +69,10 @@ module Datadog
69
69
 
70
70
  trace.resource = span.resource
71
71
 
72
+ _, path = env['sinatra.route'].split(' ', 2)
73
+ trace.set_tag(Tracing::Metadata::Ext::HTTP::TAG_ROUTE, path)
74
+ trace.set_tag(Tracing::Metadata::Ext::HTTP::TAG_ROUTE_PATH, env['SCRIPT_NAME'])
75
+
72
76
  sinatra_request_span = Sinatra::Env.datadog_span(env)
73
77
 
74
78
  sinatra_request_span.resource = span.resource
@@ -47,8 +47,9 @@ module Datadog
47
47
 
48
48
  # Measure service stats
49
49
  Contrib::Analytics.set_measured(span)
50
-
51
- span.set_tag(Ext::TAG_REQUEST_ID, event.request_id)
50
+ # `5.38.0` Add request_id to RequestEndEvent
51
+ # https://github.com/stripe/stripe-ruby/blob/master/CHANGELOG.md#5380---2021-08-10
52
+ span.set_tag(Ext::TAG_REQUEST_ID, event.request_id) if event.respond_to?(:request_id)
52
53
  span.set_tag(Ext::TAG_REQUEST_HTTP_STATUS, event.http_status.to_s)
53
54
  span.set_tag(Ext::TAG_REQUEST_METHOD, event.method)
54
55
  span.set_tag(Ext::TAG_REQUEST_PATH, event.path)