datadog 2.16.0 → 2.18.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 +72 -1
- data/ext/datadog_profiling_native_extension/collectors_cpu_and_wall_time_worker.c +12 -46
- data/ext/datadog_profiling_native_extension/collectors_stack.c +227 -49
- data/ext/datadog_profiling_native_extension/collectors_stack.h +19 -3
- data/ext/datadog_profiling_native_extension/collectors_thread_context.c +63 -12
- data/ext/datadog_profiling_native_extension/collectors_thread_context.h +1 -0
- data/ext/datadog_profiling_native_extension/encoded_profile.c +22 -12
- data/ext/datadog_profiling_native_extension/encoded_profile.h +1 -0
- data/ext/datadog_profiling_native_extension/extconf.rb +7 -0
- data/ext/datadog_profiling_native_extension/heap_recorder.c +239 -363
- data/ext/datadog_profiling_native_extension/heap_recorder.h +4 -6
- data/ext/datadog_profiling_native_extension/http_transport.c +45 -72
- data/ext/datadog_profiling_native_extension/libdatadog_helpers.c +22 -0
- data/ext/datadog_profiling_native_extension/libdatadog_helpers.h +8 -5
- data/ext/datadog_profiling_native_extension/private_vm_api_access.c +1 -0
- data/ext/datadog_profiling_native_extension/private_vm_api_access.h +6 -3
- data/ext/datadog_profiling_native_extension/ruby_helpers.c +1 -13
- data/ext/datadog_profiling_native_extension/ruby_helpers.h +2 -10
- data/ext/datadog_profiling_native_extension/stack_recorder.c +156 -60
- data/ext/libdatadog_api/crashtracker.c +10 -3
- data/ext/libdatadog_api/extconf.rb +2 -2
- data/ext/libdatadog_api/library_config.c +54 -12
- data/ext/libdatadog_api/library_config.h +6 -0
- data/ext/libdatadog_api/macos_development.md +3 -3
- data/ext/libdatadog_api/process_discovery.c +2 -7
- data/ext/libdatadog_extconf_helpers.rb +2 -2
- data/lib/datadog/appsec/api_security/lru_cache.rb +56 -0
- data/lib/datadog/appsec/api_security/route_extractor.rb +65 -0
- data/lib/datadog/appsec/api_security/sampler.rb +59 -0
- data/lib/datadog/appsec/api_security.rb +23 -0
- data/lib/datadog/appsec/assets/waf_rules/recommended.json +257 -85
- data/lib/datadog/appsec/assets/waf_rules/strict.json +10 -78
- data/lib/datadog/appsec/component.rb +30 -54
- data/lib/datadog/appsec/configuration/settings.rb +60 -2
- data/lib/datadog/appsec/context.rb +6 -6
- data/lib/datadog/appsec/contrib/devise/tracking_middleware.rb +1 -1
- data/lib/datadog/appsec/contrib/rack/request_middleware.rb +27 -16
- data/lib/datadog/appsec/processor/rule_loader.rb +5 -6
- data/lib/datadog/appsec/remote.rb +15 -55
- data/lib/datadog/appsec/security_engine/engine.rb +194 -0
- data/lib/datadog/appsec/security_engine/runner.rb +10 -11
- data/lib/datadog/appsec.rb +4 -7
- data/lib/datadog/core/buffer/random.rb +18 -2
- data/lib/datadog/core/configuration/agent_settings.rb +52 -0
- data/lib/datadog/core/configuration/agent_settings_resolver.rb +4 -46
- data/lib/datadog/core/configuration/components.rb +31 -24
- data/lib/datadog/core/configuration/components_state.rb +23 -0
- data/lib/datadog/core/configuration/option.rb +27 -27
- data/lib/datadog/core/configuration/option_definition.rb +4 -4
- data/lib/datadog/core/configuration/options.rb +1 -1
- data/lib/datadog/core/configuration/settings.rb +32 -20
- data/lib/datadog/core/configuration/stable_config.rb +1 -2
- data/lib/datadog/core/configuration.rb +16 -16
- data/lib/datadog/core/crashtracking/component.rb +2 -1
- data/lib/datadog/core/crashtracking/tag_builder.rb +4 -22
- data/lib/datadog/core/encoding.rb +1 -1
- data/lib/datadog/core/environment/cgroup.rb +10 -12
- data/lib/datadog/core/environment/container.rb +38 -40
- data/lib/datadog/core/environment/ext.rb +6 -6
- data/lib/datadog/core/environment/identity.rb +3 -3
- data/lib/datadog/core/environment/platform.rb +3 -3
- data/lib/datadog/core/error.rb +11 -9
- data/lib/datadog/core/logger.rb +2 -2
- data/lib/datadog/core/metrics/client.rb +12 -14
- data/lib/datadog/core/metrics/logging.rb +5 -5
- data/lib/datadog/core/process_discovery/tracer_memfd.rb +15 -0
- data/lib/datadog/core/process_discovery.rb +5 -1
- data/lib/datadog/core/rate_limiter.rb +4 -2
- data/lib/datadog/core/remote/client.rb +32 -31
- data/lib/datadog/core/remote/component.rb +3 -3
- data/lib/datadog/core/remote/configuration/digest.rb +7 -7
- data/lib/datadog/core/remote/configuration/path.rb +1 -1
- data/lib/datadog/core/remote/configuration/repository.rb +12 -0
- data/lib/datadog/core/remote/transport/http/client.rb +1 -1
- data/lib/datadog/core/remote/transport/http/config.rb +21 -5
- data/lib/datadog/core/remote/transport/http/negotiation.rb +1 -1
- data/lib/datadog/core/runtime/metrics.rb +3 -3
- data/lib/datadog/core/tag_builder.rb +56 -0
- data/lib/datadog/core/telemetry/component.rb +39 -24
- data/lib/datadog/core/telemetry/emitter.rb +7 -1
- data/lib/datadog/core/telemetry/event/app_client_configuration_change.rb +66 -0
- data/lib/datadog/core/telemetry/event/app_closing.rb +18 -0
- data/lib/datadog/core/telemetry/event/app_dependencies_loaded.rb +33 -0
- data/lib/datadog/core/telemetry/event/app_heartbeat.rb +18 -0
- data/lib/datadog/core/telemetry/event/app_integrations_change.rb +58 -0
- data/lib/datadog/core/telemetry/event/app_started.rb +269 -0
- data/lib/datadog/core/telemetry/event/base.rb +40 -0
- data/lib/datadog/core/telemetry/event/distributions.rb +18 -0
- data/lib/datadog/core/telemetry/event/generate_metrics.rb +43 -0
- data/lib/datadog/core/telemetry/event/log.rb +76 -0
- data/lib/datadog/core/telemetry/event/message_batch.rb +42 -0
- data/lib/datadog/core/telemetry/event/synth_app_client_configuration_change.rb +43 -0
- data/lib/datadog/core/telemetry/event.rb +17 -475
- data/lib/datadog/core/telemetry/logger.rb +5 -4
- data/lib/datadog/core/telemetry/logging.rb +11 -5
- data/lib/datadog/core/telemetry/metric.rb +3 -3
- data/lib/datadog/core/telemetry/transport/http/telemetry.rb +2 -2
- data/lib/datadog/core/telemetry/transport/telemetry.rb +0 -1
- data/lib/datadog/core/telemetry/worker.rb +48 -27
- data/lib/datadog/core/transport/http/adapters/net.rb +17 -2
- data/lib/datadog/core/transport/http/adapters/test.rb +2 -1
- data/lib/datadog/core/transport/http/builder.rb +14 -14
- data/lib/datadog/core/transport/http/env.rb +8 -0
- data/lib/datadog/core/utils/at_fork_monkey_patch.rb +6 -6
- data/lib/datadog/core/utils/duration.rb +32 -32
- data/lib/datadog/core/utils/forking.rb +2 -2
- data/lib/datadog/core/utils/network.rb +6 -6
- data/lib/datadog/core/utils/only_once_successful.rb +16 -5
- data/lib/datadog/core/utils/time.rb +10 -2
- data/lib/datadog/core/utils/truncation.rb +21 -0
- data/lib/datadog/core/utils.rb +7 -0
- data/lib/datadog/core/vendor/multipart-post/multipart/post/composite_read_io.rb +1 -1
- data/lib/datadog/core/vendor/multipart-post/multipart/post/multipartable.rb +8 -8
- data/lib/datadog/core/vendor/multipart-post/multipart/post/parts.rb +7 -7
- data/lib/datadog/core/worker.rb +1 -1
- data/lib/datadog/core/workers/async.rb +9 -10
- data/lib/datadog/di/instrumenter.rb +52 -2
- data/lib/datadog/di/probe_notification_builder.rb +31 -41
- data/lib/datadog/di/probe_notifier_worker.rb +9 -1
- data/lib/datadog/di/serializer.rb +6 -2
- data/lib/datadog/di/transport/http/input.rb +10 -0
- data/lib/datadog/di/transport/input.rb +10 -2
- data/lib/datadog/error_tracking/component.rb +2 -2
- data/lib/datadog/profiling/collectors/code_provenance.rb +18 -9
- data/lib/datadog/profiling/collectors/cpu_and_wall_time_worker.rb +4 -0
- data/lib/datadog/profiling/collectors/idle_sampling_helper.rb +1 -0
- data/lib/datadog/profiling/collectors/thread_context.rb +16 -1
- data/lib/datadog/profiling/component.rb +7 -9
- data/lib/datadog/profiling/ext.rb +0 -13
- data/lib/datadog/profiling/flush.rb +1 -1
- data/lib/datadog/profiling/http_transport.rb +3 -8
- data/lib/datadog/profiling/profiler.rb +2 -0
- data/lib/datadog/profiling/scheduler.rb +10 -2
- data/lib/datadog/profiling/stack_recorder.rb +5 -5
- data/lib/datadog/profiling/tag_builder.rb +5 -41
- data/lib/datadog/profiling/tasks/setup.rb +2 -0
- data/lib/datadog/tracing/contrib/action_pack/action_controller/instrumentation.rb +15 -0
- data/lib/datadog/tracing/contrib/action_pack/action_dispatch/instrumentation.rb +19 -12
- data/lib/datadog/tracing/contrib/action_pack/ext.rb +2 -0
- data/lib/datadog/tracing/contrib/active_support/cache/events/cache.rb +4 -1
- data/lib/datadog/tracing/contrib/active_support/cache/instrumentation.rb +33 -0
- data/lib/datadog/tracing/contrib/active_support/cache/patcher.rb +4 -0
- data/lib/datadog/tracing/contrib/active_support/cache/redis.rb +2 -4
- data/lib/datadog/tracing/contrib/aws/instrumentation.rb +10 -0
- data/lib/datadog/tracing/contrib/aws/parsed_context.rb +5 -1
- data/lib/datadog/tracing/contrib/http/instrumentation.rb +1 -5
- data/lib/datadog/tracing/contrib/httpclient/instrumentation.rb +1 -5
- data/lib/datadog/tracing/contrib/httprb/instrumentation.rb +1 -5
- data/lib/datadog/tracing/contrib/lograge/patcher.rb +4 -2
- data/lib/datadog/tracing/contrib/patcher.rb +5 -2
- data/lib/datadog/tracing/contrib/sidekiq/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/sidekiq/server_tracer.rb +5 -2
- data/lib/datadog/tracing/contrib/support.rb +28 -0
- data/lib/datadog/tracing/metadata/errors.rb +4 -4
- data/lib/datadog/tracing/sync_writer.rb +1 -1
- data/lib/datadog/tracing/trace_operation.rb +12 -4
- data/lib/datadog/tracing/tracer.rb +6 -2
- data/lib/datadog/version.rb +1 -1
- metadata +31 -12
- data/lib/datadog/appsec/assets/waf_rules/processors.json +0 -321
- data/lib/datadog/appsec/assets/waf_rules/scanners.json +0 -1023
- data/lib/datadog/appsec/processor/rule_merger.rb +0 -171
- data/lib/datadog/appsec/processor.rb +0 -107
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require_relative "../core/tag_builder"
|
3
4
|
require_relative "../core/utils"
|
4
|
-
require_relative "../core/environment/git"
|
5
5
|
|
6
6
|
module Datadog
|
7
7
|
module Profiling
|
@@ -11,49 +11,13 @@ module Datadog
|
|
11
11
|
|
12
12
|
def self.call(
|
13
13
|
settings:,
|
14
|
-
# Unified service tagging
|
15
|
-
env: settings.env,
|
16
|
-
service: settings.service,
|
17
|
-
version: settings.version,
|
18
14
|
# Other metadata
|
19
|
-
|
20
|
-
language: Core::Environment::Identity.lang,
|
21
|
-
pid: Process.pid.to_s,
|
22
|
-
# TODO: If profiling is extracted and its version diverges from the datadog gem, this is inaccurate.
|
23
|
-
# Update if this ever occurs.
|
24
|
-
profiler_version: Core::Environment::Identity.gem_datadog_version,
|
25
|
-
runtime_engine: Core::Environment::Identity.lang_engine,
|
26
|
-
runtime_id: Core::Environment::Identity.id,
|
27
|
-
runtime_platform: Core::Environment::Identity.lang_platform,
|
28
|
-
runtime_version: Core::Environment::Identity.lang_version,
|
29
|
-
git_repository_url: Core::Environment::Git.git_repository_url,
|
30
|
-
git_commit_sha: Core::Environment::Git.git_commit_sha,
|
31
|
-
# User-provided tags
|
32
|
-
user_tags: settings.tags
|
15
|
+
profiler_version: Core::Environment::Identity.gem_datadog_version
|
33
16
|
)
|
34
|
-
|
35
|
-
# When changing or adding these, make sure they are kept in sync with
|
36
|
-
# https://docs.google.com/spreadsheets/d/1LOGMf4c4Avbtn36uZ2SWvhIGKRPLM1BoWkUP4JYj7hA/ (Datadog internal link)
|
37
|
-
FORM_FIELD_TAG_HOST => host,
|
38
|
-
FORM_FIELD_TAG_LANGUAGE => language,
|
39
|
-
FORM_FIELD_TAG_PID => pid,
|
17
|
+
hash = Core::TagBuilder.tags(settings).merge(
|
40
18
|
FORM_FIELD_TAG_PROFILER_VERSION => profiler_version,
|
41
|
-
|
42
|
-
|
43
|
-
FORM_FIELD_TAG_RUNTIME_ID => runtime_id,
|
44
|
-
FORM_FIELD_TAG_RUNTIME_PLATFORM => runtime_platform,
|
45
|
-
FORM_FIELD_TAG_RUNTIME_VERSION => runtime_version,
|
46
|
-
}
|
47
|
-
tags[FORM_FIELD_TAG_ENV] = env if env
|
48
|
-
tags[FORM_FIELD_TAG_SERVICE] = service if service
|
49
|
-
tags[FORM_FIELD_TAG_VERSION] = version if version
|
50
|
-
tags[TAG_GIT_REPOSITORY_URL] = git_repository_url if git_repository_url
|
51
|
-
tags[TAG_GIT_COMMIT_SHA] = git_commit_sha if git_commit_sha
|
52
|
-
|
53
|
-
# Make sure everything is an utf-8 string, to avoid encoding issues in native code/libddprof/further downstream
|
54
|
-
user_tags.merge(tags).map do |key, value|
|
55
|
-
[Datadog::Core::Utils.utf8_encode(key), Datadog::Core::Utils.utf8_encode(value)]
|
56
|
-
end.to_h
|
19
|
+
)
|
20
|
+
Core::Utils.encode_tags(hash)
|
57
21
|
end
|
58
22
|
end
|
59
23
|
end
|
@@ -19,6 +19,7 @@ module Datadog
|
|
19
19
|
"Profiler extensions unavailable. Cause: #{e.class.name} #{e.message} " \
|
20
20
|
"Location: #{Array(e.backtrace).first}"
|
21
21
|
end
|
22
|
+
Datadog::Core::Telemetry::Logger.report(e, description: "Profiler extensions unavailable")
|
22
23
|
end
|
23
24
|
end
|
24
25
|
|
@@ -33,6 +34,7 @@ module Datadog
|
|
33
34
|
"Error during post-fork hooks. Cause: #{e.class.name} #{e.message} " \
|
34
35
|
"Location: #{Array(e.backtrace).first}"
|
35
36
|
end
|
37
|
+
Datadog::Core::Telemetry::Logger.report(e, description: "Error during post-fork hooks")
|
36
38
|
end
|
37
39
|
end
|
38
40
|
end
|
@@ -68,6 +68,12 @@ module Datadog
|
|
68
68
|
|
69
69
|
span.set_tag(Ext::TAG_ROUTE_ACTION, payload.fetch(:action))
|
70
70
|
span.set_tag(Ext::TAG_ROUTE_CONTROLLER, payload.fetch(:controller))
|
71
|
+
if (runtime = payload[:view_runtime])
|
72
|
+
span.set_tag(Ext::TAG_VIEW_RUNTIME, runtime)
|
73
|
+
end
|
74
|
+
if (runtime = payload[:db_runtime])
|
75
|
+
span.set_tag(Ext::TAG_DB_RUNTIME, runtime)
|
76
|
+
end
|
71
77
|
|
72
78
|
exception = payload[:exception_object]
|
73
79
|
if exception.nil?
|
@@ -118,6 +124,15 @@ module Datadog
|
|
118
124
|
payload[:exception] = [e.class.name, e.message]
|
119
125
|
payload[:exception_object] = e
|
120
126
|
raise e
|
127
|
+
ensure
|
128
|
+
# Database and view runtime are available for controllers
|
129
|
+
# deriving from ActionController::Base.
|
130
|
+
# They are not defined on controllers deriving from
|
131
|
+
# ActionController::Metal, unless
|
132
|
+
# ActionController::Instrumentation is explicitly included
|
133
|
+
# into the controller class.
|
134
|
+
payload[:db_runtime] = db_runtime if respond_to?(:db_runtime)
|
135
|
+
payload[:view_runtime] = view_runtime if respond_to?(:view_runtime)
|
121
136
|
end
|
122
137
|
# rubocop:enable Lint/RescueException
|
123
138
|
ensure
|
@@ -9,9 +9,12 @@ module Datadog
|
|
9
9
|
module ActionDispatch
|
10
10
|
# Instrumentation for ActionDispatch components
|
11
11
|
module Instrumentation
|
12
|
+
SCRIPT_NAME_KEY = 'SCRIPT_NAME'
|
13
|
+
FORMAT_SUFFIX = '(.:format)'
|
14
|
+
|
12
15
|
module_function
|
13
16
|
|
14
|
-
def set_http_route_tags(route_spec,
|
17
|
+
def set_http_route_tags(route_spec, route_path)
|
15
18
|
return unless Tracing.enabled?
|
16
19
|
|
17
20
|
return unless route_spec
|
@@ -19,10 +22,10 @@ module Datadog
|
|
19
22
|
request_trace = Tracing.active_trace
|
20
23
|
return unless request_trace
|
21
24
|
|
22
|
-
request_trace.set_tag(Tracing::Metadata::Ext::HTTP::TAG_ROUTE, route_spec
|
25
|
+
request_trace.set_tag(Tracing::Metadata::Ext::HTTP::TAG_ROUTE, route_spec)
|
23
26
|
|
24
|
-
if
|
25
|
-
request_trace.set_tag(Tracing::Metadata::Ext::HTTP::TAG_ROUTE_PATH,
|
27
|
+
if route_path && !route_path.empty?
|
28
|
+
request_trace.set_tag(Tracing::Metadata::Ext::HTTP::TAG_ROUTE_PATH, route_path)
|
26
29
|
end
|
27
30
|
end
|
28
31
|
|
@@ -40,16 +43,17 @@ module Datadog
|
|
40
43
|
# Instrumentation for ActionDispatch::Journey::Router for Rails versions older than 7.1
|
41
44
|
module Router
|
42
45
|
def find_routes(req)
|
46
|
+
# result is an array of [match, parameters, route] tuples
|
43
47
|
result = super
|
48
|
+
result.each do |_, _, route|
|
49
|
+
next unless Instrumentation.dispatcher_route?(route)
|
44
50
|
|
45
|
-
|
46
|
-
|
51
|
+
http_route = route.path.spec.to_s
|
52
|
+
http_route.delete_suffix!(FORMAT_SUFFIX)
|
47
53
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
break
|
52
|
-
end
|
54
|
+
Instrumentation.set_http_route_tags(http_route, req.env[SCRIPT_NAME_KEY])
|
55
|
+
|
56
|
+
break
|
53
57
|
end
|
54
58
|
|
55
59
|
result
|
@@ -62,7 +66,10 @@ module Datadog
|
|
62
66
|
def find_routes(req)
|
63
67
|
super do |match, parameters, route|
|
64
68
|
if Instrumentation.dispatcher_route?(route)
|
65
|
-
|
69
|
+
http_route = route.path.spec.to_s
|
70
|
+
http_route.delete_suffix!(FORMAT_SUFFIX)
|
71
|
+
|
72
|
+
Instrumentation.set_http_route_tags(http_route, req.env[SCRIPT_NAME_KEY])
|
66
73
|
end
|
67
74
|
|
68
75
|
yield [match, parameters, route]
|
@@ -62,7 +62,10 @@ module Datadog
|
|
62
62
|
end
|
63
63
|
|
64
64
|
def on_start(span, event, _id, payload)
|
65
|
-
key
|
65
|
+
# Since Rails 8, `dd_original_keys` contains the denormalized key provided by the user.
|
66
|
+
# In previous versions, the denormalized key is stored in the official `key` attribute.
|
67
|
+
# We fall back to `key`, even in Rails 8, as a defensive measure.
|
68
|
+
key = payload[:dd_original_keys] || payload[:key]
|
66
69
|
store = payload[:store]
|
67
70
|
|
68
71
|
mapping = MAPPING.fetch(event)
|
@@ -184,6 +184,39 @@ module Datadog
|
|
184
184
|
super(operation, key, polyfill_options)
|
185
185
|
end
|
186
186
|
end
|
187
|
+
|
188
|
+
# Save the original, user-supplied cache key, before it gets normalized.
|
189
|
+
#
|
190
|
+
# Normalized keys can include internal implementation detail,
|
191
|
+
# for example FileStore keys include temp directory names, which
|
192
|
+
# changes on every run, making it impossible to group by the cache key afterward.
|
193
|
+
# Also, the user is never exposed to the normalized key, and only sets/gets using the
|
194
|
+
# original key.
|
195
|
+
module PreserveOriginalKey
|
196
|
+
# Stores the original keys in the options hash, as an array of keys.
|
197
|
+
# It's important to keep all the keys for multi-key operations.
|
198
|
+
# For single-key operations, the key is stored as an array of a single element.
|
199
|
+
def normalize_key(key, options)
|
200
|
+
orig_keys = options[:dd_original_keys] || []
|
201
|
+
orig_keys << key
|
202
|
+
options[:dd_original_keys] = orig_keys
|
203
|
+
|
204
|
+
super
|
205
|
+
end
|
206
|
+
|
207
|
+
# Ensure we don't pollute the default Store instance `options` in {PreserveOriginalKey#normalize_key}.
|
208
|
+
# In most cases, `merged_options` returns a new hash,
|
209
|
+
# but we check for cases where it reuses the instance hash.
|
210
|
+
def merged_options(call_options)
|
211
|
+
ret = super
|
212
|
+
|
213
|
+
if ret.equal?(options)
|
214
|
+
ret.dup
|
215
|
+
else
|
216
|
+
ret
|
217
|
+
end
|
218
|
+
end
|
219
|
+
end
|
187
220
|
end
|
188
221
|
end
|
189
222
|
end
|
@@ -22,6 +22,10 @@ module Datadog
|
|
22
22
|
def patch
|
23
23
|
Events.subscribe!
|
24
24
|
|
25
|
+
if Integration.version >= Gem::Version.new('8.0.0')
|
26
|
+
::ActiveSupport::Cache::Store.prepend(Cache::Instrumentation::PreserveOriginalKey)
|
27
|
+
end
|
28
|
+
|
25
29
|
# Backfill the `:store` key in the ActiveSupport event payload for older Rails.
|
26
30
|
if Integration.version < Gem::Version.new('6.1.0')
|
27
31
|
::ActiveSupport::Cache::Store.prepend(Cache::Instrumentation::Store)
|
@@ -1,5 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require_relative '../../support'
|
3
4
|
require_relative 'patcher'
|
4
5
|
|
5
6
|
module Datadog
|
@@ -34,10 +35,7 @@ module Datadog
|
|
34
35
|
# @see https://github.com/rails/rails/blob/d0dcb8fa6073a0c4d42600c15e82e3bb386b27d3/activesupport/lib/active_support/cache/redis_cache_store.rb#L4
|
35
36
|
def patch_redis_cache_store?(meth)
|
36
37
|
Gem.loaded_specs['redis'] &&
|
37
|
-
|
38
|
-
defined?(::ActiveSupport::Cache::RedisCacheStore) &&
|
39
|
-
# ... to check that we need to call `autoload?` and check if it returns `nil`, meaning it's loaded.
|
40
|
-
::ActiveSupport::Cache.autoload?(:RedisCacheStore).nil? &&
|
38
|
+
Support.fully_loaded?(::ActiveSupport::Cache, :RedisCacheStore) &&
|
41
39
|
::ActiveSupport::Cache::RedisCacheStore.instance_methods(false).include?(meth)
|
42
40
|
end
|
43
41
|
|
@@ -35,6 +35,16 @@ module Datadog
|
|
35
35
|
span.type = Tracing::Metadata::Ext::HTTP::TYPE_OUTBOUND
|
36
36
|
span.name = Ext::SPAN_COMMAND
|
37
37
|
span.resource = context.safely(:resource)
|
38
|
+
|
39
|
+
# Set error on the span if the Response Status Code is in error range
|
40
|
+
if Tracing::Metadata::Ext::HTTP::ERROR_RANGE.cover?(context.safely(:status_code))
|
41
|
+
# At this point we do not have any additional diagnostics
|
42
|
+
# besides the HTTP status code which is recorded in the span tags
|
43
|
+
# later in this method.
|
44
|
+
# Just set the span as errored.
|
45
|
+
span.set_error(nil)
|
46
|
+
end
|
47
|
+
|
38
48
|
aws_service = span.resource.split('.')[0]
|
39
49
|
span.set_tag(Ext::TAG_AWS_SERVICE, aws_service)
|
40
50
|
params = context.safely(:params)
|
@@ -30,7 +30,7 @@ module Datadog
|
|
30
30
|
|
31
31
|
return super(req, body, &block) if Contrib::HTTP.should_skip_tracing?(req)
|
32
32
|
|
33
|
-
Tracing.trace(Ext::SPAN_REQUEST
|
33
|
+
Tracing.trace(Ext::SPAN_REQUEST) do |span, trace|
|
34
34
|
span.service = service_name(host, request_options, client_config)
|
35
35
|
span.type = Tracing::Metadata::Ext::HTTP::TYPE_OUTBOUND
|
36
36
|
span.resource = req.method
|
@@ -112,10 +112,6 @@ module Datadog
|
|
112
112
|
Datadog::Core::Telemetry::Logger.report(e)
|
113
113
|
end
|
114
114
|
|
115
|
-
def annotate_span_with_error!(span, error)
|
116
|
-
span.set_error(error)
|
117
|
-
end
|
118
|
-
|
119
115
|
def set_analytics_sample_rate(span, request_options)
|
120
116
|
return unless analytics_enabled?(request_options)
|
121
117
|
|
@@ -25,7 +25,7 @@ module Datadog
|
|
25
25
|
request_options = datadog_configuration(host)
|
26
26
|
client_config = Datadog.configuration_for(self)
|
27
27
|
|
28
|
-
Tracing.trace(Ext::SPAN_REQUEST
|
28
|
+
Tracing.trace(Ext::SPAN_REQUEST) do |span, trace|
|
29
29
|
begin
|
30
30
|
span.service = service_name(host, request_options, client_config)
|
31
31
|
span.type = Tracing::Metadata::Ext::HTTP::TYPE_OUTBOUND
|
@@ -111,10 +111,6 @@ module Datadog
|
|
111
111
|
Datadog::Core::Telemetry::Logger.report(e)
|
112
112
|
end
|
113
113
|
|
114
|
-
def annotate_span_with_error!(span, error)
|
115
|
-
span.set_error(error)
|
116
|
-
end
|
117
|
-
|
118
114
|
def datadog_configuration(host = :default)
|
119
115
|
Datadog.configuration.tracing[:httpclient, host]
|
120
116
|
end
|
@@ -25,7 +25,7 @@ module Datadog
|
|
25
25
|
request_options = datadog_configuration(host)
|
26
26
|
client_config = Datadog.configuration_for(self)
|
27
27
|
|
28
|
-
Tracing.trace(Ext::SPAN_REQUEST
|
28
|
+
Tracing.trace(Ext::SPAN_REQUEST) do |span, trace|
|
29
29
|
begin
|
30
30
|
span.service = service_name(host, request_options, client_config)
|
31
31
|
span.type = Tracing::Metadata::Ext::HTTP::TYPE_OUTBOUND
|
@@ -121,10 +121,6 @@ module Datadog
|
|
121
121
|
Datadog::Core::Telemetry::Logger.report(e)
|
122
122
|
end
|
123
123
|
|
124
|
-
def annotate_span_with_error!(span, error)
|
125
|
-
span.set_error(error)
|
126
|
-
end
|
127
|
-
|
128
124
|
def datadog_configuration(host = :default)
|
129
125
|
Datadog.configuration.tracing[:httprb, host]
|
130
126
|
end
|
@@ -20,10 +20,12 @@ module Datadog
|
|
20
20
|
|
21
21
|
# patch applies our patch
|
22
22
|
def patch
|
23
|
+
# First check Lograge logger directly for when keep_original_rails_log option is used
|
24
|
+
used_logger = ::Lograge.logger || ::Lograge::LogSubscribers::ActionController.logger
|
25
|
+
|
23
26
|
# ActiveSupport::TaggedLogging is the default Rails logger since Rails 5
|
24
27
|
if defined?(::ActiveSupport::TaggedLogging::Formatter) &&
|
25
|
-
::
|
26
|
-
.logger&.formatter.is_a?(::ActiveSupport::TaggedLogging::Formatter)
|
28
|
+
used_logger&.formatter.is_a?(::ActiveSupport::TaggedLogging::Formatter)
|
27
29
|
Datadog.logger.warn(
|
28
30
|
'Lograge and ActiveSupport::TaggedLogging (the default Rails log formatter) are not compatible: ' \
|
29
31
|
'Lograge does not account for Rails log tags, creating polluted logs and breaking log formatting. ' \
|
@@ -20,8 +20,11 @@ module Datadog
|
|
20
20
|
# @public_api
|
21
21
|
module CommonMethods
|
22
22
|
attr_accessor \
|
23
|
-
:patch_error_result
|
24
|
-
|
23
|
+
:patch_error_result
|
24
|
+
|
25
|
+
def patch_successful
|
26
|
+
!!@patch_successful
|
27
|
+
end
|
25
28
|
|
26
29
|
def patch_name
|
27
30
|
self.class != Class && self.class != Module ? self.class.name : name
|
@@ -13,6 +13,7 @@ module Datadog
|
|
13
13
|
ENV_ANALYTICS_ENABLED = 'DD_TRACE_SIDEKIQ_ANALYTICS_ENABLED'
|
14
14
|
ENV_ANALYTICS_SAMPLE_RATE = 'DD_TRACE_SIDEKIQ_ANALYTICS_SAMPLE_RATE'
|
15
15
|
SERVICE_NAME = 'sidekiq'
|
16
|
+
SIDEKIQ_8_SECONDS_PER_INTEGER = 0.001 # Sidekiq 8 uses integer epoch milliseconds, rather than epoch floats
|
16
17
|
SPAN_PUSH = 'sidekiq.push'
|
17
18
|
SPAN_JOB = 'sidekiq.job'
|
18
19
|
SPAN_JOB_FETCH = 'sidekiq.job_fetch'
|
@@ -22,7 +22,7 @@ module Datadog
|
|
22
22
|
@quantize = options[:quantize] || configuration[:quantize]
|
23
23
|
end
|
24
24
|
|
25
|
-
def call(worker, job, queue)
|
25
|
+
def call(worker, job, queue) # rubocop:disable Metrics/MethodLength
|
26
26
|
resource = job_resource(job)
|
27
27
|
|
28
28
|
if @distributed_tracing
|
@@ -61,7 +61,10 @@ module Datadog
|
|
61
61
|
span.set_tag(Ext::TAG_JOB_RETRY_COUNT, job['retry_count'])
|
62
62
|
span.set_tag(Ext::TAG_JOB_QUEUE, job['queue'])
|
63
63
|
span.set_tag(Ext::TAG_JOB_WRAPPER, job['class']) if job['wrapped']
|
64
|
-
|
64
|
+
|
65
|
+
enqueued_at = job['enqueued_at']
|
66
|
+
enqueued_at *= Ext::SIDEKIQ_8_SECONDS_PER_INTEGER if enqueued_at.is_a?(Integer)
|
67
|
+
span.set_tag(Ext::TAG_JOB_DELAY, 1000.0 * (Core::Utils::Time.now.utc.to_f - enqueued_at.to_f))
|
65
68
|
|
66
69
|
args = job['args']
|
67
70
|
if args && !args.empty?
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Datadog
|
4
|
+
module Tracing
|
5
|
+
module Contrib
|
6
|
+
# Miscellaneous support methods to aid in the creation of integrations.
|
7
|
+
module Support
|
8
|
+
module_function
|
9
|
+
|
10
|
+
# Checks if a constant is loaded in a module, handling autoloaded constants correctly.
|
11
|
+
#
|
12
|
+
# This method is particularly useful when you need to check if a constant is fully loaded,
|
13
|
+
# not just defined. It handles the special case of autoloaded constants, which return
|
14
|
+
# non-nil for `defined?` even when they haven't been loaded yet.
|
15
|
+
#
|
16
|
+
# @param base_module [Module] the module to check for the constant
|
17
|
+
# @param constant [Symbol] the name of the constant to check
|
18
|
+
# @return [Boolean] true if the constant has been loaded, false otherwise
|
19
|
+
def fully_loaded?(base_module, constant)
|
20
|
+
# Autoload constants return `constant` for `defined?`, but that doesn't mean they are loaded...
|
21
|
+
base_module.const_defined?(constant) &&
|
22
|
+
# ... to check that we need to call `autoload?`. If it returns `nil`, it's loaded.
|
23
|
+
base_module.autoload?(constant).nil?
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -10,17 +10,17 @@ module Datadog
|
|
10
10
|
# Adds error tagging behavior
|
11
11
|
# @public_api
|
12
12
|
module Errors
|
13
|
-
def set_error(
|
13
|
+
def set_error(error)
|
14
14
|
Datadog::Core.log_deprecation do
|
15
15
|
'Errors.set_error(..) is deprecated. ' \
|
16
16
|
'Use Errors.set_error_tags(..) instead.'
|
17
17
|
end
|
18
|
-
set_error_tags(
|
18
|
+
set_error_tags(error)
|
19
19
|
end
|
20
20
|
|
21
21
|
# Mark the span with the given error.
|
22
|
-
def set_error_tags(
|
23
|
-
e = Core::Error.build_from(
|
22
|
+
def set_error_tags(error)
|
23
|
+
e = Core::Error.build_from(error)
|
24
24
|
|
25
25
|
set_tag(Ext::Errors::TAG_TYPE, e.type) unless e.type.empty?
|
26
26
|
set_tag(Ext::Errors::TAG_MSG, e.message) unless e.message.empty?
|
@@ -25,7 +25,7 @@ module Datadog
|
|
25
25
|
# @param [Datadog::Tracing::Transport::Traces::Transport] transport a custom transport instance.
|
26
26
|
# If provided, overrides `transport_options` and `agent_settings`.
|
27
27
|
# @param [Hash<Symbol,Object>] transport_options options for the default transport instance.
|
28
|
-
# @param [Datadog::Tracing::Configuration::
|
28
|
+
# @param [Datadog::Tracing::Configuration::AgentSettings] agent_settings agent options for
|
29
29
|
# the default transport instance.
|
30
30
|
def initialize(transport: nil, transport_options: {}, agent_settings: nil, logger: Datadog.logger)
|
31
31
|
@logger = logger
|
@@ -79,7 +79,7 @@ module Datadog
|
|
79
79
|
trace_state: nil,
|
80
80
|
trace_state_unknown_fields: nil,
|
81
81
|
remote_parent: false,
|
82
|
-
tracer: nil,
|
82
|
+
tracer: nil, # DEV-3.0: deprecated, remove in 3.0
|
83
83
|
baggage: nil
|
84
84
|
)
|
85
85
|
@logger = logger
|
@@ -106,7 +106,6 @@ module Datadog
|
|
106
106
|
@apm_tracing_enabled = apm_tracing_enabled
|
107
107
|
@trace_state = trace_state
|
108
108
|
@trace_state_unknown_fields = trace_state_unknown_fields
|
109
|
-
@tracer = tracer
|
110
109
|
@baggage = baggage
|
111
110
|
|
112
111
|
# Generic tags
|
@@ -329,7 +328,7 @@ module Datadog
|
|
329
328
|
span_id = @active_span && @active_span.id
|
330
329
|
span_id ||= @parent_span_id unless finished?
|
331
330
|
# sample the trace_operation with the tracer
|
332
|
-
|
331
|
+
events.trace_propagated.publish(self)
|
333
332
|
|
334
333
|
TraceDigest.new(
|
335
334
|
span_id: span_id,
|
@@ -399,12 +398,14 @@ module Datadog
|
|
399
398
|
attr_reader \
|
400
399
|
:span_before_start,
|
401
400
|
:span_finished,
|
402
|
-
:trace_finished
|
401
|
+
:trace_finished,
|
402
|
+
:trace_propagated
|
403
403
|
|
404
404
|
def initialize
|
405
405
|
@span_before_start = SpanBeforeStart.new
|
406
406
|
@span_finished = SpanFinished.new
|
407
407
|
@trace_finished = TraceFinished.new
|
408
|
+
@trace_propagated = TracePropagated.new
|
408
409
|
end
|
409
410
|
|
410
411
|
# Triggered before a span starts.
|
@@ -421,6 +422,13 @@ module Datadog
|
|
421
422
|
end
|
422
423
|
end
|
423
424
|
|
425
|
+
# Triggered when trace is being propagated between applications or contexts
|
426
|
+
class TracePropagated < Tracing::Event
|
427
|
+
def initialize
|
428
|
+
super(:trace_propagated)
|
429
|
+
end
|
430
|
+
end
|
431
|
+
|
424
432
|
# Triggered when the trace finishes, regardless of error.
|
425
433
|
class TraceFinished < Tracing::Event
|
426
434
|
def initialize
|
@@ -273,7 +273,7 @@ module Datadog
|
|
273
273
|
# Sample a span, tagging the trace as appropriate.
|
274
274
|
def sample_trace(trace_op)
|
275
275
|
begin
|
276
|
-
@sampler.sample!(trace_op)
|
276
|
+
@sampler.sample!(trace_op) if trace_op.sampling_priority.nil?
|
277
277
|
rescue StandardError => e
|
278
278
|
SAMPLE_TRACE_LOG_ONLY_ONCE.run do
|
279
279
|
logger.warn { "Failed to sample trace: #{e.class.name} #{e} at #{Array(e.backtrace).first}" }
|
@@ -378,7 +378,12 @@ module Datadog
|
|
378
378
|
event_span_op.service ||= @default_service
|
379
379
|
end
|
380
380
|
|
381
|
+
events.trace_propagated.subscribe do |event_trace_op|
|
382
|
+
sample_trace(event_trace_op)
|
383
|
+
end
|
384
|
+
|
381
385
|
events.span_finished.subscribe do |event_span, event_trace_op|
|
386
|
+
sample_trace(trace_op) if event_trace_op.sampling_priority.nil?
|
382
387
|
sample_span(event_trace_op, event_span)
|
383
388
|
flush_trace(event_trace_op)
|
384
389
|
end
|
@@ -516,7 +521,6 @@ module Datadog
|
|
516
521
|
|
517
522
|
# Flush finished spans from the trace buffer, send them to writer.
|
518
523
|
def flush_trace(trace_op)
|
519
|
-
sample_trace(trace_op) unless trace_op.sampling_priority
|
520
524
|
begin
|
521
525
|
trace = @trace_flush.consume!(trace_op)
|
522
526
|
write(trace) if trace && !trace.empty?
|