ddtrace 0.52.0 → 0.54.2
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 +174 -11
- data/ddtrace.gemspec +6 -3
- data/docs/DevelopmentGuide.md +1 -6
- data/docs/GettingStarted.md +109 -18
- data/docs/ProfilingDevelopment.md +2 -2
- data/ext/ddtrace_profiling_native_extension/NativeExtensionDesign.md +86 -0
- data/ext/ddtrace_profiling_native_extension/clock_id.h +4 -0
- data/ext/ddtrace_profiling_native_extension/clock_id_from_pthread.c +52 -0
- data/ext/ddtrace_profiling_native_extension/clock_id_noop.c +14 -0
- data/ext/ddtrace_profiling_native_extension/extconf.rb +177 -8
- data/ext/ddtrace_profiling_native_extension/private_vm_api_access.c +35 -0
- data/ext/ddtrace_profiling_native_extension/private_vm_api_access.h +3 -0
- data/ext/ddtrace_profiling_native_extension/profiling.c +6 -1
- data/lib/datadog/ci/contrib/cucumber/formatter.rb +1 -0
- data/lib/datadog/ci/contrib/rspec/example.rb +1 -0
- data/lib/datadog/ci/contrib/rspec/integration.rb +2 -2
- data/lib/datadog/ci/ext/environment.rb +64 -22
- data/lib/datadog/ci/ext/test.rb +1 -0
- data/lib/datadog/ci/test.rb +5 -1
- data/lib/datadog/contrib.rb +2 -0
- data/lib/datadog/core/environment/vm_cache.rb +46 -0
- data/lib/ddtrace/buffer.rb +28 -16
- data/lib/ddtrace/configuration/agent_settings_resolver.rb +131 -53
- data/lib/ddtrace/configuration/components.rb +1 -1
- data/lib/ddtrace/configuration/settings.rb +13 -3
- data/lib/ddtrace/context.rb +10 -2
- data/lib/ddtrace/contrib/action_cable/instrumentation.rb +46 -0
- data/lib/ddtrace/contrib/action_cable/patcher.rb +1 -0
- data/lib/ddtrace/contrib/action_mailer/configuration/settings.rb +32 -0
- data/lib/ddtrace/contrib/action_mailer/event.rb +50 -0
- data/lib/ddtrace/contrib/action_mailer/events/deliver.rb +54 -0
- data/lib/ddtrace/contrib/action_mailer/events/process.rb +41 -0
- data/lib/ddtrace/contrib/action_mailer/events.rb +31 -0
- data/lib/ddtrace/contrib/action_mailer/ext.rb +32 -0
- data/lib/ddtrace/contrib/action_mailer/integration.rb +45 -0
- data/lib/ddtrace/contrib/action_mailer/patcher.rb +27 -0
- data/lib/ddtrace/contrib/active_job/configuration/settings.rb +33 -0
- data/lib/ddtrace/contrib/active_job/event.rb +54 -0
- data/lib/ddtrace/contrib/active_job/events/discard.rb +46 -0
- data/lib/ddtrace/contrib/active_job/events/enqueue.rb +45 -0
- data/lib/ddtrace/contrib/active_job/events/enqueue_at.rb +45 -0
- data/lib/ddtrace/contrib/active_job/events/enqueue_retry.rb +47 -0
- data/lib/ddtrace/contrib/active_job/events/perform.rb +45 -0
- data/lib/ddtrace/contrib/active_job/events/retry_stopped.rb +46 -0
- data/lib/ddtrace/contrib/active_job/events.rb +39 -0
- data/lib/ddtrace/contrib/active_job/ext.rb +32 -0
- data/lib/ddtrace/contrib/active_job/integration.rb +46 -0
- data/lib/ddtrace/contrib/active_job/log_injection.rb +21 -0
- data/lib/ddtrace/contrib/active_job/patcher.rb +33 -0
- data/lib/ddtrace/contrib/auto_instrument.rb +0 -1
- data/lib/ddtrace/contrib/delayed_job/plugin.rb +2 -2
- data/lib/ddtrace/contrib/mongodb/instrumentation.rb +1 -1
- data/lib/ddtrace/contrib/mongodb/integration.rb +5 -0
- data/lib/ddtrace/contrib/rails/auto_instrument_railtie.rb +0 -1
- data/lib/ddtrace/contrib/rails/configuration/settings.rb +7 -0
- data/lib/ddtrace/contrib/rails/framework.rb +24 -1
- data/lib/ddtrace/contrib/rails/patcher.rb +19 -10
- data/lib/ddtrace/contrib/redis/instrumentation.rb +90 -0
- data/lib/ddtrace/contrib/redis/patcher.rb +2 -84
- data/lib/ddtrace/contrib/registerable.rb +0 -1
- data/lib/ddtrace/contrib/resque/integration.rb +1 -5
- data/lib/ddtrace/contrib/sidekiq/ext.rb +3 -0
- data/lib/ddtrace/contrib/sidekiq/integration.rb +10 -0
- data/lib/ddtrace/contrib/sidekiq/patcher.rb +26 -0
- data/lib/ddtrace/contrib/sidekiq/server_internal_tracer/heartbeat.rb +30 -0
- data/lib/ddtrace/contrib/sidekiq/server_internal_tracer/job_fetch.rb +30 -0
- data/lib/ddtrace/contrib/sidekiq/server_internal_tracer/scheduled_push.rb +29 -0
- data/lib/ddtrace/contrib/sinatra/env.rb +2 -1
- data/lib/ddtrace/contrib/sinatra/tracer.rb +15 -2
- data/lib/ddtrace/ext/git.rb +12 -0
- data/lib/ddtrace/ext/priority.rb +6 -4
- data/lib/ddtrace/ext/profiling.rb +8 -11
- data/lib/ddtrace/ext/runtime.rb +3 -0
- data/lib/ddtrace/ext/transport.rb +11 -0
- data/lib/ddtrace/metrics.rb +2 -2
- data/lib/ddtrace/profiling/collectors/stack.rb +112 -72
- data/lib/ddtrace/profiling/encoding/profile.rb +10 -2
- data/lib/ddtrace/profiling/events/stack.rb +13 -13
- data/lib/ddtrace/profiling/native_extension.rb +23 -1
- data/lib/ddtrace/profiling/pprof/builder.rb +8 -2
- data/lib/ddtrace/profiling/pprof/converter.rb +22 -9
- data/lib/ddtrace/profiling/pprof/stack_sample.rb +32 -9
- data/lib/ddtrace/profiling/pprof/template.rb +2 -2
- data/lib/ddtrace/profiling/scheduler.rb +20 -4
- data/lib/ddtrace/profiling/tasks/setup.rb +21 -13
- data/lib/ddtrace/profiling/trace_identifiers/ddtrace.rb +10 -9
- data/lib/ddtrace/profiling/trace_identifiers/helper.rb +5 -5
- data/lib/ddtrace/profiling/transport/http/api/endpoint.rb +8 -15
- data/lib/ddtrace/profiling/transport/http.rb +8 -17
- data/lib/ddtrace/profiling.rb +0 -2
- data/lib/ddtrace/runtime/metrics.rb +14 -0
- data/lib/ddtrace/sampler.rb +18 -8
- data/lib/ddtrace/sampling/rule_sampler.rb +13 -1
- data/lib/ddtrace/span.rb +7 -19
- data/lib/ddtrace/tracer.rb +1 -1
- data/lib/ddtrace/transport/http/adapters/net.rb +13 -3
- data/lib/ddtrace/transport/http/adapters/test.rb +4 -2
- data/lib/ddtrace/transport/http/adapters/unix_socket.rb +23 -12
- data/lib/ddtrace/transport/http/builder.rb +13 -6
- data/lib/ddtrace/transport/http.rb +5 -11
- data/lib/ddtrace/utils/time.rb +11 -6
- data/lib/ddtrace/version.rb +2 -2
- data/lib/ddtrace/workers/{loop.rb → interval_loop.rb} +0 -16
- data/lib/ddtrace/workers/polling.rb +1 -1
- metadata +40 -10
- data/lib/ddtrace/profiling/ext/cpu.rb +0 -67
- data/lib/ddtrace/profiling/ext/cthread.rb +0 -156
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
# typed: false
|
|
2
2
|
require 'net/http'
|
|
3
|
+
require 'ddtrace/ext/transport'
|
|
3
4
|
require 'ddtrace/transport/http/adapters/net'
|
|
4
5
|
|
|
5
6
|
module Datadog
|
|
@@ -8,21 +9,29 @@ module Datadog
|
|
|
8
9
|
module Adapters
|
|
9
10
|
# Adapter for Unix sockets
|
|
10
11
|
class UnixSocket < Adapters::Net
|
|
11
|
-
DEFAULT_TIMEOUT = 1
|
|
12
|
-
|
|
13
12
|
attr_reader \
|
|
14
|
-
:filepath,
|
|
13
|
+
:filepath, # DEV(1.0): Rename to `uds_path`
|
|
15
14
|
:timeout
|
|
16
15
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
16
|
+
alias_method :uds_path, :filepath
|
|
17
|
+
|
|
18
|
+
# @deprecated Positional parameters are deprecated. Use named parameters instead.
|
|
19
|
+
def initialize(uds_path = nil, **options)
|
|
20
|
+
@filepath = uds_path || options.fetch(:uds_path)
|
|
21
|
+
@timeout = options[:timeout] || Ext::Transport::UnixSocket::DEFAULT_TIMEOUT_SECONDS
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def self.build(agent_settings)
|
|
25
|
+
new(
|
|
26
|
+
uds_path: agent_settings.uds_path,
|
|
27
|
+
timeout: agent_settings.timeout_seconds,
|
|
28
|
+
)
|
|
20
29
|
end
|
|
21
30
|
|
|
22
31
|
def open(&block)
|
|
23
32
|
# Open connection
|
|
24
33
|
connection = HTTP.new(
|
|
25
|
-
|
|
34
|
+
uds_path,
|
|
26
35
|
read_timeout: timeout,
|
|
27
36
|
continue_timeout: timeout
|
|
28
37
|
)
|
|
@@ -31,7 +40,7 @@ module Datadog
|
|
|
31
40
|
end
|
|
32
41
|
|
|
33
42
|
def url
|
|
34
|
-
"http+unix://#{
|
|
43
|
+
"http+unix://#{uds_path}?timeout=#{timeout}"
|
|
35
44
|
end
|
|
36
45
|
|
|
37
46
|
# Re-implements Net:HTTP with underlying Unix socket
|
|
@@ -39,19 +48,21 @@ module Datadog
|
|
|
39
48
|
DEFAULT_TIMEOUT = 1
|
|
40
49
|
|
|
41
50
|
attr_reader \
|
|
42
|
-
:filepath,
|
|
51
|
+
:filepath, # DEV(1.0): Rename to `uds_path`
|
|
43
52
|
:unix_socket
|
|
44
53
|
|
|
45
|
-
|
|
54
|
+
alias_method :uds_path, :filepath
|
|
55
|
+
|
|
56
|
+
def initialize(uds_path, options = {})
|
|
46
57
|
super('localhost', 80)
|
|
47
|
-
@filepath =
|
|
58
|
+
@filepath = uds_path
|
|
48
59
|
@read_timeout = options.fetch(:read_timeout, DEFAULT_TIMEOUT)
|
|
49
60
|
@continue_timeout = options.fetch(:continue_timeout, DEFAULT_TIMEOUT)
|
|
50
61
|
@debug_output = options[:debug_output] if options.key?(:debug_output)
|
|
51
62
|
end
|
|
52
63
|
|
|
53
64
|
def connect
|
|
54
|
-
@unix_socket = UNIXSocket.open(
|
|
65
|
+
@unix_socket = UNIXSocket.open(uds_path)
|
|
55
66
|
@socket = ::Net::BufferedIO.new(@unix_socket).tap do |socket|
|
|
56
67
|
socket.read_timeout = @read_timeout
|
|
57
68
|
socket.continue_timeout = @continue_timeout
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
# typed: true
|
|
2
|
+
require 'ddtrace/configuration/agent_settings_resolver'
|
|
2
3
|
require 'ddtrace/transport/http/adapters/registry'
|
|
3
4
|
require 'ddtrace/transport/http/api/map'
|
|
4
5
|
require 'ddtrace/transport/http/api/instance'
|
|
@@ -33,14 +34,20 @@ module Datadog
|
|
|
33
34
|
yield(self) if block_given?
|
|
34
35
|
end
|
|
35
36
|
|
|
36
|
-
def adapter(
|
|
37
|
-
@default_adapter =
|
|
38
|
-
|
|
39
|
-
|
|
37
|
+
def adapter(config, *args, **kwargs)
|
|
38
|
+
@default_adapter = case config
|
|
39
|
+
when Configuration::AgentSettingsResolver::AgentSettings
|
|
40
|
+
registry_klass = REGISTRY.get(config.adapter)
|
|
41
|
+
raise UnknownAdapterError, config.adapter if registry_klass.nil?
|
|
40
42
|
|
|
41
|
-
registry_klass.
|
|
43
|
+
registry_klass.build(config)
|
|
44
|
+
when Symbol
|
|
45
|
+
registry_klass = REGISTRY.get(config)
|
|
46
|
+
raise UnknownAdapterError, config if registry_klass.nil?
|
|
47
|
+
|
|
48
|
+
registry_klass.new(*args, **kwargs)
|
|
42
49
|
else
|
|
43
|
-
|
|
50
|
+
config
|
|
44
51
|
end
|
|
45
52
|
end
|
|
46
53
|
|
|
@@ -30,13 +30,7 @@ module Datadog
|
|
|
30
30
|
# Pass a block to override any settings.
|
|
31
31
|
def default(agent_settings: Datadog::Configuration::AgentSettingsResolver::ENVIRONMENT_AGENT_SETTINGS, **options)
|
|
32
32
|
new do |transport|
|
|
33
|
-
transport.adapter(
|
|
34
|
-
default_adapter,
|
|
35
|
-
agent_settings.hostname,
|
|
36
|
-
agent_settings.port,
|
|
37
|
-
timeout: agent_settings.timeout_seconds,
|
|
38
|
-
ssl: agent_settings.ssl
|
|
39
|
-
)
|
|
33
|
+
transport.adapter(agent_settings)
|
|
40
34
|
transport.headers default_headers
|
|
41
35
|
|
|
42
36
|
if agent_settings.deprecated_for_removal_transport_configuration_options
|
|
@@ -80,7 +74,7 @@ module Datadog
|
|
|
80
74
|
end
|
|
81
75
|
|
|
82
76
|
def default_adapter
|
|
83
|
-
|
|
77
|
+
Ext::Transport::HTTP::ADAPTER
|
|
84
78
|
end
|
|
85
79
|
|
|
86
80
|
def default_hostname(logger: Datadog.logger)
|
|
@@ -111,9 +105,9 @@ module Datadog
|
|
|
111
105
|
end
|
|
112
106
|
|
|
113
107
|
# Add adapters to registry
|
|
114
|
-
Builder::REGISTRY.set(Adapters::Net,
|
|
115
|
-
Builder::REGISTRY.set(Adapters::Test,
|
|
116
|
-
Builder::REGISTRY.set(Adapters::UnixSocket,
|
|
108
|
+
Builder::REGISTRY.set(Adapters::Net, Ext::Transport::HTTP::ADAPTER)
|
|
109
|
+
Builder::REGISTRY.set(Adapters::Test, Ext::Transport::Test::ADAPTER)
|
|
110
|
+
Builder::REGISTRY.set(Adapters::UnixSocket, Ext::Transport::UnixSocket::ADAPTER)
|
|
117
111
|
end
|
|
118
112
|
end
|
|
119
113
|
end
|
data/lib/ddtrace/utils/time.rb
CHANGED
|
@@ -7,13 +7,12 @@ module Datadog
|
|
|
7
7
|
|
|
8
8
|
module_function
|
|
9
9
|
|
|
10
|
-
# Current monotonic time
|
|
11
|
-
# Falls back to `now` if monotonic clock
|
|
12
|
-
# is not available.
|
|
10
|
+
# Current monotonic time
|
|
13
11
|
#
|
|
14
|
-
# @
|
|
15
|
-
|
|
16
|
-
|
|
12
|
+
# @param unit [Symbol] unit for the resulting value, same as ::Process#clock_gettime, defaults to :float_second
|
|
13
|
+
# @return [Numeric] timestamp in the requested unit, since some unspecified starting point
|
|
14
|
+
def get_time(unit = :float_second)
|
|
15
|
+
Process.clock_gettime(Process::CLOCK_MONOTONIC, unit)
|
|
17
16
|
end
|
|
18
17
|
|
|
19
18
|
# Current wall time.
|
|
@@ -41,6 +40,12 @@ module Datadog
|
|
|
41
40
|
after = get_time
|
|
42
41
|
after - before
|
|
43
42
|
end
|
|
43
|
+
|
|
44
|
+
def as_utc_epoch_ns(time)
|
|
45
|
+
# we use #to_r instead of #to_f because Float doesn't have enough precision to represent exact nanoseconds, see
|
|
46
|
+
# https://rubyapi.org/3.0/o/time#method-i-to_f
|
|
47
|
+
(time.to_r * 1_000_000_000).to_i
|
|
48
|
+
end
|
|
44
49
|
end
|
|
45
50
|
end
|
|
46
51
|
end
|
data/lib/ddtrace/version.rb
CHANGED
|
@@ -60,15 +60,6 @@ module Datadog
|
|
|
60
60
|
@loop_wait_time = value
|
|
61
61
|
end
|
|
62
62
|
|
|
63
|
-
def reset_loop_wait_time
|
|
64
|
-
self.loop_wait_time = loop_base_interval
|
|
65
|
-
end
|
|
66
|
-
|
|
67
|
-
# Should the loop "back off" when there's no work?
|
|
68
|
-
def loop_back_off?
|
|
69
|
-
false
|
|
70
|
-
end
|
|
71
|
-
|
|
72
63
|
def loop_back_off!
|
|
73
64
|
self.loop_wait_time = [loop_wait_time * BACK_OFF_RATIO, BACK_OFF_MAX].min
|
|
74
65
|
end
|
|
@@ -106,13 +97,6 @@ module Datadog
|
|
|
106
97
|
# There's work to do...
|
|
107
98
|
# Run the task
|
|
108
99
|
yield
|
|
109
|
-
|
|
110
|
-
# Reset the wait interval
|
|
111
|
-
reset_loop_wait_time if loop_back_off?
|
|
112
|
-
elsif loop_back_off?
|
|
113
|
-
# There's no work to do...
|
|
114
|
-
# Back off the wait interval a bit
|
|
115
|
-
loop_back_off!
|
|
116
100
|
end
|
|
117
101
|
|
|
118
102
|
# Wait for an interval, unless shutdown has been signaled.
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: ddtrace
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.54.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Datadog, Inc.
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2022-01-18 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: msgpack
|
|
@@ -25,19 +25,19 @@ dependencies:
|
|
|
25
25
|
- !ruby/object:Gem::Version
|
|
26
26
|
version: '0'
|
|
27
27
|
- !ruby/object:Gem::Dependency
|
|
28
|
-
name:
|
|
28
|
+
name: debase-ruby_core_source
|
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
|
30
30
|
requirements:
|
|
31
|
-
- - "
|
|
31
|
+
- - "<="
|
|
32
32
|
- !ruby/object:Gem::Version
|
|
33
|
-
version:
|
|
33
|
+
version: 0.10.14
|
|
34
34
|
type: :runtime
|
|
35
35
|
prerelease: false
|
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
|
37
37
|
requirements:
|
|
38
|
-
- - "
|
|
38
|
+
- - "<="
|
|
39
39
|
- !ruby/object:Gem::Version
|
|
40
|
-
version:
|
|
40
|
+
version: 0.10.14
|
|
41
41
|
description: |
|
|
42
42
|
ddtrace is Datadog’s tracing client for Ruby. It is used to trace requests
|
|
43
43
|
as they flow across web servers, databases and microservices so that developers
|
|
@@ -66,7 +66,13 @@ files:
|
|
|
66
66
|
- docs/DevelopmentGuide.md
|
|
67
67
|
- docs/GettingStarted.md
|
|
68
68
|
- docs/ProfilingDevelopment.md
|
|
69
|
+
- ext/ddtrace_profiling_native_extension/NativeExtensionDesign.md
|
|
70
|
+
- ext/ddtrace_profiling_native_extension/clock_id.h
|
|
71
|
+
- ext/ddtrace_profiling_native_extension/clock_id_from_pthread.c
|
|
72
|
+
- ext/ddtrace_profiling_native_extension/clock_id_noop.c
|
|
69
73
|
- ext/ddtrace_profiling_native_extension/extconf.rb
|
|
74
|
+
- ext/ddtrace_profiling_native_extension/private_vm_api_access.c
|
|
75
|
+
- ext/ddtrace_profiling_native_extension/private_vm_api_access.h
|
|
70
76
|
- ext/ddtrace_profiling_native_extension/profiling.c
|
|
71
77
|
- lib/datadog/ci.rb
|
|
72
78
|
- lib/datadog/ci/configuration/components.rb
|
|
@@ -99,6 +105,7 @@ files:
|
|
|
99
105
|
- lib/datadog/core/environment/socket.rb
|
|
100
106
|
- lib/datadog/core/environment/thread_count.rb
|
|
101
107
|
- lib/datadog/core/environment/variable_helpers.rb
|
|
108
|
+
- lib/datadog/core/environment/vm_cache.rb
|
|
102
109
|
- lib/ddtrace.rb
|
|
103
110
|
- lib/ddtrace/analytics.rb
|
|
104
111
|
- lib/ddtrace/auto_instrument.rb
|
|
@@ -130,6 +137,14 @@ files:
|
|
|
130
137
|
- lib/ddtrace/contrib/action_cable/instrumentation.rb
|
|
131
138
|
- lib/ddtrace/contrib/action_cable/integration.rb
|
|
132
139
|
- lib/ddtrace/contrib/action_cable/patcher.rb
|
|
140
|
+
- lib/ddtrace/contrib/action_mailer/configuration/settings.rb
|
|
141
|
+
- lib/ddtrace/contrib/action_mailer/event.rb
|
|
142
|
+
- lib/ddtrace/contrib/action_mailer/events.rb
|
|
143
|
+
- lib/ddtrace/contrib/action_mailer/events/deliver.rb
|
|
144
|
+
- lib/ddtrace/contrib/action_mailer/events/process.rb
|
|
145
|
+
- lib/ddtrace/contrib/action_mailer/ext.rb
|
|
146
|
+
- lib/ddtrace/contrib/action_mailer/integration.rb
|
|
147
|
+
- lib/ddtrace/contrib/action_mailer/patcher.rb
|
|
133
148
|
- lib/ddtrace/contrib/action_pack/action_controller/instrumentation.rb
|
|
134
149
|
- lib/ddtrace/contrib/action_pack/action_controller/patcher.rb
|
|
135
150
|
- lib/ddtrace/contrib/action_pack/configuration/settings.rb
|
|
@@ -148,6 +163,19 @@ files:
|
|
|
148
163
|
- lib/ddtrace/contrib/action_view/integration.rb
|
|
149
164
|
- lib/ddtrace/contrib/action_view/patcher.rb
|
|
150
165
|
- lib/ddtrace/contrib/action_view/utils.rb
|
|
166
|
+
- lib/ddtrace/contrib/active_job/configuration/settings.rb
|
|
167
|
+
- lib/ddtrace/contrib/active_job/event.rb
|
|
168
|
+
- lib/ddtrace/contrib/active_job/events.rb
|
|
169
|
+
- lib/ddtrace/contrib/active_job/events/discard.rb
|
|
170
|
+
- lib/ddtrace/contrib/active_job/events/enqueue.rb
|
|
171
|
+
- lib/ddtrace/contrib/active_job/events/enqueue_at.rb
|
|
172
|
+
- lib/ddtrace/contrib/active_job/events/enqueue_retry.rb
|
|
173
|
+
- lib/ddtrace/contrib/active_job/events/perform.rb
|
|
174
|
+
- lib/ddtrace/contrib/active_job/events/retry_stopped.rb
|
|
175
|
+
- lib/ddtrace/contrib/active_job/ext.rb
|
|
176
|
+
- lib/ddtrace/contrib/active_job/integration.rb
|
|
177
|
+
- lib/ddtrace/contrib/active_job/log_injection.rb
|
|
178
|
+
- lib/ddtrace/contrib/active_job/patcher.rb
|
|
151
179
|
- lib/ddtrace/contrib/active_model_serializers/configuration/settings.rb
|
|
152
180
|
- lib/ddtrace/contrib/active_model_serializers/event.rb
|
|
153
181
|
- lib/ddtrace/contrib/active_model_serializers/events.rb
|
|
@@ -352,6 +380,7 @@ files:
|
|
|
352
380
|
- lib/ddtrace/contrib/redis/configuration/resolver.rb
|
|
353
381
|
- lib/ddtrace/contrib/redis/configuration/settings.rb
|
|
354
382
|
- lib/ddtrace/contrib/redis/ext.rb
|
|
383
|
+
- lib/ddtrace/contrib/redis/instrumentation.rb
|
|
355
384
|
- lib/ddtrace/contrib/redis/integration.rb
|
|
356
385
|
- lib/ddtrace/contrib/redis/patcher.rb
|
|
357
386
|
- lib/ddtrace/contrib/redis/quantize.rb
|
|
@@ -392,6 +421,9 @@ files:
|
|
|
392
421
|
- lib/ddtrace/contrib/sidekiq/ext.rb
|
|
393
422
|
- lib/ddtrace/contrib/sidekiq/integration.rb
|
|
394
423
|
- lib/ddtrace/contrib/sidekiq/patcher.rb
|
|
424
|
+
- lib/ddtrace/contrib/sidekiq/server_internal_tracer/heartbeat.rb
|
|
425
|
+
- lib/ddtrace/contrib/sidekiq/server_internal_tracer/job_fetch.rb
|
|
426
|
+
- lib/ddtrace/contrib/sidekiq/server_internal_tracer/scheduled_push.rb
|
|
395
427
|
- lib/ddtrace/contrib/sidekiq/server_tracer.rb
|
|
396
428
|
- lib/ddtrace/contrib/sidekiq/tracing.rb
|
|
397
429
|
- lib/ddtrace/contrib/sinatra/configuration/settings.rb
|
|
@@ -480,8 +512,6 @@ files:
|
|
|
480
512
|
- lib/ddtrace/profiling/event.rb
|
|
481
513
|
- lib/ddtrace/profiling/events/stack.rb
|
|
482
514
|
- lib/ddtrace/profiling/exporter.rb
|
|
483
|
-
- lib/ddtrace/profiling/ext/cpu.rb
|
|
484
|
-
- lib/ddtrace/profiling/ext/cthread.rb
|
|
485
515
|
- lib/ddtrace/profiling/ext/forking.rb
|
|
486
516
|
- lib/ddtrace/profiling/flush.rb
|
|
487
517
|
- lib/ddtrace/profiling/native_extension.rb
|
|
@@ -581,7 +611,7 @@ files:
|
|
|
581
611
|
- lib/ddtrace/worker.rb
|
|
582
612
|
- lib/ddtrace/workers.rb
|
|
583
613
|
- lib/ddtrace/workers/async.rb
|
|
584
|
-
- lib/ddtrace/workers/
|
|
614
|
+
- lib/ddtrace/workers/interval_loop.rb
|
|
585
615
|
- lib/ddtrace/workers/polling.rb
|
|
586
616
|
- lib/ddtrace/workers/queue.rb
|
|
587
617
|
- lib/ddtrace/workers/runtime_metrics.rb
|
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
# typed: true
|
|
2
|
-
module Datadog
|
|
3
|
-
module Profiling
|
|
4
|
-
module Ext
|
|
5
|
-
# Monkey patches Ruby's `Thread` with our `Ext::CThread` to enable CPU-time profiling
|
|
6
|
-
module CPU
|
|
7
|
-
# We cannot apply our CPU extension if a broken rollbar is around because that can cause customer apps to fail
|
|
8
|
-
# with a SystemStackError: stack level too deep.
|
|
9
|
-
#
|
|
10
|
-
# This occurs whenever our extensions to Thread are applied BEFORE rollbar applies its own. This happens
|
|
11
|
-
# because a loop forms: our extension tries to call Thread#initialize, but it's intercepted by rollbar, which
|
|
12
|
-
# then tries to call the original Thread#initialize as well, but instead alls our extension, leading to stack
|
|
13
|
-
# exhaustion.
|
|
14
|
-
#
|
|
15
|
-
# See https://github.com/rollbar/rollbar-gem/pull/1018 for more details on the issue
|
|
16
|
-
ROLLBAR_INCOMPATIBLE_VERSIONS = Gem::Requirement.new('<= 3.1.1')
|
|
17
|
-
|
|
18
|
-
def self.supported?
|
|
19
|
-
unsupported_reason.nil?
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
def self.apply!
|
|
23
|
-
return false unless supported?
|
|
24
|
-
|
|
25
|
-
# Applying CThread to Thread will ensure any new threads
|
|
26
|
-
# will provide a thread/clock ID for CPU timing.
|
|
27
|
-
require 'ddtrace/profiling/ext/cthread'
|
|
28
|
-
::Thread.prepend(Profiling::Ext::CThread)
|
|
29
|
-
::Thread.singleton_class.prepend(Datadog::Profiling::Ext::WrapThreadStartFork)
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
def self.unsupported_reason
|
|
33
|
-
# NOTE: Only the first matching reason is returned, so try to keep a nice order on reasons -- e.g. tell users
|
|
34
|
-
# first that they can't use this on macOS before telling them that they have the wrong ffi version
|
|
35
|
-
|
|
36
|
-
if RUBY_ENGINE == 'jruby'
|
|
37
|
-
'JRuby is not supported'
|
|
38
|
-
elsif RUBY_PLATFORM.include?('darwin')
|
|
39
|
-
'Feature requires Linux; macOS is not supported'
|
|
40
|
-
elsif RUBY_PLATFORM =~ /(mswin|mingw)/
|
|
41
|
-
'Feature requires Linux; Windows is not supported'
|
|
42
|
-
elsif !RUBY_PLATFORM.include?('linux')
|
|
43
|
-
"Feature requires Linux; #{RUBY_PLATFORM} is not supported"
|
|
44
|
-
elsif Gem::Specification.find_all_by_name('rollbar', ROLLBAR_INCOMPATIBLE_VERSIONS).any?
|
|
45
|
-
'You have an incompatible rollbar gem version installed; ensure that you have rollbar >= 3.1.2 by ' \
|
|
46
|
-
"adding `gem 'rollbar', '>= 3.1.2'` to your Gemfile or gems.rb file. " \
|
|
47
|
-
'See https://github.com/rollbar/rollbar-gem/pull/1018 for details'
|
|
48
|
-
elsif Gem::Specification.find_all_by_name('logging').any? && logging_inherit_context_enabled?
|
|
49
|
-
'The `logging` gem is installed and its thread inherit context feature is enabled. ' \
|
|
50
|
-
"Please add LOGGING_INHERIT_CONTEXT=false to your application's environment variables to disable the " \
|
|
51
|
-
'conflicting `logging` gem feature. ' \
|
|
52
|
-
'See https://github.com/TwP/logging/pull/230 for details'
|
|
53
|
-
end
|
|
54
|
-
end
|
|
55
|
-
|
|
56
|
-
private_class_method def self.logging_inherit_context_enabled?
|
|
57
|
-
# The logging gem provides a mechanism to disable the conflicting behavior, see
|
|
58
|
-
# https://github.com/TwP/logging/blob/ae9872d093833b2a5a34cbe1faa4e895a81f6845/lib/logging/diagnostic_context.rb#L418
|
|
59
|
-
# Here we check if the behavior is enabled
|
|
60
|
-
inherit_context_configuration = ENV['LOGGING_INHERIT_CONTEXT']
|
|
61
|
-
|
|
62
|
-
inherit_context_configuration.nil? || !%w[false no 0].include?(inherit_context_configuration.downcase)
|
|
63
|
-
end
|
|
64
|
-
end
|
|
65
|
-
end
|
|
66
|
-
end
|
|
67
|
-
end
|
|
@@ -1,156 +0,0 @@
|
|
|
1
|
-
# typed: false
|
|
2
|
-
require 'ffi'
|
|
3
|
-
|
|
4
|
-
module Datadog
|
|
5
|
-
module Profiling
|
|
6
|
-
module Ext
|
|
7
|
-
# C-struct for retrieving clock ID from pthread
|
|
8
|
-
class CClockId < FFI::Struct
|
|
9
|
-
layout :value, :int
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
# Enables interfacing with pthread via FFI
|
|
13
|
-
module NativePthread
|
|
14
|
-
extend FFI::Library
|
|
15
|
-
ffi_lib ['pthread', 'libpthread.so.0']
|
|
16
|
-
attach_function :pthread_self, [], :ulong
|
|
17
|
-
attach_function :pthread_getcpuclockid, [:ulong, CClockId], :int
|
|
18
|
-
|
|
19
|
-
# NOTE: Only returns thread ID for thread that evaluates this call.
|
|
20
|
-
# a.k.a. evaluating `get_pthread_thread_id(thread_a)` from within
|
|
21
|
-
# `thread_b` will return `thread_b`'s thread ID, not `thread_a`'s.
|
|
22
|
-
def self.get_pthread_thread_id(thread)
|
|
23
|
-
return unless ::Thread.current == thread
|
|
24
|
-
|
|
25
|
-
pthread_self
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
def self.get_clock_id(thread, pthread_id)
|
|
29
|
-
return unless ::Thread.current == thread && pthread_id
|
|
30
|
-
|
|
31
|
-
clock = CClockId.new
|
|
32
|
-
clock[:value] = 0
|
|
33
|
-
pthread_getcpuclockid(pthread_id, clock).zero? ? clock[:value] : nil
|
|
34
|
-
end
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
# Extension used to enable CPU-time profiling via use of pthread's `getcpuclockid`.
|
|
38
|
-
module CThread
|
|
39
|
-
def self.prepended(base)
|
|
40
|
-
# Threads that have already been created, will not have resolved
|
|
41
|
-
# a thread/clock ID. This is because these IDs can only be resolved
|
|
42
|
-
# from within the thread's execution context, which we do not control.
|
|
43
|
-
#
|
|
44
|
-
# We can mitigate this for the current thread via #update_native_ids,
|
|
45
|
-
# since we are currently running within its execution context. We cannot
|
|
46
|
-
# do this for any other threads that may have been created already.
|
|
47
|
-
# (This is why it's important that CThread is applied before anything else runs.)
|
|
48
|
-
base.current.send(:update_native_ids) if base.current.is_a?(CThread)
|
|
49
|
-
end
|
|
50
|
-
|
|
51
|
-
# Process::Waiter crash workaround:
|
|
52
|
-
#
|
|
53
|
-
# This is a workaround for a Ruby VM segfault (usually something like
|
|
54
|
-
# "[BUG] Segmentation fault at 0x0000000000000008") in the affected Ruby versions.
|
|
55
|
-
# See https://bugs.ruby-lang.org/issues/17807 and the regression tests added to this module's specs for details.
|
|
56
|
-
#
|
|
57
|
-
# In those Ruby versions, there's a very special subclass of `Thread` called `Process::Waiter` that causes VM
|
|
58
|
-
# crashes whenever something tries to read its instance variables. This subclass of thread only shows up when
|
|
59
|
-
# the `Process.detach` API gets used.
|
|
60
|
-
# In this module's specs you can find crash regression tests that include a way of reproducing it.
|
|
61
|
-
#
|
|
62
|
-
# The workaround is to use `defined?` to check first if the instance variable exists. This seems to be fine
|
|
63
|
-
# with Ruby.
|
|
64
|
-
# Note that this crash doesn't affect `@foo ||=` nor instance variable writes (after the first write ever of any
|
|
65
|
-
# instance variable on a `Process::Waiter`, then further reads and writes to that or any other instance are OK;
|
|
66
|
-
# it looks like there's some lazily-created structure that is missing and did not get created).
|
|
67
|
-
if Gem::Version.new(RUBY_VERSION) < Gem::Version.new('2.3') &&
|
|
68
|
-
Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('2.7')
|
|
69
|
-
attr_reader :pthread_thread_id
|
|
70
|
-
else
|
|
71
|
-
def pthread_thread_id
|
|
72
|
-
defined?(@pthread_thread_id) && @pthread_thread_id
|
|
73
|
-
end
|
|
74
|
-
end
|
|
75
|
-
|
|
76
|
-
def initialize(*args)
|
|
77
|
-
@pid = ::Process.pid
|
|
78
|
-
@pthread_thread_id = nil
|
|
79
|
-
@clock_id = nil
|
|
80
|
-
|
|
81
|
-
# Wrap the work block with our own
|
|
82
|
-
# so we can retrieve the native thread ID within the thread's context.
|
|
83
|
-
wrapped_block = proc do |*t_args|
|
|
84
|
-
# Set native thread ID & clock ID
|
|
85
|
-
update_native_ids
|
|
86
|
-
yield(*t_args)
|
|
87
|
-
end
|
|
88
|
-
wrapped_block.ruby2_keywords if wrapped_block.respond_to?(:ruby2_keywords, true)
|
|
89
|
-
|
|
90
|
-
super(*args, &wrapped_block)
|
|
91
|
-
end
|
|
92
|
-
ruby2_keywords :initialize if respond_to?(:ruby2_keywords, true)
|
|
93
|
-
|
|
94
|
-
def cpu_time(unit = :float_second)
|
|
95
|
-
::Process.clock_gettime(clock_id, unit) if clock_id
|
|
96
|
-
end
|
|
97
|
-
|
|
98
|
-
def cpu_time_instrumentation_installed?
|
|
99
|
-
# If this thread was started before this module was added to Thread OR if something caused the initialize
|
|
100
|
-
# method above not to be properly called on new threads, this instance variable is never defined (never set to
|
|
101
|
-
# any value at all, including nil).
|
|
102
|
-
#
|
|
103
|
-
# Thus, we can use @clock_id as a canary to detect a thread that has missing instrumentation, because we
|
|
104
|
-
# know that in initialize above we always set this variable to nil.
|
|
105
|
-
defined?(@clock_id) != nil
|
|
106
|
-
end
|
|
107
|
-
|
|
108
|
-
private
|
|
109
|
-
|
|
110
|
-
def clock_id
|
|
111
|
-
update_native_ids if forked?
|
|
112
|
-
defined?(@clock_id) && @clock_id
|
|
113
|
-
end
|
|
114
|
-
|
|
115
|
-
def forked?
|
|
116
|
-
::Process.pid != (@pid ||= nil)
|
|
117
|
-
end
|
|
118
|
-
|
|
119
|
-
def update_native_ids
|
|
120
|
-
# Can only resolve if invoked from same thread
|
|
121
|
-
return unless ::Thread.current == self
|
|
122
|
-
|
|
123
|
-
@pid = ::Process.pid
|
|
124
|
-
@pthread_thread_id = NativePthread.get_pthread_thread_id(self)
|
|
125
|
-
@clock_id = NativePthread.get_clock_id(self, @pthread_thread_id)
|
|
126
|
-
end
|
|
127
|
-
end
|
|
128
|
-
|
|
129
|
-
# Threads in Ruby can be started by creating a new instance of `Thread` (or a subclass) OR by calling
|
|
130
|
-
# `start`/`fork` on `Thread` (or a subclass).
|
|
131
|
-
#
|
|
132
|
-
# This module intercepts calls to `start`/`fork`, ensuring that the `update_native_ids` operation is correctly
|
|
133
|
-
# called once the new thread starts.
|
|
134
|
-
#
|
|
135
|
-
# Note that unlike CThread above, this module should be prepended to the `Thread`'s singleton class, not to
|
|
136
|
-
# the class.
|
|
137
|
-
module WrapThreadStartFork
|
|
138
|
-
def start(*args)
|
|
139
|
-
# Wrap the work block with our own
|
|
140
|
-
# so we can retrieve the native thread ID within the thread's context.
|
|
141
|
-
wrapped_block = proc do |*t_args|
|
|
142
|
-
# Set native thread ID & clock ID
|
|
143
|
-
::Thread.current.send(:update_native_ids)
|
|
144
|
-
yield(*t_args)
|
|
145
|
-
end
|
|
146
|
-
wrapped_block.ruby2_keywords if wrapped_block.respond_to?(:ruby2_keywords, true)
|
|
147
|
-
|
|
148
|
-
super(*args, &wrapped_block)
|
|
149
|
-
end
|
|
150
|
-
ruby2_keywords :start if respond_to?(:ruby2_keywords, true)
|
|
151
|
-
|
|
152
|
-
alias fork start
|
|
153
|
-
end
|
|
154
|
-
end
|
|
155
|
-
end
|
|
156
|
-
end
|