datadog 2.12.2 → 2.13.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 +36 -1
- data/ext/datadog_profiling_native_extension/collectors_thread_context.c +14 -13
- data/lib/datadog/appsec/actions_handler/serializable_backtrace.rb +89 -0
- data/lib/datadog/appsec/actions_handler.rb +22 -1
- data/lib/datadog/appsec/anonymizer.rb +16 -0
- data/lib/datadog/appsec/configuration/settings.rb +62 -10
- data/lib/datadog/appsec/contrib/auto_instrument.rb +1 -1
- data/lib/datadog/appsec/contrib/devise/configuration.rb +7 -31
- data/lib/datadog/appsec/contrib/devise/data_extractor.rb +79 -0
- data/lib/datadog/appsec/contrib/devise/ext.rb +21 -0
- data/lib/datadog/appsec/contrib/devise/integration.rb +0 -1
- data/lib/datadog/appsec/contrib/devise/patcher.rb +36 -23
- data/lib/datadog/appsec/contrib/devise/patches/signin_tracking_patch.rb +102 -0
- data/lib/datadog/appsec/contrib/devise/patches/signup_tracking_patch.rb +69 -0
- data/lib/datadog/appsec/contrib/devise/{patcher/rememberable_patch.rb → patches/skip_signin_tracking_patch.rb} +2 -2
- data/lib/datadog/appsec/contrib/devise/tracking_middleware.rb +93 -0
- data/lib/datadog/appsec/contrib/rack/ext.rb +14 -0
- data/lib/datadog/appsec/contrib/rack/gateway/watcher.rb +10 -3
- data/lib/datadog/appsec/contrib/rack/request_middleware.rb +0 -2
- data/lib/datadog/appsec/event.rb +1 -1
- data/lib/datadog/appsec/ext.rb +4 -2
- data/lib/datadog/appsec/instrumentation/gateway/argument.rb +4 -2
- data/lib/datadog/appsec/monitor/gateway/watcher.rb +8 -3
- data/lib/datadog/appsec/security_engine/runner.rb +2 -2
- data/lib/datadog/appsec/utils.rb +0 -2
- data/lib/datadog/core/configuration/components.rb +2 -1
- data/lib/datadog/core/configuration/ext.rb +4 -0
- data/lib/datadog/core/configuration/options.rb +2 -2
- data/lib/datadog/core/configuration/settings.rb +53 -30
- data/lib/datadog/core/environment/agent_info.rb +4 -3
- data/lib/datadog/core/remote/component.rb +3 -6
- data/lib/datadog/core/remote/configuration/repository.rb +2 -1
- data/lib/datadog/core/remote/negotiation.rb +9 -9
- data/lib/datadog/core/remote/transport/config.rb +4 -3
- data/lib/datadog/core/remote/transport/http/client.rb +4 -3
- data/lib/datadog/core/remote/transport/http/config.rb +6 -32
- data/lib/datadog/core/remote/transport/http/negotiation.rb +6 -32
- data/lib/datadog/core/remote/transport/http.rb +22 -57
- data/lib/datadog/core/remote/transport/negotiation.rb +4 -3
- data/lib/datadog/core/runtime/metrics.rb +8 -1
- data/lib/datadog/core/telemetry/http/adapters/net.rb +1 -1
- data/lib/datadog/core/transport/http/api/instance.rb +17 -0
- data/lib/datadog/core/transport/http/api/spec.rb +17 -0
- data/lib/datadog/core/transport/http/builder.rb +5 -3
- data/lib/datadog/core/transport/http.rb +39 -2
- data/lib/datadog/di/component.rb +0 -2
- data/lib/datadog/di/probe_notifier_worker.rb +16 -16
- data/lib/datadog/di/transport/diagnostics.rb +4 -3
- data/lib/datadog/di/transport/http/api.rb +2 -12
- data/lib/datadog/di/transport/http/client.rb +4 -3
- data/lib/datadog/di/transport/http/diagnostics.rb +7 -33
- data/lib/datadog/di/transport/http/input.rb +7 -33
- data/lib/datadog/di/transport/http.rb +14 -56
- data/lib/datadog/di/transport/input.rb +4 -3
- data/lib/datadog/di/utils.rb +5 -0
- data/lib/datadog/kit/appsec/events.rb +9 -0
- data/lib/datadog/kit/identity.rb +5 -1
- data/lib/datadog/opentelemetry/api/baggage.rb +90 -0
- data/lib/datadog/opentelemetry/api/baggage.rbs +26 -0
- data/lib/datadog/opentelemetry/api/context.rb +16 -2
- data/lib/datadog/opentelemetry/sdk/trace/span.rb +1 -1
- data/lib/datadog/opentelemetry.rb +2 -1
- data/lib/datadog/profiling/collectors/thread_context.rb +1 -1
- data/lib/datadog/profiling.rb +5 -2
- data/lib/datadog/tracing/component.rb +15 -12
- data/lib/datadog/tracing/configuration/ext.rb +7 -1
- data/lib/datadog/tracing/configuration/settings.rb +18 -2
- data/lib/datadog/tracing/context_provider.rb +1 -1
- data/lib/datadog/tracing/contrib/configuration/settings.rb +1 -1
- data/lib/datadog/tracing/contrib/ethon/easy_patch.rb +4 -5
- data/lib/datadog/tracing/contrib/excon/middleware.rb +5 -3
- data/lib/datadog/tracing/contrib/faraday/middleware.rb +5 -3
- data/lib/datadog/tracing/contrib/grpc/datadog_interceptor/client.rb +7 -1
- data/lib/datadog/tracing/contrib/grpc/distributed/propagation.rb +3 -0
- data/lib/datadog/tracing/contrib/http/circuit_breaker.rb +0 -15
- data/lib/datadog/tracing/contrib/http/distributed/propagation.rb +4 -1
- data/lib/datadog/tracing/contrib/http/instrumentation.rb +5 -5
- data/lib/datadog/tracing/contrib/httpclient/instrumentation.rb +5 -11
- data/lib/datadog/tracing/contrib/httprb/instrumentation.rb +6 -10
- data/lib/datadog/tracing/contrib/rest_client/request_patch.rb +5 -3
- data/lib/datadog/tracing/contrib/sidekiq/client_tracer.rb +6 -1
- data/lib/datadog/tracing/contrib/sidekiq/distributed/propagation.rb +3 -0
- data/lib/datadog/tracing/correlation.rb +9 -2
- data/lib/datadog/tracing/distributed/baggage.rb +131 -0
- data/lib/datadog/tracing/distributed/datadog.rb +2 -0
- data/lib/datadog/tracing/distributed/propagation.rb +25 -4
- data/lib/datadog/tracing/distributed/propagation_policy.rb +42 -0
- data/lib/datadog/tracing/metadata/ext.rb +5 -0
- data/lib/datadog/tracing/sampling/span/rule.rb +0 -1
- data/lib/datadog/tracing/span_operation.rb +2 -1
- data/lib/datadog/tracing/sync_writer.rb +1 -2
- data/lib/datadog/tracing/trace_digest.rb +9 -2
- data/lib/datadog/tracing/trace_operation.rb +29 -17
- data/lib/datadog/tracing/trace_segment.rb +6 -4
- data/lib/datadog/tracing/tracer.rb +38 -2
- data/lib/datadog/tracing/transport/http/api.rb +2 -10
- data/lib/datadog/tracing/transport/http/client.rb +5 -4
- data/lib/datadog/tracing/transport/http/traces.rb +13 -41
- data/lib/datadog/tracing/transport/http.rb +11 -44
- data/lib/datadog/tracing/transport/trace_formatter.rb +7 -0
- data/lib/datadog/tracing/transport/traces.rb +21 -9
- data/lib/datadog/tracing/workers/trace_writer.rb +2 -6
- data/lib/datadog/tracing/writer.rb +2 -6
- data/lib/datadog/tracing.rb +16 -3
- data/lib/datadog/version.rb +2 -2
- metadata +17 -13
- data/lib/datadog/appsec/contrib/devise/event.rb +0 -54
- data/lib/datadog/appsec/contrib/devise/patcher/authenticatable_patch.rb +0 -72
- data/lib/datadog/appsec/contrib/devise/patcher/registration_controller_patch.rb +0 -47
- data/lib/datadog/appsec/contrib/devise/resource.rb +0 -35
- data/lib/datadog/appsec/contrib/devise/tracking.rb +0 -57
- data/lib/datadog/appsec/utils/trace_operation.rb +0 -15
@@ -80,6 +80,9 @@ module Datadog
|
|
80
80
|
# This allows later propagation to include those unknown fields, as they can represent future versions of the spec
|
81
81
|
# sending data through this service. This value ends in a trailing `;` to facilitate serialization.
|
82
82
|
# @return [String]
|
83
|
+
# @!attribute [r] baggage
|
84
|
+
# The W3C "baggage" extracted from a distributed context. This field is a hash of key/value pairs.
|
85
|
+
# @return [Hash<String,String>]
|
83
86
|
# TODO: The documentation for the last attribute above won't be rendered.
|
84
87
|
# TODO: This might be a YARD bug as adding an attribute, making it now second-last attribute, renders correctly.
|
85
88
|
attr_reader \
|
@@ -102,7 +105,8 @@ module Datadog
|
|
102
105
|
:trace_flags,
|
103
106
|
:trace_state,
|
104
107
|
:trace_state_unknown_fields,
|
105
|
-
:span_remote
|
108
|
+
:span_remote,
|
109
|
+
:baggage
|
106
110
|
|
107
111
|
def initialize(
|
108
112
|
span_id: nil,
|
@@ -124,7 +128,8 @@ module Datadog
|
|
124
128
|
trace_flags: nil,
|
125
129
|
trace_state: nil,
|
126
130
|
trace_state_unknown_fields: nil,
|
127
|
-
span_remote: true
|
131
|
+
span_remote: true,
|
132
|
+
baggage: nil
|
128
133
|
)
|
129
134
|
@span_id = span_id
|
130
135
|
@span_name = span_name && span_name.dup.freeze
|
@@ -146,6 +151,7 @@ module Datadog
|
|
146
151
|
@trace_state = trace_state && trace_state.dup.freeze
|
147
152
|
@trace_state_unknown_fields = trace_state_unknown_fields && trace_state_unknown_fields.dup.freeze
|
148
153
|
@span_remote = span_remote
|
154
|
+
@baggage = baggage && baggage.dup.freeze
|
149
155
|
freeze
|
150
156
|
end
|
151
157
|
|
@@ -177,6 +183,7 @@ module Datadog
|
|
177
183
|
trace_state: trace_state,
|
178
184
|
trace_state_unknown_fields: trace_state_unknown_fields,
|
179
185
|
span_remote: span_remote,
|
186
|
+
baggage: baggage
|
180
187
|
}.merge!(field_value_pairs)
|
181
188
|
)
|
182
189
|
end
|
@@ -2,7 +2,6 @@
|
|
2
2
|
|
3
3
|
require_relative '../core/environment/identity'
|
4
4
|
require_relative '../core/utils'
|
5
|
-
require_relative 'tracer'
|
6
5
|
require_relative 'event'
|
7
6
|
require_relative 'metadata/tagging'
|
8
7
|
require_relative 'sampling/ext'
|
@@ -37,7 +36,8 @@ module Datadog
|
|
37
36
|
:rule_sample_rate,
|
38
37
|
:sample_rate,
|
39
38
|
:sampling_priority,
|
40
|
-
:remote_parent
|
39
|
+
:remote_parent,
|
40
|
+
:baggage
|
41
41
|
|
42
42
|
attr_reader \
|
43
43
|
:active_span_count,
|
@@ -71,19 +71,21 @@ module Datadog
|
|
71
71
|
sampling_priority: nil,
|
72
72
|
service: nil,
|
73
73
|
profiling_enabled: nil,
|
74
|
+
apm_tracing_enabled: nil,
|
74
75
|
tags: nil,
|
75
76
|
metrics: nil,
|
76
77
|
trace_state: nil,
|
77
78
|
trace_state_unknown_fields: nil,
|
78
79
|
remote_parent: false,
|
79
|
-
tracer: nil
|
80
|
+
tracer: nil,
|
81
|
+
baggage: nil
|
80
82
|
|
81
83
|
)
|
82
84
|
# Attributes
|
83
85
|
@id = id || Tracing::Utils::TraceId.next_id
|
84
86
|
@max_length = max_length || DEFAULT_MAX_LENGTH
|
85
87
|
@parent_span_id = parent_span_id
|
86
|
-
@sampled = sampled.nil?
|
88
|
+
@sampled = sampled.nil? || sampled
|
87
89
|
@remote_parent = remote_parent
|
88
90
|
|
89
91
|
# Tags
|
@@ -98,9 +100,11 @@ module Datadog
|
|
98
100
|
@sampling_priority = sampling_priority
|
99
101
|
@service = service
|
100
102
|
@profiling_enabled = profiling_enabled
|
103
|
+
@apm_tracing_enabled = apm_tracing_enabled
|
101
104
|
@trace_state = trace_state
|
102
105
|
@trace_state_unknown_fields = trace_state_unknown_fields
|
103
106
|
@tracer = tracer
|
107
|
+
@baggage = baggage
|
104
108
|
|
105
109
|
# Generic tags
|
106
110
|
set_tags(tags) if tags
|
@@ -173,6 +177,12 @@ module Datadog
|
|
173
177
|
super || (root_span && root_span.get_metric(key))
|
174
178
|
end
|
175
179
|
|
180
|
+
def set_distributed_source(product_bit)
|
181
|
+
source = get_tag(Metadata::Ext::Distributed::TAG_TRACE_SOURCE)&.to_i(16) || 0
|
182
|
+
source |= product_bit
|
183
|
+
set_tag(Metadata::Ext::Distributed::TAG_TRACE_SOURCE, format('%02X', source))
|
184
|
+
end
|
185
|
+
|
176
186
|
def tags
|
177
187
|
all_tags = {}
|
178
188
|
all_tags.merge!(root_span&.tags || {}) if root_span
|
@@ -315,10 +325,10 @@ module Datadog
|
|
315
325
|
|
316
326
|
TraceDigest.new(
|
317
327
|
span_id: span_id,
|
318
|
-
span_name:
|
319
|
-
span_resource:
|
320
|
-
span_service:
|
321
|
-
span_type:
|
328
|
+
span_name: @active_span && @active_span.name,
|
329
|
+
span_resource: @active_span && @active_span.resource,
|
330
|
+
span_service: @active_span && @active_span.service,
|
331
|
+
span_type: @active_span && @active_span.type,
|
322
332
|
trace_distributed_tags: distributed_tags,
|
323
333
|
trace_hostname: @hostname,
|
324
334
|
trace_id: @id,
|
@@ -331,7 +341,8 @@ module Datadog
|
|
331
341
|
trace_service: service,
|
332
342
|
trace_state: @trace_state,
|
333
343
|
trace_state_unknown_fields: @trace_state_unknown_fields,
|
334
|
-
span_remote:
|
344
|
+
span_remote: @remote_parent && @active_span.nil?,
|
345
|
+
baggage: @baggage.nil? || @baggage.empty? ? nil : @baggage
|
335
346
|
).freeze
|
336
347
|
end
|
337
348
|
|
@@ -351,22 +362,22 @@ module Datadog
|
|
351
362
|
def fork_clone
|
352
363
|
self.class.new(
|
353
364
|
agent_sample_rate: @agent_sample_rate,
|
354
|
-
events:
|
355
|
-
hostname:
|
365
|
+
events: @events && @events.dup,
|
366
|
+
hostname: @hostname && @hostname.dup,
|
356
367
|
id: @id,
|
357
368
|
max_length: @max_length,
|
358
|
-
name:
|
359
|
-
origin:
|
369
|
+
name: name && name.dup,
|
370
|
+
origin: @origin && @origin.dup,
|
360
371
|
parent_span_id: (@active_span && @active_span.id) || @parent_span_id,
|
361
372
|
rate_limiter_rate: @rate_limiter_rate,
|
362
|
-
resource:
|
373
|
+
resource: resource && resource.dup,
|
363
374
|
rule_sample_rate: @rule_sample_rate,
|
364
375
|
sample_rate: @sample_rate,
|
365
376
|
sampled: @sampled,
|
366
377
|
sampling_priority: @sampling_priority,
|
367
|
-
service:
|
368
|
-
trace_state:
|
369
|
-
trace_state_unknown_fields:
|
378
|
+
service: service && service.dup,
|
379
|
+
trace_state: @trace_state && @trace_state.dup,
|
380
|
+
trace_state_unknown_fields: @trace_state_unknown_fields && @trace_state_unknown_fields.dup,
|
370
381
|
tags: meta.dup,
|
371
382
|
metrics: metrics.dup,
|
372
383
|
remote_parent: @remote_parent
|
@@ -510,6 +521,7 @@ module Datadog
|
|
510
521
|
metrics: metrics,
|
511
522
|
root_span_id: !partial ? root_span && root_span.id : nil,
|
512
523
|
profiling_enabled: @profiling_enabled,
|
524
|
+
apm_tracing_enabled: @apm_tracing_enabled
|
513
525
|
)
|
514
526
|
end
|
515
527
|
|
@@ -34,7 +34,8 @@ module Datadog
|
|
34
34
|
:sampling_decision_maker,
|
35
35
|
:sampling_priority,
|
36
36
|
:service,
|
37
|
-
:profiling_enabled
|
37
|
+
:profiling_enabled,
|
38
|
+
:apm_tracing_enabled
|
38
39
|
|
39
40
|
# rubocop:disable Metrics/CyclomaticComplexity
|
40
41
|
# rubocop:disable Metrics/PerceivedComplexity
|
@@ -58,7 +59,8 @@ module Datadog
|
|
58
59
|
service: nil,
|
59
60
|
tags: nil,
|
60
61
|
metrics: nil,
|
61
|
-
profiling_enabled: nil
|
62
|
+
profiling_enabled: nil,
|
63
|
+
apm_tracing_enabled: nil
|
62
64
|
)
|
63
65
|
@id = id
|
64
66
|
@root_span_id = root_span_id
|
@@ -85,6 +87,7 @@ module Datadog
|
|
85
87
|
@sampling_priority = sampling_priority || sampling_priority_tag
|
86
88
|
@service = Core::Utils::SafeDup.frozen_or_dup(service || service_tag)
|
87
89
|
@profiling_enabled = profiling_enabled
|
90
|
+
@apm_tracing_enabled = apm_tracing_enabled
|
88
91
|
end
|
89
92
|
# rubocop:enable Metrics/PerceivedComplexity
|
90
93
|
# rubocop:enable Metrics/CyclomaticComplexity
|
@@ -128,8 +131,7 @@ module Datadog
|
|
128
131
|
end
|
129
132
|
|
130
133
|
def sampled?
|
131
|
-
|
132
|
-
|| sampling_priority == Sampling::Ext::Priority::USER_KEEP
|
134
|
+
[Sampling::Ext::Priority::AUTO_KEEP, Sampling::Ext::Priority::USER_KEEP].include?(sampling_priority)
|
133
135
|
end
|
134
136
|
|
135
137
|
# Returns the high order part of the trace id as a hexadecimal string; the most significant 64 bits.
|
@@ -338,24 +338,30 @@ module Datadog
|
|
338
338
|
hostname = hostname && !hostname.empty? ? hostname : nil
|
339
339
|
|
340
340
|
if digest
|
341
|
+
sampling_priority = if propagate_sampling_priority?(upstream_tags: digest.trace_distributed_tags)
|
342
|
+
digest.trace_sampling_priority
|
343
|
+
end
|
341
344
|
TraceOperation.new(
|
342
345
|
hostname: hostname,
|
343
346
|
profiling_enabled: profiling_enabled,
|
347
|
+
apm_tracing_enabled: apm_tracing_enabled,
|
344
348
|
id: digest.trace_id,
|
345
349
|
origin: digest.trace_origin,
|
346
350
|
parent_span_id: digest.span_id,
|
347
|
-
sampling_priority:
|
351
|
+
sampling_priority: sampling_priority,
|
348
352
|
# Distributed tags are just regular trace tags with special meaning to Datadog
|
349
353
|
tags: digest.trace_distributed_tags,
|
350
354
|
trace_state: digest.trace_state,
|
351
355
|
trace_state_unknown_fields: digest.trace_state_unknown_fields,
|
352
356
|
remote_parent: digest.span_remote,
|
353
|
-
tracer: self
|
357
|
+
tracer: self,
|
358
|
+
baggage: digest.baggage
|
354
359
|
)
|
355
360
|
else
|
356
361
|
TraceOperation.new(
|
357
362
|
hostname: hostname,
|
358
363
|
profiling_enabled: profiling_enabled,
|
364
|
+
apm_tracing_enabled: apm_tracing_enabled,
|
359
365
|
remote_parent: false,
|
360
366
|
tracer: self
|
361
367
|
)
|
@@ -545,10 +551,40 @@ module Datadog
|
|
545
551
|
end
|
546
552
|
end
|
547
553
|
|
554
|
+
# Decide whether upstream sampling priority should be propagated, by taking into account
|
555
|
+
# the upstream tags and the configuration.
|
556
|
+
# We should always propagate if APM is enabled.
|
557
|
+
#
|
558
|
+
# e.g.: upstream tags containing dd.p.ts: 02, and appsec is enabled, return true.
|
559
|
+
def propagate_sampling_priority?(upstream_tags:)
|
560
|
+
return true if apm_tracing_enabled
|
561
|
+
|
562
|
+
if upstream_tags&.key?(Tracing::Metadata::Ext::Distributed::TAG_TRACE_SOURCE)
|
563
|
+
appsec_bit = upstream_tags[Tracing::Metadata::Ext::Distributed::TAG_TRACE_SOURCE].to_i(16) &
|
564
|
+
Datadog::AppSec::Ext::PRODUCT_BIT
|
565
|
+
return appsec_enabled if appsec_bit != 0
|
566
|
+
end
|
567
|
+
|
568
|
+
false
|
569
|
+
end
|
570
|
+
|
548
571
|
def profiling_enabled
|
549
572
|
@profiling_enabled ||=
|
550
573
|
!!(defined?(Datadog::Profiling) && Datadog::Profiling.respond_to?(:enabled?) && Datadog::Profiling.enabled?)
|
551
574
|
end
|
575
|
+
|
576
|
+
def appsec_enabled
|
577
|
+
@appsec_enabled ||= Datadog.configuration.appsec.enabled
|
578
|
+
end
|
579
|
+
|
580
|
+
# Due to APM Tracing (the product) and Tracing (the transport) being intertwined, we cannot completely disabled APM
|
581
|
+
# without also disabling the tracer. When setting `@apm_tracing_enabled` to `false`, it does not disable the tracer,
|
582
|
+
# but rather only sends heartbeat traces (1 per minutes), so that the service is considered alive in the backend.
|
583
|
+
# Other products (like ASM) can then set the sampling priority of their traces to `MANUAL_KEEP`,
|
584
|
+
# effectively allowing standalone products to work without APM.
|
585
|
+
def apm_tracing_enabled
|
586
|
+
@apm_tracing_enabled ||= Datadog.configuration.apm.tracing.enabled
|
587
|
+
end
|
552
588
|
end
|
553
589
|
end
|
554
590
|
end
|
@@ -22,14 +22,14 @@ module Datadog
|
|
22
22
|
|
23
23
|
def defaults
|
24
24
|
Core::Transport::HTTP::API::Map[
|
25
|
-
V4 => Spec.new do |s|
|
25
|
+
V4 => Traces::API::Spec.new do |s|
|
26
26
|
s.traces = Traces::API::Endpoint.new(
|
27
27
|
'/v0.4/traces',
|
28
28
|
Core::Encoding::MsgpackEncoder,
|
29
29
|
service_rates: true
|
30
30
|
)
|
31
31
|
end,
|
32
|
-
V3 => Spec.new do |s|
|
32
|
+
V3 => Traces::API::Spec.new do |s|
|
33
33
|
s.traces = Traces::API::Endpoint.new(
|
34
34
|
'/v0.3/traces',
|
35
35
|
Core::Encoding::MsgpackEncoder
|
@@ -37,14 +37,6 @@ module Datadog
|
|
37
37
|
end,
|
38
38
|
].with_fallbacks(V4 => V3)
|
39
39
|
end
|
40
|
-
|
41
|
-
class Instance < Core::Transport::HTTP::API::Instance
|
42
|
-
include Traces::API::Instance
|
43
|
-
end
|
44
|
-
|
45
|
-
class Spec < Core::Transport::HTTP::API::Spec
|
46
|
-
include Traces::API::Spec
|
47
|
-
end
|
48
40
|
end
|
49
41
|
end
|
50
42
|
end
|
@@ -12,10 +12,11 @@ module Datadog
|
|
12
12
|
class Client
|
13
13
|
include Datadog::Tracing::Transport::HTTP::Statistics
|
14
14
|
|
15
|
-
attr_reader :api
|
15
|
+
attr_reader :api, :logger
|
16
16
|
|
17
|
-
def initialize(api)
|
17
|
+
def initialize(api, logger)
|
18
18
|
@api = api
|
19
|
+
@logger = logger
|
19
20
|
end
|
20
21
|
|
21
22
|
def send_request(request, &block)
|
@@ -36,10 +37,10 @@ module Datadog
|
|
36
37
|
|
37
38
|
# Log error
|
38
39
|
if stats.consecutive_errors > 0
|
39
|
-
|
40
|
+
logger.debug(message)
|
40
41
|
else
|
41
42
|
# Not to report telemetry logs
|
42
|
-
|
43
|
+
logger.error(message)
|
43
44
|
end
|
44
45
|
|
45
46
|
# Update statistics
|
@@ -6,6 +6,8 @@ require_relative '../traces'
|
|
6
6
|
require_relative 'client'
|
7
7
|
require_relative '../../../core/transport/http/response'
|
8
8
|
require_relative '../../../core/transport/http/api/endpoint'
|
9
|
+
require_relative '../../../core/transport/http/api/spec'
|
10
|
+
require_relative '../../../core/transport/http/api/instance'
|
9
11
|
|
10
12
|
module Datadog
|
11
13
|
module Tracing
|
@@ -35,16 +37,12 @@ module Datadog
|
|
35
37
|
end
|
36
38
|
|
37
39
|
module API
|
38
|
-
#
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
def traces=(endpoint)
|
43
|
-
@traces = endpoint
|
44
|
-
end
|
40
|
+
# HTTP API Spec
|
41
|
+
class Spec < Core::Transport::HTTP::API::Spec
|
42
|
+
attr_accessor :traces
|
45
43
|
|
46
44
|
def send_traces(env, &block)
|
47
|
-
raise
|
45
|
+
raise Core::Transport::HTTP::API::Spec::EndpointNotDefinedError.new('traces', self) if traces.nil?
|
48
46
|
|
49
47
|
traces.call(env, &block)
|
50
48
|
end
|
@@ -52,47 +50,21 @@ module Datadog
|
|
52
50
|
def encoder
|
53
51
|
traces.encoder
|
54
52
|
end
|
55
|
-
|
56
|
-
# Raised when traces sent but no traces endpoint is defined
|
57
|
-
class NoTraceEndpointDefinedError < StandardError
|
58
|
-
attr_reader :spec
|
59
|
-
|
60
|
-
def initialize(spec)
|
61
|
-
super
|
62
|
-
|
63
|
-
@spec = spec
|
64
|
-
end
|
65
|
-
|
66
|
-
def message
|
67
|
-
'No trace endpoint is defined for API specification!'
|
68
|
-
end
|
69
|
-
end
|
70
53
|
end
|
71
54
|
|
72
|
-
#
|
73
|
-
|
55
|
+
# HTTP API Instance
|
56
|
+
class Instance < Core::Transport::HTTP::API::Instance
|
74
57
|
def send_traces(env)
|
75
|
-
|
58
|
+
unless spec.is_a?(Traces::API::Spec)
|
59
|
+
raise Core::Transport::HTTP::API::Instance::EndpointNotSupportedError.new(
|
60
|
+
'traces', self
|
61
|
+
)
|
62
|
+
end
|
76
63
|
|
77
64
|
spec.send_traces(env) do |request_env|
|
78
65
|
call(request_env)
|
79
66
|
end
|
80
67
|
end
|
81
|
-
|
82
|
-
# Raised when traces sent to API that does not support traces
|
83
|
-
class TracesNotSupportedError < StandardError
|
84
|
-
attr_reader :spec
|
85
|
-
|
86
|
-
def initialize(spec)
|
87
|
-
super
|
88
|
-
|
89
|
-
@spec = spec
|
90
|
-
end
|
91
|
-
|
92
|
-
def message
|
93
|
-
'Traces not supported for this API!'
|
94
|
-
end
|
95
|
-
end
|
96
68
|
end
|
97
69
|
|
98
70
|
# Endpoint for submitting trace data
|
@@ -14,62 +14,29 @@ module Datadog
|
|
14
14
|
module HTTP
|
15
15
|
module_function
|
16
16
|
|
17
|
-
# Builds a new Transport::HTTP::Client
|
18
|
-
def new(klass, &block)
|
19
|
-
Core::Transport::HTTP.build(
|
20
|
-
api_instance_class: API::Instance, &block
|
21
|
-
).to_transport(klass)
|
22
|
-
end
|
23
|
-
|
24
17
|
# Builds a new Transport::HTTP::Client with default settings
|
25
18
|
# Pass a block to override any settings.
|
26
19
|
def default(
|
27
20
|
agent_settings:,
|
28
|
-
|
21
|
+
logger:,
|
22
|
+
api_version: nil,
|
23
|
+
headers: nil
|
29
24
|
)
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
25
|
+
Core::Transport::HTTP.build(
|
26
|
+
api_instance_class: Traces::API::Instance,
|
27
|
+
agent_settings: agent_settings,
|
28
|
+
logger: logger,
|
29
|
+
api_version: api_version,
|
30
|
+
headers: headers
|
31
|
+
) do |transport|
|
34
32
|
apis = API.defaults
|
35
33
|
|
36
34
|
transport.api API::V4, apis[API::V4], fallback: API::V3, default: true
|
37
35
|
transport.api API::V3, apis[API::V3]
|
38
36
|
|
39
|
-
# Apply any settings given by options
|
40
|
-
unless options.empty?
|
41
|
-
transport.default_api = options[:api_version] if options.key?(:api_version)
|
42
|
-
transport.headers options[:headers] if options.key?(:headers)
|
43
|
-
end
|
44
|
-
|
45
37
|
# Call block to apply any customization, if provided
|
46
38
|
yield(transport) if block_given?
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
def default_headers
|
51
|
-
{
|
52
|
-
Datadog::Core::Transport::Ext::HTTP::HEADER_CLIENT_COMPUTED_TOP_LEVEL => '1',
|
53
|
-
Datadog::Core::Transport::Ext::HTTP::HEADER_META_LANG => Datadog::Core::Environment::Ext::LANG,
|
54
|
-
Datadog::Core::Transport::Ext::HTTP::HEADER_META_LANG_VERSION => Datadog::Core::Environment::Ext::LANG_VERSION,
|
55
|
-
Datadog::Core::Transport::Ext::HTTP::HEADER_META_LANG_INTERPRETER =>
|
56
|
-
Datadog::Core::Environment::Ext::LANG_INTERPRETER,
|
57
|
-
Datadog::Core::Transport::Ext::HTTP::HEADER_META_LANG_INTERPRETER_VENDOR => Core::Environment::Ext::LANG_ENGINE,
|
58
|
-
Datadog::Core::Transport::Ext::HTTP::HEADER_META_TRACER_VERSION =>
|
59
|
-
Datadog::Core::Environment::Ext::GEM_DATADOG_VERSION
|
60
|
-
}.tap do |headers|
|
61
|
-
# Add container ID, if present.
|
62
|
-
container_id = Datadog::Core::Environment::Container.container_id
|
63
|
-
headers[Datadog::Core::Transport::Ext::HTTP::HEADER_CONTAINER_ID] = container_id unless container_id.nil?
|
64
|
-
# Pretend that stats computation are already done by the client
|
65
|
-
if Datadog.configuration.appsec.standalone.enabled
|
66
|
-
headers[Datadog::Core::Transport::Ext::HTTP::HEADER_CLIENT_COMPUTED_STATS] = 'yes'
|
67
|
-
end
|
68
|
-
end
|
69
|
-
end
|
70
|
-
|
71
|
-
def default_adapter
|
72
|
-
Datadog::Core::Configuration::Ext::Agent::HTTP::ADAPTER
|
39
|
+
end.to_transport(Transport::Traces::Transport)
|
73
40
|
end
|
74
41
|
end
|
75
42
|
end
|
@@ -59,6 +59,7 @@ module Datadog
|
|
59
59
|
tag_high_order_trace_id!
|
60
60
|
tag_sampling_priority!
|
61
61
|
tag_profiling_enabled!
|
62
|
+
tag_apm_tracing_disabled!
|
62
63
|
|
63
64
|
if first_span
|
64
65
|
tag_git_repository_url!
|
@@ -196,6 +197,12 @@ module Datadog
|
|
196
197
|
)
|
197
198
|
end
|
198
199
|
|
200
|
+
def tag_apm_tracing_disabled!
|
201
|
+
return if trace.apm_tracing_enabled
|
202
|
+
|
203
|
+
root_span.set_tag(Tracing::Metadata::Ext::TAG_APM_ENABLED, 0)
|
204
|
+
end
|
205
|
+
|
199
206
|
def tag_git_repository_url!
|
200
207
|
return if git_repository_url.nil?
|
201
208
|
|
@@ -43,15 +43,17 @@ module Datadog
|
|
43
43
|
# We set the value to a conservative 5 MiB, in case network speed is slow.
|
44
44
|
DEFAULT_MAX_PAYLOAD_SIZE = 5 * 1024 * 1024
|
45
45
|
|
46
|
-
attr_reader :encoder, :max_size
|
46
|
+
attr_reader :encoder, :max_size, :logger
|
47
47
|
|
48
48
|
#
|
49
49
|
# Single traces larger than +max_size+ will be discarded.
|
50
50
|
#
|
51
51
|
# @param encoder [Datadog::Core::Encoding::Encoder]
|
52
|
+
# @param logger [Datadog::Core::Logger]
|
52
53
|
# @param max_size [String] maximum acceptable payload size
|
53
|
-
def initialize(encoder, native_events_supported:, max_size: DEFAULT_MAX_PAYLOAD_SIZE)
|
54
|
+
def initialize(encoder, logger, native_events_supported:, max_size: DEFAULT_MAX_PAYLOAD_SIZE)
|
54
55
|
@encoder = encoder
|
56
|
+
@logger = logger
|
55
57
|
@native_events_supported = native_events_supported
|
56
58
|
@max_size = max_size
|
57
59
|
end
|
@@ -78,11 +80,11 @@ module Datadog
|
|
78
80
|
private
|
79
81
|
|
80
82
|
def encode_one(trace)
|
81
|
-
encoded = Encoder.encode_trace(encoder, trace, native_events_supported: @native_events_supported)
|
83
|
+
encoded = Encoder.encode_trace(encoder, trace, logger, native_events_supported: @native_events_supported)
|
82
84
|
|
83
85
|
if encoded.size > max_size
|
84
86
|
# This single trace is too large, we can't flush it
|
85
|
-
|
87
|
+
logger.debug { "Dropping trace. Payload too large: '#{trace.inspect}'" }
|
86
88
|
Datadog.health_metrics.transport_trace_too_large(1)
|
87
89
|
|
88
90
|
return nil
|
@@ -96,7 +98,7 @@ module Datadog
|
|
96
98
|
module Encoder
|
97
99
|
module_function
|
98
100
|
|
99
|
-
def encode_trace(encoder, trace, native_events_supported:)
|
101
|
+
def encode_trace(encoder, trace, logger, native_events_supported:)
|
100
102
|
# Format the trace for transport
|
101
103
|
TraceFormatter.format!(trace)
|
102
104
|
|
@@ -106,7 +108,7 @@ module Datadog
|
|
106
108
|
# Encode the trace
|
107
109
|
encoder.encode(serializable_trace).tap do |encoded|
|
108
110
|
# Print the actual serialized trace, since the encoder can change make non-trivial changes
|
109
|
-
|
111
|
+
logger.debug { "Flushing trace: #{encoder.decode(encoded)}" }
|
110
112
|
end
|
111
113
|
end
|
112
114
|
end
|
@@ -117,11 +119,12 @@ module Datadog
|
|
117
119
|
# batches of traces into smaller chunks and handles
|
118
120
|
# API version downgrade handshake.
|
119
121
|
class Transport
|
120
|
-
attr_reader :client, :apis, :default_api, :current_api_id
|
122
|
+
attr_reader :client, :apis, :default_api, :current_api_id, :logger
|
121
123
|
|
122
|
-
def initialize(apis, default_api)
|
124
|
+
def initialize(apis, default_api, logger)
|
123
125
|
@apis = apis
|
124
126
|
@default_api = default_api
|
127
|
+
@logger = logger
|
125
128
|
|
126
129
|
change_api!(default_api)
|
127
130
|
end
|
@@ -130,6 +133,7 @@ module Datadog
|
|
130
133
|
encoder = current_api.encoder
|
131
134
|
chunker = Datadog::Tracing::Transport::Traces::Chunker.new(
|
132
135
|
encoder,
|
136
|
+
logger,
|
133
137
|
native_events_supported: native_events_supported?
|
134
138
|
)
|
135
139
|
|
@@ -190,7 +194,7 @@ module Datadog
|
|
190
194
|
raise UnknownApiVersionError, api_id unless apis.key?(api_id)
|
191
195
|
|
192
196
|
@current_api_id = api_id
|
193
|
-
@client = HTTP::Client.new(current_api)
|
197
|
+
@client = HTTP::Client.new(current_api, logger)
|
194
198
|
end
|
195
199
|
|
196
200
|
# Queries the agent for native span events serialization support.
|
@@ -198,6 +202,14 @@ module Datadog
|
|
198
202
|
def native_events_supported?
|
199
203
|
return @native_events_supported if defined?(@native_events_supported)
|
200
204
|
|
205
|
+
# Check for an explicit override
|
206
|
+
option = Datadog.configuration.tracing.native_span_events
|
207
|
+
unless option.nil?
|
208
|
+
@native_events_supported = option
|
209
|
+
return option
|
210
|
+
end
|
211
|
+
|
212
|
+
# Otherwise, check for agent support, to ensure a configuration-less setup.
|
201
213
|
if (res = Datadog.send(:components).agent_info.fetch)
|
202
214
|
@native_events_supported = res.span_events == true
|
203
215
|
else
|
@@ -26,14 +26,10 @@ module Datadog
|
|
26
26
|
@logger = options[:logger] || Datadog.logger
|
27
27
|
|
28
28
|
transport_options = options.fetch(:transport_options, {})
|
29
|
-
|
30
|
-
if options.key?(:agent_settings)
|
31
|
-
@agent_settings = options[:agent_settings]
|
32
|
-
transport_options = transport_options.merge(agent_settings: @agent_settings)
|
33
|
-
end
|
29
|
+
@agent_settings = options[:agent_settings]
|
34
30
|
|
35
31
|
@transport = options.fetch(:transport) do
|
36
|
-
Datadog::Tracing::Transport::HTTP.default(**transport_options)
|
32
|
+
Datadog::Tracing::Transport::HTTP.default(agent_settings: agent_settings, logger: logger, **transport_options)
|
37
33
|
end
|
38
34
|
end
|
39
35
|
# rubocop:enable Lint/MissingSuper
|
@@ -26,15 +26,11 @@ module Datadog
|
|
26
26
|
@buff_size = options.fetch(:buffer_size, Workers::AsyncTransport::DEFAULT_BUFFER_MAX_SIZE)
|
27
27
|
@flush_interval = options.fetch(:flush_interval, Workers::AsyncTransport::DEFAULT_FLUSH_INTERVAL)
|
28
28
|
transport_options = options.fetch(:transport_options, {})
|
29
|
-
|
30
|
-
if options.key?(:agent_settings)
|
31
|
-
@agent_settings = options[:agent_settings]
|
32
|
-
transport_options = transport_options.merge(agent_settings: @agent_settings)
|
33
|
-
end
|
29
|
+
@agent_settings = options[:agent_settings]
|
34
30
|
|
35
31
|
# transport and buffers
|
36
32
|
@transport = options.fetch(:transport) do
|
37
|
-
Transport::HTTP.default(**transport_options)
|
33
|
+
Transport::HTTP.default(agent_settings: agent_settings, logger: logger, **transport_options)
|
38
34
|
end
|
39
35
|
|
40
36
|
@shutdown_timeout = options.fetch(:shutdown_timeout, Workers::AsyncTransport::DEFAULT_SHUTDOWN_TIMEOUT)
|