ddtrace 1.0.0 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +4 -16
- data/CHANGELOG.md +31 -2
- data/LICENSE-3rdparty.csv +3 -2
- data/README.md +2 -2
- data/ddtrace.gemspec +12 -3
- data/docs/GettingStarted.md +19 -2
- data/docs/ProfilingDevelopment.md +8 -8
- data/docs/UpgradeGuide.md +3 -3
- data/ext/ddtrace_profiling_loader/ddtrace_profiling_loader.c +118 -0
- data/ext/ddtrace_profiling_loader/extconf.rb +53 -0
- data/ext/ddtrace_profiling_native_extension/NativeExtensionDesign.md +31 -5
- data/ext/ddtrace_profiling_native_extension/clock_id_from_pthread.c +0 -8
- data/ext/ddtrace_profiling_native_extension/collectors_stack.c +278 -0
- data/ext/ddtrace_profiling_native_extension/extconf.rb +70 -100
- data/ext/ddtrace_profiling_native_extension/libddprof_helpers.h +13 -0
- data/ext/ddtrace_profiling_native_extension/native_extension_helpers.rb +186 -0
- data/ext/ddtrace_profiling_native_extension/private_vm_api_access.c +579 -7
- data/ext/ddtrace_profiling_native_extension/private_vm_api_access.h +30 -0
- data/ext/ddtrace_profiling_native_extension/profiling.c +7 -0
- data/ext/ddtrace_profiling_native_extension/stack_recorder.c +139 -0
- data/ext/ddtrace_profiling_native_extension/stack_recorder.h +28 -0
- data/lib/datadog/appsec/autoload.rb +2 -2
- data/lib/datadog/appsec/configuration/settings.rb +19 -0
- data/lib/datadog/appsec/configuration.rb +8 -0
- data/lib/datadog/appsec/contrib/rack/gateway/watcher.rb +76 -33
- data/lib/datadog/appsec/contrib/rack/integration.rb +1 -0
- data/lib/datadog/appsec/contrib/rack/patcher.rb +0 -1
- data/lib/datadog/appsec/contrib/rack/reactive/request_body.rb +64 -0
- data/lib/datadog/appsec/contrib/rack/request.rb +6 -0
- data/lib/datadog/appsec/contrib/rack/request_body_middleware.rb +41 -0
- data/lib/datadog/appsec/contrib/rack/request_middleware.rb +60 -5
- data/lib/datadog/appsec/contrib/rails/gateway/watcher.rb +81 -0
- data/lib/datadog/appsec/contrib/rails/patcher.rb +34 -1
- data/lib/datadog/appsec/contrib/rails/reactive/action.rb +68 -0
- data/lib/datadog/appsec/contrib/rails/request.rb +33 -0
- data/lib/datadog/appsec/contrib/sinatra/gateway/watcher.rb +124 -0
- data/lib/datadog/appsec/contrib/sinatra/patcher.rb +69 -2
- data/lib/datadog/appsec/contrib/sinatra/reactive/routed.rb +63 -0
- data/lib/datadog/appsec/event.rb +33 -18
- data/lib/datadog/appsec/extensions.rb +0 -3
- data/lib/datadog/appsec/processor.rb +45 -2
- data/lib/datadog/appsec/rate_limiter.rb +5 -0
- data/lib/datadog/appsec/reactive/operation.rb +0 -1
- data/lib/datadog/ci/ext/environment.rb +21 -7
- data/lib/datadog/core/configuration/agent_settings_resolver.rb +1 -1
- data/lib/datadog/core/configuration/components.rb +22 -4
- data/lib/datadog/core/configuration/settings.rb +3 -3
- data/lib/datadog/core/configuration.rb +7 -5
- data/lib/datadog/core/environment/cgroup.rb +3 -1
- data/lib/datadog/core/environment/container.rb +2 -1
- data/lib/datadog/core/environment/variable_helpers.rb +26 -2
- data/lib/datadog/core/logging/ext.rb +11 -0
- data/lib/datadog/core/metrics/client.rb +15 -5
- data/lib/datadog/core/runtime/metrics.rb +1 -1
- data/lib/datadog/core/workers/async.rb +3 -1
- data/lib/datadog/core/workers/runtime_metrics.rb +0 -3
- data/lib/datadog/core.rb +6 -0
- data/lib/datadog/kit/enable_core_dumps.rb +50 -0
- data/lib/datadog/kit/identity.rb +63 -0
- data/lib/datadog/kit.rb +11 -0
- data/lib/datadog/opentracer/tracer.rb +0 -2
- data/lib/datadog/profiling/collectors/old_stack.rb +298 -0
- data/lib/datadog/profiling/collectors/stack.rb +6 -287
- data/lib/datadog/profiling/encoding/profile.rb +0 -1
- data/lib/datadog/profiling/ext.rb +1 -1
- data/lib/datadog/profiling/flush.rb +1 -1
- data/lib/datadog/profiling/load_native_extension.rb +22 -0
- data/lib/datadog/profiling/recorder.rb +1 -1
- data/lib/datadog/profiling/scheduler.rb +1 -1
- data/lib/datadog/profiling/stack_recorder.rb +33 -0
- data/lib/datadog/profiling/tag_builder.rb +48 -0
- data/lib/datadog/profiling/tasks/exec.rb +2 -2
- data/lib/datadog/profiling/tasks/setup.rb +6 -4
- data/lib/datadog/profiling.rb +29 -27
- data/lib/datadog/tracing/buffer.rb +9 -3
- data/lib/datadog/tracing/contrib/action_view/patcher.rb +0 -1
- data/lib/datadog/tracing/contrib/active_record/configuration/resolver.rb +2 -2
- data/lib/datadog/tracing/contrib/active_record/utils.rb +1 -1
- data/lib/datadog/tracing/contrib/active_record/vendor/connection_specification.rb +1 -1
- data/lib/datadog/tracing/contrib/active_support/notifications/subscription.rb +4 -2
- data/lib/datadog/tracing/contrib/concurrent_ruby/context_composite_executor_service.rb +10 -3
- data/lib/datadog/tracing/contrib/dalli/patcher.rb +0 -1
- data/lib/datadog/tracing/contrib/delayed_job/patcher.rb +0 -1
- data/lib/datadog/tracing/contrib/elasticsearch/integration.rb +9 -3
- data/lib/datadog/tracing/contrib/elasticsearch/patcher.rb +38 -2
- data/lib/datadog/tracing/contrib/ethon/patcher.rb +0 -1
- data/lib/datadog/tracing/contrib/extensions.rb +0 -2
- data/lib/datadog/tracing/contrib/faraday/patcher.rb +0 -1
- data/lib/datadog/tracing/contrib/grape/patcher.rb +0 -1
- data/lib/datadog/tracing/contrib/graphql/patcher.rb +0 -1
- data/lib/datadog/tracing/contrib/grpc/patcher.rb +0 -1
- data/lib/datadog/tracing/contrib/kafka/patcher.rb +0 -1
- data/lib/datadog/tracing/contrib/lograge/instrumentation.rb +2 -1
- data/lib/datadog/tracing/contrib/qless/patcher.rb +0 -1
- data/lib/datadog/tracing/contrib/que/patcher.rb +0 -1
- data/lib/datadog/tracing/contrib/racecar/patcher.rb +0 -1
- data/lib/datadog/tracing/contrib/rails/log_injection.rb +3 -16
- data/lib/datadog/tracing/contrib/rake/instrumentation.rb +2 -2
- data/lib/datadog/tracing/contrib/rake/patcher.rb +0 -1
- data/lib/datadog/tracing/contrib/redis/patcher.rb +0 -1
- data/lib/datadog/tracing/contrib/resque/patcher.rb +0 -1
- data/lib/datadog/tracing/contrib/rest_client/patcher.rb +0 -1
- data/lib/datadog/tracing/contrib/semantic_logger/instrumentation.rb +2 -1
- data/lib/datadog/tracing/contrib/sidekiq/configuration/settings.rb +1 -0
- data/lib/datadog/tracing/contrib/sidekiq/server_tracer.rb +20 -1
- data/lib/datadog/tracing/contrib/sinatra/framework.rb +11 -0
- data/lib/datadog/tracing/contrib/sinatra/patcher.rb +0 -1
- data/lib/datadog/tracing/contrib/sneakers/patcher.rb +0 -1
- data/lib/datadog/tracing/contrib/sucker_punch/patcher.rb +0 -1
- data/lib/datadog/tracing/event.rb +2 -1
- data/lib/datadog/tracing/sampling/priority_sampler.rb +4 -5
- data/lib/datadog/tracing/sampling/rule.rb +12 -6
- data/lib/datadog/tracing/sampling/rule_sampler.rb +3 -5
- data/lib/datadog/tracing/span_operation.rb +2 -3
- data/lib/datadog/tracing/trace_operation.rb +0 -1
- data/lib/ddtrace/transport/http/client.rb +2 -1
- data/lib/ddtrace/transport/http/response.rb +34 -4
- data/lib/ddtrace/transport/io/client.rb +3 -1
- data/lib/ddtrace/version.rb +1 -1
- data/lib/ddtrace.rb +1 -0
- metadata +43 -6
@@ -0,0 +1,33 @@
|
|
1
|
+
# typed: false
|
2
|
+
|
3
|
+
module Datadog
|
4
|
+
module Profiling
|
5
|
+
# Used to wrap a ddprof_ffi_Profile in a Ruby object and expose Ruby-level serialization APIs
|
6
|
+
# Methods prefixed with _native_ are implemented in `stack_recorder.c`
|
7
|
+
class StackRecorder
|
8
|
+
def serialize
|
9
|
+
status, result = self.class._native_serialize(self)
|
10
|
+
|
11
|
+
if status == :ok
|
12
|
+
start, finish, encoded_pprof = result
|
13
|
+
|
14
|
+
Datadog.logger.debug { "Encoded profile covering #{start.iso8601} to #{finish.iso8601}" }
|
15
|
+
|
16
|
+
[start, finish, encoded_pprof]
|
17
|
+
else
|
18
|
+
error_message = result
|
19
|
+
|
20
|
+
Datadog.logger.error("Failed to serialize profiling data: #{error_message}")
|
21
|
+
|
22
|
+
nil
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
# Used only for Ruby 2.2 and below which don't have the native `rb_time_timespec_new` API
|
27
|
+
# Called from native code
|
28
|
+
def self.ruby_time_from(timespec_seconds, timespec_nanoseconds)
|
29
|
+
Time.at(0).utc + timespec_seconds + (timespec_nanoseconds.to_r / 1_000_000_000)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# typed: true
|
2
|
+
|
3
|
+
module Datadog
|
4
|
+
module Profiling
|
5
|
+
# Builds a hash of default plus user tags to be included in a profile
|
6
|
+
module TagBuilder
|
7
|
+
include Datadog::Profiling::Ext::Transport::HTTP # Tag name constants
|
8
|
+
|
9
|
+
def self.call(
|
10
|
+
settings:,
|
11
|
+
# Unified service tagging
|
12
|
+
env: settings.env,
|
13
|
+
service: settings.service,
|
14
|
+
version: settings.version,
|
15
|
+
# Other metadata
|
16
|
+
host: Core::Environment::Socket.hostname,
|
17
|
+
language: Core::Environment::Identity.lang,
|
18
|
+
pid: Process.pid.to_s,
|
19
|
+
profiler_version: Core::Environment::Identity.tracer_version,
|
20
|
+
runtime_engine: Core::Environment::Identity.lang_engine,
|
21
|
+
runtime_id: Core::Environment::Identity.id,
|
22
|
+
runtime_platform: Core::Environment::Identity.lang_platform,
|
23
|
+
runtime_version: Core::Environment::Identity.lang_version,
|
24
|
+
# User-provided tags
|
25
|
+
user_tags: settings.tags
|
26
|
+
)
|
27
|
+
tags = {
|
28
|
+
# When changing or adding these, make sure they are kept in sync with
|
29
|
+
# https://docs.google.com/spreadsheets/d/1LOGMf4c4Avbtn36uZ2SWvhIGKRPLM1BoWkUP4JYj7hA/ (Datadog internal link)
|
30
|
+
FORM_FIELD_TAG_HOST => host,
|
31
|
+
FORM_FIELD_TAG_LANGUAGE => language,
|
32
|
+
FORM_FIELD_TAG_PID => pid,
|
33
|
+
FORM_FIELD_TAG_PROFILER_VERSION => profiler_version,
|
34
|
+
FORM_FIELD_TAG_RUNTIME => language, # This is known to be repeated from language, above
|
35
|
+
FORM_FIELD_TAG_RUNTIME_ENGINE => runtime_engine,
|
36
|
+
FORM_FIELD_TAG_RUNTIME_ID => runtime_id,
|
37
|
+
FORM_FIELD_TAG_RUNTIME_PLATFORM => runtime_platform,
|
38
|
+
FORM_FIELD_TAG_RUNTIME_VERSION => runtime_version,
|
39
|
+
}
|
40
|
+
tags[FORM_FIELD_TAG_ENV] = env if env
|
41
|
+
tags[FORM_FIELD_TAG_SERVICE] = service if service
|
42
|
+
tags[FORM_FIELD_TAG_VERSION] = version if version
|
43
|
+
|
44
|
+
user_tags.merge(tags)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -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 "ddtracerb exec failed: #{e.message} (command was '#{args.join(' ')}')"
|
41
|
+
Kernel.warn "ddtracerb 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 "ddtracerb exec failed: #{e.message} (command was '#{args.join(' ')}')"
|
44
|
+
Kernel.warn "ddtracerb exec failed: #{e.class.name} #{e.message} (command was '#{args.join(' ')}')"
|
45
45
|
Kernel.exit 126
|
46
46
|
end
|
47
47
|
end
|
@@ -1,7 +1,6 @@
|
|
1
1
|
# typed: false
|
2
2
|
|
3
3
|
require 'datadog/core/utils/only_once'
|
4
|
-
require 'datadog/profiling'
|
5
4
|
require 'datadog/profiling/ext/forking'
|
6
5
|
|
7
6
|
module Datadog
|
@@ -19,7 +18,8 @@ module Datadog
|
|
19
18
|
setup_at_fork_hooks
|
20
19
|
rescue StandardError, ScriptError => e
|
21
20
|
Datadog.logger.warn do
|
22
|
-
"Profiler extensions unavailable. Cause: #{e.
|
21
|
+
"Profiler extensions unavailable. Cause: #{e.class.name} #{e.message} " \
|
22
|
+
"Location: #{Array(e.backtrace).first}"
|
23
23
|
end
|
24
24
|
end
|
25
25
|
end
|
@@ -35,7 +35,8 @@ module Datadog
|
|
35
35
|
end
|
36
36
|
rescue StandardError, ScriptError => e
|
37
37
|
Datadog.logger.warn do
|
38
|
-
"Profiler forking extensions unavailable. Cause: #{e.
|
38
|
+
"Profiler forking extensions unavailable. Cause: #{e.class.name} #{e.message} " \
|
39
|
+
"Location: #{Array(e.backtrace).first}"
|
39
40
|
end
|
40
41
|
end
|
41
42
|
|
@@ -65,7 +66,8 @@ module Datadog
|
|
65
66
|
Profiling.start_if_enabled
|
66
67
|
rescue StandardError => e
|
67
68
|
Datadog.logger.warn do
|
68
|
-
"Error during post-fork hooks. Cause: #{e.
|
69
|
+
"Error during post-fork hooks. Cause: #{e.class.name} #{e.message} " \
|
70
|
+
"Location: #{Array(e.backtrace).first}"
|
69
71
|
end
|
70
72
|
end
|
71
73
|
end
|
data/lib/datadog/profiling.rb
CHANGED
@@ -10,9 +10,6 @@ module Datadog
|
|
10
10
|
GOOGLE_PROTOBUF_MINIMUM_VERSION = Gem::Version.new('3.0')
|
11
11
|
private_constant :GOOGLE_PROTOBUF_MINIMUM_VERSION
|
12
12
|
|
13
|
-
SKIPPED_NATIVE_EXTENSION_ONLY_ONCE = Core::Utils::OnlyOnce.new
|
14
|
-
private_constant :SKIPPED_NATIVE_EXTENSION_ONLY_ONCE
|
15
|
-
|
16
13
|
def self.supported?
|
17
14
|
unsupported_reason.nil?
|
18
15
|
end
|
@@ -21,7 +18,7 @@ module Datadog
|
|
21
18
|
# NOTE: Only the first matching reason is returned, so try to keep a nice order on reasons -- e.g. tell users
|
22
19
|
# first that they can't use this on JRuby before telling them that they are missing protobuf
|
23
20
|
|
24
|
-
|
21
|
+
native_library_compilation_skipped? ||
|
25
22
|
native_library_failed_to_load? ||
|
26
23
|
protobuf_gem_unavailable? ||
|
27
24
|
protobuf_version_unsupported? ||
|
@@ -44,8 +41,24 @@ module Datadog
|
|
44
41
|
!!profiler
|
45
42
|
end
|
46
43
|
|
47
|
-
private_class_method def self.
|
48
|
-
|
44
|
+
private_class_method def self.native_library_compilation_skipped?
|
45
|
+
skipped_reason = try_reading_skipped_reason_file
|
46
|
+
|
47
|
+
"Your ddtrace installation is missing support for the Continuous Profiler because #{skipped_reason}" if skipped_reason
|
48
|
+
end
|
49
|
+
|
50
|
+
private_class_method def self.try_reading_skipped_reason_file(file_api = File)
|
51
|
+
# This file, if it exists, is recorded by extconf.rb during compilation of the native extension
|
52
|
+
skipped_reason_file = "#{__dir__}/../../ext/ddtrace_profiling_native_extension/skipped_reason.txt"
|
53
|
+
|
54
|
+
begin
|
55
|
+
return unless file_api.exist?(skipped_reason_file)
|
56
|
+
|
57
|
+
contents = file_api.read(skipped_reason_file).strip
|
58
|
+
contents unless contents.empty?
|
59
|
+
rescue StandardError
|
60
|
+
# Do nothing
|
61
|
+
end
|
49
62
|
end
|
50
63
|
|
51
64
|
private_class_method def self.protobuf_gem_unavailable?
|
@@ -93,12 +106,11 @@ module Datadog
|
|
93
106
|
# In the future it'd be nice to shuffle the logger startup to happen first to avoid this special case.
|
94
107
|
Kernel.warn(
|
95
108
|
'[DDTRACE] Error while loading google-protobuf gem. ' \
|
96
|
-
"Cause: '#{e.message}' Location: '#{Array(e.backtrace).first}'. " \
|
109
|
+
"Cause: '#{e.class.name} #{e.message}' Location: '#{Array(e.backtrace).first}'. " \
|
97
110
|
'This can happen when google-protobuf is missing its native components. ' \
|
98
111
|
'To fix this, try removing and reinstalling the gem, forcing it to recompile the components: ' \
|
99
112
|
'`gem uninstall google-protobuf -a; BUNDLE_FORCE_RUBY_PLATFORM=true bundle install`. ' \
|
100
|
-
'If the error persists, please contact support
|
101
|
-
'file a bug at <https://github.com/DataDog/dd-trace-rb/blob/master/CONTRIBUTING.md#found-a-bug>.'
|
113
|
+
'If the error persists, please contact Datadog support at <https://docs.datadoghq.com/help/>.'
|
102
114
|
)
|
103
115
|
@protobuf_loaded = false
|
104
116
|
end
|
@@ -110,31 +122,18 @@ module Datadog
|
|
110
122
|
unless success
|
111
123
|
if exception
|
112
124
|
'There was an error loading the profiling native extension due to ' \
|
113
|
-
"'#{exception.message}' at '#{exception.backtrace.first}'"
|
125
|
+
"'#{exception.class.name} #{exception.message}' at '#{exception.backtrace.first}'"
|
114
126
|
else
|
115
127
|
'The profiling native extension did not load correctly. ' \
|
116
|
-
'
|
117
|
-
'file a bug at <https://github.com/DataDog/dd-trace-rb/blob/master/CONTRIBUTING.md#found-a-bug>.'
|
128
|
+
'For help solving this issue, please contact Datadog support at <https://docs.datadoghq.com/help/>.' \
|
118
129
|
end
|
119
130
|
end
|
120
131
|
end
|
121
132
|
|
122
133
|
private_class_method def self.try_loading_native_library
|
123
|
-
if Core::Environment::VariableHelpers.env_to_bool('DD_PROFILING_NO_EXTENSION', false)
|
124
|
-
SKIPPED_NATIVE_EXTENSION_ONLY_ONCE.run do
|
125
|
-
Kernel.warn(
|
126
|
-
'[DDTRACE] Skipped loading of profiling native extension due to DD_PROFILING_NO_EXTENSION environment ' \
|
127
|
-
'variable being set. ' \
|
128
|
-
'This option is experimental and will lead to the profiler not working in future releases. ' \
|
129
|
-
'If you needed to use this, please tell us why on <https://github.com/DataDog/dd-trace-rb/issues/new>.'
|
130
|
-
)
|
131
|
-
end
|
132
|
-
|
133
|
-
return [true, nil]
|
134
|
-
end
|
135
|
-
|
136
134
|
begin
|
137
|
-
require
|
135
|
+
require 'datadog/profiling/load_native_extension'
|
136
|
+
|
138
137
|
success =
|
139
138
|
defined?(Profiling::NativeExtension) && Profiling::NativeExtension.send(:native_working?)
|
140
139
|
[success, nil]
|
@@ -148,7 +147,9 @@ module Datadog
|
|
148
147
|
|
149
148
|
require 'datadog/profiling/ext/forking'
|
150
149
|
require 'datadog/profiling/collectors/code_provenance'
|
150
|
+
require 'datadog/profiling/collectors/old_stack'
|
151
151
|
require 'datadog/profiling/collectors/stack'
|
152
|
+
require 'datadog/profiling/stack_recorder'
|
152
153
|
require 'datadog/profiling/exporter'
|
153
154
|
require 'datadog/profiling/recorder'
|
154
155
|
require 'datadog/profiling/scheduler'
|
@@ -159,10 +160,11 @@ module Datadog
|
|
159
160
|
require 'datadog/profiling/native_extension'
|
160
161
|
require 'datadog/profiling/trace_identifiers/helper'
|
161
162
|
require 'datadog/profiling/pprof/pprof_pb'
|
163
|
+
require 'datadog/profiling/tag_builder'
|
162
164
|
|
163
165
|
true
|
164
166
|
end
|
165
167
|
|
166
|
-
load_profiling
|
168
|
+
load_profiling
|
167
169
|
end
|
168
170
|
end
|
@@ -58,7 +58,9 @@ module Datadog
|
|
58
58
|
|
59
59
|
@buffer_spans += trace.length
|
60
60
|
rescue StandardError => e
|
61
|
-
Datadog.logger.debug(
|
61
|
+
Datadog.logger.debug(
|
62
|
+
"Failed to measure queue accept. Cause: #{e.class.name} #{e.message} Source: #{Array(e.backtrace).first}"
|
63
|
+
)
|
62
64
|
end
|
63
65
|
|
64
66
|
def measure_drop(trace)
|
@@ -66,7 +68,9 @@ module Datadog
|
|
66
68
|
|
67
69
|
@buffer_spans -= trace.length
|
68
70
|
rescue StandardError => e
|
69
|
-
Datadog.logger.debug(
|
71
|
+
Datadog.logger.debug(
|
72
|
+
"Failed to measure queue drop. Cause: #{e.class.name} #{e.message} Source: #{Array(e.backtrace).first}"
|
73
|
+
)
|
70
74
|
end
|
71
75
|
|
72
76
|
def measure_pop(traces)
|
@@ -89,7 +93,9 @@ module Datadog
|
|
89
93
|
@buffer_dropped = 0
|
90
94
|
@buffer_spans = 0
|
91
95
|
rescue StandardError => e
|
92
|
-
Datadog.logger.debug(
|
96
|
+
Datadog.logger.debug(
|
97
|
+
"Failed to measure queue. Cause: #{e.class.name} #{e.message} Source: #{Array(e.backtrace).first}"
|
98
|
+
)
|
93
99
|
end
|
94
100
|
end
|
95
101
|
|
@@ -4,7 +4,6 @@ require 'datadog/core'
|
|
4
4
|
require 'datadog/tracing/contrib/patcher'
|
5
5
|
require 'datadog/tracing/contrib/action_view/events'
|
6
6
|
require 'datadog/tracing/contrib/action_view/ext'
|
7
|
-
require 'datadog/tracing/contrib/action_view/integration'
|
8
7
|
require 'datadog/tracing/contrib/action_view/instrumentation/partial_renderer'
|
9
8
|
require 'datadog/tracing/contrib/action_view/instrumentation/template_renderer'
|
10
9
|
require 'datadog/tracing/contrib/action_view/utils'
|
@@ -69,7 +69,7 @@ module Datadog
|
|
69
69
|
rescue => e
|
70
70
|
Datadog.logger.error(
|
71
71
|
"Failed to resolve ActiveRecord configuration key #{db_config.inspect}. " \
|
72
|
-
"Cause: #{e.message} Source: #{Array(e.backtrace).first}"
|
72
|
+
"Cause: #{e.class.name} #{e.message} Source: #{Array(e.backtrace).first}"
|
73
73
|
)
|
74
74
|
|
75
75
|
nil
|
@@ -88,7 +88,7 @@ module Datadog
|
|
88
88
|
rescue => e
|
89
89
|
Datadog.logger.error(
|
90
90
|
"Failed to resolve ActiveRecord configuration key #{matcher.inspect}. " \
|
91
|
-
"Cause: #{e.message} Source: #{Array(e.backtrace).first}"
|
91
|
+
"Cause: #{e.class.name} #{e.message} Source: #{Array(e.backtrace).first}"
|
92
92
|
)
|
93
93
|
end
|
94
94
|
|
@@ -77,7 +77,7 @@ module Datadog
|
|
77
77
|
# in case.
|
78
78
|
Datadog.logger.debug(
|
79
79
|
"connection_id #{connection_id} does not represent a valid object. " \
|
80
|
-
"Cause: #{e.message} Source: #{Array(e.backtrace).first}"
|
80
|
+
"Cause: #{e.class.name} #{e.message} Source: #{Array(e.backtrace).first}"
|
81
81
|
)
|
82
82
|
end
|
83
83
|
else
|
@@ -216,7 +216,7 @@ module Datadog
|
|
216
216
|
# Bubbled up from the adapter require. Prefix the exception message
|
217
217
|
# with some guidance about how to address it and reraise.
|
218
218
|
else
|
219
|
-
raise e.class, "Error loading the '#{spec[:adapter]}' Active Record adapter. Missing a gem it depends on? #{e.message}", e.backtrace
|
219
|
+
raise e.class, "Error loading the '#{spec[:adapter]}' Active Record adapter. Missing a gem it depends on? #{e.class.name} #{e.message}", e.backtrace
|
220
220
|
end
|
221
221
|
end
|
222
222
|
|
@@ -116,7 +116,9 @@ module Datadog
|
|
116
116
|
def run(span, name, id, payload)
|
117
117
|
run!(span, name, id, payload)
|
118
118
|
rescue StandardError => e
|
119
|
-
Datadog.logger.debug(
|
119
|
+
Datadog.logger.debug(
|
120
|
+
"ActiveSupport::Notifications handler for '#{name}' failed: #{e.class.name} #{e.message}"
|
121
|
+
)
|
120
122
|
end
|
121
123
|
|
122
124
|
def run!(*args)
|
@@ -142,7 +144,7 @@ module Datadog
|
|
142
144
|
callback.call(event, key, *args)
|
143
145
|
rescue StandardError => e
|
144
146
|
Datadog.logger.debug(
|
145
|
-
"ActiveSupport::Notifications '#{key}' callback for '#{event}' failed: #{e.message}"
|
147
|
+
"ActiveSupport::Notifications '#{key}' callback for '#{event}' failed: #{e.class.name} #{e.message}"
|
146
148
|
)
|
147
149
|
end
|
148
150
|
end
|
@@ -8,7 +8,6 @@ module Datadog
|
|
8
8
|
module ConcurrentRuby
|
9
9
|
# wraps existing executor to carry over trace context
|
10
10
|
class ContextCompositeExecutorService
|
11
|
-
extend Forwardable
|
12
11
|
include Concurrent::ExecutorService
|
13
12
|
|
14
13
|
attr_accessor :composited_executor
|
@@ -34,11 +33,19 @@ module Datadog
|
|
34
33
|
end
|
35
34
|
end
|
36
35
|
|
36
|
+
# Respect the {Concurrent::ExecutorService} interface
|
37
|
+
def can_overflow?
|
38
|
+
@composited_executor.can_overflow?
|
39
|
+
end
|
40
|
+
|
41
|
+
# Respect the {Concurrent::ExecutorService} interface
|
42
|
+
def serialized?
|
43
|
+
@composited_executor.serialized?
|
44
|
+
end
|
45
|
+
|
37
46
|
def datadog_configuration
|
38
47
|
Datadog.configuration.tracing[:concurrent_ruby]
|
39
48
|
end
|
40
|
-
|
41
|
-
delegate [:can_overflow?, :serialized?] => :composited_executor
|
42
49
|
end
|
43
50
|
end
|
44
51
|
end
|
@@ -18,12 +18,18 @@ module Datadog
|
|
18
18
|
register_as :elasticsearch, auto_patch: true
|
19
19
|
|
20
20
|
def self.version
|
21
|
-
|
22
|
-
|
21
|
+
# elastic-transport gem for version >= 8.0.0
|
22
|
+
# elasticsearch-transport gem for version < 8.0.0
|
23
|
+
Gem.loaded_specs['elastic-transport'] \
|
24
|
+
&& Gem.loaded_specs['elastic-transport'].version || \
|
25
|
+
Gem.loaded_specs['elasticsearch-transport'] \
|
26
|
+
&& Gem.loaded_specs['elasticsearch-transport'].version
|
23
27
|
end
|
24
28
|
|
25
29
|
def self.loaded?
|
26
|
-
|
30
|
+
# Elastic::Transport gem for version >= 8.0.0
|
31
|
+
# Elasticsearch::Transport gem for version < 8.0.0
|
32
|
+
!defined?(::Elastic::Transport).nil? || !defined?(::Elasticsearch::Transport).nil?
|
27
33
|
end
|
28
34
|
|
29
35
|
def self.compatible?
|
@@ -29,16 +29,40 @@ module Datadog
|
|
29
29
|
patch_elasticsearch_transport_client
|
30
30
|
end
|
31
31
|
|
32
|
+
SELF_DEPRECATION_ONLY_ONCE = Core::Utils::OnlyOnce.new
|
33
|
+
|
32
34
|
# rubocop:disable Metrics/MethodLength
|
33
35
|
# rubocop:disable Metrics/AbcSize
|
36
|
+
# rubocop:disable Metrics/CyclomaticComplexity
|
37
|
+
# rubocop:disable Metrics/PerceivedComplexity
|
34
38
|
def patch_elasticsearch_transport_client
|
35
39
|
# rubocop:disable Metrics/BlockLength
|
36
|
-
::
|
40
|
+
transport_module::Client.class_eval do
|
37
41
|
alias_method :perform_request_without_datadog, :perform_request
|
38
42
|
remove_method :perform_request
|
39
43
|
|
40
44
|
def perform_request(*args)
|
41
|
-
|
45
|
+
# DEV-2.0: Remove this access, as `Client#self` in this context is not exposed to the user
|
46
|
+
# since `elasticsearch` v8.0.0. In contrast, `Client#transport` is always available across
|
47
|
+
# all `elasticsearch` gem versions and should be used instead.
|
48
|
+
service = Datadog.configuration_for(self, :service_name)
|
49
|
+
|
50
|
+
if service
|
51
|
+
SELF_DEPRECATION_ONLY_ONCE.run do
|
52
|
+
Datadog.logger.warn(
|
53
|
+
'Providing configuration though the Elasticsearch client object is deprecated.' \
|
54
|
+
'Configure the `client#transport` object instead: ' \
|
55
|
+
'Datadog.configure_onto(client.transport, service_name: service_name, ...)'
|
56
|
+
)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
# `Client#transport` is most convenient object both this integration and the library
|
61
|
+
# user have shared access to across all `elasticsearch` versions.
|
62
|
+
#
|
63
|
+
# `Client#self` in this context is an internal object that the library user
|
64
|
+
# does not have access to since `elasticsearch` v8.0.0.
|
65
|
+
service ||= Datadog.configuration_for(transport, :service_name) || datadog_configuration[:service_name]
|
42
66
|
|
43
67
|
method = args[0]
|
44
68
|
path = args[1]
|
@@ -108,6 +132,18 @@ module Datadog
|
|
108
132
|
end
|
109
133
|
# rubocop:enable Metrics/MethodLength
|
110
134
|
# rubocop:enable Metrics/AbcSize
|
135
|
+
# rubocop:enable Metrics/CyclomaticComplexity
|
136
|
+
# rubocop:enable Metrics/PerceivedComplexity
|
137
|
+
|
138
|
+
# `Elasticsearch` namespace renamed to `Elastic` in version 8.0.0 of the transport gem:
|
139
|
+
# @see https://github.com/elastic/elastic-transport-ruby/commit/ef804cbbd284f2a82d825221f87124f8b5ff823c
|
140
|
+
def transport_module
|
141
|
+
if Integration.version >= Gem::Version.new('8.0.0')
|
142
|
+
::Elastic::Transport
|
143
|
+
else
|
144
|
+
::Elasticsearch::Transport
|
145
|
+
end
|
146
|
+
end
|
111
147
|
end
|
112
148
|
end
|
113
149
|
end
|
@@ -3,7 +3,6 @@
|
|
3
3
|
require 'datadog/tracing/contrib/grape/endpoint'
|
4
4
|
require 'datadog/tracing/contrib/grape/ext'
|
5
5
|
require 'datadog/tracing/contrib/grape/instrumentation'
|
6
|
-
require 'datadog/tracing/contrib/grape/integration'
|
7
6
|
require 'datadog/tracing/contrib/patcher'
|
8
7
|
|
9
8
|
module Datadog
|
@@ -1,6 +1,7 @@
|
|
1
1
|
# typed: true
|
2
2
|
|
3
3
|
require 'datadog/tracing'
|
4
|
+
require 'datadog/core/logging/ext'
|
4
5
|
|
5
6
|
module Datadog
|
6
7
|
module Tracing
|
@@ -33,7 +34,7 @@ module Datadog
|
|
33
34
|
service: correlation.service.to_s,
|
34
35
|
version: correlation.version.to_s
|
35
36
|
},
|
36
|
-
ddsource:
|
37
|
+
ddsource: Core::Logging::Ext::DD_SOURCE
|
37
38
|
}
|
38
39
|
|
39
40
|
datadog_trace_log_hash.merge(original_custom_options)
|
@@ -22,24 +22,11 @@ module Datadog
|
|
22
22
|
end
|
23
23
|
rescue StandardError => e
|
24
24
|
# TODO: can we use Datadog.logger at this point?
|
25
|
-
Datadog.logger.warn(
|
25
|
+
Datadog.logger.warn(
|
26
|
+
"Unable to add Datadog Trace context to ActiveSupport::TaggedLogging: #{e.class.name} #{e.message}"
|
27
|
+
)
|
26
28
|
false
|
27
29
|
end
|
28
|
-
|
29
|
-
def datadog_trace_log_hash(correlation)
|
30
|
-
{
|
31
|
-
# Adds IDs as tags to log output
|
32
|
-
dd: {
|
33
|
-
# To preserve precision during JSON serialization, use strings for large numbers
|
34
|
-
trace_id: correlation.trace_id.to_s,
|
35
|
-
span_id: correlation.span_id.to_s,
|
36
|
-
env: correlation.env.to_s,
|
37
|
-
service: correlation.service.to_s,
|
38
|
-
version: correlation.version.to_s
|
39
|
-
},
|
40
|
-
ddsource: ['ruby']
|
41
|
-
}
|
42
|
-
end
|
43
30
|
end
|
44
31
|
end
|
45
32
|
end
|
@@ -61,7 +61,7 @@ module Datadog
|
|
61
61
|
span.set_tag(Ext::TAG_TASK_ARG_NAMES, arg_names)
|
62
62
|
span.set_tag(Ext::TAG_INVOKE_ARGS, quantize_args(args)) unless args.nil?
|
63
63
|
rescue StandardError => e
|
64
|
-
Datadog.logger.debug("Error while tracing Rake invoke: #{e.message}")
|
64
|
+
Datadog.logger.debug("Error while tracing Rake invoke: #{e.class.name} #{e.message}")
|
65
65
|
end
|
66
66
|
|
67
67
|
def annotate_execute!(span, args)
|
@@ -70,7 +70,7 @@ module Datadog
|
|
70
70
|
span.set_tag(Tracing::Metadata::Ext::TAG_OPERATION, Ext::TAG_OPERATION_EXECUTE)
|
71
71
|
span.set_tag(Ext::TAG_EXECUTE_ARGS, quantize_args(args.to_hash)) unless args.nil?
|
72
72
|
rescue StandardError => e
|
73
|
-
Datadog.logger.debug("Error while tracing Rake execute: #{e.message}")
|
73
|
+
Datadog.logger.debug("Error while tracing Rake execute: #{e.class.name} #{e.message}")
|
74
74
|
end
|
75
75
|
|
76
76
|
def quantize_args(args)
|