datadog 2.14.0 → 2.16.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 (149) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +67 -1
  3. data/ext/datadog_profiling_native_extension/collectors_thread_context.c +7 -6
  4. data/ext/datadog_profiling_native_extension/datadog_ruby_common.c +1 -4
  5. data/ext/datadog_profiling_native_extension/datadog_ruby_common.h +10 -0
  6. data/ext/datadog_profiling_native_extension/encoded_profile.c +69 -0
  7. data/ext/datadog_profiling_native_extension/encoded_profile.h +7 -0
  8. data/ext/datadog_profiling_native_extension/extconf.rb +3 -0
  9. data/ext/datadog_profiling_native_extension/heap_recorder.c +8 -1
  10. data/ext/datadog_profiling_native_extension/http_transport.c +25 -32
  11. data/ext/datadog_profiling_native_extension/profiling.c +2 -0
  12. data/ext/datadog_profiling_native_extension/stack_recorder.c +22 -21
  13. data/ext/libdatadog_api/crashtracker.c +1 -9
  14. data/ext/libdatadog_api/crashtracker.h +5 -0
  15. data/ext/libdatadog_api/datadog_ruby_common.c +1 -4
  16. data/ext/libdatadog_api/datadog_ruby_common.h +10 -0
  17. data/ext/libdatadog_api/init.c +15 -0
  18. data/ext/libdatadog_api/library_config.c +122 -0
  19. data/ext/libdatadog_api/library_config.h +19 -0
  20. data/ext/libdatadog_api/process_discovery.c +117 -0
  21. data/ext/libdatadog_api/process_discovery.h +5 -0
  22. data/lib/datadog/appsec/actions_handler.rb +3 -2
  23. data/lib/datadog/appsec/assets/waf_rules/README.md +50 -5
  24. data/lib/datadog/appsec/assets/waf_rules/processors.json +239 -10
  25. data/lib/datadog/appsec/assets/waf_rules/scanners.json +926 -17
  26. data/lib/datadog/appsec/autoload.rb +1 -1
  27. data/lib/datadog/appsec/component.rb +29 -20
  28. data/lib/datadog/appsec/compressed_json.rb +40 -0
  29. data/lib/datadog/appsec/configuration/settings.rb +31 -18
  30. data/lib/datadog/appsec/context.rb +1 -1
  31. data/lib/datadog/appsec/contrib/active_record/instrumentation.rb +10 -12
  32. data/lib/datadog/appsec/contrib/active_record/integration.rb +2 -2
  33. data/lib/datadog/appsec/contrib/active_record/patcher.rb +22 -22
  34. data/lib/datadog/appsec/contrib/devise/data_extractor.rb +2 -3
  35. data/lib/datadog/appsec/contrib/devise/ext.rb +1 -0
  36. data/lib/datadog/appsec/contrib/devise/integration.rb +1 -1
  37. data/lib/datadog/appsec/contrib/devise/patcher.rb +3 -5
  38. data/lib/datadog/appsec/contrib/devise/tracking_middleware.rb +17 -4
  39. data/lib/datadog/appsec/contrib/excon/integration.rb +1 -1
  40. data/lib/datadog/appsec/contrib/excon/ssrf_detection_middleware.rb +9 -10
  41. data/lib/datadog/appsec/contrib/faraday/integration.rb +1 -1
  42. data/lib/datadog/appsec/contrib/faraday/ssrf_detection_middleware.rb +8 -9
  43. data/lib/datadog/appsec/contrib/graphql/gateway/watcher.rb +8 -9
  44. data/lib/datadog/appsec/contrib/graphql/integration.rb +1 -1
  45. data/lib/datadog/appsec/contrib/rack/gateway/watcher.rb +22 -32
  46. data/lib/datadog/appsec/contrib/rack/integration.rb +1 -1
  47. data/lib/datadog/appsec/contrib/rack/request_middleware.rb +16 -16
  48. data/lib/datadog/appsec/contrib/rails/gateway/watcher.rb +11 -13
  49. data/lib/datadog/appsec/contrib/rails/integration.rb +1 -1
  50. data/lib/datadog/appsec/contrib/rails/patcher.rb +21 -21
  51. data/lib/datadog/appsec/contrib/rest_client/integration.rb +1 -1
  52. data/lib/datadog/appsec/contrib/rest_client/request_ssrf_detection_patch.rb +10 -11
  53. data/lib/datadog/appsec/contrib/sinatra/gateway/watcher.rb +17 -23
  54. data/lib/datadog/appsec/contrib/sinatra/integration.rb +1 -1
  55. data/lib/datadog/appsec/event.rb +95 -134
  56. data/lib/datadog/appsec/instrumentation/gateway/argument.rb +5 -2
  57. data/lib/datadog/appsec/metrics/telemetry.rb +1 -1
  58. data/lib/datadog/appsec/monitor/gateway/watcher.rb +42 -12
  59. data/lib/datadog/appsec/processor/rule_loader.rb +26 -28
  60. data/lib/datadog/appsec/processor/rule_merger.rb +5 -5
  61. data/lib/datadog/appsec/processor.rb +1 -1
  62. data/lib/datadog/appsec/remote.rb +16 -11
  63. data/lib/datadog/appsec/response.rb +6 -6
  64. data/lib/datadog/appsec/security_engine/runner.rb +1 -1
  65. data/lib/datadog/appsec/security_event.rb +39 -0
  66. data/lib/datadog/appsec.rb +1 -1
  67. data/lib/datadog/core/configuration/agentless_settings_resolver.rb +176 -0
  68. data/lib/datadog/core/configuration/components.rb +19 -10
  69. data/lib/datadog/core/configuration/option.rb +61 -25
  70. data/lib/datadog/core/configuration/settings.rb +10 -0
  71. data/lib/datadog/core/configuration/stable_config.rb +23 -0
  72. data/lib/datadog/core/configuration.rb +24 -0
  73. data/lib/datadog/core/crashtracking/component.rb +1 -9
  74. data/lib/datadog/core/diagnostics/environment_logger.rb +1 -1
  75. data/lib/datadog/core/environment/git.rb +1 -0
  76. data/lib/datadog/core/environment/variable_helpers.rb +1 -1
  77. data/lib/datadog/core/metrics/client.rb +8 -7
  78. data/lib/datadog/core/process_discovery.rb +32 -0
  79. data/lib/datadog/core/remote/client.rb +7 -0
  80. data/lib/datadog/core/runtime/metrics.rb +1 -1
  81. data/lib/datadog/core/telemetry/component.rb +60 -50
  82. data/lib/datadog/core/telemetry/emitter.rb +17 -11
  83. data/lib/datadog/core/telemetry/event.rb +7 -4
  84. data/lib/datadog/core/telemetry/http/adapters/net.rb +12 -97
  85. data/lib/datadog/core/telemetry/metric.rb +5 -5
  86. data/lib/datadog/core/telemetry/request.rb +4 -4
  87. data/lib/datadog/core/telemetry/transport/http/api.rb +43 -0
  88. data/lib/datadog/core/telemetry/transport/http/client.rb +49 -0
  89. data/lib/datadog/core/telemetry/transport/http/telemetry.rb +92 -0
  90. data/lib/datadog/core/telemetry/transport/http.rb +63 -0
  91. data/lib/datadog/core/telemetry/transport/telemetry.rb +52 -0
  92. data/lib/datadog/core/telemetry/worker.rb +45 -0
  93. data/lib/datadog/core/utils/time.rb +12 -0
  94. data/lib/datadog/core/workers/async.rb +20 -2
  95. data/lib/datadog/core/workers/interval_loop.rb +12 -1
  96. data/lib/datadog/core/workers/runtime_metrics.rb +2 -2
  97. data/lib/datadog/core.rb +8 -0
  98. data/lib/datadog/di/boot.rb +34 -0
  99. data/lib/datadog/di/probe_notification_builder.rb +1 -1
  100. data/lib/datadog/di/remote.rb +2 -0
  101. data/lib/datadog/di/transport/http/diagnostics.rb +0 -1
  102. data/lib/datadog/di/transport/http/input.rb +0 -1
  103. data/lib/datadog/di/transport/http.rb +0 -6
  104. data/lib/datadog/di.rb +5 -32
  105. data/lib/datadog/error_tracking/collector.rb +87 -0
  106. data/lib/datadog/error_tracking/component.rb +167 -0
  107. data/lib/datadog/error_tracking/configuration/settings.rb +63 -0
  108. data/lib/datadog/error_tracking/configuration.rb +11 -0
  109. data/lib/datadog/error_tracking/ext.rb +18 -0
  110. data/lib/datadog/error_tracking/extensions.rb +16 -0
  111. data/lib/datadog/error_tracking/filters.rb +77 -0
  112. data/lib/datadog/error_tracking.rb +18 -0
  113. data/lib/datadog/kit/identity.rb +1 -1
  114. data/lib/datadog/profiling/collectors/info.rb +3 -0
  115. data/lib/datadog/profiling/encoded_profile.rb +11 -0
  116. data/lib/datadog/profiling/exporter.rb +3 -4
  117. data/lib/datadog/profiling/ext.rb +0 -1
  118. data/lib/datadog/profiling/flush.rb +4 -7
  119. data/lib/datadog/profiling/http_transport.rb +10 -59
  120. data/lib/datadog/profiling/stack_recorder.rb +4 -4
  121. data/lib/datadog/profiling.rb +1 -0
  122. data/lib/datadog/tracing/analytics.rb +1 -1
  123. data/lib/datadog/tracing/contrib/active_record/integration.rb +1 -1
  124. data/lib/datadog/tracing/contrib/karafka/distributed/propagation.rb +2 -0
  125. data/lib/datadog/tracing/contrib/karafka/monitor.rb +1 -1
  126. data/lib/datadog/tracing/contrib/mongodb/configuration/settings.rb +8 -0
  127. data/lib/datadog/tracing/contrib/mongodb/ext.rb +1 -0
  128. data/lib/datadog/tracing/contrib/mongodb/subscribers.rb +18 -1
  129. data/lib/datadog/tracing/contrib/opensearch/configuration/settings.rb +17 -0
  130. data/lib/datadog/tracing/contrib/opensearch/ext.rb +9 -0
  131. data/lib/datadog/tracing/contrib/opensearch/patcher.rb +5 -1
  132. data/lib/datadog/tracing/contrib/rack/request_queue.rb +1 -1
  133. data/lib/datadog/tracing/contrib/sidekiq/server_tracer.rb +1 -1
  134. data/lib/datadog/tracing/distributed/b3_multi.rb +1 -1
  135. data/lib/datadog/tracing/distributed/b3_single.rb +1 -1
  136. data/lib/datadog/tracing/distributed/datadog.rb +2 -2
  137. data/lib/datadog/tracing/sampling/rate_sampler.rb +2 -1
  138. data/lib/datadog/tracing/span_event.rb +1 -1
  139. data/lib/datadog/tracing/span_operation.rb +38 -14
  140. data/lib/datadog/tracing/trace_operation.rb +15 -7
  141. data/lib/datadog/tracing/tracer.rb +7 -3
  142. data/lib/datadog/tracing/utils.rb +1 -1
  143. data/lib/datadog/version.rb +1 -1
  144. data/lib/datadog.rb +2 -3
  145. metadata +40 -10
  146. data/lib/datadog/core/telemetry/http/env.rb +0 -20
  147. data/lib/datadog/core/telemetry/http/ext.rb +0 -28
  148. data/lib/datadog/core/telemetry/http/response.rb +0 -70
  149. data/lib/datadog/core/telemetry/http/transport.rb +0 -90
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'json'
4
+
3
5
  require_relative '../analytics'
4
6
  require_relative 'ext'
5
7
  require_relative '../ext'
@@ -30,7 +32,7 @@ module Datadog
30
32
 
31
33
  # build a quantized Query using the Parser module
32
34
  query = MongoDB.query_builder(event.command_name, event.database_name, event.command)
33
- serialized_query = query.to_s
35
+ serialized_query = serialize_query(query)
34
36
 
35
37
  if datadog_configuration[:peer_service]
36
38
  span.set_tag(
@@ -109,6 +111,21 @@ module Datadog
109
111
 
110
112
  private
111
113
 
114
+ def serialize_query(query)
115
+ if datadog_configuration[:json_command]
116
+ query.to_json
117
+ else
118
+ # Incorrect Hash#to_s serialization. The Mongo command should only be encoded as JSON.
119
+ # This code path should be removed, and is only kept to avoid a breaking change.
120
+ Datadog::Core.log_deprecation(key: :mongo_json_command) do
121
+ 'MongoDB integration: `json_command: false` causes invalid command serialization. '\
122
+ 'Use `json_command: true` or `DD_TRACE_MONGO_JSON_COMMAND=1` instead.'
123
+ end
124
+
125
+ query.to_s
126
+ end
127
+ end
128
+
112
129
  def get_span(event)
113
130
  Thread.current[:datadog_mongo_span] \
114
131
  && Thread.current[:datadog_mongo_span][event.request_id]
@@ -46,6 +46,23 @@ module Datadog
46
46
  o.type :string, nilable: true
47
47
  o.env Ext::ENV_PEER_SERVICE
48
48
  end
49
+
50
+ option :resource_pattern do |o|
51
+ o.type :string
52
+ o.env Ext::ENV_RESOURCE_PATTERN
53
+ o.default Ext::DEFAULT_RESOURCE_PATTERN
54
+ o.setter do |value|
55
+ next value if Ext::VALID_RESOURCE_PATTERNS.include?(value)
56
+
57
+ Datadog.logger.warn(
58
+ "Invalid resource pattern: #{value}. " \
59
+ "Supported values are: #{Ext::VALID_RESOURCE_PATTERNS.join(' | ')}. " \
60
+ "Using default value: #{Ext::DEFAULT_RESOURCE_PATTERN}."
61
+ )
62
+
63
+ Ext::DEFAULT_RESOURCE_PATTERN
64
+ end
65
+ end
49
66
  end
50
67
  end
51
68
  end
@@ -13,6 +13,15 @@ module Datadog
13
13
  # @!visibility private
14
14
  ENV_ANALYTICS_ENABLED = 'DD_TRACE_OPENSEARCH_ANALYTICS_ENABLED'
15
15
  ENV_ANALYTICS_SAMPLE_RATE = 'DD_TRACE_OPENSEARCH_ANALYTICS_SAMPLE_RATE'
16
+ ENV_RESOURCE_PATTERN = 'DD_TRACE_OPENSEARCH_RESOURCE_PATTERN'
17
+ ABSOLUTE_RESOURCE_PATTERN = 'absolute'
18
+ RELATIVE_RESOURCE_PATTERN = 'relative'
19
+ VALID_RESOURCE_PATTERNS = [
20
+ ABSOLUTE_RESOURCE_PATTERN,
21
+ RELATIVE_RESOURCE_PATTERN
22
+ ].freeze
23
+ # Default should be changed to RELATIVE in 3.0 to match the Elasticsearch integration
24
+ DEFAULT_RESOURCE_PATTERN = ABSOLUTE_RESOURCE_PATTERN
16
25
  DEFAULT_PEER_SERVICE_NAME = 'opensearch'
17
26
  SPAN_QUERY = 'opensearch.query'
18
27
  SPAN_TYPE_QUERY = 'opensearch'
@@ -77,7 +77,11 @@ module Datadog
77
77
  span.set_tag(Tracing::Metadata::Ext::TAG_PEER_HOSTNAME, host) if host
78
78
 
79
79
  # Define span resource
80
- quantized_url = OpenSearch::Quantize.format_url(url)
80
+ quantized_url = if datadog_configuration[:resource_pattern] == Ext::RELATIVE_RESOURCE_PATTERN
81
+ OpenSearch::Quantize.format_url(url.path)
82
+ else # Default to Ext::ABSOLUTE_RESOURCE_PATTERN
83
+ OpenSearch::Quantize.format_url(url)
84
+ end
81
85
  span.resource = "#{method} #{quantized_url}"
82
86
  Contrib::SpanAttributeSchema.set_peer_service!(span, Ext::PEER_SERVICE_SOURCES)
83
87
  rescue StandardError => e
@@ -17,7 +17,7 @@ module Datadog
17
17
 
18
18
  module_function
19
19
 
20
- def get_request_start(env, now = Time.now.utc)
20
+ def get_request_start(env, now = Core::Utils::Time.now.utc)
21
21
  header = env[REQUEST_START] || env[QUEUE_START]
22
22
  return unless header
23
23
 
@@ -61,7 +61,7 @@ module Datadog
61
61
  span.set_tag(Ext::TAG_JOB_RETRY_COUNT, job['retry_count'])
62
62
  span.set_tag(Ext::TAG_JOB_QUEUE, job['queue'])
63
63
  span.set_tag(Ext::TAG_JOB_WRAPPER, job['class']) if job['wrapped']
64
- span.set_tag(Ext::TAG_JOB_DELAY, 1000.0 * (Time.now.utc.to_f - job['enqueued_at'].to_f))
64
+ span.set_tag(Ext::TAG_JOB_DELAY, 1000.0 * (Core::Utils::Time.now.utc.to_f - job['enqueued_at'].to_f))
65
65
 
66
66
  args = job['args']
67
67
  if args && !args.empty?
@@ -55,7 +55,7 @@ module Datadog
55
55
  span_id = Helpers.parse_hex_id(fetcher[@span_id_key])
56
56
 
57
57
  # Return early if this propagation is not valid
58
- return if span_id.nil? || span_id <= 0 || span_id >= Tracing::Utils::EXTERNAL_MAX_ID
58
+ return if span_id.nil? || span_id <= 0 || span_id > Tracing::Utils::EXTERNAL_MAX_ID
59
59
 
60
60
  # We don't need to try and convert sampled since B3 supports 0/1 (AUTO_REJECT/AUTO_KEEP)
61
61
  sampling_priority = Helpers.parse_decimal_id(fetcher[@sampled_key])
@@ -54,7 +54,7 @@ module Datadog
54
54
 
55
55
  span_id = Helpers.parse_hex_id(parts[1]) if parts.length > 1
56
56
  # Return early if this propagation is not valid
57
- return if span_id.nil? || span_id <= 0 || span_id >= Tracing::Utils::EXTERNAL_MAX_ID
57
+ return if span_id.nil? || span_id <= 0 || span_id > Tracing::Utils::EXTERNAL_MAX_ID
58
58
 
59
59
  sampling_priority = Helpers.parse_decimal_id(parts[2]) if parts.length > 2
60
60
 
@@ -89,7 +89,7 @@ module Datadog
89
89
  trace_id = Helpers.parse_decimal_id(fetcher_object[@trace_id_key])
90
90
 
91
91
  return unless trace_id
92
- return if trace_id <= 0 || trace_id >= Tracing::Utils::EXTERNAL_MAX_ID
92
+ return if trace_id <= 0 || trace_id > Tracing::Utils::EXTERNAL_MAX_ID
93
93
 
94
94
  trace_id
95
95
  end
@@ -98,7 +98,7 @@ module Datadog
98
98
  parent_id = Helpers.parse_decimal_id(fetcher_object[@parent_id_key])
99
99
 
100
100
  return unless parent_id
101
- return if parent_id <= 0 || parent_id >= Tracing::Utils::EXTERNAL_MAX_ID
101
+ return if parent_id <= 0 || parent_id > Tracing::Utils::EXTERNAL_MAX_ID
102
102
 
103
103
  parent_id
104
104
  end
@@ -9,6 +9,7 @@ module Datadog
9
9
  # {Datadog::Tracing::Sampling::RateSampler} is based on a sample rate.
10
10
  class RateSampler < Sampler
11
11
  KNUTH_FACTOR = 1111111111111111111
12
+ UINT64_MODULO = (1 << 64)
12
13
 
13
14
  # Initialize a {Datadog::Tracing::Sampling::RateSampler}.
14
15
  # This sampler keeps a random subset of the traces. Its main purpose is to
@@ -39,7 +40,7 @@ module Datadog
39
40
  end
40
41
 
41
42
  def sample?(trace)
42
- ((trace.id * KNUTH_FACTOR) % Tracing::Utils::EXTERNAL_MAX_ID) <= @sampling_id_threshold
43
+ ((trace.id * KNUTH_FACTOR) % UINT64_MODULO) <= @sampling_id_threshold
43
44
  end
44
45
 
45
46
  def sample!(trace)
@@ -33,7 +33,7 @@ module Datadog
33
33
 
34
34
  # OpenTelemetry SDK stores span event timestamps in nanoseconds (not seconds).
35
35
  # We will do the same here to avoid unnecessary conversions and inconsistencies.
36
- @time_unix_nano = time_unix_nano || (Time.now.to_r * 1_000_000_000).to_i
36
+ @time_unix_nano = time_unix_nano || (Core::Utils::Time.now.to_r * 1_000_000_000).to_i
37
37
  end
38
38
 
39
39
  # Converts the span event into a hash to be used by with the span tag serialization
@@ -28,6 +28,7 @@ module Datadog
28
28
  # Span attributes
29
29
  # NOTE: In the future, we should drop the me
30
30
  attr_reader \
31
+ :logger,
31
32
  :end_time,
32
33
  :id,
33
34
  :name,
@@ -37,10 +38,12 @@ module Datadog
37
38
  :start_time,
38
39
  :trace_id,
39
40
  :type
41
+
40
42
  attr_accessor :links, :status, :span_events
41
43
 
42
44
  def initialize(
43
45
  name,
46
+ logger: Datadog.logger,
44
47
  events: nil,
45
48
  on_error: nil,
46
49
  parent_id: 0,
@@ -54,6 +57,8 @@ module Datadog
54
57
  span_events: nil,
55
58
  id: nil
56
59
  )
60
+ @logger = logger
61
+
57
62
  # Ensure dynamically created strings are UTF-8 encoded.
58
63
  #
59
64
  # All strings created in Ruby land are UTF-8. The only sources of non-UTF-8 string are:
@@ -90,11 +95,17 @@ module Datadog
90
95
  set_tags(tags) if tags
91
96
 
92
97
  # Some other SpanOperation-specific behavior
93
- @events = events || Events.new
98
+ @events = events || Events.new(logger: logger)
94
99
  @span = nil
95
100
 
96
- # Subscribe :on_error event
97
- @events.on_error.wrap_default(&on_error) if on_error.is_a?(Proc)
101
+ if on_error.nil?
102
+ # Nothing, default error handler is already set up.
103
+ elsif on_error.is_a?(Proc)
104
+ # Subscribe :on_error event
105
+ @events.on_error.wrap_default(&on_error)
106
+ else
107
+ logger.warn("on_error argument to SpanOperation ignored because is not a Proc: #{on_error}")
108
+ end
98
109
 
99
110
  # Start the span with start time, if given.
100
111
  start(start_time) if start_time
@@ -130,6 +141,10 @@ module Datadog
130
141
  @resource = resource.nil? ? nil : Core::Utils.utf8_encode(resource) # Allow this to be explicitly set to nil
131
142
  end
132
143
 
144
+ def get_collector_or_initialize
145
+ @collector ||= yield
146
+ end
147
+
133
148
  def measure
134
149
  raise ArgumentError, 'Must provide block to measure!' unless block_given?
135
150
  # TODO: Should we just invoke the block and skip tracing instead?
@@ -143,7 +158,7 @@ module Datadog
143
158
  begin
144
159
  start
145
160
  rescue StandardError => e
146
- Datadog.logger.debug { "Failed to start span: #{e}" }
161
+ logger.debug { "Failed to start span: #{e}" }
147
162
  ensure
148
163
  # We should yield to the provided block when possible, as this
149
164
  # block is application code that we don't want to hinder.
@@ -161,7 +176,7 @@ module Datadog
161
176
  # Stop the span first, so timing is a more accurate.
162
177
  # If the span failed to start, timing may be inaccurate,
163
178
  # but this is not really a serious concern.
164
- stop
179
+ stop(exception: e)
165
180
 
166
181
  # Trigger the on_error event
167
182
  events.on_error.publish(self, e)
@@ -202,7 +217,7 @@ module Datadog
202
217
  #
203
218
  # steep:ignore:start
204
219
  # Steep issue fixed in https://github.com/soutaro/steep/pull/1467
205
- def stop(stop_time = nil)
220
+ def stop(stop_time = nil, exception: nil)
206
221
  # A span should not be stopped twice. Note that this is not thread-safe,
207
222
  # stop is called from multiple threads, a given span might be stopped
208
223
  # several times. Again, one should not do this, so this test is more a
@@ -220,7 +235,7 @@ module Datadog
220
235
  @duration_end = stop_time.nil? ? duration_marker : nil
221
236
 
222
237
  # Trigger after_stop event
223
- events.after_stop.publish(self)
238
+ events.after_stop.publish(self, exception)
224
239
 
225
240
  self
226
241
  end
@@ -236,6 +251,10 @@ module Datadog
236
251
  !@end_time.nil?
237
252
  end
238
253
 
254
+ def root?
255
+ parent_id == 0
256
+ end
257
+
239
258
  # for backwards compatibility
240
259
  def start_time=(time)
241
260
  time.tap { start(time) }
@@ -349,11 +368,13 @@ module Datadog
349
368
  DEFAULT_ON_ERROR = proc { |span_op, error| span_op.set_error(error) unless span_op.nil? }
350
369
 
351
370
  attr_reader \
371
+ :logger,
352
372
  :after_finish,
353
373
  :after_stop,
354
374
  :before_start
355
375
 
356
- def initialize(on_error: nil)
376
+ def initialize(logger: Datadog.logger, on_error: nil)
377
+ @logger = logger
357
378
  @after_finish = AfterFinish.new
358
379
  @after_stop = AfterStop.new
359
380
  @before_start = BeforeStart.new
@@ -362,7 +383,7 @@ module Datadog
362
383
  # This event is lazily initialized as error paths
363
384
  # are normally less common that non-error paths.
364
385
  def on_error
365
- @on_error ||= OnError.new(DEFAULT_ON_ERROR)
386
+ @on_error ||= OnError.new(DEFAULT_ON_ERROR, logger: logger)
366
387
  end
367
388
 
368
389
  # Triggered when the span is finished, regardless of error.
@@ -388,10 +409,13 @@ module Datadog
388
409
 
389
410
  # Triggered when the span raises an error during measurement.
390
411
  class OnError
391
- def initialize(default)
412
+ def initialize(default, logger: Datadog.logger)
392
413
  @handler = default
414
+ @logger = logger
393
415
  end
394
416
 
417
+ attr_reader :logger
418
+
395
419
  # Call custom error handler but fallback to default behavior on failure.
396
420
 
397
421
  # DEV: Revisit this before full 1.0 release.
@@ -405,9 +429,9 @@ module Datadog
405
429
  begin
406
430
  yield(op, error)
407
431
  rescue StandardError => e
408
- Datadog.logger.debug do
432
+ logger.debug do
409
433
  "Custom on_error handler #{@handler} failed, using fallback behavior. \
410
- Cause: #{e.class.name} #{e.message} Location: #{Array(e.backtrace).first}"
434
+ Cause: #{e.class}: #{e} Location: #{Array(e.backtrace).first}"
411
435
  end
412
436
 
413
437
  original.call(op, error) if original
@@ -419,8 +443,8 @@ module Datadog
419
443
  begin
420
444
  @handler.call(*args)
421
445
  rescue StandardError => e
422
- Datadog.logger.debug do
423
- "Error in on_error handler '#{@default}': #{e.class.name} #{e.message} at #{Array(e.backtrace).first}"
446
+ logger.debug do
447
+ "Error in on_error handler '#{@default}': #{e.class}: #{e} at #{Array(e.backtrace).first}"
424
448
  end
425
449
  end
426
450
 
@@ -40,6 +40,7 @@ module Datadog
40
40
  :baggage
41
41
 
42
42
  attr_reader \
43
+ :logger,
43
44
  :active_span_count,
44
45
  :active_span,
45
46
  :id,
@@ -55,6 +56,7 @@ module Datadog
55
56
  :service
56
57
 
57
58
  def initialize(
59
+ logger: Datadog.logger,
58
60
  agent_sample_rate: nil,
59
61
  events: nil,
60
62
  hostname: nil,
@@ -79,8 +81,9 @@ module Datadog
79
81
  remote_parent: false,
80
82
  tracer: nil,
81
83
  baggage: nil
82
-
83
84
  )
85
+ @logger = logger
86
+
84
87
  # Attributes
85
88
  @id = id || Tracing::Utils::TraceId.next_id
86
89
  @max_length = max_length || DEFAULT_MAX_LENGTH
@@ -204,6 +207,7 @@ module Datadog
204
207
 
205
208
  def measure(
206
209
  op_name,
210
+ logger: Datadog.logger,
207
211
  events: nil,
208
212
  on_error: nil,
209
213
  resource: nil,
@@ -217,7 +221,9 @@ module Datadog
217
221
  # Don't allow more span measurements if the
218
222
  # trace is already completed. Prevents multiple
219
223
  # root spans with parent_span_id = 0.
220
- return yield(SpanOperation.new(op_name), TraceOperation.new) if finished? || full?
224
+ return yield( # rubocop:disable Style/MultilineIfModifier
225
+ SpanOperation.new(op_name, logger: logger),
226
+ TraceOperation.new(logger: logger)) if finished? || full?
221
227
 
222
228
  # Create new span
223
229
  span_op = build_span(
@@ -238,6 +244,7 @@ module Datadog
238
244
 
239
245
  def build_span(
240
246
  op_name,
247
+ logger: Datadog.logger,
241
248
  events: nil,
242
249
  on_error: nil,
243
250
  resource: nil,
@@ -259,7 +266,7 @@ module Datadog
259
266
  parent_id = parent ? parent.id : @parent_span_id || 0
260
267
 
261
268
  # Build events
262
- events ||= SpanOperation::Events.new
269
+ events ||= SpanOperation::Events.new(logger: logger)
263
270
 
264
271
  # Before start: activate the span, publish events.
265
272
  events.before_start.subscribe do |span_op|
@@ -274,6 +281,7 @@ module Datadog
274
281
  # Build a new span operation
275
282
  SpanOperation.new(
276
283
  op_name,
284
+ logger: logger,
277
285
  events: events,
278
286
  on_error: on_error,
279
287
  parent_id: parent_id,
@@ -286,10 +294,10 @@ module Datadog
286
294
  id: id
287
295
  )
288
296
  rescue StandardError => e
289
- Datadog.logger.debug { "Failed to build new span: #{e}" }
297
+ logger.debug { "Failed to build new span: #{e}" }
290
298
 
291
299
  # Return dummy span
292
- SpanOperation.new(op_name)
300
+ SpanOperation.new(op_name, logger: logger)
293
301
  end
294
302
  end
295
303
 
@@ -465,7 +473,7 @@ module Datadog
465
473
  # Publish :span_before_start event
466
474
  events.span_before_start.publish(span_op, self)
467
475
  rescue StandardError => e
468
- Datadog.logger.debug { "Error starting span on trace: #{e} Backtrace: #{e.backtrace.first(3)}" }
476
+ logger.debug { "Error starting span on trace: #{e} Backtrace: #{e.backtrace.first(3)}" }
469
477
  end
470
478
  end
471
479
 
@@ -489,7 +497,7 @@ module Datadog
489
497
  # Publish :trace_finished event
490
498
  events.trace_finished.publish(self) if finished?
491
499
  rescue StandardError => e
492
- Datadog.logger.debug { "Error finishing span on trace: #{e} Backtrace: #{e.backtrace.first(3)}" }
500
+ logger.debug { "Error finishing span on trace: #{e} Backtrace: #{e.backtrace.first(3)}" }
493
501
  end
494
502
  end
495
503
 
@@ -342,6 +342,7 @@ module Datadog
342
342
  digest.trace_sampling_priority
343
343
  end
344
344
  TraceOperation.new(
345
+ logger: logger,
345
346
  hostname: hostname,
346
347
  profiling_enabled: profiling_enabled,
347
348
  apm_tracing_enabled: apm_tracing_enabled,
@@ -359,6 +360,7 @@ module Datadog
359
360
  )
360
361
  else
361
362
  TraceOperation.new(
363
+ logger: logger,
362
364
  hostname: hostname,
363
365
  profiling_enabled: profiling_enabled,
364
366
  apm_tracing_enabled: apm_tracing_enabled,
@@ -410,12 +412,13 @@ module Datadog
410
412
  )
411
413
  trace = _trace || start_trace(continue_from: continue_from)
412
414
 
413
- events = SpanOperation::Events.new
415
+ events = SpanOperation::Events.new(logger: logger)
414
416
 
415
417
  if block
416
418
  # Ignore start time if a block has been given
417
419
  trace.measure(
418
420
  name,
421
+ logger: logger,
419
422
  events: events,
420
423
  on_error: on_error,
421
424
  resource: resource,
@@ -429,6 +432,7 @@ module Datadog
429
432
  # Return the new span
430
433
  span = trace.build_span(
431
434
  name,
435
+ logger: logger,
432
436
  events: events,
433
437
  on_error: on_error,
434
438
  resource: resource,
@@ -541,10 +545,10 @@ module Datadog
541
545
 
542
546
  # TODO: Make these dummy objects singletons to preserve memory.
543
547
  def skip_trace(name)
544
- span = SpanOperation.new(name)
548
+ span = SpanOperation.new(name, logger: logger)
545
549
 
546
550
  if block_given?
547
- trace = TraceOperation.new
551
+ trace = TraceOperation.new(logger: logger)
548
552
  yield(span, trace)
549
553
  else
550
554
  span
@@ -24,7 +24,7 @@ module Datadog
24
24
 
25
25
  # While we only generate 63-bit integers due to limitations in other languages, we support
26
26
  # parsing 64-bit integers for distributed tracing since an upstream system may generate one
27
- EXTERNAL_MAX_ID = 1 << 64
27
+ EXTERNAL_MAX_ID = (1 << 64) - 1
28
28
 
29
29
  # We use a custom random number generator because we want no interference
30
30
  # with the default one. Using the default prng, we could break code that
@@ -3,7 +3,7 @@
3
3
  module Datadog
4
4
  module VERSION
5
5
  MAJOR = 2
6
- MINOR = 14
6
+ MINOR = 16
7
7
  PATCH = 0
8
8
  PRE = nil
9
9
  BUILD = nil
data/lib/datadog.rb CHANGED
@@ -7,7 +7,6 @@ require_relative 'datadog/tracing/contrib'
7
7
  # Load other products (must follow tracing)
8
8
  require_relative 'datadog/profiling'
9
9
  require_relative 'datadog/appsec'
10
- # Line probes will not work on Ruby < 2.6 because of lack of :script_compiled
11
- # trace point. Only load DI on supported Ruby versions.
12
- require_relative 'datadog/di' if RUBY_VERSION >= '2.6' && RUBY_ENGINE != 'jruby'
10
+ require_relative 'datadog/di'
11
+ require_relative 'datadog/error_tracking'
13
12
  require_relative 'datadog/kit'