datadog 2.10.0 → 2.12.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 +56 -1
- data/ext/datadog_profiling_native_extension/collectors_stack.c +3 -3
- data/ext/datadog_profiling_native_extension/collectors_thread_context.c +44 -1
- data/ext/datadog_profiling_native_extension/extconf.rb +4 -0
- data/ext/datadog_profiling_native_extension/gvl_profiling_helper.c +2 -0
- data/ext/datadog_profiling_native_extension/gvl_profiling_helper.h +0 -8
- data/ext/datadog_profiling_native_extension/heap_recorder.c +1 -1
- data/ext/datadog_profiling_native_extension/private_vm_api_access.c +56 -0
- data/ext/datadog_profiling_native_extension/private_vm_api_access.h +7 -0
- data/ext/datadog_profiling_native_extension/profiling.c +7 -0
- data/ext/libdatadog_api/crashtracker.c +4 -4
- data/ext/libdatadog_extconf_helpers.rb +1 -1
- data/lib/datadog/appsec/configuration/settings.rb +64 -11
- data/lib/datadog/appsec/contrib/active_record/patcher.rb +0 -3
- data/lib/datadog/appsec/contrib/devise/configuration.rb +76 -0
- data/lib/datadog/appsec/contrib/devise/event.rb +4 -7
- data/lib/datadog/appsec/contrib/devise/patcher/authenticatable_patch.rb +16 -21
- data/lib/datadog/appsec/contrib/devise/patcher/registration_controller_patch.rb +8 -15
- data/lib/datadog/appsec/contrib/devise/patcher/rememberable_patch.rb +1 -1
- data/lib/datadog/appsec/contrib/devise/patcher.rb +0 -3
- data/lib/datadog/appsec/contrib/devise/tracking.rb +1 -1
- data/lib/datadog/appsec/contrib/excon/integration.rb +41 -0
- data/lib/datadog/appsec/contrib/excon/patcher.rb +28 -0
- data/lib/datadog/appsec/contrib/excon/ssrf_detection_middleware.rb +43 -0
- data/lib/datadog/appsec/contrib/faraday/connection_patch.rb +22 -0
- data/lib/datadog/appsec/contrib/faraday/integration.rb +42 -0
- data/lib/datadog/appsec/contrib/faraday/patcher.rb +53 -0
- data/lib/datadog/appsec/contrib/faraday/rack_builder_patch.rb +22 -0
- data/lib/datadog/appsec/contrib/faraday/ssrf_detection_middleware.rb +42 -0
- data/lib/datadog/appsec/contrib/graphql/gateway/watcher.rb +10 -12
- data/lib/datadog/appsec/contrib/graphql/patcher.rb +0 -3
- data/lib/datadog/appsec/contrib/rack/gateway/watcher.rb +65 -73
- data/lib/datadog/appsec/contrib/rack/patcher.rb +0 -3
- data/lib/datadog/appsec/contrib/rails/gateway/watcher.rb +20 -25
- data/lib/datadog/appsec/contrib/rails/patcher.rb +0 -3
- data/lib/datadog/appsec/contrib/rest_client/integration.rb +45 -0
- data/lib/datadog/appsec/contrib/rest_client/patcher.rb +28 -0
- data/lib/datadog/appsec/contrib/rest_client/request_ssrf_detection_patch.rb +39 -0
- data/lib/datadog/appsec/contrib/sinatra/gateway/watcher.rb +38 -49
- data/lib/datadog/appsec/contrib/sinatra/patcher.rb +0 -3
- data/lib/datadog/appsec/monitor/gateway/watcher.rb +19 -25
- data/lib/datadog/appsec/remote.rb +4 -0
- data/lib/datadog/appsec.rb +3 -0
- data/lib/datadog/core/configuration/components.rb +8 -2
- data/lib/datadog/core/configuration/ext.rb +1 -1
- data/lib/datadog/core/configuration/option_definition.rb +2 -0
- data/lib/datadog/core/configuration/settings.rb +22 -6
- data/lib/datadog/core/encoding.rb +16 -0
- data/lib/datadog/core/environment/agent_info.rb +77 -0
- data/lib/datadog/core/remote/component.rb +11 -9
- data/lib/datadog/core/remote/transport/http/api.rb +13 -18
- data/lib/datadog/core/remote/transport/http/config.rb +0 -18
- data/lib/datadog/core/remote/transport/http/negotiation.rb +1 -18
- data/lib/datadog/core/remote/transport/http.rb +7 -12
- data/lib/datadog/core/remote/transport/negotiation.rb +13 -1
- data/lib/datadog/core/remote/worker.rb +10 -7
- data/lib/datadog/core/telemetry/component.rb +5 -1
- data/lib/datadog/core/telemetry/event.rb +5 -0
- data/lib/datadog/core/telemetry/worker.rb +9 -5
- data/lib/datadog/core/transport/http/adapters/unix_socket.rb +1 -1
- data/lib/datadog/{tracing → core}/transport/http/api/instance.rb +1 -1
- data/lib/datadog/{tracing → core}/transport/http/api/spec.rb +1 -1
- data/lib/datadog/{tracing → core}/transport/http/builder.rb +37 -17
- data/lib/datadog/core/transport/response.rb +4 -0
- data/lib/datadog/di/code_tracker.rb +15 -8
- data/lib/datadog/di/component.rb +2 -3
- data/lib/datadog/di/configuration/settings.rb +14 -0
- data/lib/datadog/di/contrib.rb +2 -0
- data/lib/datadog/di/logger.rb +30 -0
- data/lib/datadog/di/probe.rb +3 -6
- data/lib/datadog/di/probe_manager.rb +5 -2
- data/lib/datadog/di/probe_notifier_worker.rb +35 -8
- data/lib/datadog/di/remote.rb +3 -3
- data/lib/datadog/di/transport/diagnostics.rb +61 -0
- data/lib/datadog/di/transport/http/api.rb +52 -0
- data/lib/datadog/di/transport/http/client.rb +46 -0
- data/lib/datadog/di/transport/http/diagnostics.rb +92 -0
- data/lib/datadog/di/transport/http/input.rb +94 -0
- data/lib/datadog/di/transport/http.rb +119 -0
- data/lib/datadog/di/transport/input.rb +61 -0
- data/lib/datadog/di/utils.rb +91 -0
- data/lib/datadog/di.rb +5 -1
- data/lib/datadog/profiling/component.rb +2 -8
- data/lib/datadog/profiling/load_native_extension.rb +1 -33
- data/lib/datadog/tracing/component.rb +1 -0
- data/lib/datadog/tracing/configuration/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/extensions.rb +14 -0
- data/lib/datadog/tracing/contrib/graphql/configuration/error_extension_env_parser.rb +21 -0
- data/lib/datadog/tracing/contrib/graphql/configuration/settings.rb +11 -0
- data/lib/datadog/tracing/contrib/graphql/ext.rb +5 -0
- data/lib/datadog/tracing/contrib/graphql/unified_trace.rb +102 -11
- data/lib/datadog/tracing/contrib/rack/header_collection.rb +11 -1
- data/lib/datadog/tracing/contrib/rack/middlewares.rb +1 -1
- data/lib/datadog/tracing/contrib/span_attribute_schema.rb +6 -1
- data/lib/datadog/tracing/sync_writer.rb +5 -2
- data/lib/datadog/tracing/tracer.rb +10 -7
- data/lib/datadog/tracing/transport/http/api.rb +11 -2
- data/lib/datadog/tracing/transport/http/traces.rb +0 -3
- data/lib/datadog/tracing/transport/http.rb +12 -7
- data/lib/datadog/tracing/transport/serializable_trace.rb +8 -4
- data/lib/datadog/tracing/transport/traces.rb +25 -8
- data/lib/datadog/tracing/workers/trace_writer.rb +4 -1
- data/lib/datadog/tracing/workers.rb +5 -4
- data/lib/datadog/tracing/writer.rb +6 -2
- data/lib/datadog/version.rb +1 -1
- metadata +33 -29
- data/ext/datadog_profiling_loader/datadog_profiling_loader.c +0 -142
- data/ext/datadog_profiling_loader/extconf.rb +0 -60
- data/lib/datadog/appsec/contrib/graphql/reactive/multiplex.rb +0 -46
- data/lib/datadog/appsec/contrib/patcher.rb +0 -12
- data/lib/datadog/appsec/contrib/rack/reactive/request.rb +0 -69
- data/lib/datadog/appsec/contrib/rack/reactive/request_body.rb +0 -47
- data/lib/datadog/appsec/contrib/rack/reactive/response.rb +0 -53
- data/lib/datadog/appsec/contrib/rails/reactive/action.rb +0 -53
- data/lib/datadog/appsec/contrib/sinatra/reactive/routed.rb +0 -48
- data/lib/datadog/appsec/monitor/reactive/set_user.rb +0 -45
- data/lib/datadog/appsec/reactive/address_hash.rb +0 -22
- data/lib/datadog/appsec/reactive/engine.rb +0 -47
- data/lib/datadog/appsec/reactive/subscriber.rb +0 -19
- data/lib/datadog/core/remote/transport/http/api/instance.rb +0 -39
- data/lib/datadog/core/remote/transport/http/api/spec.rb +0 -21
- data/lib/datadog/core/remote/transport/http/builder.rb +0 -219
- data/lib/datadog/di/transport.rb +0 -79
@@ -47,14 +47,26 @@ module Datadog
|
|
47
47
|
end
|
48
48
|
|
49
49
|
def execute_query(*args, query:, **kwargs)
|
50
|
-
trace(
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
span.set_tag(
|
56
|
-
|
57
|
-
|
50
|
+
trace(
|
51
|
+
proc { super },
|
52
|
+
'execute',
|
53
|
+
query.selected_operation_name,
|
54
|
+
lambda { |span|
|
55
|
+
span.set_tag('graphql.source', query.query_string)
|
56
|
+
span.set_tag('graphql.operation.type', query.selected_operation.operation_type)
|
57
|
+
if query.selected_operation_name
|
58
|
+
span.set_tag(
|
59
|
+
'graphql.operation.name',
|
60
|
+
query.selected_operation_name
|
61
|
+
)
|
62
|
+
end
|
63
|
+
query.variables.instance_variable_get(:@storage).each do |key, value|
|
64
|
+
span.set_tag("graphql.variables.#{key}", value)
|
65
|
+
end
|
66
|
+
},
|
67
|
+
->(span) { add_query_error_events(span, query.context.errors) },
|
68
|
+
query: query,
|
69
|
+
)
|
58
70
|
end
|
59
71
|
|
60
72
|
def execute_query_lazy(*args, query:, multiplex:, **kwargs)
|
@@ -131,7 +143,16 @@ module Datadog
|
|
131
143
|
|
132
144
|
private
|
133
145
|
|
134
|
-
|
146
|
+
# Traces the given callable with the given trace key, resource, and kwargs.
|
147
|
+
#
|
148
|
+
# @param callable [Proc] the original method call
|
149
|
+
# @param trace_key [String] the sub-operation name (`"graphql.#{trace_key}"`)
|
150
|
+
# @param resource [String] the resource name for the trace
|
151
|
+
# @param before [Proc, nil] a callable to run before the trace, same as the block parameter
|
152
|
+
# @param after [Proc, nil] a callable to run after the trace, which has access to query values after execution
|
153
|
+
# @param kwargs [Hash] the arguments to pass to `prepare_span`
|
154
|
+
# @yield [Span] the block to run before the trace, same as the `before` parameter
|
155
|
+
def trace(callable, trace_key, resource, before = nil, after = nil, **kwargs, &before_block)
|
135
156
|
config = Datadog.configuration.tracing[:graphql]
|
136
157
|
|
137
158
|
Tracing.trace(
|
@@ -144,11 +165,20 @@ module Datadog
|
|
144
165
|
Contrib::Analytics.set_sample_rate(span, config[:analytics_sample_rate])
|
145
166
|
end
|
146
167
|
|
147
|
-
|
168
|
+
# A sanity check for us.
|
169
|
+
raise 'Please provide either `before` or a block, but not both' if before && before_block
|
170
|
+
|
171
|
+
if (before_callable = before || before_block)
|
172
|
+
before_callable.call(span)
|
173
|
+
end
|
148
174
|
|
149
175
|
prepare_span(trace_key, kwargs, span) if @has_prepare_span
|
150
176
|
|
151
|
-
callable.call
|
177
|
+
ret = callable.call
|
178
|
+
|
179
|
+
after.call(span) if after
|
180
|
+
|
181
|
+
ret
|
152
182
|
end
|
153
183
|
end
|
154
184
|
|
@@ -163,6 +193,67 @@ module Datadog
|
|
163
193
|
operations
|
164
194
|
end
|
165
195
|
end
|
196
|
+
|
197
|
+
# Create a Span Event for each error that occurs at query level.
|
198
|
+
#
|
199
|
+
# These are represented in the Datadog App as special GraphQL errors,
|
200
|
+
# given their event name `dd.graphql.query.error`.
|
201
|
+
def add_query_error_events(span, errors)
|
202
|
+
capture_extensions = Datadog.configuration.tracing[:graphql][:error_extensions]
|
203
|
+
errors.each do |error|
|
204
|
+
extensions = if !capture_extensions.empty? && (extensions = error.extensions)
|
205
|
+
# Capture extensions, ensuring all values are primitives
|
206
|
+
extensions.each_with_object({}) do |(key, value), hash|
|
207
|
+
next unless capture_extensions.include?(key.to_s)
|
208
|
+
|
209
|
+
value = case value
|
210
|
+
when TrueClass, FalseClass, Integer, Float
|
211
|
+
value
|
212
|
+
else
|
213
|
+
# Stringify anything that is not a boolean or a number
|
214
|
+
value.to_s
|
215
|
+
end
|
216
|
+
|
217
|
+
hash["extensions.#{key}"] = value
|
218
|
+
end
|
219
|
+
else
|
220
|
+
{}
|
221
|
+
end
|
222
|
+
|
223
|
+
# {::GraphQL::Error#to_h} returns the error formatted in compliance with the GraphQL spec.
|
224
|
+
# This is an unwritten contract in the `graphql` library.
|
225
|
+
# See for an example: https://github.com/rmosolgo/graphql-ruby/blob/0afa241775e5a113863766cce126214dee093464/lib/graphql/execution_error.rb#L32
|
226
|
+
graphql_error = error.to_h
|
227
|
+
error = Core::Error.build_from(error)
|
228
|
+
|
229
|
+
span.span_events << Datadog::Tracing::SpanEvent.new(
|
230
|
+
Ext::EVENT_QUERY_ERROR,
|
231
|
+
attributes: extensions.merge!(
|
232
|
+
message: graphql_error['message'],
|
233
|
+
type: error.type,
|
234
|
+
stacktrace: error.backtrace,
|
235
|
+
locations: serialize_error_locations(graphql_error['locations']),
|
236
|
+
path: graphql_error['path'],
|
237
|
+
)
|
238
|
+
)
|
239
|
+
end
|
240
|
+
end
|
241
|
+
|
242
|
+
# Serialize error's `locations` array as an array of Strings, given
|
243
|
+
# Span Events do not support hashes nested inside arrays.
|
244
|
+
#
|
245
|
+
# Here's an example in which `locations`:
|
246
|
+
# [
|
247
|
+
# {"line" => 3, "column" => 10},
|
248
|
+
# {"line" => 7, "column" => 8},
|
249
|
+
# ]
|
250
|
+
# is serialized as:
|
251
|
+
# ["3:10", "7:8"]
|
252
|
+
def serialize_error_locations(locations)
|
253
|
+
locations.map do |location|
|
254
|
+
"#{location['line']}:#{location['column']}"
|
255
|
+
end
|
256
|
+
end
|
166
257
|
end
|
167
258
|
end
|
168
259
|
end
|
@@ -31,7 +31,17 @@ module Datadog
|
|
31
31
|
end
|
32
32
|
|
33
33
|
def self.to_rack_header(name)
|
34
|
-
|
34
|
+
key = name.to_s.upcase.gsub(/[-\s]/, '_')
|
35
|
+
case key
|
36
|
+
when 'CONTENT_TYPE', 'CONTENT_LENGTH'
|
37
|
+
# NOTE: The Rack spec says:
|
38
|
+
# > The environment must not contain the keys HTTP_CONTENT_TYPE or HTTP_CONTENT_LENGTH
|
39
|
+
# > (use the versions without HTTP_).
|
40
|
+
# See https://github.com/rack/rack/blob/e217a399eb116362710aac7c5b8dc691ea2189b3/SPEC.rdoc?plain=1#L119-L121
|
41
|
+
key
|
42
|
+
else
|
43
|
+
"HTTP_#{key}"
|
44
|
+
end
|
35
45
|
end
|
36
46
|
end
|
37
47
|
end
|
@@ -43,7 +43,7 @@ module Datadog
|
|
43
43
|
# so that all spans will be added to the distributed trace.
|
44
44
|
if configuration[:distributed_tracing]
|
45
45
|
trace_digest = Contrib::HTTP.extract(env)
|
46
|
-
Tracing.continue_trace!(trace_digest)
|
46
|
+
Tracing.continue_trace!(trace_digest) if trace_digest
|
47
47
|
end
|
48
48
|
|
49
49
|
TraceProxyMiddleware.call(env, configuration) do
|
@@ -21,9 +21,14 @@ module Datadog
|
|
21
21
|
end
|
22
22
|
|
23
23
|
def self.set_peer_service!(span, sources)
|
24
|
+
config = Datadog.configuration.tracing.contrib
|
25
|
+
|
26
|
+
# If `peer_service_defaults` is disabled, we only read peer service from an explicitly set `peer.service` tag
|
27
|
+
sources = Datadog::Tracing::Contrib::SpanAttributeSchema::REFLEXIVE_SOURCES unless config.peer_service_defaults
|
28
|
+
|
24
29
|
# Acquire all peer.service values as well as any potential remapping
|
25
30
|
peer_service_val, peer_service_source = set_peer_service_from_source(span, sources)
|
26
|
-
remap_val =
|
31
|
+
remap_val = config.peer_service_mapping[peer_service_val]
|
27
32
|
|
28
33
|
# Only continue to setting peer.service if actual source is found
|
29
34
|
return false unless peer_service_source
|
@@ -17,6 +17,7 @@ module Datadog
|
|
17
17
|
# @public_api
|
18
18
|
class SyncWriter
|
19
19
|
attr_reader \
|
20
|
+
:logger,
|
20
21
|
:events,
|
21
22
|
:transport
|
22
23
|
|
@@ -25,7 +26,9 @@ module Datadog
|
|
25
26
|
# @param [Hash<Symbol,Object>] transport_options options for the default transport instance.
|
26
27
|
# @param [Datadog::Tracing::Configuration::AgentSettingsResolver::AgentSettings] agent_settings agent options for
|
27
28
|
# the default transport instance.
|
28
|
-
def initialize(transport: nil, transport_options: {}, agent_settings: nil)
|
29
|
+
def initialize(transport: nil, transport_options: {}, agent_settings: nil, logger: Datadog.logger)
|
30
|
+
@logger = logger
|
31
|
+
|
29
32
|
@transport = transport || begin
|
30
33
|
transport_options[:agent_settings] = agent_settings if agent_settings
|
31
34
|
Transport::HTTP.default(**transport_options)
|
@@ -40,7 +43,7 @@ module Datadog
|
|
40
43
|
def write(trace)
|
41
44
|
flush_trace(trace)
|
42
45
|
rescue => e
|
43
|
-
|
46
|
+
logger.debug(e)
|
44
47
|
end
|
45
48
|
|
46
49
|
# Does nothing.
|
@@ -28,7 +28,8 @@ module Datadog
|
|
28
28
|
:provider,
|
29
29
|
:sampler,
|
30
30
|
:span_sampler,
|
31
|
-
:tags
|
31
|
+
:tags,
|
32
|
+
:logger
|
32
33
|
|
33
34
|
attr_accessor \
|
34
35
|
:default_service,
|
@@ -52,17 +53,19 @@ module Datadog
|
|
52
53
|
context_provider: DefaultContextProvider.new,
|
53
54
|
default_service: Core::Environment::Ext::FALLBACK_SERVICE_NAME,
|
54
55
|
enabled: true,
|
56
|
+
logger: Datadog.logger,
|
55
57
|
sampler: Sampling::PrioritySampler.new(
|
56
58
|
base_sampler: Sampling::AllSampler.new,
|
57
59
|
post_sampler: Sampling::RuleSampler.new
|
58
60
|
),
|
59
61
|
span_sampler: Sampling::Span::Sampler.new,
|
60
62
|
tags: {},
|
61
|
-
writer: Writer.new
|
63
|
+
writer: Writer.new(logger: logger)
|
62
64
|
)
|
63
65
|
@trace_flush = trace_flush
|
64
66
|
@default_service = default_service
|
65
67
|
@enabled = enabled
|
68
|
+
@logger = logger
|
66
69
|
@provider = context_provider
|
67
70
|
@sampler = sampler
|
68
71
|
@span_sampler = span_sampler
|
@@ -146,7 +149,7 @@ module Datadog
|
|
146
149
|
active_trace
|
147
150
|
end
|
148
151
|
rescue StandardError => e
|
149
|
-
|
152
|
+
logger.debug { "Failed to trace: #{e}" }
|
150
153
|
|
151
154
|
# Tracing failed: fallback and run code without tracing.
|
152
155
|
return skip_trace(name, &block)
|
@@ -268,7 +271,7 @@ module Datadog
|
|
268
271
|
@sampler.sample!(trace_op)
|
269
272
|
rescue StandardError => e
|
270
273
|
SAMPLE_TRACE_LOG_ONLY_ONCE.run do
|
271
|
-
|
274
|
+
logger.warn { "Failed to sample trace: #{e.class.name} #{e} at #{Array(e.backtrace).first}" }
|
272
275
|
end
|
273
276
|
end
|
274
277
|
end
|
@@ -488,7 +491,7 @@ module Datadog
|
|
488
491
|
@span_sampler.sample!(trace_op, span)
|
489
492
|
rescue StandardError => e
|
490
493
|
SAMPLE_SPAN_LOG_ONLY_ONCE.run do
|
491
|
-
|
494
|
+
logger.warn { "Failed to sample span: #{e.class.name} #{e} at #{Array(e.backtrace).first}" }
|
492
495
|
end
|
493
496
|
end
|
494
497
|
end
|
@@ -504,7 +507,7 @@ module Datadog
|
|
504
507
|
write(trace) if trace && !trace.empty?
|
505
508
|
rescue StandardError => e
|
506
509
|
FLUSH_TRACE_LOG_ONLY_ONCE.run do
|
507
|
-
|
510
|
+
logger.warn { "Failed to flush trace: #{e.class.name} #{e} at #{Array(e.backtrace).first}" }
|
508
511
|
end
|
509
512
|
end
|
510
513
|
end
|
@@ -518,7 +521,7 @@ module Datadog
|
|
518
521
|
return unless trace && @writer
|
519
522
|
|
520
523
|
if Datadog.configuration.diagnostics.debug
|
521
|
-
|
524
|
+
logger.debug { "Writing #{trace.length} spans (enabled: #{@enabled})\n#{trace.spans.pretty_inspect}" }
|
522
525
|
end
|
523
526
|
|
524
527
|
@writer.write(trace)
|
@@ -3,7 +3,8 @@
|
|
3
3
|
require_relative '../../../core/encoding'
|
4
4
|
|
5
5
|
require_relative '../../../core/transport/http/api/map'
|
6
|
-
require_relative 'api/
|
6
|
+
require_relative '../../../core/transport/http/api/instance'
|
7
|
+
require_relative '../../../core/transport/http/api/spec'
|
7
8
|
|
8
9
|
require_relative 'traces'
|
9
10
|
|
@@ -20,7 +21,7 @@ module Datadog
|
|
20
21
|
module_function
|
21
22
|
|
22
23
|
def defaults
|
23
|
-
|
24
|
+
Core::Transport::HTTP::API::Map[
|
24
25
|
V4 => Spec.new do |s|
|
25
26
|
s.traces = Traces::API::Endpoint.new(
|
26
27
|
'/v0.4/traces',
|
@@ -36,6 +37,14 @@ module Datadog
|
|
36
37
|
end,
|
37
38
|
].with_fallbacks(V4 => V3)
|
38
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
|
39
48
|
end
|
40
49
|
end
|
41
50
|
end
|
@@ -6,7 +6,6 @@ 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 'api/instance'
|
10
9
|
|
11
10
|
module Datadog
|
12
11
|
module Tracing
|
@@ -143,8 +142,6 @@ module Datadog
|
|
143
142
|
|
144
143
|
# Add traces behavior to transport components
|
145
144
|
HTTP::Client.include(Traces::Client)
|
146
|
-
HTTP::API::Spec.include(Traces::API::Spec)
|
147
|
-
HTTP::API::Instance.include(Traces::API::Instance)
|
148
145
|
end
|
149
146
|
end
|
150
147
|
end
|
@@ -8,8 +8,8 @@ require_relative '../../core/transport/ext'
|
|
8
8
|
require_relative '../../core/transport/http/adapters/net'
|
9
9
|
require_relative '../../core/transport/http/adapters/test'
|
10
10
|
require_relative '../../core/transport/http/adapters/unix_socket'
|
11
|
+
require_relative '../../core/transport/http/builder'
|
11
12
|
require_relative 'http/api'
|
12
|
-
require_relative 'http/builder'
|
13
13
|
require_relative '../../../datadog/version'
|
14
14
|
|
15
15
|
module Datadog
|
@@ -30,8 +30,10 @@ module Datadog
|
|
30
30
|
module_function
|
31
31
|
|
32
32
|
# Builds a new Transport::HTTP::Client
|
33
|
-
def new(&block)
|
34
|
-
Builder.new(
|
33
|
+
def new(klass, &block)
|
34
|
+
Core::Transport::HTTP::Builder.new(
|
35
|
+
api_instance_class: API::Instance, &block
|
36
|
+
).to_transport(klass)
|
35
37
|
end
|
36
38
|
|
37
39
|
# Builds a new Transport::HTTP::Client with default settings
|
@@ -40,7 +42,7 @@ module Datadog
|
|
40
42
|
agent_settings: DO_NOT_USE_ENVIRONMENT_AGENT_SETTINGS,
|
41
43
|
**options
|
42
44
|
)
|
43
|
-
new do |transport|
|
45
|
+
new(Transport::Traces::Transport) do |transport|
|
44
46
|
transport.adapter(agent_settings)
|
45
47
|
transport.headers default_headers
|
46
48
|
|
@@ -86,12 +88,15 @@ module Datadog
|
|
86
88
|
end
|
87
89
|
|
88
90
|
# Add adapters to registry
|
89
|
-
Builder::REGISTRY.set(
|
91
|
+
Core::Transport::HTTP::Builder::REGISTRY.set(
|
90
92
|
Datadog::Core::Transport::HTTP::Adapters::Net,
|
91
93
|
Datadog::Core::Configuration::Ext::Agent::HTTP::ADAPTER
|
92
94
|
)
|
93
|
-
|
94
|
-
|
95
|
+
Core::Transport::HTTP::Builder::REGISTRY.set(
|
96
|
+
Datadog::Core::Transport::HTTP::Adapters::Test,
|
97
|
+
Datadog::Core::Transport::Ext::Test::ADAPTER
|
98
|
+
)
|
99
|
+
Core::Transport::HTTP::Builder::REGISTRY.set(
|
95
100
|
Datadog::Core::Transport::HTTP::Adapters::UnixSocket,
|
96
101
|
Datadog::Core::Transport::Ext::UnixSocket::ADAPTER
|
97
102
|
)
|
@@ -14,7 +14,7 @@ module Datadog
|
|
14
14
|
|
15
15
|
# @param trace [Datadog::Trace] the trace to serialize
|
16
16
|
# @param native_events_supported [Boolean] whether the agent supports span events as a top-level field
|
17
|
-
def initialize(trace, native_events_supported
|
17
|
+
def initialize(trace, native_events_supported:)
|
18
18
|
@trace = trace
|
19
19
|
@native_events_supported = native_events_supported
|
20
20
|
end
|
@@ -29,13 +29,17 @@ module Datadog
|
|
29
29
|
# @param packer [MessagePack::Packer] serialization buffer, can be +nil+ with JRuby
|
30
30
|
def to_msgpack(packer = nil)
|
31
31
|
# As of 1.3.3, JRuby implementation doesn't pass an existing packer
|
32
|
-
trace.spans.map
|
32
|
+
trace.spans.map do |s|
|
33
|
+
SerializableSpan.new(s, native_events_supported: @native_events_supported)
|
34
|
+
end.to_msgpack(packer)
|
33
35
|
end
|
34
36
|
|
35
37
|
# JSON serializer interface.
|
36
38
|
# Used by older version of the transport.
|
37
39
|
def to_json(*args)
|
38
|
-
trace.spans.map
|
40
|
+
trace.spans.map do |s|
|
41
|
+
SerializableSpan.new(s, native_events_supported: @native_events_supported).to_hash
|
42
|
+
end.to_json(*args)
|
39
43
|
end
|
40
44
|
end
|
41
45
|
|
@@ -46,7 +50,7 @@ module Datadog
|
|
46
50
|
|
47
51
|
# @param span [Datadog::Span] the span to serialize
|
48
52
|
# @param native_events_supported [Boolean] whether the agent supports span events as a top-level field
|
49
|
-
def initialize(span, native_events_supported)
|
53
|
+
def initialize(span, native_events_supported:)
|
50
54
|
@span = span
|
51
55
|
@trace_id = Tracing::Utils::TraceId.to_low_order(span.trace_id)
|
52
56
|
@native_events_supported = native_events_supported
|
@@ -50,8 +50,9 @@ module Datadog
|
|
50
50
|
#
|
51
51
|
# @param encoder [Datadog::Core::Encoding::Encoder]
|
52
52
|
# @param max_size [String] maximum acceptable payload size
|
53
|
-
def initialize(encoder, max_size: DEFAULT_MAX_PAYLOAD_SIZE)
|
53
|
+
def initialize(encoder, native_events_supported:, max_size: DEFAULT_MAX_PAYLOAD_SIZE)
|
54
54
|
@encoder = encoder
|
55
|
+
@native_events_supported = native_events_supported
|
55
56
|
@max_size = max_size
|
56
57
|
end
|
57
58
|
|
@@ -77,7 +78,7 @@ module Datadog
|
|
77
78
|
private
|
78
79
|
|
79
80
|
def encode_one(trace)
|
80
|
-
encoded = Encoder.encode_trace(encoder, trace)
|
81
|
+
encoded = Encoder.encode_trace(encoder, trace, native_events_supported: @native_events_supported)
|
81
82
|
|
82
83
|
if encoded.size > max_size
|
83
84
|
# This single trace is too large, we can't flush it
|
@@ -95,17 +96,18 @@ module Datadog
|
|
95
96
|
module Encoder
|
96
97
|
module_function
|
97
98
|
|
98
|
-
def encode_trace(encoder, trace)
|
99
|
+
def encode_trace(encoder, trace, native_events_supported:)
|
99
100
|
# Format the trace for transport
|
100
101
|
TraceFormatter.format!(trace)
|
101
102
|
|
102
103
|
# Make the trace serializable
|
103
|
-
serializable_trace = SerializableTrace.new(trace)
|
104
|
-
|
105
|
-
Datadog.logger.debug { "Flushing trace: #{JSON.dump(serializable_trace)}" }
|
104
|
+
serializable_trace = SerializableTrace.new(trace, native_events_supported: native_events_supported)
|
106
105
|
|
107
106
|
# Encode the trace
|
108
|
-
encoder.encode(serializable_trace)
|
107
|
+
encoder.encode(serializable_trace).tap do |encoded|
|
108
|
+
# Print the actual serialized trace, since the encoder can change make non-trivial changes
|
109
|
+
Datadog.logger.debug { "Flushing trace: #{encoder.decode(encoded)}" }
|
110
|
+
end
|
109
111
|
end
|
110
112
|
end
|
111
113
|
|
@@ -126,7 +128,10 @@ module Datadog
|
|
126
128
|
|
127
129
|
def send_traces(traces)
|
128
130
|
encoder = current_api.encoder
|
129
|
-
chunker = Datadog::Tracing::Transport::Traces::Chunker.new(
|
131
|
+
chunker = Datadog::Tracing::Transport::Traces::Chunker.new(
|
132
|
+
encoder,
|
133
|
+
native_events_supported: native_events_supported?
|
134
|
+
)
|
130
135
|
|
131
136
|
responses = chunker.encode_in_chunks(traces.lazy).map do |encoded_traces, trace_count|
|
132
137
|
request = Request.new(EncodedParcel.new(encoded_traces, trace_count))
|
@@ -188,6 +193,18 @@ module Datadog
|
|
188
193
|
@client = HTTP::Client.new(current_api)
|
189
194
|
end
|
190
195
|
|
196
|
+
# Queries the agent for native span events serialization support.
|
197
|
+
# This changes how the serialization of span events performed.
|
198
|
+
def native_events_supported?
|
199
|
+
return @native_events_supported if defined?(@native_events_supported)
|
200
|
+
|
201
|
+
if (res = Datadog.send(:components).agent_info.fetch)
|
202
|
+
@native_events_supported = res.span_events == true
|
203
|
+
else
|
204
|
+
false
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
191
208
|
# Raised when configured with an unknown API version
|
192
209
|
class UnknownApiVersionError < StandardError
|
193
210
|
attr_reader :version
|
@@ -17,10 +17,13 @@ module Datadog
|
|
17
17
|
# Writes traces to transport synchronously
|
18
18
|
class TraceWriter < Core::Worker
|
19
19
|
attr_reader \
|
20
|
+
:logger,
|
20
21
|
:transport
|
21
22
|
|
22
23
|
# rubocop:disable Lint/MissingSuper
|
23
24
|
def initialize(options = {})
|
25
|
+
@logger = options[:logger] || Datadog.logger
|
26
|
+
|
24
27
|
transport_options = options.fetch(:transport_options, {})
|
25
28
|
|
26
29
|
transport_options[:agent_settings] = options[:agent_settings] if options.key?(:agent_settings)
|
@@ -43,7 +46,7 @@ module Datadog
|
|
43
46
|
traces = process_traces(traces)
|
44
47
|
flush_traces(traces)
|
45
48
|
rescue StandardError => e
|
46
|
-
|
49
|
+
logger.warn(
|
47
50
|
"Error while writing traces: dropped #{traces.length} items. Cause: #{e} Location: #{Array(e.backtrace).first}"
|
48
51
|
)
|
49
52
|
end
|
@@ -18,8 +18,7 @@ module Datadog
|
|
18
18
|
BACK_OFF_MAX = 5
|
19
19
|
DEFAULT_SHUTDOWN_TIMEOUT = 1
|
20
20
|
|
21
|
-
attr_reader
|
22
|
-
:trace_buffer
|
21
|
+
attr_reader :trace_buffer, :logger
|
23
22
|
|
24
23
|
def initialize(options = {})
|
25
24
|
@transport = options[:transport]
|
@@ -42,6 +41,8 @@ module Datadog
|
|
42
41
|
@mutex = Mutex.new
|
43
42
|
@worker = nil
|
44
43
|
@run = false
|
44
|
+
|
45
|
+
@logger = options.fetch(:logger)
|
45
46
|
end
|
46
47
|
|
47
48
|
# Callback function that process traces and executes the +send_traces()+ method.
|
@@ -56,7 +57,7 @@ module Datadog
|
|
56
57
|
# ensures that the thread will not die because of an exception.
|
57
58
|
# TODO[manu]: findout the reason and reschedule the send if it's not
|
58
59
|
# a fatal exception
|
59
|
-
|
60
|
+
logger.warn(
|
60
61
|
"Error during traces flush: dropped #{traces.length} items. Cause: #{e} Location: #{Array(e.backtrace).first}"
|
61
62
|
)
|
62
63
|
end
|
@@ -68,7 +69,7 @@ module Datadog
|
|
68
69
|
return if @run
|
69
70
|
|
70
71
|
@run = true
|
71
|
-
|
72
|
+
logger.debug { "Starting thread for: #{self}" }
|
72
73
|
@worker = Thread.new { perform }
|
73
74
|
@worker.name = self.class.name
|
74
75
|
@worker.thread_variable_set(:fork_safe, true)
|
@@ -13,11 +13,14 @@ module Datadog
|
|
13
13
|
# @public_api
|
14
14
|
class Writer
|
15
15
|
attr_reader \
|
16
|
+
:logger,
|
16
17
|
:transport,
|
17
18
|
:worker,
|
18
19
|
:events
|
19
20
|
|
20
21
|
def initialize(options = {})
|
22
|
+
@logger = options[:logger] || Datadog.logger
|
23
|
+
|
21
24
|
# writer and transport parameters
|
22
25
|
@buff_size = options.fetch(:buffer_size, Workers::AsyncTransport::DEFAULT_BUFFER_MAX_SIZE)
|
23
26
|
@flush_interval = options.fetch(:flush_interval, Workers::AsyncTransport::DEFAULT_FLUSH_INTERVAL)
|
@@ -119,7 +122,7 @@ module Datadog
|
|
119
122
|
if worker_local
|
120
123
|
worker_local.enqueue_trace(trace)
|
121
124
|
elsif !@stopped
|
122
|
-
|
125
|
+
logger.debug('Writer either failed to start or was stopped before #write could complete')
|
123
126
|
end
|
124
127
|
end
|
125
128
|
|
@@ -160,7 +163,8 @@ module Datadog
|
|
160
163
|
buffer_size: @buff_size,
|
161
164
|
on_trace: @trace_handler,
|
162
165
|
interval: @flush_interval,
|
163
|
-
shutdown_timeout: @shutdown_timeout
|
166
|
+
shutdown_timeout: @shutdown_timeout,
|
167
|
+
logger: logger,
|
164
168
|
)
|
165
169
|
|
166
170
|
@worker.start
|