ddtrace 1.16.0 → 1.18.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|