ddtrace 1.16.0 → 1.18.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +86 -1
- data/ext/ddtrace_profiling_native_extension/clock_id_from_pthread.c +3 -0
- data/ext/ddtrace_profiling_native_extension/collectors_thread_context.c +8 -1
- data/ext/ddtrace_profiling_native_extension/extconf.rb +28 -10
- data/ext/ddtrace_profiling_native_extension/http_transport.c +5 -2
- data/ext/ddtrace_profiling_native_extension/private_vm_api_access.c +78 -18
- data/ext/ddtrace_profiling_native_extension/private_vm_api_access.h +6 -0
- data/ext/ddtrace_profiling_native_extension/profiling.c +1 -0
- data/ext/ddtrace_profiling_native_extension/stack_recorder.c +1 -3
- data/lib/datadog/appsec/component.rb +4 -1
- data/lib/datadog/appsec/configuration/settings.rb +4 -6
- data/lib/datadog/appsec/contrib/devise/patcher/registration_controller_patch.rb +2 -0
- data/lib/datadog/appsec/contrib/rack/gateway/response.rb +0 -46
- data/lib/datadog/appsec/contrib/rack/reactive/response.rb +0 -5
- data/lib/datadog/appsec/contrib/rack/request_middleware.rb +0 -10
- data/lib/datadog/appsec/processor/rule_loader.rb +60 -0
- data/lib/datadog/appsec/remote.rb +12 -9
- data/lib/datadog/core/configuration/settings.rb +1 -1
- data/lib/datadog/core/configuration.rb +4 -0
- data/lib/datadog/core/remote/worker.rb +1 -0
- data/lib/datadog/core/workers/async.rb +1 -0
- data/lib/datadog/kit/enable_core_dumps.rb +5 -6
- data/lib/datadog/opentelemetry/sdk/span_processor.rb +39 -8
- data/lib/datadog/opentelemetry/sdk/trace/span.rb +102 -3
- data/lib/datadog/opentracer/text_map_propagator.rb +2 -1
- data/lib/datadog/profiling/collectors/cpu_and_wall_time_worker.rb +1 -0
- data/lib/datadog/profiling/collectors/idle_sampling_helper.rb +1 -0
- data/lib/datadog/profiling/component.rb +13 -5
- data/lib/datadog/tracing/configuration/ext.rb +3 -0
- data/lib/datadog/tracing/configuration/settings.rb +18 -3
- data/lib/datadog/tracing/contrib/concurrent_ruby/context_composite_executor_service.rb +1 -1
- data/lib/datadog/tracing/contrib/pg/configuration/settings.rb +5 -0
- data/lib/datadog/tracing/contrib/pg/instrumentation.rb +24 -0
- data/lib/datadog/tracing/distributed/datadog.rb +0 -1
- data/lib/datadog/tracing/distributed/propagation.rb +25 -4
- data/lib/datadog/tracing/trace_digest.rb +31 -0
- data/lib/datadog/tracing/workers.rb +1 -0
- data/lib/ddtrace/version.rb +1 -1
- metadata +7 -7
@@ -47,6 +47,13 @@ module Datadog
|
|
47
47
|
data
|
48
48
|
end
|
49
49
|
|
50
|
+
def load_exclusions(ip_passlist: [])
|
51
|
+
exclusions = []
|
52
|
+
exclusions << [passlist_exclusions(ip_passlist)] if ip_passlist.any?
|
53
|
+
|
54
|
+
exclusions
|
55
|
+
end
|
56
|
+
|
50
57
|
private
|
51
58
|
|
52
59
|
def denylist_data(id, denylist)
|
@@ -56,6 +63,59 @@ module Datadog
|
|
56
63
|
'data' => denylist.map { |v| { 'value' => v.to_s, 'expiration' => 2**63 } }
|
57
64
|
}
|
58
65
|
end
|
66
|
+
|
67
|
+
def passlist_exclusions(ip_passlist) # rubocop:disable Metrics/MethodLength
|
68
|
+
case ip_passlist
|
69
|
+
when Array
|
70
|
+
pass = ip_passlist
|
71
|
+
monitor = []
|
72
|
+
when Hash
|
73
|
+
pass = ip_passlist[:pass]
|
74
|
+
monitor = ip_passlist[:monitor]
|
75
|
+
else
|
76
|
+
pass = []
|
77
|
+
monitor = []
|
78
|
+
end
|
79
|
+
|
80
|
+
exclusions = []
|
81
|
+
|
82
|
+
exclusions << {
|
83
|
+
'conditions' => [
|
84
|
+
{
|
85
|
+
'operator' => 'ip_match',
|
86
|
+
'parameters' => {
|
87
|
+
'inputs' => [
|
88
|
+
{
|
89
|
+
'address' => 'http.client_ip'
|
90
|
+
}
|
91
|
+
],
|
92
|
+
'list' => pass
|
93
|
+
}
|
94
|
+
}
|
95
|
+
],
|
96
|
+
'id' => SecureRandom.uuid,
|
97
|
+
}
|
98
|
+
|
99
|
+
exclusions << {
|
100
|
+
'conditions' => [
|
101
|
+
{
|
102
|
+
'operator' => 'ip_match',
|
103
|
+
'parameters' => {
|
104
|
+
'inputs' => [
|
105
|
+
{
|
106
|
+
'address' => 'http.client_ip'
|
107
|
+
}
|
108
|
+
],
|
109
|
+
'list' => monitor
|
110
|
+
}
|
111
|
+
}
|
112
|
+
],
|
113
|
+
'id' => SecureRandom.uuid,
|
114
|
+
'on_match' => 'monitor'
|
115
|
+
}
|
116
|
+
|
117
|
+
exclusions
|
118
|
+
end
|
59
119
|
end
|
60
120
|
end
|
61
121
|
end
|
@@ -12,15 +12,17 @@ module Datadog
|
|
12
12
|
class NoRulesError < StandardError; end
|
13
13
|
|
14
14
|
class << self
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
15
|
+
CAP_ASM_RESERVED_1 = 1 << 0 # RESERVED
|
16
|
+
CAP_ASM_ACTIVATION = 1 << 1 # Remote activation via ASM_FEATURES product
|
17
|
+
CAP_ASM_IP_BLOCKING = 1 << 2 # accept IP blocking data from ASM_DATA product
|
18
|
+
CAP_ASM_DD_RULES = 1 << 3 # read ASM rules from ASM_DD product
|
19
|
+
CAP_ASM_EXCLUSIONS = 1 << 4 # exclusion filters (passlist) via ASM product
|
20
|
+
CAP_ASM_REQUEST_BLOCKING = 1 << 5 # can block on request info
|
21
|
+
CAP_ASM_RESPONSE_BLOCKING = 1 << 6 # can block on response info
|
22
|
+
CAP_ASM_USER_BLOCKING = 1 << 7 # accept user blocking data from ASM_DATA product
|
23
|
+
CAP_ASM_CUSTOM_RULES = 1 << 8 # accept custom rules
|
24
|
+
CAP_ASM_CUSTOM_BLOCKING_RESPONSE = 1 << 9 # supports custom http code or redirect sa blocking response
|
25
|
+
CAP_ASM_TRUSTED_IPS = 1 << 10 # supports trusted ip
|
24
26
|
|
25
27
|
# TODO: we need to dynamically add CAP_ASM_ACTIVATION once we support it
|
26
28
|
ASM_CAPABILITIES = [
|
@@ -32,6 +34,7 @@ module Datadog
|
|
32
34
|
CAP_ASM_DD_RULES,
|
33
35
|
CAP_ASM_CUSTOM_RULES,
|
34
36
|
CAP_ASM_CUSTOM_BLOCKING_RESPONSE,
|
37
|
+
CAP_ASM_TRUSTED_IPS,
|
35
38
|
].freeze
|
36
39
|
|
37
40
|
ASM_PRODUCTS = [
|
@@ -330,7 +330,7 @@ module Datadog
|
|
330
330
|
# Caveat 3 (severe):
|
331
331
|
# Ruby 3.2.0 to 3.2.2 have a bug in the newobj tracepoint (https://bugs.ruby-lang.org/issues/19482,
|
332
332
|
# https://github.com/ruby/ruby/pull/7464) so that's an extra reason why it's not safe on those Rubies.
|
333
|
-
# This bug is fixed on Ruby versions 3.2.
|
333
|
+
# This bug is fixed on Ruby versions 3.2.3 and 3.3.0.
|
334
334
|
#
|
335
335
|
# @default `true` on Ruby 2.x and 3.1.4+, 3.2.3+ and 3.3.0+; `false` for Ruby 3.0 and unpatched Rubies.
|
336
336
|
option :allocation_counting_enabled do |o|
|
@@ -273,6 +273,10 @@ module Datadog
|
|
273
273
|
def handle_interrupt_shutdown!
|
274
274
|
logger = Datadog.logger
|
275
275
|
shutdown_thread = Thread.new { shutdown! }
|
276
|
+
unless Gem::Version.new(RUBY_VERSION) < Gem::Version.new('2.3')
|
277
|
+
shutdown_thread.name = Datadog::Core::Configuration.name
|
278
|
+
end
|
279
|
+
|
276
280
|
print_message_treshold_seconds = 0.2
|
277
281
|
|
278
282
|
slow_shutdown = shutdown_thread.join(print_message_treshold_seconds).nil?
|
@@ -16,11 +16,13 @@ module Datadog
|
|
16
16
|
'(Could not open /proc/sys/kernel/core_pattern)'
|
17
17
|
end
|
18
18
|
|
19
|
+
enabled_status = "Maximum size: #{maximum_size} Output pattern: '#{core_pattern}'"
|
20
|
+
|
19
21
|
if maximum_size <= 0
|
20
22
|
Kernel.warn("[ddtrace] Could not enable core dumps on crash, maximum size is #{maximum_size} (disabled).")
|
21
23
|
return
|
22
24
|
elsif maximum_size == current_size
|
23
|
-
Kernel.warn(
|
25
|
+
Kernel.warn("[ddtrace] Core dumps already enabled, nothing to do. #{enabled_status}")
|
24
26
|
return
|
25
27
|
end
|
26
28
|
|
@@ -35,12 +37,9 @@ module Datadog
|
|
35
37
|
end
|
36
38
|
|
37
39
|
if current_size == 0
|
38
|
-
Kernel.warn("[ddtrace] Enabled core dumps.
|
40
|
+
Kernel.warn("[ddtrace] Enabled core dumps. #{enabled_status}")
|
39
41
|
else
|
40
|
-
Kernel.warn(
|
41
|
-
"[ddtrace] Raised core dump limit. Old size: #{current_size} " \
|
42
|
-
"Maximum size: #{maximum_size} Output pattern: '#{core_pattern}'"
|
43
|
-
)
|
42
|
+
Kernel.warn("[ddtrace] Raised core dump limit. Old size: #{current_size} #{enabled_status}")
|
44
43
|
end
|
45
44
|
end
|
46
45
|
end
|
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require_relative 'trace/span'
|
4
|
+
|
3
5
|
module Datadog
|
4
6
|
module OpenTelemetry
|
5
7
|
module SDK
|
@@ -76,16 +78,11 @@ module Datadog
|
|
76
78
|
end
|
77
79
|
|
78
80
|
def start_datadog_span(span)
|
79
|
-
|
81
|
+
attributes = span.attributes.dup # Dup to allow modification of frozen Hash
|
80
82
|
|
81
|
-
|
82
|
-
tags[Tracing::Metadata::Ext::TAG_KIND] = kind
|
83
|
+
name, kwargs = span_arguments(span, attributes)
|
83
84
|
|
84
|
-
datadog_span = Tracing.trace(
|
85
|
-
span.name,
|
86
|
-
tags: tags,
|
87
|
-
start_time: ns_to_time(span.start_timestamp)
|
88
|
-
)
|
85
|
+
datadog_span = Tracing.trace(name, **kwargs)
|
89
86
|
|
90
87
|
datadog_span.set_error([nil, span.status.description]) unless span.status.ok?
|
91
88
|
datadog_span.set_tags(span.attributes)
|
@@ -93,6 +90,40 @@ module Datadog
|
|
93
90
|
datadog_span
|
94
91
|
end
|
95
92
|
|
93
|
+
# Some special attributes can override Datadog Span fields
|
94
|
+
def span_arguments(span, attributes)
|
95
|
+
if attributes.key?('analytics.event') && (analytics_event = attributes['analytics.event']).respond_to?(:casecmp)
|
96
|
+
attributes[Tracing::Metadata::Ext::Analytics::TAG_SAMPLE_RATE] = analytics_event.casecmp('true') == 0 ? 1 : 0
|
97
|
+
end
|
98
|
+
attributes[Tracing::Metadata::Ext::TAG_KIND] = span.kind || 'internal'
|
99
|
+
|
100
|
+
kwargs = { start_time: ns_to_time(span.start_timestamp) }
|
101
|
+
|
102
|
+
name = if attributes.key?('operation.name')
|
103
|
+
attributes['operation.name']
|
104
|
+
elsif (rich_name = Datadog::OpenTelemetry::Trace::Span.enrich_name(span.kind, attributes))
|
105
|
+
rich_name.downcase
|
106
|
+
else
|
107
|
+
span.kind
|
108
|
+
end
|
109
|
+
|
110
|
+
kwargs[:resource] = attributes.key?('resource.name') ? attributes['resource.name'] : span.name
|
111
|
+
kwargs[:service] = attributes['service.name'] if attributes.key?('service.name')
|
112
|
+
kwargs[:type] = attributes['span.type'] if attributes.key?('span.type')
|
113
|
+
|
114
|
+
attributes.reject! { |key, _| OpenTelemetry::Trace::Span::DATADOG_SPAN_ATTRIBUTE_OVERRIDES.include?(key) }
|
115
|
+
|
116
|
+
# DEV: There's no `flat_map!`; we have to split it into two operations
|
117
|
+
attributes = attributes.map do |key, value|
|
118
|
+
Datadog::OpenTelemetry::Trace::Span.serialize_attribute(key, value)
|
119
|
+
end
|
120
|
+
attributes.flatten!(1)
|
121
|
+
|
122
|
+
kwargs[:tags] = attributes
|
123
|
+
|
124
|
+
[name, kwargs]
|
125
|
+
end
|
126
|
+
|
96
127
|
# From nanoseconds, used by OpenTelemetry, to a {Time} object, used by the Datadog Tracer.
|
97
128
|
def ns_to_time(timestamp_ns)
|
98
129
|
Time.at(timestamp_ns / 1000000000.0)
|
@@ -36,6 +36,78 @@ module Datadog
|
|
36
36
|
span.set_error(status.description) if status && status.code == ::OpenTelemetry::Trace::Status::ERROR
|
37
37
|
end
|
38
38
|
|
39
|
+
# Serialize values into Datadog span tags and metrics.
|
40
|
+
# Notably, arrays are exploded into many keys, each with
|
41
|
+
# a numeric suffix representing the array index, for example:
|
42
|
+
# `'foo' => ['a','b']` becomes `'foo.0' => 'a', 'foo.1' => 'b'`
|
43
|
+
def self.serialize_attribute(key, value)
|
44
|
+
if value.is_a?(Array)
|
45
|
+
value.flat_map.with_index do |v, idx|
|
46
|
+
serialize_attribute("#{key}.#{idx}", v)
|
47
|
+
end
|
48
|
+
elsif value.is_a?(TrueClass) || value.is_a?(FalseClass)
|
49
|
+
[[key, value.to_s]]
|
50
|
+
else
|
51
|
+
[[key, value]]
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
# Create a meaningful Datadog operation name from the OpenTelemetry
|
56
|
+
# semantic convention for span kind and span attributes.
|
57
|
+
# @see https://opentelemetry.io/docs/specs/semconv/general/trace/
|
58
|
+
|
59
|
+
# rubocop:disable Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity
|
60
|
+
def self.enrich_name(kind, attrs)
|
61
|
+
if attrs.key?('http.request.method')
|
62
|
+
return 'http.server.request' if kind == :server
|
63
|
+
return 'http.client.request' if kind == :client
|
64
|
+
end
|
65
|
+
|
66
|
+
return "#{attrs['db.system']}.query" if attrs.key?('db.system') && kind == :client
|
67
|
+
|
68
|
+
if (attrs.key?('messaging.system') || attrs.key?('messaging.operation')) &&
|
69
|
+
[:consumer, :producer, :server, :client].include?(kind)
|
70
|
+
|
71
|
+
return "#{attrs['messaging.system']}.#{attrs['messaging.operation']}"
|
72
|
+
end
|
73
|
+
|
74
|
+
if attrs.key?('rpc.system')
|
75
|
+
if attrs['rpc.system'] == 'aws-api' && kind == :client
|
76
|
+
service = attrs['rpc.service']
|
77
|
+
return "aws.#{service || 'client'}.request"
|
78
|
+
end
|
79
|
+
|
80
|
+
if kind == :client
|
81
|
+
return "#{attrs['rpc.system']}.client.request"
|
82
|
+
elsif kind == :server
|
83
|
+
return "#{attrs['rpc.system']}.server.request"
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
if attrs.key?('faas.invoked_provider') && attrs.key?('faas.invoked_name') && kind == :client
|
88
|
+
provider = attrs['faas.invoked_provider']
|
89
|
+
name = attrs['faas.invoked_name']
|
90
|
+
return "#{provider}.#{name}.invoke"
|
91
|
+
end
|
92
|
+
|
93
|
+
return "#{attrs['faas.trigger']}.invoke" if attrs.key?('faas.trigger') && kind == :server
|
94
|
+
|
95
|
+
return 'graphql.server.request' if attrs.key?('graphql.operation.type')
|
96
|
+
|
97
|
+
if kind == :server
|
98
|
+
protocol = attrs['network.protocol.name']
|
99
|
+
return protocol ? "#{protocol}.server.request" : 'server.request'
|
100
|
+
end
|
101
|
+
|
102
|
+
if kind == :client
|
103
|
+
protocol = attrs['network.protocol.name']
|
104
|
+
return protocol ? "#{protocol}.client.request" : 'client.request'
|
105
|
+
end
|
106
|
+
|
107
|
+
kind.to_s
|
108
|
+
end
|
109
|
+
# rubocop:enable Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity
|
110
|
+
|
39
111
|
private
|
40
112
|
|
41
113
|
def datadog_set_attribute(key)
|
@@ -46,10 +118,18 @@ module Datadog
|
|
46
118
|
# DEV: Accesses `@attributes` directly, since using `#attributes`
|
47
119
|
# DEV: clones the hash, causing unnecessary overhead.
|
48
120
|
if @attributes.key?(key)
|
49
|
-
|
50
|
-
|
121
|
+
# Try to find a richer operation name, unless an explicit override was provided.
|
122
|
+
if !@attributes.key?('operation.name') && (rich_name = Span.enrich_name(kind, @attributes))
|
123
|
+
span.name = rich_name.downcase
|
124
|
+
end
|
125
|
+
|
126
|
+
Span.serialize_attribute(key, @attributes[key]).each do |new_key, value|
|
127
|
+
override_datadog_values(span, new_key, value)
|
51
128
|
|
52
|
-
|
129
|
+
# When an attribute is used to override a Datadog Span property,
|
130
|
+
# it should NOT be set as a Datadog Span tag.
|
131
|
+
span.set_tag(new_key, value) unless DATADOG_SPAN_ATTRIBUTE_OVERRIDES.include?(new_key)
|
132
|
+
end
|
53
133
|
else
|
54
134
|
span.clear_tag(key)
|
55
135
|
|
@@ -61,6 +141,25 @@ module Datadog
|
|
61
141
|
end
|
62
142
|
end
|
63
143
|
|
144
|
+
# Some special attributes can override Datadog Span fields beyond tags and metrics.
|
145
|
+
# @return [Boolean] true if the key is a Datadog Span override attribute, false otherwise
|
146
|
+
def override_datadog_values(span, key, value)
|
147
|
+
span.name = value if key == 'operation.name'
|
148
|
+
span.resource = value if key == 'resource.name'
|
149
|
+
span.service = value if key == 'service.name'
|
150
|
+
span.type = value if key == 'span.type'
|
151
|
+
|
152
|
+
if key == 'analytics.event' && value.respond_to?(:casecmp)
|
153
|
+
Datadog::Tracing::Analytics.set_sample_rate(
|
154
|
+
span,
|
155
|
+
value.casecmp('true') == 0 ? 1 : 0
|
156
|
+
)
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
DATADOG_SPAN_ATTRIBUTE_OVERRIDES = ['analytics.event', 'operation.name', 'resource.name', 'service.name',
|
161
|
+
'span.type'].freeze
|
162
|
+
|
64
163
|
::OpenTelemetry::SDK::Trace::Span.prepend(self)
|
65
164
|
end
|
66
165
|
end
|
@@ -33,7 +33,8 @@ module Datadog
|
|
33
33
|
carrier[Tracing::Distributed::Datadog::ORIGIN_KEY] = digest.trace_origin
|
34
34
|
carrier[Tracing::Distributed::Datadog::PARENT_ID_KEY] = digest.span_id
|
35
35
|
carrier[Tracing::Distributed::Datadog::SAMPLING_PRIORITY_KEY] = digest.trace_sampling_priority
|
36
|
-
carrier[Tracing::Distributed::Datadog::TRACE_ID_KEY] =
|
36
|
+
carrier[Tracing::Distributed::Datadog::TRACE_ID_KEY] =
|
37
|
+
Datadog::Tracing::Utils::TraceId.to_low_order(digest.trace_id)
|
37
38
|
|
38
39
|
nil
|
39
40
|
end
|
@@ -171,12 +171,11 @@ module Datadog
|
|
171
171
|
return true
|
172
172
|
end
|
173
173
|
|
174
|
-
if defined?(::PhusionPassenger)
|
174
|
+
if (defined?(::PhusionPassenger) || Gem.loaded_specs['passenger']) && incompatible_passenger_version?
|
175
175
|
Datadog.logger.warn(
|
176
|
-
'Enabling the profiling "no signals" workaround because the passenger
|
177
|
-
'
|
178
|
-
'
|
179
|
-
'Profiling data will have lower quality.'
|
176
|
+
'Enabling the profiling "no signals" workaround because an incompatible version of the passenger gem is ' \
|
177
|
+
'installed. Profiling data will have lower quality.' \
|
178
|
+
'To fix this, upgrade the passenger gem to version 6.0.19 or above.'
|
180
179
|
)
|
181
180
|
return true
|
182
181
|
end
|
@@ -237,6 +236,15 @@ module Datadog
|
|
237
236
|
true
|
238
237
|
end
|
239
238
|
end
|
239
|
+
|
240
|
+
# See https://github.com/datadog/dd-trace-rb/issues/2976 for details.
|
241
|
+
private_class_method def self.incompatible_passenger_version?
|
242
|
+
if Gem.loaded_specs['passenger']
|
243
|
+
Gem.loaded_specs['passenger'].version < Gem::Version.new('6.0.19')
|
244
|
+
else
|
245
|
+
true
|
246
|
+
end
|
247
|
+
end
|
240
248
|
end
|
241
249
|
end
|
242
250
|
end
|
@@ -62,6 +62,9 @@ module Datadog
|
|
62
62
|
# @see https://opentelemetry.io/docs/concepts/sdk-configuration/general-sdk-configuration/#get_otel__propagators
|
63
63
|
PROPAGATION_STYLE_NONE = 'none'
|
64
64
|
|
65
|
+
# Strictly stop at the first successfully serialized style.
|
66
|
+
EXTRACT_FIRST = 'DD_TRACE_PROPAGATION_EXTRACT_FIRST'
|
67
|
+
|
65
68
|
ENV_X_DATADOG_TAGS_MAX_LENGTH = 'DD_TRACE_X_DATADOG_TAGS_MAX_LENGTH'
|
66
69
|
end
|
67
70
|
|
@@ -63,6 +63,7 @@ module Datadog
|
|
63
63
|
Tracing::Configuration::Ext::Distributed::PROPAGATION_STYLE_DATADOG,
|
64
64
|
Tracing::Configuration::Ext::Distributed::PROPAGATION_STYLE_B3_MULTI_HEADER,
|
65
65
|
Tracing::Configuration::Ext::Distributed::PROPAGATION_STYLE_B3_SINGLE_HEADER,
|
66
|
+
Tracing::Configuration::Ext::Distributed::PROPAGATION_STYLE_TRACE_CONTEXT,
|
66
67
|
]
|
67
68
|
)
|
68
69
|
o.after_set do |styles|
|
@@ -93,7 +94,10 @@ module Datadog
|
|
93
94
|
o.deprecated_env Tracing::Configuration::Ext::Distributed::ENV_PROPAGATION_STYLE_INJECT_OLD
|
94
95
|
o.env Tracing::Configuration::Ext::Distributed::ENV_PROPAGATION_STYLE_INJECT
|
95
96
|
# DEV-2.0: Change default value to `tracecontext, Datadog`.
|
96
|
-
o.default [
|
97
|
+
o.default [
|
98
|
+
Tracing::Configuration::Ext::Distributed::PROPAGATION_STYLE_DATADOG,
|
99
|
+
Tracing::Configuration::Ext::Distributed::PROPAGATION_STYLE_TRACE_CONTEXT,
|
100
|
+
]
|
97
101
|
o.after_set do |styles|
|
98
102
|
# Modernize B3 options
|
99
103
|
# DEV-2.0: Can be removed with the removal of deprecated B3 constants.
|
@@ -142,6 +146,17 @@ module Datadog
|
|
142
146
|
set_option(:propagation_inject_style, styles)
|
143
147
|
end
|
144
148
|
end
|
149
|
+
|
150
|
+
# Strictly stop at the first successfully serialized style.
|
151
|
+
# This prevents the tracer from enriching the extracted context with information from
|
152
|
+
# other valid propagations styles present in the request.
|
153
|
+
# @default `DD_TRACE_PROPAGATION_EXTRACT_FIRST` environment variable, otherwise `false`.
|
154
|
+
# @return [Boolean]
|
155
|
+
option :propagation_extract_first do |o|
|
156
|
+
o.env Tracing::Configuration::Ext::Distributed::EXTRACT_FIRST
|
157
|
+
o.default false
|
158
|
+
o.type :bool
|
159
|
+
end
|
145
160
|
end
|
146
161
|
|
147
162
|
# Enable trace collection and span generation.
|
@@ -177,11 +192,11 @@ module Datadog
|
|
177
192
|
|
178
193
|
# Enable 128 bit trace id generation.
|
179
194
|
#
|
180
|
-
# @default `DD_TRACE_128_BIT_TRACEID_GENERATION_ENABLED` environment variable, otherwise `
|
195
|
+
# @default `DD_TRACE_128_BIT_TRACEID_GENERATION_ENABLED` environment variable, otherwise `true`
|
181
196
|
# @return [Boolean]
|
182
197
|
option :trace_id_128_bit_generation_enabled do |o|
|
183
198
|
o.env Tracing::Configuration::Ext::ENV_TRACE_ID_128_BIT_GENERATION_ENABLED
|
184
|
-
o.default
|
199
|
+
o.default true
|
185
200
|
o.type :bool
|
186
201
|
end
|
187
202
|
|
@@ -19,7 +19,7 @@ module Datadog
|
|
19
19
|
# post method runs the task within composited executor - in a different thread. The original arguments are
|
20
20
|
# captured to be propagated to the composited executor post method
|
21
21
|
def post(*args, &task)
|
22
|
-
digest = Tracing.active_trace.to_digest
|
22
|
+
digest = Tracing.active_trace && Tracing.active_trace.to_digest
|
23
23
|
executor = @composited_executor.is_a?(Symbol) ? Concurrent.executor(@composited_executor) : @composited_executor
|
24
24
|
|
25
25
|
# Pass the original arguments to the composited executor, which
|
@@ -25,6 +25,11 @@ module Datadog
|
|
25
25
|
o.default false
|
26
26
|
end
|
27
27
|
|
28
|
+
option :error_handler do |o|
|
29
|
+
o.type :proc
|
30
|
+
o.default_proc(&Tracing::SpanOperation::Events::DEFAULT_ON_ERROR)
|
31
|
+
end
|
32
|
+
|
28
33
|
option :analytics_sample_rate do |o|
|
29
34
|
o.type :float
|
30
35
|
o.env Ext::ENV_ANALYTICS_SAMPLE_RATE
|
@@ -21,18 +21,24 @@ module Datadog
|
|
21
21
|
# PG::Connection patch methods
|
22
22
|
module InstanceMethods
|
23
23
|
def exec(sql, *args, &block)
|
24
|
+
return super unless enabled?
|
25
|
+
|
24
26
|
trace(Ext::SPAN_EXEC, sql: sql, block: block) do |sql_statement, wrapped_block|
|
25
27
|
super(sql_statement, *args, &wrapped_block)
|
26
28
|
end
|
27
29
|
end
|
28
30
|
|
29
31
|
def exec_params(sql, params, *args, &block)
|
32
|
+
return super unless enabled?
|
33
|
+
|
30
34
|
trace(Ext::SPAN_EXEC_PARAMS, sql: sql, block: block) do |sql_statement, wrapped_block|
|
31
35
|
super(sql_statement, params, *args, &wrapped_block)
|
32
36
|
end
|
33
37
|
end
|
34
38
|
|
35
39
|
def exec_prepared(statement_name, params, *args, &block)
|
40
|
+
return super unless enabled?
|
41
|
+
|
36
42
|
trace(Ext::SPAN_EXEC_PREPARED, statement_name: statement_name, block: block) do |_, wrapped_block|
|
37
43
|
super(statement_name, params, *args, &wrapped_block)
|
38
44
|
end
|
@@ -40,6 +46,8 @@ module Datadog
|
|
40
46
|
|
41
47
|
# async_exec is an alias to exec
|
42
48
|
def async_exec(sql, *args, &block)
|
49
|
+
return super unless enabled?
|
50
|
+
|
43
51
|
trace(Ext::SPAN_ASYNC_EXEC, sql: sql, block: block) do |sql_statement, wrapped_block|
|
44
52
|
super(sql_statement, *args, &wrapped_block)
|
45
53
|
end
|
@@ -47,6 +55,8 @@ module Datadog
|
|
47
55
|
|
48
56
|
# async_exec_params is an alias to exec_params
|
49
57
|
def async_exec_params(sql, params, *args, &block)
|
58
|
+
return super unless enabled?
|
59
|
+
|
50
60
|
trace(Ext::SPAN_ASYNC_EXEC_PARAMS, sql: sql, block: block) do |sql_statement, wrapped_block|
|
51
61
|
super(sql_statement, params, *args, &wrapped_block)
|
52
62
|
end
|
@@ -54,24 +64,32 @@ module Datadog
|
|
54
64
|
|
55
65
|
# async_exec_prepared is an alias to exec_prepared
|
56
66
|
def async_exec_prepared(statement_name, params, *args, &block)
|
67
|
+
return super unless enabled?
|
68
|
+
|
57
69
|
trace(Ext::SPAN_ASYNC_EXEC_PREPARED, statement_name: statement_name, block: block) do |_, wrapped_block|
|
58
70
|
super(statement_name, params, *args, &wrapped_block)
|
59
71
|
end
|
60
72
|
end
|
61
73
|
|
62
74
|
def sync_exec(sql, *args, &block)
|
75
|
+
return super unless enabled?
|
76
|
+
|
63
77
|
trace(Ext::SPAN_SYNC_EXEC, sql: sql, block: block) do |sql_statement, wrapped_block|
|
64
78
|
super(sql_statement, *args, &wrapped_block)
|
65
79
|
end
|
66
80
|
end
|
67
81
|
|
68
82
|
def sync_exec_params(sql, params, *args, &block)
|
83
|
+
return super unless enabled?
|
84
|
+
|
69
85
|
trace(Ext::SPAN_SYNC_EXEC_PARAMS, sql: sql, block: block) do |sql_statement, wrapped_block|
|
70
86
|
super(sql_statement, params, *args, &wrapped_block)
|
71
87
|
end
|
72
88
|
end
|
73
89
|
|
74
90
|
def sync_exec_prepared(statement_name, params, *args, &block)
|
91
|
+
return super unless enabled?
|
92
|
+
|
75
93
|
trace(Ext::SPAN_SYNC_EXEC_PREPARED, statement_name: statement_name, block: block) do |_, wrapped_block|
|
76
94
|
super(statement_name, params, *args, &wrapped_block)
|
77
95
|
end
|
@@ -81,10 +99,12 @@ module Datadog
|
|
81
99
|
|
82
100
|
def trace(name, sql: nil, statement_name: nil, block: nil)
|
83
101
|
service = Datadog.configuration_for(self, :service_name) || datadog_configuration[:service_name]
|
102
|
+
error_handler = datadog_configuration[:error_handler]
|
84
103
|
resource = statement_name || sql
|
85
104
|
|
86
105
|
Tracing.trace(
|
87
106
|
name,
|
107
|
+
on_error: error_handler,
|
88
108
|
service: service,
|
89
109
|
resource: resource,
|
90
110
|
type: Tracing::Metadata::Ext::SQL::TYPE
|
@@ -172,6 +192,10 @@ module Datadog
|
|
172
192
|
def comment_propagation
|
173
193
|
datadog_configuration[:comment_propagation]
|
174
194
|
end
|
195
|
+
|
196
|
+
def enabled?
|
197
|
+
datadog_configuration[:enabled]
|
198
|
+
end
|
175
199
|
end
|
176
200
|
end
|
177
201
|
end
|