datadog 2.3.0 → 2.4.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 +37 -1
- data/ext/datadog_profiling_loader/datadog_profiling_loader.c +9 -1
- data/ext/datadog_profiling_loader/extconf.rb +10 -22
- data/ext/datadog_profiling_native_extension/collectors_cpu_and_wall_time_worker.c +148 -30
- data/ext/datadog_profiling_native_extension/collectors_discrete_dynamic_sampler.c +4 -2
- data/ext/datadog_profiling_native_extension/collectors_stack.c +89 -46
- data/ext/datadog_profiling_native_extension/collectors_thread_context.c +580 -29
- data/ext/datadog_profiling_native_extension/collectors_thread_context.h +9 -1
- data/ext/datadog_profiling_native_extension/datadog_ruby_common.c +0 -27
- data/ext/datadog_profiling_native_extension/datadog_ruby_common.h +0 -4
- data/ext/datadog_profiling_native_extension/extconf.rb +38 -21
- data/ext/datadog_profiling_native_extension/gvl_profiling_helper.c +50 -0
- data/ext/datadog_profiling_native_extension/gvl_profiling_helper.h +75 -0
- data/ext/datadog_profiling_native_extension/heap_recorder.c +20 -6
- data/ext/datadog_profiling_native_extension/http_transport.c +38 -6
- data/ext/datadog_profiling_native_extension/private_vm_api_access.c +52 -1
- data/ext/datadog_profiling_native_extension/private_vm_api_access.h +3 -0
- data/ext/datadog_profiling_native_extension/profiling.c +1 -1
- data/ext/datadog_profiling_native_extension/stack_recorder.h +1 -0
- data/ext/libdatadog_api/crashtracker.c +20 -18
- data/ext/libdatadog_api/datadog_ruby_common.c +0 -27
- data/ext/libdatadog_api/datadog_ruby_common.h +0 -4
- data/ext/libdatadog_extconf_helpers.rb +1 -1
- data/lib/datadog/appsec/assets/waf_rules/recommended.json +2184 -108
- data/lib/datadog/appsec/assets/waf_rules/strict.json +1430 -2
- data/lib/datadog/appsec/component.rb +29 -8
- data/lib/datadog/appsec/configuration/settings.rb +2 -2
- data/lib/datadog/appsec/contrib/devise/patcher/authenticatable_patch.rb +1 -0
- data/lib/datadog/appsec/contrib/devise/patcher/rememberable_patch.rb +21 -0
- data/lib/datadog/appsec/contrib/devise/patcher.rb +12 -2
- data/lib/datadog/appsec/contrib/graphql/appsec_trace.rb +0 -14
- data/lib/datadog/appsec/contrib/graphql/gateway/multiplex.rb +67 -31
- data/lib/datadog/appsec/contrib/graphql/gateway/watcher.rb +18 -15
- data/lib/datadog/appsec/contrib/graphql/integration.rb +14 -1
- data/lib/datadog/appsec/contrib/rack/gateway/request.rb +2 -5
- data/lib/datadog/appsec/event.rb +1 -1
- data/lib/datadog/appsec/processor/rule_loader.rb +3 -1
- data/lib/datadog/appsec/processor/rule_merger.rb +33 -15
- data/lib/datadog/appsec/processor.rb +36 -37
- data/lib/datadog/appsec/rate_limiter.rb +25 -40
- data/lib/datadog/appsec/remote.rb +7 -3
- data/lib/datadog/appsec.rb +2 -2
- data/lib/datadog/core/configuration/components.rb +4 -3
- data/lib/datadog/core/configuration/settings.rb +84 -5
- data/lib/datadog/core/crashtracking/component.rb +1 -1
- data/lib/datadog/core/environment/execution.rb +5 -5
- data/lib/datadog/core/metrics/client.rb +7 -0
- data/lib/datadog/core/rate_limiter.rb +183 -0
- data/lib/datadog/core/remote/client/capabilities.rb +4 -3
- data/lib/datadog/core/remote/component.rb +4 -2
- data/lib/datadog/core/remote/negotiation.rb +4 -4
- data/lib/datadog/core/remote/tie.rb +2 -0
- data/lib/datadog/core/runtime/metrics.rb +1 -1
- data/lib/datadog/core/telemetry/component.rb +2 -0
- data/lib/datadog/core/telemetry/event.rb +12 -7
- data/lib/datadog/core/telemetry/logger.rb +51 -0
- data/lib/datadog/core/telemetry/logging.rb +50 -14
- data/lib/datadog/core/telemetry/request.rb +13 -1
- data/lib/datadog/core/utils/time.rb +12 -0
- data/lib/datadog/di/code_tracker.rb +168 -0
- data/lib/datadog/di/configuration/settings.rb +163 -0
- data/lib/datadog/di/configuration.rb +11 -0
- data/lib/datadog/di/error.rb +31 -0
- data/lib/datadog/di/extensions.rb +16 -0
- data/lib/datadog/di/probe.rb +133 -0
- data/lib/datadog/di/probe_builder.rb +41 -0
- data/lib/datadog/di/redactor.rb +188 -0
- data/lib/datadog/di/serializer.rb +193 -0
- data/lib/datadog/di.rb +14 -0
- data/lib/datadog/opentelemetry/sdk/propagator.rb +2 -0
- data/lib/datadog/profiling/collectors/cpu_and_wall_time_worker.rb +12 -10
- data/lib/datadog/profiling/collectors/info.rb +12 -3
- data/lib/datadog/profiling/collectors/thread_context.rb +26 -0
- data/lib/datadog/profiling/component.rb +20 -4
- data/lib/datadog/profiling/http_transport.rb +6 -1
- data/lib/datadog/profiling/scheduler.rb +2 -0
- data/lib/datadog/profiling/stack_recorder.rb +3 -0
- data/lib/datadog/single_step_instrument.rb +12 -0
- data/lib/datadog/tracing/contrib/action_cable/instrumentation.rb +8 -12
- data/lib/datadog/tracing/contrib/action_pack/action_controller/instrumentation.rb +5 -0
- data/lib/datadog/tracing/contrib/action_pack/action_dispatch/instrumentation.rb +78 -0
- data/lib/datadog/tracing/contrib/action_pack/action_dispatch/patcher.rb +33 -0
- data/lib/datadog/tracing/contrib/action_pack/patcher.rb +2 -0
- data/lib/datadog/tracing/contrib/active_record/configuration/resolver.rb +4 -0
- data/lib/datadog/tracing/contrib/active_record/events/instantiation.rb +3 -1
- data/lib/datadog/tracing/contrib/active_record/events/sql.rb +3 -1
- data/lib/datadog/tracing/contrib/active_support/cache/events/cache.rb +5 -1
- data/lib/datadog/tracing/contrib/aws/instrumentation.rb +5 -0
- data/lib/datadog/tracing/contrib/elasticsearch/patcher.rb +6 -1
- data/lib/datadog/tracing/contrib/faraday/middleware.rb +9 -0
- data/lib/datadog/tracing/contrib/grape/endpoint.rb +19 -0
- data/lib/datadog/tracing/contrib/graphql/patcher.rb +9 -12
- data/lib/datadog/tracing/contrib/graphql/trace_patcher.rb +3 -3
- data/lib/datadog/tracing/contrib/graphql/tracing_patcher.rb +3 -3
- data/lib/datadog/tracing/contrib/graphql/unified_trace.rb +13 -9
- data/lib/datadog/tracing/contrib/graphql/unified_trace_patcher.rb +6 -3
- data/lib/datadog/tracing/contrib/http/instrumentation.rb +18 -15
- data/lib/datadog/tracing/contrib/httpclient/instrumentation.rb +6 -5
- data/lib/datadog/tracing/contrib/httpclient/patcher.rb +1 -14
- data/lib/datadog/tracing/contrib/httprb/instrumentation.rb +5 -0
- data/lib/datadog/tracing/contrib/httprb/patcher.rb +1 -14
- data/lib/datadog/tracing/contrib/lograge/patcher.rb +1 -2
- data/lib/datadog/tracing/contrib/mongodb/subscribers.rb +2 -0
- data/lib/datadog/tracing/contrib/opensearch/patcher.rb +13 -6
- data/lib/datadog/tracing/contrib/patcher.rb +2 -1
- data/lib/datadog/tracing/contrib/presto/patcher.rb +1 -13
- data/lib/datadog/tracing/contrib/rack/middlewares.rb +27 -0
- data/lib/datadog/tracing/contrib/redis/tags.rb +4 -0
- data/lib/datadog/tracing/contrib/sinatra/tracer.rb +4 -0
- data/lib/datadog/tracing/contrib/stripe/request.rb +3 -2
- data/lib/datadog/tracing/distributed/propagation.rb +7 -0
- data/lib/datadog/tracing/metadata/ext.rb +2 -0
- data/lib/datadog/tracing/remote.rb +5 -2
- data/lib/datadog/tracing/sampling/matcher.rb +6 -1
- data/lib/datadog/tracing/sampling/rate_sampler.rb +1 -1
- data/lib/datadog/tracing/sampling/rule.rb +2 -0
- data/lib/datadog/tracing/sampling/rule_sampler.rb +9 -5
- data/lib/datadog/tracing/sampling/span/ext.rb +1 -1
- data/lib/datadog/tracing/sampling/span/rule.rb +2 -2
- data/lib/datadog/tracing/trace_operation.rb +26 -2
- data/lib/datadog/tracing/tracer.rb +14 -12
- data/lib/datadog/tracing/transport/http/client.rb +1 -0
- data/lib/datadog/tracing/transport/io/client.rb +1 -0
- data/lib/datadog/tracing/workers/trace_writer.rb +1 -1
- data/lib/datadog/tracing/workers.rb +1 -1
- data/lib/datadog/version.rb +1 -1
- metadata +25 -8
- data/lib/datadog/tracing/sampling/rate_limiter.rb +0 -185
@@ -20,6 +20,8 @@ module Datadog
|
|
20
20
|
tracer:,
|
21
21
|
endpoint_collection_enabled:,
|
22
22
|
timeline_enabled:,
|
23
|
+
waiting_for_gvl_threshold_ns:,
|
24
|
+
otel_context_enabled:,
|
23
25
|
allocation_type_enabled: true
|
24
26
|
)
|
25
27
|
tracer_context_key = safely_extract_context_key_from(tracer)
|
@@ -30,10 +32,34 @@ module Datadog
|
|
30
32
|
tracer_context_key,
|
31
33
|
endpoint_collection_enabled,
|
32
34
|
timeline_enabled,
|
35
|
+
waiting_for_gvl_threshold_ns,
|
36
|
+
otel_context_enabled,
|
33
37
|
allocation_type_enabled,
|
34
38
|
)
|
35
39
|
end
|
36
40
|
|
41
|
+
def self.for_testing(
|
42
|
+
recorder:,
|
43
|
+
max_frames: 400,
|
44
|
+
tracer: nil,
|
45
|
+
endpoint_collection_enabled: false,
|
46
|
+
timeline_enabled: false,
|
47
|
+
waiting_for_gvl_threshold_ns: 10_000_000,
|
48
|
+
otel_context_enabled: false,
|
49
|
+
**options
|
50
|
+
)
|
51
|
+
new(
|
52
|
+
recorder: recorder,
|
53
|
+
max_frames: max_frames,
|
54
|
+
tracer: tracer,
|
55
|
+
endpoint_collection_enabled: endpoint_collection_enabled,
|
56
|
+
timeline_enabled: timeline_enabled,
|
57
|
+
waiting_for_gvl_threshold_ns: waiting_for_gvl_threshold_ns,
|
58
|
+
otel_context_enabled: otel_context_enabled,
|
59
|
+
**options,
|
60
|
+
)
|
61
|
+
end
|
62
|
+
|
37
63
|
def inspect
|
38
64
|
# Compose Ruby's default inspect with our custom inspect for the native parts
|
39
65
|
result = super()
|
@@ -62,6 +62,7 @@ module Datadog
|
|
62
62
|
dynamic_sampling_rate_overhead_target_percentage: overhead_target_percentage,
|
63
63
|
allocation_profiling_enabled: allocation_profiling_enabled,
|
64
64
|
allocation_counting_enabled: settings.profiling.advanced.allocation_counting_enabled,
|
65
|
+
gvl_profiling_enabled: enable_gvl_profiling?(settings),
|
65
66
|
)
|
66
67
|
|
67
68
|
internal_metadata = {
|
@@ -89,6 +90,8 @@ module Datadog
|
|
89
90
|
tracer: optional_tracer,
|
90
91
|
endpoint_collection_enabled: settings.profiling.advanced.endpoint.collection.enabled,
|
91
92
|
timeline_enabled: timeline_enabled,
|
93
|
+
waiting_for_gvl_threshold_ns: settings.profiling.advanced.waiting_for_gvl_threshold_ns,
|
94
|
+
otel_context_enabled: settings.profiling.advanced.preview_otel_context_enabled,
|
92
95
|
)
|
93
96
|
end
|
94
97
|
|
@@ -252,6 +255,7 @@ module Datadog
|
|
252
255
|
legacy_ruby_that_should_use_workaround = RUBY_VERSION.start_with?("2.5.")
|
253
256
|
|
254
257
|
unless [true, false, :auto].include?(setting_value)
|
258
|
+
# TODO: Replace with a warning instead.
|
255
259
|
Datadog.logger.error(
|
256
260
|
"Ignoring invalid value for profiling no_signals_workaround_enabled setting: #{setting_value.inspect}. " \
|
257
261
|
"Valid options are `true`, `false` or (default) `:auto`."
|
@@ -394,6 +398,7 @@ module Datadog
|
|
394
398
|
if overhead_target_percentage > 0 && overhead_target_percentage <= 20
|
395
399
|
overhead_target_percentage
|
396
400
|
else
|
401
|
+
# TODO: Replace with a warning instead.
|
397
402
|
Datadog.logger.error(
|
398
403
|
"Ignoring invalid value for profiling overhead_target_percentage setting: " \
|
399
404
|
"#{overhead_target_percentage.inspect}. Falling back to default value."
|
@@ -433,13 +438,24 @@ module Datadog
|
|
433
438
|
end
|
434
439
|
|
435
440
|
private_class_method def self.dir_interruption_workaround_enabled?(settings, no_signals_workaround_enabled)
|
436
|
-
return false if no_signals_workaround_enabled
|
437
|
-
|
438
|
-
# NOTE: In the future this method will evolve to check for Ruby versions affected and not apply the workaround
|
439
|
-
# when it's not needed but currently all known Ruby versions are affected.
|
441
|
+
return false if no_signals_workaround_enabled || RUBY_VERSION >= "3.4"
|
440
442
|
|
441
443
|
settings.profiling.advanced.dir_interruption_workaround_enabled
|
442
444
|
end
|
445
|
+
|
446
|
+
private_class_method def self.enable_gvl_profiling?(settings)
|
447
|
+
if RUBY_VERSION < "3.2"
|
448
|
+
if settings.profiling.advanced.preview_gvl_enabled
|
449
|
+
Datadog.logger.warn("GVL profiling is currently not supported in Ruby < 3.2 and will not be enabled.")
|
450
|
+
end
|
451
|
+
|
452
|
+
return false
|
453
|
+
end
|
454
|
+
|
455
|
+
# GVL profiling only makes sense in the context of timeline. We could emit a warning here, but not sure how
|
456
|
+
# useful it is -- if a customer disables timeline, there's nowhere to look for GVL profiling anyway!
|
457
|
+
settings.profiling.advanced.timeline_enabled && settings.profiling.advanced.preview_gvl_enabled
|
458
|
+
end
|
443
459
|
end
|
444
460
|
end
|
445
461
|
end
|
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require_relative "../core/transport/ext"
|
4
|
+
require_relative "../core/telemetry/logger"
|
4
5
|
|
5
6
|
module Datadog
|
6
7
|
module Profiling
|
@@ -60,10 +61,14 @@ module Datadog
|
|
60
61
|
"Failed to report profiling data (#{config_without_api_key}): " \
|
61
62
|
"server returned unexpected HTTP #{result} status code"
|
62
63
|
)
|
64
|
+
Datadog::Core::Telemetry::Logger.error(
|
65
|
+
"Failed to report profiling data: unexpected HTTP #{result} status code"
|
66
|
+
)
|
63
67
|
false
|
64
68
|
end
|
65
69
|
else
|
66
70
|
Datadog.logger.error("Failed to report profiling data (#{config_without_api_key}): #{result}")
|
71
|
+
Datadog::Core::Telemetry::Logger.error("Failed to report profiling data")
|
67
72
|
false
|
68
73
|
end
|
69
74
|
end
|
@@ -134,7 +139,7 @@ module Datadog
|
|
134
139
|
end
|
135
140
|
|
136
141
|
def config_without_api_key
|
137
|
-
[exporter_configuration[
|
142
|
+
"#{exporter_configuration[0]}: #{exporter_configuration[1]}"
|
138
143
|
end
|
139
144
|
end
|
140
145
|
end
|
@@ -4,6 +4,7 @@ require_relative "../core/utils/time"
|
|
4
4
|
|
5
5
|
require_relative "../core/worker"
|
6
6
|
require_relative "../core/workers/polling"
|
7
|
+
require_relative "../core/telemetry/logger"
|
7
8
|
|
8
9
|
module Datadog
|
9
10
|
module Profiling
|
@@ -134,6 +135,7 @@ module Datadog
|
|
134
135
|
Datadog.logger.error(
|
135
136
|
"Unable to report profile. Cause: #{e.class.name} #{e.message} Location: #{Array(e.backtrace).first}"
|
136
137
|
)
|
138
|
+
Datadog::Core::Telemetry::Logger.report(e, description: "Unable to report profile")
|
137
139
|
end
|
138
140
|
|
139
141
|
true
|
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require_relative "../core/telemetry/logger"
|
4
|
+
|
3
5
|
module Datadog
|
4
6
|
module Profiling
|
5
7
|
# Stores stack samples in a native libdatadog data structure and expose Ruby-level serialization APIs
|
@@ -42,6 +44,7 @@ module Datadog
|
|
42
44
|
error_message = result
|
43
45
|
|
44
46
|
Datadog.logger.error("Failed to serialize profiling data: #{error_message}")
|
47
|
+
Datadog::Core::Telemetry::Logger.error("Failed to serialize profiling data")
|
45
48
|
|
46
49
|
nil
|
47
50
|
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
#
|
4
|
+
# Entrypoint file for single step instrumentation.
|
5
|
+
#
|
6
|
+
# This file's path is private. Do not reference this file.
|
7
|
+
#
|
8
|
+
begin
|
9
|
+
require_relative 'auto_instrument'
|
10
|
+
rescue StandardError, LoadError => e
|
11
|
+
warn "Single step instrumentation failed: #{e.class}:#{e.message}\n\tSource:\n\t#{Array(e.backtrace).join("\n\t")}"
|
12
|
+
end
|
@@ -14,21 +14,17 @@ module Datadog
|
|
14
14
|
module ActionCableConnection
|
15
15
|
def on_open
|
16
16
|
Tracing.trace(Ext::SPAN_ON_OPEN) do |span, trace|
|
17
|
-
|
18
|
-
|
19
|
-
span.type = Tracing::Metadata::Ext::AppTypes::TYPE_WEB
|
17
|
+
span.resource = "#{self.class}#on_open"
|
18
|
+
span.type = Tracing::Metadata::Ext::AppTypes::TYPE_WEB
|
20
19
|
|
21
|
-
|
22
|
-
|
20
|
+
span.set_tag(Ext::TAG_ACTION, 'on_open')
|
21
|
+
span.set_tag(Ext::TAG_CONNECTION, self.class.to_s)
|
23
22
|
|
24
|
-
|
25
|
-
|
23
|
+
span.set_tag(Tracing::Metadata::Ext::TAG_COMPONENT, Ext::TAG_COMPONENT)
|
24
|
+
span.set_tag(Tracing::Metadata::Ext::TAG_OPERATION, Ext::TAG_OPERATION_ON_OPEN)
|
26
25
|
|
27
|
-
|
28
|
-
|
29
|
-
rescue StandardError => e
|
30
|
-
Datadog.logger.error("Error preparing span for ActionCable::Connection: #{e}")
|
31
|
-
end
|
26
|
+
# Set the resource name of the trace
|
27
|
+
trace.resource = span.resource
|
32
28
|
|
33
29
|
super
|
34
30
|
end
|
@@ -7,6 +7,7 @@ require_relative '../ext'
|
|
7
7
|
require_relative '../utils'
|
8
8
|
require_relative '../../rack/middlewares'
|
9
9
|
require_relative '../../analytics'
|
10
|
+
require_relative '../../../../core/telemetry/logger'
|
10
11
|
|
11
12
|
module Datadog
|
12
13
|
module Tracing
|
@@ -43,6 +44,7 @@ module Datadog
|
|
43
44
|
span.set_tag(Tracing::Metadata::Ext::TAG_OPERATION, Ext::TAG_OPERATION_CONTROLLER)
|
44
45
|
rescue StandardError => e
|
45
46
|
Datadog.logger.error(e.message)
|
47
|
+
Datadog::Core::Telemetry::Logger.report(e)
|
46
48
|
end
|
47
49
|
|
48
50
|
def finish_processing(payload)
|
@@ -81,10 +83,13 @@ module Datadog
|
|
81
83
|
end
|
82
84
|
rescue StandardError => e
|
83
85
|
Datadog.logger.error(e.message)
|
86
|
+
Datadog::Core::Telemetry::Logger.report(e)
|
84
87
|
end
|
85
88
|
|
86
89
|
# Instrumentation for ActionController::Metal
|
87
90
|
module Metal
|
91
|
+
# TODO: Refactor this method to avoid using async API that splits the logic
|
92
|
+
# into two different methods (`start_processing` and `finish_processing`)
|
88
93
|
def process_action(*args)
|
89
94
|
# mutable payload with a tracing context that is used in two different
|
90
95
|
# signals; it propagates the request span so that it can be finished
|
@@ -0,0 +1,78 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../../../metadata/ext'
|
4
|
+
|
5
|
+
module Datadog
|
6
|
+
module Tracing
|
7
|
+
module Contrib
|
8
|
+
module ActionPack
|
9
|
+
module ActionDispatch
|
10
|
+
# Instrumentation for ActionDispatch components
|
11
|
+
module Instrumentation
|
12
|
+
module_function
|
13
|
+
|
14
|
+
def set_http_route_tags(route_spec, script_name)
|
15
|
+
return unless Tracing.enabled?
|
16
|
+
|
17
|
+
return unless route_spec
|
18
|
+
|
19
|
+
request_trace = Tracing.active_trace
|
20
|
+
return unless request_trace
|
21
|
+
|
22
|
+
request_trace.set_tag(Tracing::Metadata::Ext::HTTP::TAG_ROUTE, route_spec.to_s.gsub(/\(.:format\)\z/, ''))
|
23
|
+
|
24
|
+
if script_name && !script_name.empty?
|
25
|
+
request_trace.set_tag(Tracing::Metadata::Ext::HTTP::TAG_ROUTE_PATH, script_name)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def dispatcher_route?(route)
|
30
|
+
return true if route.dispatcher?
|
31
|
+
|
32
|
+
# in Rails 4 there is no #rack_app method on the app
|
33
|
+
return true if route.app.respond_to?(:rack_app) && !route.app.rack_app.nil?
|
34
|
+
|
35
|
+
false
|
36
|
+
end
|
37
|
+
|
38
|
+
# Instrumentation for ActionDispatch::Journey components
|
39
|
+
module Journey
|
40
|
+
# Instrumentation for ActionDispatch::Journey::Router for Rails versions older than 7.1
|
41
|
+
module Router
|
42
|
+
def find_routes(req)
|
43
|
+
result = super
|
44
|
+
|
45
|
+
# result is an array of [match, parameters, route] tuples
|
46
|
+
routes = result.map(&:last)
|
47
|
+
|
48
|
+
routes.each do |route|
|
49
|
+
if Instrumentation.dispatcher_route?(route)
|
50
|
+
Instrumentation.set_http_route_tags(route.path.spec, req.env['SCRIPT_NAME'])
|
51
|
+
break
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
result
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
# Since Rails 7.1 `Router#find_routes` makes the route computation lazy
|
60
|
+
# https://github.com/rails/rails/commit/35b280fcc2d5d474f9f2be3aca3ae7aa6bba66eb
|
61
|
+
module LazyRouter
|
62
|
+
def find_routes(req)
|
63
|
+
super do |match, parameters, route|
|
64
|
+
if Instrumentation.dispatcher_route?(route)
|
65
|
+
Instrumentation.set_http_route_tags(route.path.spec, req.env['SCRIPT_NAME'])
|
66
|
+
end
|
67
|
+
|
68
|
+
yield [match, parameters, route]
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../../patcher'
|
4
|
+
require_relative 'instrumentation'
|
5
|
+
|
6
|
+
module Datadog
|
7
|
+
module Tracing
|
8
|
+
module Contrib
|
9
|
+
module ActionPack
|
10
|
+
module ActionDispatch
|
11
|
+
# Patcher for ActionController components
|
12
|
+
module Patcher
|
13
|
+
include Contrib::Patcher
|
14
|
+
|
15
|
+
module_function
|
16
|
+
|
17
|
+
def target_version
|
18
|
+
Integration.version
|
19
|
+
end
|
20
|
+
|
21
|
+
def patch
|
22
|
+
if ::ActionPack.gem_version >= Gem::Version.new('7.1')
|
23
|
+
::ActionDispatch::Journey::Router.prepend(ActionDispatch::Instrumentation::Journey::LazyRouter)
|
24
|
+
else
|
25
|
+
::ActionDispatch::Journey::Router.prepend(ActionDispatch::Instrumentation::Journey::Router)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
require_relative '../patcher'
|
4
4
|
require_relative 'action_controller/patcher'
|
5
|
+
require_relative 'action_dispatch/patcher'
|
5
6
|
|
6
7
|
module Datadog
|
7
8
|
module Tracing
|
@@ -19,6 +20,7 @@ module Datadog
|
|
19
20
|
|
20
21
|
def patch
|
21
22
|
ActionController::Patcher.patch
|
23
|
+
ActionDispatch::Patcher.patch
|
22
24
|
end
|
23
25
|
end
|
24
26
|
end
|
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
require_relative '../../configuration/resolver'
|
4
4
|
require_relative 'makara_resolver'
|
5
|
+
require_relative '../../../../core/telemetry/logger'
|
5
6
|
|
6
7
|
module Datadog
|
7
8
|
module Tracing
|
@@ -72,10 +73,12 @@ module Datadog
|
|
72
73
|
#
|
73
74
|
# `db_config` input may contain sensitive information such as passwords,
|
74
75
|
# hence provide a succinct summary for the error logging.
|
76
|
+
#
|
75
77
|
Datadog.logger.error(
|
76
78
|
'Failed to resolve ActiveRecord database configuration. '\
|
77
79
|
"Cause: #{e.class.name} Source: #{Array(e.backtrace).first}"
|
78
80
|
)
|
81
|
+
Core::Telemetry::Logger.report(e, description: 'Failed to resolve ActiveRecord database configuration')
|
79
82
|
|
80
83
|
nil
|
81
84
|
end
|
@@ -95,6 +98,7 @@ module Datadog
|
|
95
98
|
"Failed to resolve key #{matcher.inspect}. " \
|
96
99
|
"Cause: #{e.class.name} Source: #{Array(e.backtrace).first}"
|
97
100
|
)
|
101
|
+
Core::Telemetry::Logger.report(e, description: 'Failed to resolve key')
|
98
102
|
|
99
103
|
nil
|
100
104
|
end
|
@@ -4,6 +4,7 @@ require_relative '../../../metadata/ext'
|
|
4
4
|
require_relative '../../analytics'
|
5
5
|
require_relative '../ext'
|
6
6
|
require_relative '../event'
|
7
|
+
require_relative '../../../../core/telemetry/logger'
|
7
8
|
|
8
9
|
module Datadog
|
9
10
|
module Tracing
|
@@ -48,7 +49,8 @@ module Datadog
|
|
48
49
|
span.set_tag(Ext::TAG_INSTANTIATION_CLASS_NAME, payload.fetch(:class_name))
|
49
50
|
span.set_tag(Ext::TAG_INSTANTIATION_RECORD_COUNT, payload.fetch(:record_count))
|
50
51
|
rescue StandardError => e
|
51
|
-
Datadog.logger.
|
52
|
+
Datadog.logger.error(e.message)
|
53
|
+
Datadog::Core::Telemetry::Logger.report(e)
|
52
54
|
end
|
53
55
|
end
|
54
56
|
end
|
@@ -6,6 +6,7 @@ require_relative '../event'
|
|
6
6
|
require_relative '../ext'
|
7
7
|
require_relative '../../analytics'
|
8
8
|
require_relative '../../utils/database'
|
9
|
+
require_relative '../../../../core/telemetry/logger'
|
9
10
|
|
10
11
|
module Datadog
|
11
12
|
module Tracing
|
@@ -68,7 +69,8 @@ module Datadog
|
|
68
69
|
span.set_tag(Tracing::Metadata::Ext::NET::TAG_TARGET_HOST, config[:host]) if config[:host]
|
69
70
|
span.set_tag(Tracing::Metadata::Ext::NET::TAG_TARGET_PORT, config[:port]) if config[:port]
|
70
71
|
rescue StandardError => e
|
71
|
-
Datadog.logger.
|
72
|
+
Datadog.logger.error(e.message)
|
73
|
+
Datadog::Core::Telemetry::Logger.report(e)
|
72
74
|
end
|
73
75
|
end
|
74
76
|
end
|
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
require_relative '../../ext'
|
4
4
|
require_relative '../event'
|
5
|
+
require_relative '../../../../../core/telemetry/logger'
|
5
6
|
|
6
7
|
module Datadog
|
7
8
|
module Tracing
|
@@ -64,7 +65,7 @@ module Datadog
|
|
64
65
|
key = payload[:key]
|
65
66
|
store = payload[:store]
|
66
67
|
|
67
|
-
mapping = MAPPING
|
68
|
+
mapping = MAPPING.fetch(event)
|
68
69
|
|
69
70
|
span.service = configuration[:cache_service]
|
70
71
|
span.resource = mapping[:resource]
|
@@ -81,6 +82,9 @@ module Datadog
|
|
81
82
|
span.set_tag('EVENT', event)
|
82
83
|
|
83
84
|
set_cache_key(span, key, mapping[:multi_key])
|
85
|
+
rescue StandardError => e
|
86
|
+
Datadog.logger.error(e.message)
|
87
|
+
Datadog::Core::Telemetry::Logger.report(e)
|
84
88
|
end
|
85
89
|
|
86
90
|
def set_cache_key(span, key, multi_key)
|
@@ -29,6 +29,7 @@ module Datadog
|
|
29
29
|
private
|
30
30
|
|
31
31
|
# rubocop:disable Metrics/AbcSize
|
32
|
+
# rubocop:disable Metrics/MethodLength
|
32
33
|
def annotate!(span, context)
|
33
34
|
span.service = configuration[:service_name]
|
34
35
|
span.type = Tracing::Metadata::Ext::HTTP::TYPE_OUTBOUND
|
@@ -76,7 +77,11 @@ module Datadog
|
|
76
77
|
span.set_tag(Tracing::Metadata::Ext::HTTP::TAG_STATUS_CODE, context.safely(:status_code))
|
77
78
|
|
78
79
|
Contrib::SpanAttributeSchema.set_peer_service!(span, Ext::PEER_SERVICE_SOURCES)
|
80
|
+
rescue StandardError => e
|
81
|
+
Datadog.logger.error(e.message)
|
82
|
+
Datadog::Core::Telemetry::Logger.report(e)
|
79
83
|
end
|
84
|
+
# rubocop:enable Metrics/MethodLength
|
80
85
|
# rubocop:enable Metrics/AbcSize
|
81
86
|
|
82
87
|
def configuration
|
@@ -93,11 +93,16 @@ module Datadog
|
|
93
93
|
span.resource = "#{method} #{quantized_url}"
|
94
94
|
Contrib::SpanAttributeSchema.set_peer_service!(span, Ext::PEER_SERVICE_SOURCES)
|
95
95
|
rescue StandardError => e
|
96
|
+
# TODO: Refactor the code to streamline the execution without ensure
|
96
97
|
Datadog.logger.error(e.message)
|
98
|
+
Datadog::Core::Telemetry::Logger.report(e)
|
97
99
|
ensure
|
98
100
|
# the call is still executed
|
99
101
|
response = super
|
100
|
-
|
102
|
+
|
103
|
+
if response && response.respond_to?(:status)
|
104
|
+
span.set_tag(Tracing::Metadata::Ext::HTTP::TAG_STATUS_CODE, response.status)
|
105
|
+
end
|
101
106
|
end
|
102
107
|
end
|
103
108
|
response
|
@@ -7,6 +7,7 @@ require_relative '../http'
|
|
7
7
|
require_relative '../analytics'
|
8
8
|
require_relative 'ext'
|
9
9
|
require_relative '../http_annotation_helper'
|
10
|
+
require_relative '../../../core/telemetry/logger'
|
10
11
|
|
11
12
|
module Datadog
|
12
13
|
module Tracing
|
@@ -37,6 +38,7 @@ module Datadog
|
|
37
38
|
|
38
39
|
attr_reader :app
|
39
40
|
|
41
|
+
# rubocop:disable Metrics/AbcSize
|
40
42
|
def annotate!(span, env, options)
|
41
43
|
span.resource = resource_name(env)
|
42
44
|
span.service = service_name(env[:url].host, options)
|
@@ -75,7 +77,11 @@ module Datadog
|
|
75
77
|
)
|
76
78
|
|
77
79
|
Contrib::SpanAttributeSchema.set_peer_service!(span, Ext::PEER_SERVICE_SOURCES)
|
80
|
+
rescue StandardError => e
|
81
|
+
Datadog.logger.error(e.message)
|
82
|
+
Datadog::Core::Telemetry::Logger.report(e)
|
78
83
|
end
|
84
|
+
# rubocop:enable Metrics/AbcSize
|
79
85
|
|
80
86
|
def handle_response(span, env, options)
|
81
87
|
span.set_error(["Error #{env[:status]}", env[:body]]) if options[:error_status_codes].include? env[:status]
|
@@ -85,6 +91,9 @@ module Datadog
|
|
85
91
|
span.set_tags(
|
86
92
|
Datadog.configuration.tracing.header_tags.response_tags(env[:response_headers])
|
87
93
|
)
|
94
|
+
rescue StandardError => e
|
95
|
+
Datadog.logger.error(e.message)
|
96
|
+
Datadog::Core::Telemetry::Logger.report(e)
|
88
97
|
end
|
89
98
|
|
90
99
|
def propagate!(trace, span, env)
|
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require_relative '../../../core'
|
4
|
+
require_relative '../../../core/telemetry/logger'
|
4
5
|
require_relative '../../metadata/ext'
|
5
6
|
require_relative '../analytics'
|
6
7
|
require_relative '../rack/ext'
|
@@ -41,6 +42,7 @@ module Datadog
|
|
41
42
|
|
42
43
|
# collect endpoint details
|
43
44
|
endpoint = payload.fetch(:endpoint)
|
45
|
+
env = payload.fetch(:env)
|
44
46
|
api_view = api_view(endpoint.options[:for])
|
45
47
|
request_method = endpoint.options.fetch(:method).first
|
46
48
|
path = endpoint_expand_path(endpoint)
|
@@ -61,9 +63,22 @@ module Datadog
|
|
61
63
|
span.set_tag(Tracing::Metadata::Ext::TAG_COMPONENT, Ext::TAG_COMPONENT)
|
62
64
|
span.set_tag(Tracing::Metadata::Ext::TAG_OPERATION, Ext::TAG_OPERATION_ENDPOINT_RUN)
|
63
65
|
|
66
|
+
if (grape_route = env['grape.routing_args']) && grape_route[:route_info]
|
67
|
+
trace.set_tag(
|
68
|
+
Tracing::Metadata::Ext::HTTP::TAG_ROUTE,
|
69
|
+
# here we are removing the format from the path:
|
70
|
+
# e.g. /path/to/resource(.json) => /path/to/resource
|
71
|
+
# e.g. /path/to/resource(.:format) => /path/to/resource
|
72
|
+
grape_route[:route_info].path&.gsub(/\(\.:?\w+\)\z/, '')
|
73
|
+
)
|
74
|
+
|
75
|
+
trace.set_tag(Tracing::Metadata::Ext::HTTP::TAG_ROUTE_PATH, env['SCRIPT_NAME'])
|
76
|
+
end
|
77
|
+
|
64
78
|
Thread.current[KEY_RUN] = true
|
65
79
|
rescue StandardError => e
|
66
80
|
Datadog.logger.error(e.message)
|
81
|
+
Datadog::Core::Telemetry::Logger.report(e)
|
67
82
|
end
|
68
83
|
|
69
84
|
def endpoint_run(name, start, finish, id, payload)
|
@@ -107,6 +122,7 @@ module Datadog
|
|
107
122
|
end
|
108
123
|
rescue StandardError => e
|
109
124
|
Datadog.logger.error(e.message)
|
125
|
+
Datadog::Core::Telemetry::Logger.report(e)
|
110
126
|
end
|
111
127
|
|
112
128
|
# Status code resolution is tied to the exception handling
|
@@ -150,6 +166,7 @@ module Datadog
|
|
150
166
|
Thread.current[KEY_RENDER] = true
|
151
167
|
rescue StandardError => e
|
152
168
|
Datadog.logger.error(e.message)
|
169
|
+
Datadog::Core::Telemetry::Logger.report(e)
|
153
170
|
end
|
154
171
|
|
155
172
|
def endpoint_render(name, start, finish, id, payload)
|
@@ -174,6 +191,7 @@ module Datadog
|
|
174
191
|
end
|
175
192
|
rescue StandardError => e
|
176
193
|
Datadog.logger.error(e.message)
|
194
|
+
Datadog::Core::Telemetry::Logger.report(e)
|
177
195
|
end
|
178
196
|
|
179
197
|
def endpoint_run_filters(name, start, finish, id, payload)
|
@@ -212,6 +230,7 @@ module Datadog
|
|
212
230
|
end
|
213
231
|
rescue StandardError => e
|
214
232
|
Datadog.logger.error(e.message)
|
233
|
+
Datadog::Core::Telemetry::Logger.report(e)
|
215
234
|
end
|
216
235
|
|
217
236
|
private
|
@@ -21,13 +21,18 @@ module Datadog
|
|
21
21
|
end
|
22
22
|
|
23
23
|
def patch
|
24
|
+
# DEV-3.0: We should remove as many patching options as possible, given the alternatives do not
|
25
|
+
# DEV-3.0: provide any benefit to the recommended `with_unified_tracer` patching method.
|
26
|
+
# DEV-3.0: `with_deprecated_tracer` is likely safe to remove.
|
27
|
+
# DEV-3.0: `with_unified_tracer: false` should be removed if possible.
|
28
|
+
# DEV-3.0: `with_unified_tracer: true` should be the default and hopefully not even necessary as an option.
|
24
29
|
if configuration[:with_deprecated_tracer]
|
25
|
-
TracingPatcher.patch!(schemas
|
30
|
+
TracingPatcher.patch!(schemas)
|
26
31
|
elsif Integration.trace_supported?
|
27
32
|
if configuration[:with_unified_tracer]
|
28
|
-
UnifiedTracePatcher.patch!(schemas
|
33
|
+
UnifiedTracePatcher.patch!(schemas)
|
29
34
|
else
|
30
|
-
TracePatcher.patch!(schemas
|
35
|
+
TracePatcher.patch!(schemas)
|
31
36
|
end
|
32
37
|
else
|
33
38
|
Datadog.logger.warn(
|
@@ -35,18 +40,10 @@ module Datadog
|
|
35
40
|
'or Datadog::Tracing::Contrib::GraphQL::UnifiedTrace.'\
|
36
41
|
'Falling back to GraphQL::Tracing::DataDogTracing.'
|
37
42
|
)
|
38
|
-
TracingPatcher.patch!(schemas
|
43
|
+
TracingPatcher.patch!(schemas)
|
39
44
|
end
|
40
45
|
end
|
41
46
|
|
42
|
-
def trace_options
|
43
|
-
{
|
44
|
-
service: configuration[:service_name],
|
45
|
-
analytics_enabled: Contrib::Analytics.enabled?(configuration[:analytics_enabled]),
|
46
|
-
analytics_sample_rate: configuration[:analytics_sample_rate]
|
47
|
-
}
|
48
|
-
end
|
49
|
-
|
50
47
|
def configuration
|
51
48
|
Datadog.configuration.tracing[:graphql]
|
52
49
|
end
|
@@ -8,12 +8,12 @@ module Datadog
|
|
8
8
|
module TracePatcher
|
9
9
|
module_function
|
10
10
|
|
11
|
-
def patch!(schemas
|
11
|
+
def patch!(schemas)
|
12
12
|
if schemas.empty?
|
13
|
-
::GraphQL::Schema.trace_with(::GraphQL::Tracing::DataDogTrace
|
13
|
+
::GraphQL::Schema.trace_with(::GraphQL::Tracing::DataDogTrace)
|
14
14
|
else
|
15
15
|
schemas.each do |schema|
|
16
|
-
schema.trace_with(::GraphQL::Tracing::DataDogTrace
|
16
|
+
schema.trace_with(::GraphQL::Tracing::DataDogTrace)
|
17
17
|
end
|
18
18
|
end
|
19
19
|
end
|