datadog 2.3.0 → 2.4.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 (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
@@ -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
@@ -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,19 @@ 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 Tracing.enabled? && !Contrib::HTTP.should_skip_distributed_tracing?(client_config)
39
+ Contrib::HTTP.inject(trace, req)
48
40
  end
49
41
 
42
+ # Add additional request specific tags to the span.
43
+ annotate_span_with_request!(span, req, request_options)
44
+
45
+ response = super(req, body, &block)
46
+
50
47
  # Add additional response specific tags to the span.
51
48
  annotate_span_with_response!(span, response, request_options)
52
49
 
@@ -91,6 +88,9 @@ module Datadog
91
88
  )
92
89
 
93
90
  Contrib::SpanAttributeSchema.set_peer_service!(span, Ext::PEER_SERVICE_SOURCES)
91
+ rescue StandardError => e
92
+ Datadog.logger.error("error preparing span from http request: #{e}")
93
+ Datadog::Core::Telemetry::Logger.report(e)
94
94
  end
95
95
 
96
96
  def annotate_span_with_response!(span, response, request_options)
@@ -103,6 +103,9 @@ module Datadog
103
103
  span.set_tags(
104
104
  Datadog.configuration.tracing.header_tags.response_tags(response)
105
105
  )
106
+ rescue StandardError => e
107
+ Datadog.logger.error("error preparing span from http response: #{e}")
108
+ Datadog::Core::Telemetry::Logger.report(e)
106
109
  end
107
110
 
108
111
  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
@@ -36,7 +37,8 @@ module Datadog
36
37
  # Add additional request specific tags to the span.
37
38
  annotate_span_with_request!(span, req, request_options)
38
39
  rescue StandardError => e
39
- logger.error("error preparing span for httpclient request: #{e}, Source: #{e.backtrace}")
40
+ Datadog.logger.error("error preparing span for httpclient request: #{e}, Source: #{e.backtrace}")
41
+ Datadog::Core::Telemetry::Logger.report(e)
40
42
  ensure
41
43
  res = super
42
44
  end
@@ -100,6 +102,9 @@ module Datadog
100
102
  span.set_tags(
101
103
  Datadog.configuration.tracing.header_tags.response_tags(response.header)
102
104
  )
105
+ rescue StandardError => e
106
+ Datadog.logger.error("error preparing span from httpclient response: #{e}, Source: #{e.backtrace}")
107
+ Datadog::Core::Telemetry::Logger.report(e)
103
108
  end
104
109
 
105
110
  def annotate_span_with_error!(span, error)
@@ -114,10 +119,6 @@ module Datadog
114
119
  Contrib::Analytics.enabled?(request_options[:analytics_enabled])
115
120
  end
116
121
 
117
- def logger
118
- Datadog.logger
119
- end
120
-
121
122
  def should_skip_distributed_tracing?(client_config)
122
123
  return !client_config[:distributed_tracing] if client_config && client_config.key?(:distributed_tracing)
123
124
 
@@ -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
@@ -35,6 +36,7 @@ module Datadog
35
36
  annotate_span_with_request!(span, req, request_options)
36
37
  rescue StandardError => e
37
38
  logger.error("error preparing span for http.rb request: #{e}, Source: #{e.backtrace}")
39
+ Datadog::Core::Telemetry::Logger.report(e)
38
40
  ensure
39
41
  res = super(req, options)
40
42
  end
@@ -108,6 +110,9 @@ module Datadog
108
110
  span.set_tags(
109
111
  Datadog.configuration.tracing.header_tags.response_tags(response.headers)
110
112
  )
113
+ rescue StandardError => e
114
+ logger.error("error preparing span from http.rb response: #{e}, Source: #{e.backtrace}")
115
+ Datadog::Core::Telemetry::Logger.report(e)
111
116
  end
112
117
 
113
118
  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
 
@@ -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
@@ -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)
@@ -3,6 +3,7 @@
3
3
  require_relative '../configuration/ext'
4
4
  require_relative '../trace_digest'
5
5
  require_relative '../trace_operation'
6
+ require_relative '../../core/telemetry/logger'
6
7
 
7
8
  module Datadog
8
9
  module Tracing
@@ -43,6 +44,7 @@ module Datadog
43
44
  # DEV-2.0: if needed.
44
45
  # DEV-2.0: Ideally, we'd have a separate stream to report tracer errors and never
45
46
  # DEV-2.0: touch the active span.
47
+ # DEV-3.0: Sample trace here instead of when generating digest.
46
48
  #
47
49
  # @param digest [TraceDigest]
48
50
  # @param data [Hash]
@@ -72,6 +74,10 @@ module Datadog
72
74
  ::Datadog.logger.error(
73
75
  "Error injecting distributed trace data. Cause: #{e} Location: #{Array(e.backtrace).first}"
74
76
  )
77
+ ::Datadog::Core::Telemetry::Logger.report(
78
+ e,
79
+ description: "Error injecting distributed trace data with #{propagator.class.name}"
80
+ )
75
81
  end
76
82
 
77
83
  result
@@ -127,6 +133,7 @@ module Datadog
127
133
  )
128
134
  end
129
135
  rescue => e
136
+ # TODO: Not to report Telemetry logs for now
130
137
  ::Datadog.logger.error(
131
138
  "Error extracting distributed trace data. Cause: #{e} Location: #{Array(e.backtrace).first}"
132
139
  )
@@ -87,6 +87,8 @@ module Datadog
87
87
  TAG_STATUS_CODE = 'http.status_code'
88
88
  TAG_USER_AGENT = 'http.useragent'
89
89
  TAG_URL = 'http.url'
90
+ TAG_ROUTE = 'http.route'
91
+ TAG_ROUTE_PATH = 'http.route.path'
90
92
  TYPE_INBOUND = AppTypes::TYPE_WEB.freeze
91
93
  TYPE_OUTBOUND = 'http'
92
94
  TYPE_PROXY = 'proxy'
@@ -13,7 +13,10 @@ module Datadog
13
13
  PRODUCT = 'APM_TRACING'
14
14
 
15
15
  CAPABILITIES = [
16
- 1 << 29 # APM_TRACING_SAMPLE_RULES: Dynamic trace sampling rules configuration
16
+ 1 << 12, # APM_TRACING_SAMPLE_RATE: Dynamic trace sampling rate configuration
17
+ 1 << 13, # APM_TRACING_LOGS_INJECTION: Dynamic trace logs injection configuration
18
+ 1 << 14, # APM_TRACING_HTTP_HEADER_TAGS: Dynamic trace HTTP header tags configuration
19
+ 1 << 29, # APM_TRACING_SAMPLE_RULES: Dynamic trace sampling rules configuration
17
20
  ].freeze
18
21
 
19
22
  def products
@@ -45,7 +48,7 @@ module Datadog
45
48
  content.errored("#{e.class.name} #{e.message}: #{Array(e.backtrace).join("\n")}")
46
49
  end
47
50
 
48
- def receivers
51
+ def receivers(_telemetry)
49
52
  receiver do |repository, _changes|
50
53
  # DEV: Filter our by product. Given it will be very common
51
54
  # DEV: we can filter this out before we receive the data in this method.
@@ -28,7 +28,7 @@ module Datadog
28
28
  # @return [#match?(String)]
29
29
  def self.glob_to_regex(glob)
30
30
  # Optimization for match-all case
31
- return MATCH_ALL if glob == MATCH_ALL_PATTERN
31
+ return MATCH_ALL if /\A\*+\z/.match?(glob)
32
32
 
33
33
  # Ensure no undesired characters are treated as regex.
34
34
  glob = Regexp.quote(glob)
@@ -100,6 +100,11 @@ module Datadog
100
100
  @tags.all? do |name, matcher|
101
101
  tag = trace.get_tag(name)
102
102
 
103
+ # Floats: Matching floating point values with a non-zero decimal part is not supported.
104
+ # For floating point values with a non-zero decimal part, any all * pattern always returns true.
105
+ # Other patterns always return false.
106
+ return false if tag.is_a?(Float) && tag.truncate != tag && matcher != MATCH_ALL
107
+
103
108
  # Format metrics as strings, to allow for partial number matching (/4.*/ matching '400', '404', etc.).
104
109
  # Because metrics are floats, we use the '%g' format specifier to avoid trailing zeros, which
105
110
  # can affect exact string matching (e.g. '400' matching '400.0').
@@ -20,7 +20,7 @@ module Datadog
20
20
  super()
21
21
 
22
22
  unless sample_rate >= 0.0 && sample_rate <= 1.0
23
- Datadog.logger.error('sample rate is not between 0 and 1, falling back to 1')
23
+ Datadog.logger.warn('sample rate is not between 0 and 1, falling back to 1')
24
24
  sample_rate = 1.0
25
25
  end
26
26
 
@@ -2,6 +2,7 @@
2
2
 
3
3
  require_relative 'matcher'
4
4
  require_relative 'rate_sampler'
5
+ require_relative '../../core/telemetry/logger'
5
6
 
6
7
  module Datadog
7
8
  module Tracing
@@ -35,6 +36,7 @@ module Datadog
35
36
  Datadog.logger.error(
36
37
  "Matcher failed. Cause: #{e.class.name} #{e.message} Source: #{Array(e.backtrace).first}"
37
38
  )
39
+ Datadog::Core::Telemetry::Logger.report(e, description: 'Matcher failed')
38
40
  nil
39
41
  end
40
42
 
@@ -1,8 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative 'ext'
4
- require_relative 'rate_limiter'
4
+ require_relative '../../core/rate_limiter'
5
5
  require_relative 'rule'
6
+ require_relative '../../core/telemetry/logger'
6
7
 
7
8
  module Datadog
8
9
  module Tracing
@@ -32,9 +33,9 @@ module Datadog
32
33
  @rate_limiter = if rate_limiter
33
34
  rate_limiter
34
35
  elsif rate_limit
35
- TokenBucket.new(rate_limit)
36
+ Core::TokenBucket.new(rate_limit)
36
37
  else
37
- UnlimitedLimiter.new
38
+ Core::UnlimitedLimiter.new
38
39
  end
39
40
 
40
41
  @default_sampler = if default_sampler
@@ -80,9 +81,10 @@ module Datadog
80
81
 
81
82
  new(parsed_rules, rate_limit: rate_limit, default_sample_rate: default_sample_rate)
82
83
  rescue => e
83
- Datadog.logger.error do
84
+ Datadog.logger.warn do
84
85
  "Could not parse trace sampling rules '#{rules}': #{e.class.name} #{e.message} at #{Array(e.backtrace).first}"
85
86
  end
87
+
86
88
  nil
87
89
  end
88
90
 
@@ -121,7 +123,7 @@ module Datadog
121
123
 
122
124
  return false unless sampled
123
125
 
124
- rate_limiter.allow?(1).tap do |allowed|
126
+ rate_limiter.allow?.tap do |allowed|
125
127
  set_priority(trace, allowed)
126
128
  set_limiter_metrics(trace, rate_limiter.effective_rate)
127
129
 
@@ -140,6 +142,8 @@ module Datadog
140
142
  Datadog.logger.error(
141
143
  "Rule sampling failed. Cause: #{e.class.name} #{e.message} Source: #{Array(e.backtrace).first}"
142
144
  )
145
+ Datadog::Core::Telemetry::Logger.report(e, description: 'Rule sampling failed')
146
+
143
147
  yield(trace)
144
148
  end
145
149
 
@@ -9,7 +9,7 @@ module Datadog
9
9
  # Accept all spans (100% retention).
10
10
  DEFAULT_SAMPLE_RATE = 1.0
11
11
  # Unlimited.
12
- # @see Datadog::Tracing::Sampling::TokenBucket
12
+ # @see Datadog::Core::TokenBucket
13
13
  DEFAULT_MAX_PER_SECOND = -1
14
14
 
15
15
  # Sampling decision method used to come to the sampling decision for this span
@@ -30,7 +30,7 @@ module Datadog
30
30
  @rate_limit = rate_limit
31
31
 
32
32
  @sampler = Sampling::RateSampler.new(sample_rate)
33
- @rate_limiter = Sampling::TokenBucket.new(rate_limit)
33
+ @rate_limiter = Core::TokenBucket.new(rate_limit)
34
34
  end
35
35
 
36
36
  # This method should only be invoked for spans that are part
@@ -54,7 +54,7 @@ module Datadog
54
54
  def sample!(trace_op, span_op)
55
55
  return :not_matched unless @matcher.match?(span_op)
56
56
 
57
- if @rate_limiter.allow?(1) && @sampler.sample!(trace_op)
57
+ if @rate_limiter.allow? && @sampler.sample!(trace_op)
58
58
  span_op.set_metric(Span::Ext::TAG_MECHANISM, Sampling::Ext::Mechanism::SPAN_SAMPLING_RATE)
59
59
  span_op.set_metric(Span::Ext::TAG_RULE_RATE, @sample_rate)
60
60
  span_op.set_metric(Span::Ext::TAG_MAX_PER_SECOND, @rate_limit)