datadog 2.2.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 +87 -2
- data/ext/datadog_profiling_loader/datadog_profiling_loader.c +9 -1
- data/ext/datadog_profiling_loader/extconf.rb +14 -26
- data/ext/datadog_profiling_native_extension/clock_id.h +1 -0
- data/ext/datadog_profiling_native_extension/clock_id_from_pthread.c +1 -2
- data/ext/datadog_profiling_native_extension/clock_id_noop.c +1 -2
- data/ext/datadog_profiling_native_extension/collectors_cpu_and_wall_time_worker.c +257 -69
- data/ext/datadog_profiling_native_extension/collectors_discrete_dynamic_sampler.c +53 -28
- data/ext/datadog_profiling_native_extension/collectors_discrete_dynamic_sampler.h +34 -4
- data/ext/datadog_profiling_native_extension/collectors_idle_sampling_helper.c +4 -0
- data/ext/datadog_profiling_native_extension/collectors_stack.c +136 -81
- data/ext/datadog_profiling_native_extension/collectors_stack.h +2 -2
- data/ext/datadog_profiling_native_extension/collectors_thread_context.c +661 -48
- data/ext/datadog_profiling_native_extension/collectors_thread_context.h +10 -1
- data/ext/datadog_profiling_native_extension/datadog_ruby_common.c +83 -0
- data/ext/datadog_profiling_native_extension/datadog_ruby_common.h +53 -0
- data/ext/datadog_profiling_native_extension/extconf.rb +91 -69
- 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 +54 -12
- data/ext/datadog_profiling_native_extension/heap_recorder.h +3 -1
- data/ext/datadog_profiling_native_extension/helpers.h +6 -17
- data/ext/datadog_profiling_native_extension/http_transport.c +41 -9
- data/ext/datadog_profiling_native_extension/libdatadog_helpers.c +0 -86
- data/ext/datadog_profiling_native_extension/libdatadog_helpers.h +2 -23
- data/ext/datadog_profiling_native_extension/native_extension_helpers.rb +61 -172
- data/ext/datadog_profiling_native_extension/private_vm_api_access.c +116 -139
- data/ext/datadog_profiling_native_extension/private_vm_api_access.h +20 -11
- data/ext/datadog_profiling_native_extension/profiling.c +1 -3
- data/ext/datadog_profiling_native_extension/ruby_helpers.c +0 -33
- data/ext/datadog_profiling_native_extension/ruby_helpers.h +1 -26
- data/ext/datadog_profiling_native_extension/setup_signal_handler.h +1 -0
- data/ext/datadog_profiling_native_extension/stack_recorder.c +14 -2
- data/ext/datadog_profiling_native_extension/stack_recorder.h +2 -0
- data/ext/datadog_profiling_native_extension/time_helpers.c +0 -15
- data/ext/datadog_profiling_native_extension/time_helpers.h +36 -6
- data/ext/{datadog_profiling_native_extension → libdatadog_api}/crashtracker.c +37 -22
- data/ext/libdatadog_api/datadog_ruby_common.c +83 -0
- data/ext/libdatadog_api/datadog_ruby_common.h +53 -0
- data/ext/libdatadog_api/extconf.rb +108 -0
- data/ext/libdatadog_api/macos_development.md +26 -0
- data/ext/libdatadog_extconf_helpers.rb +130 -0
- 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 +35 -0
- data/lib/datadog/appsec/contrib/graphql/gateway/multiplex.rb +109 -0
- data/lib/datadog/appsec/contrib/graphql/gateway/watcher.rb +71 -0
- data/lib/datadog/appsec/contrib/graphql/integration.rb +54 -0
- data/lib/datadog/appsec/contrib/graphql/patcher.rb +37 -0
- data/lib/datadog/appsec/contrib/graphql/reactive/multiplex.rb +59 -0
- data/lib/datadog/appsec/contrib/rack/gateway/request.rb +3 -6
- data/lib/datadog/appsec/event.rb +1 -1
- data/lib/datadog/appsec/processor/actions.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/response.rb +15 -1
- data/lib/datadog/appsec.rb +3 -2
- data/lib/datadog/core/configuration/components.rb +18 -15
- data/lib/datadog/core/configuration/settings.rb +135 -9
- data/lib/datadog/core/crashtracking/agent_base_url.rb +21 -0
- data/lib/datadog/core/crashtracking/component.rb +111 -0
- data/lib/datadog/core/crashtracking/tag_builder.rb +39 -0
- data/lib/datadog/core/diagnostics/environment_logger.rb +8 -11
- 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 +51 -2
- data/lib/datadog/core/telemetry/emitter.rb +9 -11
- data/lib/datadog/core/telemetry/event.rb +37 -1
- data/lib/datadog/core/telemetry/ext.rb +1 -0
- data/lib/datadog/core/telemetry/http/adapters/net.rb +10 -12
- data/lib/datadog/core/telemetry/http/ext.rb +3 -0
- data/lib/datadog/core/telemetry/http/transport.rb +38 -9
- data/lib/datadog/core/telemetry/logger.rb +51 -0
- data/lib/datadog/core/telemetry/logging.rb +71 -0
- data/lib/datadog/core/telemetry/request.rb +13 -1
- data/lib/datadog/core/utils/at_fork_monkey_patch.rb +102 -0
- 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/kit/appsec/events.rb +2 -4
- data/lib/datadog/opentelemetry/sdk/propagator.rb +2 -0
- data/lib/datadog/opentelemetry/sdk/span_processor.rb +10 -0
- data/lib/datadog/opentelemetry/sdk/trace/span.rb +23 -0
- data/lib/datadog/profiling/collectors/code_provenance.rb +7 -7
- data/lib/datadog/profiling/collectors/cpu_and_wall_time_worker.rb +28 -26
- data/lib/datadog/profiling/collectors/idle_sampling_helper.rb +11 -13
- data/lib/datadog/profiling/collectors/info.rb +15 -6
- data/lib/datadog/profiling/collectors/thread_context.rb +30 -2
- data/lib/datadog/profiling/component.rb +89 -95
- data/lib/datadog/profiling/exporter.rb +3 -3
- data/lib/datadog/profiling/ext/dir_monkey_patches.rb +3 -3
- data/lib/datadog/profiling/ext.rb +21 -21
- data/lib/datadog/profiling/flush.rb +1 -1
- data/lib/datadog/profiling/http_transport.rb +14 -7
- data/lib/datadog/profiling/load_native_extension.rb +5 -5
- data/lib/datadog/profiling/preload.rb +1 -1
- data/lib/datadog/profiling/profiler.rb +5 -8
- data/lib/datadog/profiling/scheduler.rb +33 -25
- data/lib/datadog/profiling/stack_recorder.rb +3 -0
- data/lib/datadog/profiling/tag_builder.rb +2 -2
- data/lib/datadog/profiling/tasks/exec.rb +5 -5
- data/lib/datadog/profiling/tasks/setup.rb +16 -35
- data/lib/datadog/profiling.rb +4 -5
- 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 +4 -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/ext.rb +14 -0
- 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 +14 -10
- data/lib/datadog/tracing/contrib/graphql/unified_trace_patcher.rb +10 -4
- 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 +15 -0
- data/lib/datadog/tracing/contrib/mongodb/subscribers.rb +2 -0
- data/lib/datadog/tracing/contrib/mysql2/configuration/settings.rb +5 -0
- data/lib/datadog/tracing/contrib/mysql2/instrumentation.rb +17 -13
- data/lib/datadog/tracing/contrib/opensearch/patcher.rb +13 -6
- data/lib/datadog/tracing/contrib/patcher.rb +2 -1
- data/lib/datadog/tracing/contrib/pg/configuration/settings.rb +5 -0
- data/lib/datadog/tracing/contrib/pg/instrumentation.rb +4 -1
- data/lib/datadog/tracing/contrib/presto/patcher.rb +1 -13
- data/lib/datadog/tracing/contrib/propagation/sql_comment/ext.rb +28 -0
- data/lib/datadog/tracing/contrib/propagation/sql_comment/mode.rb +5 -1
- data/lib/datadog/tracing/contrib/propagation/sql_comment.rb +22 -10
- 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/contrib/trilogy/configuration/settings.rb +5 -0
- data/lib/datadog/tracing/contrib/trilogy/instrumentation.rb +4 -1
- data/lib/datadog/tracing/diagnostics/environment_logger.rb +14 -16
- data/lib/datadog/tracing/distributed/propagation.rb +7 -0
- data/lib/datadog/tracing/metadata/errors.rb +9 -1
- data/lib/datadog/tracing/metadata/ext.rb +6 -0
- data/lib/datadog/tracing/pipeline/span_filter.rb +2 -2
- 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/span.rb +9 -2
- data/lib/datadog/tracing/span_event.rb +41 -0
- data/lib/datadog/tracing/span_operation.rb +6 -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/transport/serializable_trace.rb +3 -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 +46 -11
- data/lib/datadog/profiling/crashtracker.rb +0 -91
- data/lib/datadog/profiling/ext/forking.rb +0 -98
- data/lib/datadog/tracing/sampling/rate_limiter.rb +0 -185
@@ -8,34 +8,30 @@ module Datadog
|
|
8
8
|
|
9
9
|
private
|
10
10
|
|
11
|
-
attr_reader :worker, :scheduler
|
11
|
+
attr_reader :worker, :scheduler
|
12
12
|
|
13
13
|
public
|
14
14
|
|
15
|
-
def initialize(worker:, scheduler
|
15
|
+
def initialize(worker:, scheduler:)
|
16
16
|
@worker = worker
|
17
17
|
@scheduler = scheduler
|
18
|
-
@optional_crashtracker = optional_crashtracker
|
19
18
|
end
|
20
19
|
|
21
20
|
def start
|
22
21
|
after_fork! do
|
23
|
-
optional_crashtracker.reset_after_fork if optional_crashtracker
|
24
22
|
worker.reset_after_fork
|
25
23
|
scheduler.reset_after_fork
|
26
24
|
end
|
27
25
|
|
28
|
-
optional_crashtracker.start if optional_crashtracker
|
29
26
|
worker.start(on_failure_proc: proc { component_failed(:worker) })
|
30
27
|
scheduler.start(on_failure_proc: proc { component_failed(:scheduler) })
|
31
28
|
end
|
32
29
|
|
33
30
|
def shutdown!
|
34
|
-
Datadog.logger.debug(
|
31
|
+
Datadog.logger.debug("Shutting down profiler")
|
35
32
|
|
36
33
|
stop_worker
|
37
34
|
stop_scheduler
|
38
|
-
optional_crashtracker.stop if optional_crashtracker
|
39
35
|
end
|
40
36
|
|
41
37
|
private
|
@@ -52,13 +48,14 @@ module Datadog
|
|
52
48
|
def component_failed(failed_component)
|
53
49
|
Datadog.logger.warn(
|
54
50
|
"Detected issue with profiler (#{failed_component} component), stopping profiling. " \
|
55
|
-
|
51
|
+
"See previous log messages for details."
|
56
52
|
)
|
57
53
|
|
58
54
|
# We explicitly not stop the crash tracker in this situation, under the assumption that, if a component failed,
|
59
55
|
# we're operating in a degraded state and crash tracking may still be helpful.
|
60
56
|
|
61
57
|
if failed_component == :worker
|
58
|
+
scheduler.mark_profiler_failed
|
62
59
|
stop_scheduler
|
63
60
|
elsif failed_component == :scheduler
|
64
61
|
stop_worker
|
@@ -1,9 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative
|
3
|
+
require_relative "../core/utils/time"
|
4
4
|
|
5
|
-
require_relative
|
6
|
-
require_relative
|
5
|
+
require_relative "../core/worker"
|
6
|
+
require_relative "../core/workers/polling"
|
7
|
+
require_relative "../core/telemetry/logger"
|
7
8
|
|
8
9
|
module Datadog
|
9
10
|
module Profiling
|
@@ -22,7 +23,8 @@ module Datadog
|
|
22
23
|
|
23
24
|
attr_reader \
|
24
25
|
:exporter,
|
25
|
-
:transport
|
26
|
+
:transport,
|
27
|
+
:profiler_failed
|
26
28
|
|
27
29
|
public
|
28
30
|
|
@@ -34,6 +36,7 @@ module Datadog
|
|
34
36
|
)
|
35
37
|
@exporter = exporter
|
36
38
|
@transport = transport
|
39
|
+
@profiler_failed = false
|
37
40
|
|
38
41
|
# Workers::Async::Thread settings
|
39
42
|
self.fork_policy = fork_policy
|
@@ -50,25 +53,23 @@ module Datadog
|
|
50
53
|
end
|
51
54
|
|
52
55
|
def perform(on_failure_proc)
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
Datadog.logger.debug('#flush was interrupted or failed before it could complete') if interrupted
|
71
|
-
end
|
56
|
+
# A profiling flush may be called while the VM is shutting down, to report the last profile. When we do so,
|
57
|
+
# we impose a strict timeout. This means this last profile may or may not be sent, depending on if the flush can
|
58
|
+
# successfully finish in the strict timeout.
|
59
|
+
# This can be somewhat confusing (why did it not get reported?), so let's at least log what happened.
|
60
|
+
interrupted = true
|
61
|
+
|
62
|
+
flush_and_wait
|
63
|
+
interrupted = false
|
64
|
+
rescue Exception => e # rubocop:disable Lint/RescueException
|
65
|
+
Datadog.logger.warn(
|
66
|
+
"Profiling::Scheduler thread error. " \
|
67
|
+
"Cause: #{e.class.name} #{e.message} Location: #{Array(e.backtrace).first}"
|
68
|
+
)
|
69
|
+
on_failure_proc&.call
|
70
|
+
raise
|
71
|
+
ensure
|
72
|
+
Datadog.logger.debug("#flush was interrupted or failed before it could complete") if interrupted
|
72
73
|
end
|
73
74
|
|
74
75
|
# Configure Workers::IntervalLoop to not report immediately when scheduler starts
|
@@ -80,8 +81,14 @@ module Datadog
|
|
80
81
|
true
|
81
82
|
end
|
82
83
|
|
84
|
+
# This is called by the Profiler class whenever an issue happened in the profiler. This makes sure that even
|
85
|
+
# if there is data to be flushed, we don't try to flush it.
|
86
|
+
def mark_profiler_failed
|
87
|
+
@profiler_failed = true
|
88
|
+
end
|
89
|
+
|
83
90
|
def work_pending?
|
84
|
-
exporter.can_flush?
|
91
|
+
!profiler_failed && exporter.can_flush?
|
85
92
|
end
|
86
93
|
|
87
94
|
def reset_after_fork
|
@@ -124,10 +131,11 @@ module Datadog
|
|
124
131
|
|
125
132
|
begin
|
126
133
|
transport.export(flush)
|
127
|
-
rescue
|
134
|
+
rescue => e
|
128
135
|
Datadog.logger.error(
|
129
136
|
"Unable to report profile. Cause: #{e.class.name} #{e.message} Location: #{Array(e.backtrace).first}"
|
130
137
|
)
|
138
|
+
Datadog::Core::Telemetry::Logger.report(e, description: "Unable to report profile")
|
131
139
|
end
|
132
140
|
|
133
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
|
@@ -18,16 +18,16 @@ module Datadog
|
|
18
18
|
|
19
19
|
def rubyopts
|
20
20
|
[
|
21
|
-
|
21
|
+
"-rdatadog/profiling/preload"
|
22
22
|
]
|
23
23
|
end
|
24
24
|
|
25
25
|
private
|
26
26
|
|
27
27
|
def set_rubyopt!
|
28
|
-
existing_rubyopt = ENV[
|
28
|
+
existing_rubyopt = ENV["RUBYOPT"]
|
29
29
|
|
30
|
-
ENV[
|
30
|
+
ENV["RUBYOPT"] = existing_rubyopt ? "#{existing_rubyopt} #{rubyopts.join(" ")}" : rubyopts.join(" ")
|
31
31
|
end
|
32
32
|
|
33
33
|
# If there's an error here, rather than throwing a cryptic stack trace, let's instead have clearer messages, and
|
@@ -38,10 +38,10 @@ module Datadog
|
|
38
38
|
def exec_with_error_handling(args)
|
39
39
|
Kernel.exec(*args)
|
40
40
|
rescue Errno::ENOENT => e
|
41
|
-
Kernel.warn "ddprofrb exec failed: #{e.class.name} #{e.message} (command was '#{args.join(
|
41
|
+
Kernel.warn "ddprofrb exec failed: #{e.class.name} #{e.message} (command was '#{args.join(" ")}')"
|
42
42
|
Kernel.exit 127
|
43
43
|
rescue Errno::EACCES, Errno::ENOEXEC => e
|
44
|
-
Kernel.warn "ddprofrb exec failed: #{e.class.name} #{e.message} (command was '#{args.join(
|
44
|
+
Kernel.warn "ddprofrb exec failed: #{e.class.name} #{e.message} (command was '#{args.join(" ")}')"
|
45
45
|
Kernel.exit 126
|
46
46
|
end
|
47
47
|
end
|
@@ -1,56 +1,37 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative
|
4
|
-
require_relative
|
3
|
+
require_relative "../../core/utils/only_once"
|
4
|
+
require_relative "../../core/utils/at_fork_monkey_patch"
|
5
5
|
|
6
6
|
module Datadog
|
7
7
|
module Profiling
|
8
8
|
module Tasks
|
9
|
-
# Takes care of
|
9
|
+
# Takes care of restarting the profiler when the process forks
|
10
10
|
class Setup
|
11
11
|
ACTIVATE_EXTENSIONS_ONLY_ONCE = Core::Utils::OnlyOnce.new
|
12
12
|
|
13
13
|
def run
|
14
14
|
ACTIVATE_EXTENSIONS_ONLY_ONCE.run do
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
"Location: #{Array(e.backtrace).first}"
|
22
|
-
end
|
15
|
+
Datadog::Core::Utils::AtForkMonkeyPatch.apply!
|
16
|
+
setup_at_fork_hooks
|
17
|
+
rescue StandardError, ScriptError => e
|
18
|
+
Datadog.logger.warn do
|
19
|
+
"Profiler extensions unavailable. Cause: #{e.class.name} #{e.message} " \
|
20
|
+
"Location: #{Array(e.backtrace).first}"
|
23
21
|
end
|
24
22
|
end
|
25
23
|
end
|
26
24
|
|
27
25
|
private
|
28
26
|
|
29
|
-
def activate_forking_extensions
|
30
|
-
if Ext::Forking.supported?
|
31
|
-
Ext::Forking.apply!
|
32
|
-
elsif Datadog.configuration.profiling.enabled
|
33
|
-
Datadog.logger.debug('Profiler forking extensions skipped; forking not supported.')
|
34
|
-
end
|
35
|
-
rescue StandardError, ScriptError => e
|
36
|
-
Datadog.logger.warn do
|
37
|
-
"Profiler forking extensions unavailable. Cause: #{e.class.name} #{e.message} " \
|
38
|
-
"Location: #{Array(e.backtrace).first}"
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
27
|
def setup_at_fork_hooks
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
"Error during post-fork hooks. Cause: #{e.class.name} #{e.message} " \
|
51
|
-
"Location: #{Array(e.backtrace).first}"
|
52
|
-
end
|
53
|
-
end
|
28
|
+
Datadog::Core::Utils::AtForkMonkeyPatch.at_fork(:child) do
|
29
|
+
# Restart profiler, if enabled
|
30
|
+
Profiling.start_if_enabled
|
31
|
+
rescue => e
|
32
|
+
Datadog.logger.warn do
|
33
|
+
"Error during post-fork hooks. Cause: #{e.class.name} #{e.message} " \
|
34
|
+
"Location: #{Array(e.backtrace).first}"
|
54
35
|
end
|
55
36
|
end
|
56
37
|
end
|
data/lib/datadog/profiling.rb
CHANGED
@@ -30,7 +30,7 @@ module Datadog
|
|
30
30
|
profiler = Datadog.send(:components).profiler
|
31
31
|
# ...but we still try to start it BECAUSE if the process forks, the profiler will exist but may
|
32
32
|
# not yet have been started in the fork
|
33
|
-
profiler
|
33
|
+
profiler&.start
|
34
34
|
!!profiler
|
35
35
|
end
|
36
36
|
|
@@ -47,6 +47,7 @@ module Datadog
|
|
47
47
|
# (This is similar to some OS-based time representations.)
|
48
48
|
#
|
49
49
|
# Note 2: All fibers in the same thread will share the same counter values.
|
50
|
+
# Note 3: This counter is not accurate when using the M:N scheduler.
|
50
51
|
#
|
51
52
|
# Only available when the profiler is running, and allocation-related features are not disabled via configuration.
|
52
53
|
#
|
@@ -62,7 +63,7 @@ module Datadog
|
|
62
63
|
def self.enabled?
|
63
64
|
profiler = Datadog.send(:components).profiler
|
64
65
|
# Use .send(...) to avoid exposing the attr_reader as an API to the outside
|
65
|
-
!!
|
66
|
+
!!profiler&.send(:scheduler)&.running?
|
66
67
|
end
|
67
68
|
|
68
69
|
def self.wait_until_running(timeout_seconds: 5)
|
@@ -97,7 +98,7 @@ module Datadog
|
|
97
98
|
|
98
99
|
contents = file_api.read(skipped_reason_file).strip
|
99
100
|
contents unless contents.empty?
|
100
|
-
rescue
|
101
|
+
rescue
|
101
102
|
# Do nothing
|
102
103
|
end
|
103
104
|
end
|
@@ -135,7 +136,6 @@ module Datadog
|
|
135
136
|
private_class_method def self.load_profiling
|
136
137
|
return false unless supported?
|
137
138
|
|
138
|
-
require_relative 'profiling/ext/forking'
|
139
139
|
require_relative 'profiling/ext/dir_monkey_patches'
|
140
140
|
require_relative 'profiling/collectors/info'
|
141
141
|
require_relative 'profiling/collectors/code_provenance'
|
@@ -144,7 +144,6 @@ module Datadog
|
|
144
144
|
require_relative 'profiling/collectors/idle_sampling_helper'
|
145
145
|
require_relative 'profiling/collectors/stack'
|
146
146
|
require_relative 'profiling/collectors/thread_context'
|
147
|
-
require_relative 'profiling/crashtracker'
|
148
147
|
require_relative 'profiling/stack_recorder'
|
149
148
|
require_relative 'profiling/exporter'
|
150
149
|
require_relative 'profiling/flush'
|
@@ -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
|
@@ -62,12 +63,14 @@ module Datadog
|
|
62
63
|
cached = payload[:cached] || (payload[:name] == PAYLOAD_CACHE)
|
63
64
|
|
64
65
|
span.set_tag(Ext::TAG_DB_VENDOR, adapter_name)
|
66
|
+
span.set_tag(Contrib::Ext::DB::TAG_INSTANCE, config[:database])
|
65
67
|
span.set_tag(Ext::TAG_DB_NAME, config[:database])
|
66
68
|
span.set_tag(Ext::TAG_DB_CACHED, cached) if cached
|
67
69
|
span.set_tag(Tracing::Metadata::Ext::NET::TAG_TARGET_HOST, config[:host]) if config[:host]
|
68
70
|
span.set_tag(Tracing::Metadata::Ext::NET::TAG_TARGET_PORT, config[:port]) if config[:port]
|
69
71
|
rescue StandardError => e
|
70
|
-
Datadog.logger.
|
72
|
+
Datadog.logger.error(e.message)
|
73
|
+
Datadog::Core::Telemetry::Logger.report(e)
|
71
74
|
end
|
72
75
|
end
|
73
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
|