datadog 2.35.0 → 2.37.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 +85 -1
- data/ext/datadog_profiling_native_extension/clock_id_from_mach.c +5 -12
- data/ext/datadog_profiling_native_extension/collectors_cpu_and_wall_time_worker.c +71 -31
- data/ext/datadog_profiling_native_extension/collectors_discrete_dynamic_sampler.c +1 -1
- data/ext/datadog_profiling_native_extension/collectors_idle_sampling_helper.c +18 -4
- data/ext/datadog_profiling_native_extension/collectors_stack.c +37 -18
- data/ext/datadog_profiling_native_extension/collectors_stack.h +8 -2
- data/ext/datadog_profiling_native_extension/collectors_thread_context.c +596 -341
- data/ext/datadog_profiling_native_extension/collectors_thread_context.h +11 -7
- data/ext/datadog_profiling_native_extension/datadog_ruby_common.c +7 -8
- data/ext/datadog_profiling_native_extension/datadog_ruby_common.h +0 -12
- data/ext/datadog_profiling_native_extension/extconf.rb +13 -2
- data/ext/datadog_profiling_native_extension/gvl_profiling_helper.c +4 -43
- data/ext/datadog_profiling_native_extension/gvl_profiling_helper.h +15 -47
- data/ext/datadog_profiling_native_extension/heap_recorder.c +44 -26
- data/ext/datadog_profiling_native_extension/private_vm_api_access.c +14 -35
- data/ext/datadog_profiling_native_extension/profiling.c +41 -4
- data/ext/datadog_profiling_native_extension/ruby_helpers.c +40 -34
- data/ext/datadog_profiling_native_extension/stack_recorder.c +24 -3
- data/ext/datadog_profiling_native_extension/stack_recorder.h +1 -0
- data/ext/datadog_profiling_native_extension/unsafe_api_calls_check.h +4 -2
- data/ext/libdatadog_api/datadog_ruby_common.c +7 -8
- data/ext/libdatadog_api/datadog_ruby_common.h +0 -12
- data/ext/libdatadog_api/di.c +76 -0
- data/ext/libdatadog_api/extconf.rb +6 -0
- data/ext/libdatadog_extconf_helpers.rb +1 -1
- data/lib/datadog/ai_guard/api_client.rb +6 -4
- data/lib/datadog/appsec/api_security/route_extractor.rb +13 -4
- data/lib/datadog/appsec/component.rb +1 -1
- data/lib/datadog/appsec/configuration.rb +13 -0
- data/lib/datadog/appsec/context.rb +4 -2
- data/lib/datadog/appsec/contrib/aws_lambda/waf_addresses.rb +37 -4
- data/lib/datadog/appsec/contrib/excon/ssrf_detection_middleware.rb +59 -4
- data/lib/datadog/appsec/contrib/faraday/ssrf_detection_middleware.rb +59 -5
- data/lib/datadog/appsec/contrib/graphql/gateway/multiplex.rb +64 -19
- data/lib/datadog/appsec/contrib/graphql/integration.rb +1 -0
- data/lib/datadog/appsec/contrib/rack/buffered_input.rb +83 -0
- data/lib/datadog/appsec/contrib/rack/gateway/request.rb +41 -3
- data/lib/datadog/appsec/contrib/rack/gateway/watcher.rb +24 -7
- data/lib/datadog/appsec/contrib/rack/input_peeker.rb +79 -0
- data/lib/datadog/appsec/contrib/rack/request_middleware.rb +21 -0
- data/lib/datadog/appsec/contrib/rails/gateway/request.rb +35 -1
- data/lib/datadog/appsec/contrib/rails/gateway/watcher.rb +17 -1
- data/lib/datadog/appsec/contrib/rest_client/request_ssrf_detection_patch.rb +60 -7
- data/lib/datadog/appsec/contrib/sinatra/gateway/watcher.rb +24 -3
- data/lib/datadog/appsec/default_header_tags.rb +10 -6
- data/lib/datadog/appsec/ext.rb +1 -0
- data/lib/datadog/appsec/metrics/collector.rb +18 -1
- data/lib/datadog/appsec/metrics/exporter.rb +9 -3
- data/lib/datadog/appsec/remote.rb +9 -3
- data/lib/datadog/appsec/route_normalizer/rails_route_pattern.rb +176 -0
- data/lib/datadog/appsec/route_normalizer/route_pattern.rb +378 -0
- data/lib/datadog/appsec/route_normalizer/route_text.rb +57 -0
- data/lib/datadog/appsec/route_normalizer.rb +80 -0
- data/lib/datadog/appsec/utils/http/body_reader.rb +61 -0
- data/lib/datadog/core/configuration/components.rb +83 -2
- data/lib/datadog/core/configuration/components_state.rb +6 -1
- data/lib/datadog/core/configuration/settings.rb +1 -5
- data/lib/datadog/core/configuration/supported_configurations.rb +4 -0
- data/lib/datadog/core/evp.rb +11 -0
- data/lib/datadog/core/remote/client/capabilities.rb +34 -7
- data/lib/datadog/core/remote/component.rb +1 -1
- data/lib/datadog/core/telemetry/event/app_started.rb +8 -22
- data/lib/datadog/core/utils/at_fork_monkey_patch.rb +1 -1
- data/lib/datadog/core/utils/forking.rb +3 -1
- data/lib/datadog/core/utils/spawn_monkey_patch.rb +3 -1
- data/lib/datadog/core.rb +3 -0
- data/lib/datadog/di/base.rb +7 -2
- data/lib/datadog/di/code_tracker.rb +5 -2
- data/lib/datadog/di/component.rb +110 -36
- data/lib/datadog/di/error.rb +10 -0
- data/lib/datadog/di/fatal_exceptions.rb +26 -0
- data/lib/datadog/di/instrumenter.rb +381 -165
- data/lib/datadog/di/probe.rb +14 -0
- data/lib/datadog/di/probe_file_loader.rb +8 -3
- data/lib/datadog/di/probe_manager.rb +67 -9
- data/lib/datadog/di/probe_notification_builder.rb +4 -1
- data/lib/datadog/di/probe_notifier_worker.rb +52 -32
- data/lib/datadog/di/redactor.rb +16 -1
- data/lib/datadog/di/remote.rb +175 -14
- data/lib/datadog/di/serializer.rb +12 -5
- data/lib/datadog/di/transport/input.rb +8 -4
- data/lib/datadog/di.rb +63 -0
- data/lib/datadog/error_tracking/collector.rb +2 -1
- data/lib/datadog/error_tracking/component.rb +2 -2
- data/lib/datadog/kit/appsec/events/v2.rb +60 -2
- data/lib/datadog/kit/tracing/method_tracer.rb +4 -1
- data/lib/datadog/open_feature/component.rb +29 -6
- data/lib/datadog/open_feature/configuration.rb +8 -0
- data/lib/datadog/open_feature/ext.rb +2 -0
- data/lib/datadog/open_feature/flag_evaluation/aggregator.rb +286 -0
- data/lib/datadog/open_feature/flag_evaluation/writer.rb +433 -0
- data/lib/datadog/open_feature/hooks/flag_eval_evp_hook.rb +101 -0
- data/lib/datadog/open_feature/hooks/{flag_eval_hook.rb → flag_eval_metrics_hook.rb} +1 -1
- data/lib/datadog/open_feature/native_evaluator.rb +22 -0
- data/lib/datadog/open_feature/provider.rb +59 -27
- data/lib/datadog/open_feature/transport.rb +55 -1
- data/lib/datadog/opentelemetry/sdk/logs_exporter.rb +5 -12
- data/lib/datadog/opentelemetry/sdk/metrics_exporter.rb +4 -11
- data/lib/datadog/opentelemetry/sdk/propagator.rb +9 -3
- data/lib/datadog/opentelemetry/sdk/span_processor.rb +4 -1
- data/lib/datadog/opentelemetry/sdk.rb +19 -0
- data/lib/datadog/profiling/collectors/cpu_and_wall_time_worker.rb +1 -1
- data/lib/datadog/profiling/collectors/idle_sampling_helper.rb +5 -3
- data/lib/datadog/profiling/collectors/thread_context.rb +1 -0
- data/lib/datadog/profiling/component.rb +13 -15
- data/lib/datadog/profiling/ext/dir_monkey_patches.rb +3 -3
- data/lib/datadog/ruby_version.rb +25 -0
- data/lib/datadog/symbol_database/component.rb +453 -128
- data/lib/datadog/symbol_database/configuration.rb +12 -4
- data/lib/datadog/symbol_database/extensions.rb +19 -0
- data/lib/datadog/symbol_database/extractor.rb +326 -150
- data/lib/datadog/symbol_database/file_hash.rb +3 -1
- data/lib/datadog/symbol_database/remote.rb +8 -3
- data/lib/datadog/symbol_database/scope_batcher.rb +7 -3
- data/lib/datadog/symbol_database/uploader.rb +9 -2
- data/lib/datadog/symbol_database.rb +22 -0
- data/lib/datadog/tracing/configuration/ext.rb +13 -0
- data/lib/datadog/tracing/configuration/settings.rb +17 -0
- data/lib/datadog/tracing/contrib/configuration/resolver.rb +7 -0
- data/lib/datadog/tracing/contrib/grpc/distributed/propagation.rb +2 -0
- data/lib/datadog/tracing/contrib/grpc.rb +1 -0
- data/lib/datadog/tracing/contrib/http/distributed/propagation.rb +2 -0
- data/lib/datadog/tracing/contrib/http.rb +1 -0
- data/lib/datadog/tracing/contrib/karafka/distributed/propagation.rb +2 -0
- data/lib/datadog/tracing/contrib/karafka.rb +1 -0
- data/lib/datadog/tracing/contrib/rack/middlewares.rb +3 -1
- data/lib/datadog/tracing/contrib/rack/route_inference.rb +3 -1
- data/lib/datadog/tracing/contrib/sidekiq/distributed/propagation.rb +2 -0
- data/lib/datadog/tracing/contrib/sidekiq.rb +1 -0
- data/lib/datadog/tracing/contrib/waterdrop/distributed/propagation.rb +2 -0
- data/lib/datadog/tracing/contrib/waterdrop.rb +1 -0
- data/lib/datadog/tracing/distributed/baggage.rb +2 -1
- data/lib/datadog/tracing/distributed/propagation.rb +33 -1
- data/lib/datadog/tracing/distributed/trace_context.rb +11 -2
- data/lib/datadog/tracing/ext.rb +9 -0
- data/lib/datadog/tracing/remote.rb +34 -3
- data/lib/datadog/tracing/trace_digest.rb +7 -0
- data/lib/datadog/tracing/trace_operation.rb +4 -1
- data/lib/datadog/tracing/tracer.rb +1 -0
- data/lib/datadog/version.rb +1 -1
- data/lib/datadog.rb +5 -1
- metadata +22 -6
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require 'digest/sha1'
|
|
4
|
+
require_relative '../di/fatal_exceptions'
|
|
4
5
|
|
|
5
6
|
module Datadog
|
|
6
7
|
module SymbolDatabase
|
|
@@ -37,7 +38,8 @@ module Datadog
|
|
|
37
38
|
# This is not a security vulnerability - we're computing file content hashes
|
|
38
39
|
# to match against Git objects, not using SHA-1 for authentication/integrity.
|
|
39
40
|
Digest::SHA1.hexdigest(git_blob) # nosemgrep: ruby.lang.security.weak-hashes-sha1.weak-hashes-sha1
|
|
40
|
-
rescue => e
|
|
41
|
+
rescue Exception => e # standard:disable Lint/RescueException
|
|
42
|
+
Datadog::DI.reraise_if_fatal(e)
|
|
41
43
|
logger.debug { "symdb: file hash failed for #{file_path}: #{e.class}: #{e.message}" }
|
|
42
44
|
nil
|
|
43
45
|
end
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require_relative '../di/fatal_exceptions'
|
|
4
|
+
|
|
3
5
|
module Datadog
|
|
4
6
|
module SymbolDatabase
|
|
5
7
|
# Provides remote configuration integration for symbol database.
|
|
@@ -44,7 +46,8 @@ module Datadog
|
|
|
44
46
|
telemetry = lookup_telemetry
|
|
45
47
|
component = begin
|
|
46
48
|
Datadog.send(:components, allow_initialization: false)&.symbol_database
|
|
47
|
-
rescue => e
|
|
49
|
+
rescue Exception => e # standard:disable Lint/RescueException
|
|
50
|
+
Datadog::DI.reraise_if_fatal(e)
|
|
48
51
|
Datadog.logger.debug { "symdb: failed to look up component in RC receiver: #{e.class}: #{e.message}" }
|
|
49
52
|
telemetry&.report(e, description: 'symdb: failed to look up component in RC receiver')
|
|
50
53
|
nil
|
|
@@ -76,7 +79,8 @@ module Datadog
|
|
|
76
79
|
# @api private
|
|
77
80
|
def lookup_telemetry
|
|
78
81
|
Datadog.send(:components, allow_initialization: false)&.telemetry
|
|
79
|
-
rescue
|
|
82
|
+
rescue Exception => e # standard:disable Lint/RescueException
|
|
83
|
+
Datadog::DI.reraise_if_fatal(e)
|
|
80
84
|
nil
|
|
81
85
|
end
|
|
82
86
|
|
|
@@ -107,7 +111,8 @@ module Datadog
|
|
|
107
111
|
# the Repository::Change union type where `Deleted` lacks `content`.
|
|
108
112
|
change.content.errored("Unrecognized change type: #{change.type}") if change.respond_to?(:content) # steep:ignore NoMethod
|
|
109
113
|
end
|
|
110
|
-
rescue => e
|
|
114
|
+
rescue Exception => e # standard:disable Lint/RescueException
|
|
115
|
+
Datadog::DI.reraise_if_fatal(e)
|
|
111
116
|
component.logger.debug { "symdb: error processing remote config change: #{e.class}: #{e.message}" }
|
|
112
117
|
telemetry&.report(e, description: 'symdb: error processing remote config change')
|
|
113
118
|
# Rescue runs regardless of which branch raised — Steep cannot narrow the
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require 'set'
|
|
4
|
+
require_relative '../di/fatal_exceptions'
|
|
4
5
|
|
|
5
6
|
module Datadog
|
|
6
7
|
module SymbolDatabase
|
|
@@ -122,7 +123,8 @@ module Datadog
|
|
|
122
123
|
|
|
123
124
|
# Upload outside mutex (if batch was full)
|
|
124
125
|
perform_upload(scopes_to_upload) if scopes_to_upload
|
|
125
|
-
rescue => e
|
|
126
|
+
rescue Exception => e # standard:disable Lint/RescueException
|
|
127
|
+
Datadog::DI.reraise_if_fatal(e)
|
|
126
128
|
@logger.debug { "symdb: failed to add scope: #{e.class}: #{e.message}" }
|
|
127
129
|
# Don't propagate, continue operation
|
|
128
130
|
end
|
|
@@ -267,7 +269,8 @@ module Datadog
|
|
|
267
269
|
flush
|
|
268
270
|
end
|
|
269
271
|
end
|
|
270
|
-
rescue => e
|
|
272
|
+
rescue Exception => e # standard:disable Lint/RescueException
|
|
273
|
+
Datadog::DI.reraise_if_fatal(e)
|
|
271
274
|
@logger.debug { "symdb: timer thread error: #{e.class}: #{e.message}" }
|
|
272
275
|
end
|
|
273
276
|
|
|
@@ -279,7 +282,8 @@ module Datadog
|
|
|
279
282
|
|
|
280
283
|
@uploader.upload_scopes(scopes)
|
|
281
284
|
@on_upload&.call(scopes) # Notify tests after upload
|
|
282
|
-
rescue => e
|
|
285
|
+
rescue Exception => e # standard:disable Lint/RescueException
|
|
286
|
+
Datadog::DI.reraise_if_fatal(e)
|
|
283
287
|
@logger.debug { "symdb: upload failed: #{e.class}: #{e.message}" }
|
|
284
288
|
# Don't propagate, uploader handles retries
|
|
285
289
|
end
|
|
@@ -6,8 +6,10 @@ require 'zlib'
|
|
|
6
6
|
require 'stringio'
|
|
7
7
|
require_relative '../core/environment/identity'
|
|
8
8
|
require_relative '../core/vendor/multipart-post/multipart/post/composite_read_io'
|
|
9
|
+
require_relative '../tracing/ext'
|
|
9
10
|
require_relative 'service_version'
|
|
10
11
|
require_relative 'transport/http'
|
|
12
|
+
require_relative '../di/fatal_exceptions'
|
|
11
13
|
|
|
12
14
|
module Datadog
|
|
13
15
|
module SymbolDatabase
|
|
@@ -68,7 +70,11 @@ module Datadog
|
|
|
68
70
|
compressed_data = Zlib.gzip(json_data)
|
|
69
71
|
|
|
70
72
|
# Emitted unconditionally so the rare oversized case is observable.
|
|
71
|
-
@telemetry&.distribution(
|
|
73
|
+
@telemetry&.distribution(
|
|
74
|
+
Tracing::Ext::TELEMETRY_METRICS_NAMESPACE,
|
|
75
|
+
'symbol_database.payload_size',
|
|
76
|
+
compressed_data.bytesize
|
|
77
|
+
)
|
|
72
78
|
|
|
73
79
|
# Symbols for very large applications (>50MB after gzip) are dropped:
|
|
74
80
|
# the upload is skipped and the customer sees no autocomplete /
|
|
@@ -81,7 +87,8 @@ module Datadog
|
|
|
81
87
|
end
|
|
82
88
|
|
|
83
89
|
perform_http_upload(compressed_data, scopes.size, upload_id: upload_id, batch_num: batch_num)
|
|
84
|
-
rescue => e
|
|
90
|
+
rescue Exception => e # standard:disable Lint/RescueException
|
|
91
|
+
Datadog::DI.reraise_if_fatal(e)
|
|
85
92
|
@logger.debug { "symdb: upload failed: #{e.class}: #{e.message}" }
|
|
86
93
|
@telemetry&.report(e, description: 'symdb: upload failed')
|
|
87
94
|
end
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require_relative 'ruby_version'
|
|
4
|
+
|
|
3
5
|
module Datadog
|
|
4
6
|
# Namespace for Datadog symbol database upload.
|
|
5
7
|
#
|
|
@@ -45,5 +47,25 @@ module Datadog
|
|
|
45
47
|
# Reference: Symbol Database Backend RFC, section "Scope" and "Edge Cases"
|
|
46
48
|
# @see https://www.postgresql.org/docs/current/datatype-numeric.html
|
|
47
49
|
UNKNOWN_MAX_LINE = 2147483647
|
|
50
|
+
|
|
51
|
+
# Collapses the symbol_database.enabled tri-state setting to a boolean.
|
|
52
|
+
# An explicit true/false wins; nil (unconfigured) yields the caller-supplied
|
|
53
|
+
# fallback.
|
|
54
|
+
# @param setting_value [Boolean, nil] the symbol_database.enabled setting
|
|
55
|
+
# @param di_fallback [Boolean] value used when the setting is unconfigured
|
|
56
|
+
# @return [Boolean]
|
|
57
|
+
def self.resolve_enabled(setting_value, di_fallback)
|
|
58
|
+
setting_value.nil? ? di_fallback : setting_value
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# Whether the current Ruby runtime can run symbol database extraction:
|
|
62
|
+
# MRI (CRuby) on Ruby 2.7 or later. Used by the remote-config layer to avoid
|
|
63
|
+
# advertising the product on runtimes where Component.build would return nil
|
|
64
|
+
# (e.g. Ruby 2.6, which Dynamic Instrumentation supports but Symbol Database
|
|
65
|
+
# does not).
|
|
66
|
+
# @return [Boolean]
|
|
67
|
+
def self.supported_runtime?
|
|
68
|
+
RUBY_ENGINE == 'ruby' && RubyVersion.is?('>= 2.7')
|
|
69
|
+
end
|
|
48
70
|
end
|
|
49
71
|
end
|
|
@@ -62,6 +62,19 @@ module Datadog
|
|
|
62
62
|
|
|
63
63
|
ENV_PROPAGATION_STYLE_EXTRACT = 'DD_TRACE_PROPAGATION_STYLE_EXTRACT'
|
|
64
64
|
|
|
65
|
+
PROPAGATION_BEHAVIOR_EXTRACT_CONTINUE = 'continue'
|
|
66
|
+
PROPAGATION_BEHAVIOR_EXTRACT_RESTART = 'restart'
|
|
67
|
+
PROPAGATION_BEHAVIOR_EXTRACT_IGNORE = 'ignore'
|
|
68
|
+
|
|
69
|
+
PROPAGATION_BEHAVIOR_EXTRACT_SUPPORTED = [
|
|
70
|
+
PROPAGATION_BEHAVIOR_EXTRACT_CONTINUE,
|
|
71
|
+
PROPAGATION_BEHAVIOR_EXTRACT_RESTART,
|
|
72
|
+
PROPAGATION_BEHAVIOR_EXTRACT_IGNORE,
|
|
73
|
+
].freeze
|
|
74
|
+
|
|
75
|
+
# Behavior applied to a distributed-trace context extracted from incoming requests.
|
|
76
|
+
ENV_PROPAGATION_BEHAVIOR_EXTRACT = 'DD_TRACE_PROPAGATION_BEHAVIOR_EXTRACT'
|
|
77
|
+
|
|
65
78
|
# A no-op propagator. Compatible with OpenTelemetry's `none` propagator.
|
|
66
79
|
# @see https://opentelemetry.io/docs/concepts/sdk-configuration/general-sdk-configuration/#get_otel__propagators
|
|
67
80
|
PROPAGATION_STYLE_NONE = 'none'
|
|
@@ -117,6 +117,23 @@ module Datadog
|
|
|
117
117
|
end
|
|
118
118
|
end
|
|
119
119
|
|
|
120
|
+
# Behavior applied to a distributed-trace context extracted from incoming requests.
|
|
121
|
+
option :propagation_behavior_extract do |o|
|
|
122
|
+
o.env Tracing::Configuration::Ext::Distributed::ENV_PROPAGATION_BEHAVIOR_EXTRACT
|
|
123
|
+
o.default Tracing::Configuration::Ext::Distributed::PROPAGATION_BEHAVIOR_EXTRACT_CONTINUE
|
|
124
|
+
o.type :string
|
|
125
|
+
o.env_parser do |value|
|
|
126
|
+
value = value&.downcase
|
|
127
|
+
if Tracing::Configuration::Ext::Distributed::PROPAGATION_BEHAVIOR_EXTRACT_SUPPORTED.include?(value)
|
|
128
|
+
value
|
|
129
|
+
else
|
|
130
|
+
Datadog.logger.warn("Unsupported propagation behavior extract: #{value.inspect}. " \
|
|
131
|
+
"Set to default value (#{Tracing::Configuration::Ext::Distributed::PROPAGATION_BEHAVIOR_EXTRACT_CONTINUE}).")
|
|
132
|
+
nil
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
|
|
120
137
|
# Strictly stop at the first successfully serialized style.
|
|
121
138
|
# This prevents the tracer from enriching the extracted context with information from
|
|
122
139
|
# other valid propagations styles present in the request.
|
|
@@ -101,6 +101,13 @@ module Datadog
|
|
|
101
101
|
# shrink a Hash using an "st_table" back to an "ar_table")
|
|
102
102
|
@cache = Hash[*1..20]
|
|
103
103
|
@cache.clear
|
|
104
|
+
# Workaround for the segfault from https://github.com/DataDog/dd-trace-rb/issues/5718#issuecomment-4421844775.
|
|
105
|
+
# It crashes on a simple {Hash} lookup, {Hash#key?}, called from `@cache.fetch(value)`.
|
|
106
|
+
# Using an identity-based {Hash} avoids {Hash#key?} calls.
|
|
107
|
+
# We should attempt to remove this workaround when we only support Ruby 4+,
|
|
108
|
+
# as large change around the crash site was done in that version (https://github.com/ruby/ruby/pull/14039/changes#diff-884a5a8a369ef1b4c7597e00aa65974cec8c5f54f25f03ad5d24848f64892869R1743),
|
|
109
|
+
# where `RClass.cc_table` (the NULL dereferenced pointer) became a GC-managed object,
|
|
110
|
+
@cache.compare_by_identity
|
|
104
111
|
end
|
|
105
112
|
|
|
106
113
|
# (see Resolver#resolve)
|
|
@@ -20,6 +20,7 @@ module Datadog
|
|
|
20
20
|
def initialize(
|
|
21
21
|
propagation_style_inject:,
|
|
22
22
|
propagation_style_extract:,
|
|
23
|
+
propagation_behavior_extract:,
|
|
23
24
|
propagation_extract_first:
|
|
24
25
|
)
|
|
25
26
|
super(
|
|
@@ -38,6 +39,7 @@ module Datadog
|
|
|
38
39
|
},
|
|
39
40
|
propagation_style_inject: propagation_style_inject,
|
|
40
41
|
propagation_style_extract: propagation_style_extract,
|
|
42
|
+
propagation_behavior_extract: propagation_behavior_extract,
|
|
41
43
|
propagation_extract_first: propagation_extract_first
|
|
42
44
|
)
|
|
43
45
|
end
|
|
@@ -36,6 +36,7 @@ module Datadog
|
|
|
36
36
|
@propagation = GRPC::Distributed::Propagation.new(
|
|
37
37
|
propagation_style_inject: tracing.propagation_style_inject,
|
|
38
38
|
propagation_style_extract: tracing.propagation_style_extract,
|
|
39
|
+
propagation_behavior_extract: tracing.propagation_behavior_extract,
|
|
39
40
|
propagation_extract_first: tracing.propagation_extract_first
|
|
40
41
|
)
|
|
41
42
|
end
|
|
@@ -19,6 +19,7 @@ module Datadog
|
|
|
19
19
|
def initialize(
|
|
20
20
|
propagation_style_inject:,
|
|
21
21
|
propagation_style_extract:,
|
|
22
|
+
propagation_behavior_extract:,
|
|
22
23
|
propagation_extract_first:
|
|
23
24
|
)
|
|
24
25
|
super(
|
|
@@ -37,6 +38,7 @@ module Datadog
|
|
|
37
38
|
},
|
|
38
39
|
propagation_style_inject: propagation_style_inject,
|
|
39
40
|
propagation_style_extract: propagation_style_extract,
|
|
41
|
+
propagation_behavior_extract: propagation_behavior_extract,
|
|
40
42
|
propagation_extract_first: propagation_extract_first
|
|
41
43
|
)
|
|
42
44
|
end
|
|
@@ -36,6 +36,7 @@ module Datadog
|
|
|
36
36
|
@propagation = HTTP::Distributed::Propagation.new(
|
|
37
37
|
propagation_style_inject: tracing.propagation_style_inject,
|
|
38
38
|
propagation_style_extract: tracing.propagation_style_extract,
|
|
39
|
+
propagation_behavior_extract: tracing.propagation_behavior_extract,
|
|
39
40
|
propagation_extract_first: tracing.propagation_extract_first
|
|
40
41
|
)
|
|
41
42
|
end
|
|
@@ -19,6 +19,7 @@ module Datadog
|
|
|
19
19
|
def initialize(
|
|
20
20
|
propagation_style_inject:,
|
|
21
21
|
propagation_style_extract:,
|
|
22
|
+
propagation_behavior_extract:,
|
|
22
23
|
propagation_extract_first:
|
|
23
24
|
)
|
|
24
25
|
super(
|
|
@@ -37,6 +38,7 @@ module Datadog
|
|
|
37
38
|
},
|
|
38
39
|
propagation_style_inject: propagation_style_inject,
|
|
39
40
|
propagation_style_extract: propagation_style_extract,
|
|
41
|
+
propagation_behavior_extract: propagation_behavior_extract,
|
|
40
42
|
propagation_extract_first: propagation_extract_first
|
|
41
43
|
)
|
|
42
44
|
end
|
|
@@ -28,6 +28,7 @@ module Datadog
|
|
|
28
28
|
@propagation = Karafka::Distributed::Propagation.new(
|
|
29
29
|
propagation_style_inject: tracing.propagation_style_inject,
|
|
30
30
|
propagation_style_extract: tracing.propagation_style_extract,
|
|
31
|
+
propagation_behavior_extract: tracing.propagation_behavior_extract,
|
|
31
32
|
propagation_extract_first: tracing.propagation_extract_first
|
|
32
33
|
)
|
|
33
34
|
end
|
|
@@ -268,7 +268,9 @@ module Datadog
|
|
|
268
268
|
# 1. resource renaming is enabled
|
|
269
269
|
# 2. AppSec is enabled and resource renaming is disabled (by default, not explicitly)
|
|
270
270
|
if Datadog.configuration.tracing.resource_renaming.enabled ||
|
|
271
|
-
Datadog.configuration.appsec
|
|
271
|
+
Datadog.configuration.respond_to?(:appsec) &&
|
|
272
|
+
Datadog.configuration.appsec&.enabled &&
|
|
273
|
+
Datadog.configuration.tracing.resource_renaming.options[:enabled].default_precedence?
|
|
272
274
|
request_span.set_tag(Tracing::Metadata::Ext::HTTP::TAG_ENDPOINT, value)
|
|
273
275
|
end
|
|
274
276
|
end
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require_relative '../../../ruby_version'
|
|
4
|
+
|
|
3
5
|
module Datadog
|
|
4
6
|
module Tracing
|
|
5
7
|
module Contrib
|
|
@@ -48,7 +50,7 @@ module Datadog
|
|
|
48
50
|
nil
|
|
49
51
|
end
|
|
50
52
|
|
|
51
|
-
if
|
|
53
|
+
if RubyVersion.is?('>= 2.6')
|
|
52
54
|
def split(path, pattern = nil, &block)
|
|
53
55
|
path.split(pattern, &block)
|
|
54
56
|
end
|
|
@@ -20,6 +20,7 @@ module Datadog
|
|
|
20
20
|
def initialize(
|
|
21
21
|
propagation_style_inject:,
|
|
22
22
|
propagation_style_extract:,
|
|
23
|
+
propagation_behavior_extract:,
|
|
23
24
|
propagation_extract_first:
|
|
24
25
|
)
|
|
25
26
|
super(
|
|
@@ -38,6 +39,7 @@ module Datadog
|
|
|
38
39
|
},
|
|
39
40
|
propagation_style_inject: propagation_style_inject,
|
|
40
41
|
propagation_style_extract: propagation_style_extract,
|
|
42
|
+
propagation_behavior_extract: propagation_behavior_extract,
|
|
41
43
|
propagation_extract_first: propagation_extract_first
|
|
42
44
|
)
|
|
43
45
|
end
|
|
@@ -28,6 +28,7 @@ module Datadog
|
|
|
28
28
|
@propagation = Sidekiq::Distributed::Propagation.new(
|
|
29
29
|
propagation_style_inject: tracing.propagation_style_inject,
|
|
30
30
|
propagation_style_extract: tracing.propagation_style_extract,
|
|
31
|
+
propagation_behavior_extract: tracing.propagation_behavior_extract,
|
|
31
32
|
propagation_extract_first: tracing.propagation_extract_first
|
|
32
33
|
)
|
|
33
34
|
end
|
|
@@ -19,6 +19,7 @@ module Datadog
|
|
|
19
19
|
def initialize(
|
|
20
20
|
propagation_style_inject:,
|
|
21
21
|
propagation_style_extract:,
|
|
22
|
+
propagation_behavior_extract:,
|
|
22
23
|
propagation_extract_first:
|
|
23
24
|
)
|
|
24
25
|
super(
|
|
@@ -37,6 +38,7 @@ module Datadog
|
|
|
37
38
|
},
|
|
38
39
|
propagation_style_inject: propagation_style_inject,
|
|
39
40
|
propagation_style_extract: propagation_style_extract,
|
|
41
|
+
propagation_behavior_extract: propagation_behavior_extract,
|
|
40
42
|
propagation_extract_first: propagation_extract_first
|
|
41
43
|
)
|
|
42
44
|
end
|
|
@@ -32,6 +32,7 @@ module Datadog
|
|
|
32
32
|
@propagation = WaterDrop::Distributed::Propagation.new(
|
|
33
33
|
propagation_style_inject: tracing.propagation_style_inject,
|
|
34
34
|
propagation_style_extract: tracing.propagation_style_extract,
|
|
35
|
+
propagation_behavior_extract: tracing.propagation_behavior_extract,
|
|
35
36
|
propagation_extract_first: tracing.propagation_extract_first
|
|
36
37
|
)
|
|
37
38
|
end
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require_relative '../ext'
|
|
3
4
|
require_relative '../metadata/ext'
|
|
4
5
|
require_relative '../trace_digest'
|
|
5
6
|
require_relative 'datadog_tags_codec'
|
|
@@ -243,7 +244,7 @@ module Datadog
|
|
|
243
244
|
# Record telemetry metrics for baggage operations
|
|
244
245
|
def record_telemetry_metric(metric_name, value, tags)
|
|
245
246
|
telemetry = ::Datadog.send(:components).telemetry
|
|
246
|
-
telemetry.inc(
|
|
247
|
+
telemetry.inc(Tracing::Ext::TELEMETRY_METRICS_NAMESPACE, metric_name, value, tags: tags)
|
|
247
248
|
end
|
|
248
249
|
end
|
|
249
250
|
end
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
require_relative '../configuration/ext'
|
|
4
4
|
require_relative '../trace_digest'
|
|
5
5
|
require_relative '../trace_operation'
|
|
6
|
+
require_relative '../span_link'
|
|
6
7
|
require_relative '../../core/telemetry/logger'
|
|
7
8
|
require_relative 'baggage'
|
|
8
9
|
|
|
@@ -13,6 +14,8 @@ module Datadog
|
|
|
13
14
|
class Propagation
|
|
14
15
|
# @param propagation_styles [Hash<String,Object>]
|
|
15
16
|
# a map of propagation styles to their corresponding implementations
|
|
17
|
+
# @param propagation_behavior_extract [String]
|
|
18
|
+
# the behavior to apply when extracting distributed trace data
|
|
16
19
|
# @param propagation_style_inject [Array<String>]
|
|
17
20
|
# a list of styles to use when injecting distributed trace data
|
|
18
21
|
# @param propagation_style_extract [Array<String>]
|
|
@@ -23,9 +26,11 @@ module Datadog
|
|
|
23
26
|
propagation_styles:,
|
|
24
27
|
propagation_style_inject:,
|
|
25
28
|
propagation_style_extract:,
|
|
29
|
+
propagation_behavior_extract:,
|
|
26
30
|
propagation_extract_first:
|
|
27
31
|
)
|
|
28
32
|
@propagation_styles = propagation_styles
|
|
33
|
+
@propagation_behavior_extract = propagation_behavior_extract
|
|
29
34
|
@propagation_extract_first = propagation_extract_first
|
|
30
35
|
@propagation_style_inject = propagation_style_inject.map { |style| propagation_styles[style] }
|
|
31
36
|
@propagation_style_extract = propagation_style_extract.map { |style| propagation_styles[style] }
|
|
@@ -97,12 +102,20 @@ module Datadog
|
|
|
97
102
|
return unless data
|
|
98
103
|
return if data.empty?
|
|
99
104
|
|
|
105
|
+
if @propagation_behavior_extract == Tracing::Configuration::Ext::Distributed::PROPAGATION_BEHAVIOR_EXTRACT_IGNORE
|
|
106
|
+
return nil
|
|
107
|
+
end
|
|
108
|
+
|
|
100
109
|
extracted_trace_digest = nil
|
|
110
|
+
# Name of the propagation style that first produced a trace context.
|
|
111
|
+
# Used as the `context_headers` span-link attribute when restarting a trace.
|
|
112
|
+
extracted_style_name = nil
|
|
101
113
|
|
|
102
114
|
@propagation_style_extract.each do |propagator|
|
|
103
115
|
# First extraction?
|
|
104
116
|
unless extracted_trace_digest
|
|
105
117
|
extracted_trace_digest = propagator.extract(data)
|
|
118
|
+
extracted_style_name = @propagation_styles.key(propagator) if extracted_trace_digest
|
|
106
119
|
next
|
|
107
120
|
end
|
|
108
121
|
|
|
@@ -145,7 +158,26 @@ module Datadog
|
|
|
145
158
|
# Handle baggage after all other styles if present
|
|
146
159
|
extracted_trace_digest = propagate_baggage(data, extracted_trace_digest) if @baggage_propagator
|
|
147
160
|
|
|
148
|
-
|
|
161
|
+
# Default mode: Current digest continues the upstream trace.
|
|
162
|
+
return extracted_trace_digest if @propagation_behavior_extract != Tracing::Configuration::Ext::Distributed::PROPAGATION_BEHAVIOR_EXTRACT_RESTART || extracted_trace_digest&.trace_id.nil?
|
|
163
|
+
|
|
164
|
+
# Restart mode: start a new local digest and create a Span Link on
|
|
165
|
+
# the service-entry span with the original propagation data.
|
|
166
|
+
link = SpanLink.new(
|
|
167
|
+
extracted_trace_digest,
|
|
168
|
+
attributes: {
|
|
169
|
+
'reason' => 'propagation_behavior_extract',
|
|
170
|
+
'context_headers' => extracted_style_name,
|
|
171
|
+
}
|
|
172
|
+
)
|
|
173
|
+
baggage_tags = extracted_trace_digest.trace_distributed_tags&.select { |k, _| k.start_with?('baggage.') }
|
|
174
|
+
baggage_tags = nil if baggage_tags&.empty?
|
|
175
|
+
TraceDigest.new(
|
|
176
|
+
span_links: [link],
|
|
177
|
+
baggage: extracted_trace_digest.baggage,
|
|
178
|
+
trace_distributed_tags: baggage_tags,
|
|
179
|
+
span_remote: false,
|
|
180
|
+
)
|
|
149
181
|
end
|
|
150
182
|
|
|
151
183
|
private
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require_relative '../../core/utils'
|
|
4
|
+
require_relative 'helpers'
|
|
5
|
+
|
|
3
6
|
module Datadog
|
|
4
7
|
module Tracing
|
|
5
8
|
module Distributed
|
|
@@ -282,8 +285,11 @@ module Datadog
|
|
|
282
285
|
trace_flags & TRACE_FLAGS_SAMPLED
|
|
283
286
|
end
|
|
284
287
|
|
|
285
|
-
# @return [
|
|
286
|
-
#
|
|
288
|
+
# @return [nil] when the tracestate is absent or has no vendor entries.
|
|
289
|
+
# @return [String] when no `dd=` entry is present, the joined vendor list.
|
|
290
|
+
# @return [Array(String, Integer, String, String, Hash, String)] when a `dd=`
|
|
291
|
+
# entry is present: [tracestate without `dd=`, sampling_priority, origin,
|
|
292
|
+
# ts_parent_id, tags, unknown_fields]. All elements past the first may be nil.
|
|
287
293
|
def extract_tracestate(tracestate)
|
|
288
294
|
vendors = split_tracestate(tracestate)
|
|
289
295
|
return unless vendors && !vendors.empty?
|
|
@@ -395,6 +401,9 @@ module Datadog
|
|
|
395
401
|
tracestate = tracestate.chop
|
|
396
402
|
end
|
|
397
403
|
|
|
404
|
+
tracestate = ::Datadog::Core::Utils.utf8_encode(tracestate, placeholder: nil)
|
|
405
|
+
return unless tracestate
|
|
406
|
+
|
|
398
407
|
vendors = tracestate.split(',', TRACESTATE_MAX_LIST_MEMBERS + 1)
|
|
399
408
|
if vendors.length > TRACESTATE_MAX_LIST_MEMBERS || remove_last_member
|
|
400
409
|
vendors.pop
|
|
@@ -15,6 +15,9 @@ module Datadog
|
|
|
15
15
|
1 << 13, # APM_TRACING_LOGS_INJECTION: Dynamic trace logs injection configuration
|
|
16
16
|
1 << 14, # APM_TRACING_HTTP_HEADER_TAGS: Dynamic trace HTTP header tags configuration
|
|
17
17
|
1 << 29, # APM_TRACING_SAMPLE_RULES: Dynamic trace sampling rules configuration
|
|
18
|
+
# APM_TRACING_ENABLE_DYNAMIC_INSTRUMENTATION (bit 38) is declared in
|
|
19
|
+
# DI::Remote.capabilities, not here, so it is registered only when DI
|
|
20
|
+
# is not explicitly disabled and the runtime supports DI.
|
|
18
21
|
].freeze
|
|
19
22
|
|
|
20
23
|
def products
|
|
@@ -25,7 +28,7 @@ module Datadog
|
|
|
25
28
|
CAPABILITIES
|
|
26
29
|
end
|
|
27
30
|
|
|
28
|
-
def process_config(config, content)
|
|
31
|
+
def process_config(config, content, repository = nil)
|
|
29
32
|
lib_config = config['lib_config']
|
|
30
33
|
|
|
31
34
|
env_vars = Datadog::Tracing::Configuration::Dynamic::OPTIONS.map do |name, env_var, option|
|
|
@@ -39,9 +42,37 @@ module Datadog
|
|
|
39
42
|
[env_var, value]
|
|
40
43
|
end
|
|
41
44
|
|
|
45
|
+
if (di_enabled = lib_config['dynamic_instrumentation_enabled']) != nil # rubocop:disable Style/NonNilCheck
|
|
46
|
+
# repository is forwarded so that an enable signal can reconcile DI
|
|
47
|
+
# against probes delivered in an earlier poll while DI was stopped
|
|
48
|
+
# (see Datadog::DI::Remote.handle_rc_enablement).
|
|
49
|
+
Datadog::DI::Remote.handle_rc_enablement(di_enabled, repository)
|
|
50
|
+
|
|
51
|
+
if di_enabled
|
|
52
|
+
# DI was just (implicitly) enabled. A Symbol Database upload signal
|
|
53
|
+
# received in an earlier poll while DI was inactive was deferred by
|
|
54
|
+
# the component's DI-active gate; re-attempt it now. Mirrors the DI
|
|
55
|
+
# probe replay in handle_rc_enablement above. allow_initialization:
|
|
56
|
+
# false because this runs on the remote-config worker thread.
|
|
57
|
+
Datadog.send(:components, allow_initialization: false)&.symbol_database&.resume_pending_upload
|
|
58
|
+
else
|
|
59
|
+
# DI was disabled via remote configuration. In the nil-default
|
|
60
|
+
# (follows-DI) case, stop Symbol Database too so its TracePoint and
|
|
61
|
+
# scheduler don't keep uploading while DI is off. An explicit
|
|
62
|
+
# symbol_database.enabled = true is independent and keeps running.
|
|
63
|
+
Datadog.send(:components, allow_initialization: false)&.symbol_database&.stop_for_di_disable
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
42
67
|
content.applied
|
|
43
68
|
|
|
44
|
-
|
|
69
|
+
# allow_initialization: false because process_config runs on the
|
|
70
|
+
# remote-config worker thread. If components haven't been built yet
|
|
71
|
+
# (e.g. during a teardown/reset window), the default `true` would
|
|
72
|
+
# synchronously build the entire component tree from this thread.
|
|
73
|
+
# The &. chain matches the pattern used by DI::Remote.handle_rc_enablement
|
|
74
|
+
# in the same dispatch path.
|
|
75
|
+
Datadog.send(:components, allow_initialization: false)&.telemetry&.client_configuration_change!(env_vars)
|
|
45
76
|
rescue => e
|
|
46
77
|
content.errored("#{e.class}: #{e.message}: #{Array(e.backtrace).join("\n")}")
|
|
47
78
|
end
|
|
@@ -55,7 +86,7 @@ module Datadog
|
|
|
55
86
|
case content.path.product
|
|
56
87
|
when PRODUCT
|
|
57
88
|
config = parse_content(content)
|
|
58
|
-
process_config(config, content)
|
|
89
|
+
process_config(config, content, repository)
|
|
59
90
|
end
|
|
60
91
|
end
|
|
61
92
|
end
|
|
@@ -22,6 +22,9 @@ module Datadog
|
|
|
22
22
|
# @!attribute [r] span_type
|
|
23
23
|
# The type of the currently active span.
|
|
24
24
|
# @return [String]
|
|
25
|
+
# @!attribute [r] span_links
|
|
26
|
+
# Span links associated with this trace context.
|
|
27
|
+
# @return [Array<Datadog::Tracing::SpanLink>, nil]
|
|
25
28
|
# @!attribute [r] trace_distributed_tags
|
|
26
29
|
# Datadog-specific tags that support richer distributed tracing association.
|
|
27
30
|
# @return [Hash<String,String>]
|
|
@@ -91,6 +94,7 @@ module Datadog
|
|
|
91
94
|
:span_resource,
|
|
92
95
|
:span_service,
|
|
93
96
|
:span_type,
|
|
97
|
+
:span_links,
|
|
94
98
|
:trace_distributed_tags,
|
|
95
99
|
:trace_hostname,
|
|
96
100
|
:trace_id,
|
|
@@ -114,6 +118,7 @@ module Datadog
|
|
|
114
118
|
span_resource: nil,
|
|
115
119
|
span_service: nil,
|
|
116
120
|
span_type: nil,
|
|
121
|
+
span_links: nil,
|
|
117
122
|
trace_distributed_tags: nil,
|
|
118
123
|
trace_hostname: nil,
|
|
119
124
|
trace_id: nil,
|
|
@@ -136,6 +141,7 @@ module Datadog
|
|
|
136
141
|
@span_resource = span_resource && span_resource.dup.freeze
|
|
137
142
|
@span_service = span_service && span_service.dup.freeze
|
|
138
143
|
@span_type = span_type && span_type.dup.freeze
|
|
144
|
+
@span_links = span_links && span_links.dup.freeze
|
|
139
145
|
@trace_distributed_tags = trace_distributed_tags && trace_distributed_tags.dup.freeze
|
|
140
146
|
@trace_hostname = trace_hostname && trace_hostname.dup.freeze
|
|
141
147
|
@trace_id = trace_id
|
|
@@ -167,6 +173,7 @@ module Datadog
|
|
|
167
173
|
span_resource: span_resource,
|
|
168
174
|
span_service: span_service,
|
|
169
175
|
span_type: span_type,
|
|
176
|
+
span_links: span_links,
|
|
170
177
|
trace_distributed_tags: trace_distributed_tags,
|
|
171
178
|
trace_hostname: trace_hostname,
|
|
172
179
|
trace_id: trace_id,
|
|
@@ -58,6 +58,7 @@ module Datadog
|
|
|
58
58
|
|
|
59
59
|
# Creates a new TraceOperation.
|
|
60
60
|
#
|
|
61
|
+
# @param span_links [Array<Datadog::Tracing::SpanLink>, nil] links to attach to the local root span.
|
|
61
62
|
# @param auto_finish [Boolean] when true, automatically finishes the trace when the local root span finishes.
|
|
62
63
|
# When false, the trace remains unfinished until {#finish!} is called.
|
|
63
64
|
# This is useful when this {TraceOperation} represents the continuation of a remote {TraceDigest},
|
|
@@ -72,6 +73,7 @@ module Datadog
|
|
|
72
73
|
name: nil,
|
|
73
74
|
origin: nil,
|
|
74
75
|
parent_span_id: nil,
|
|
76
|
+
span_links: nil,
|
|
75
77
|
rate_limiter_rate: nil,
|
|
76
78
|
resource: nil,
|
|
77
79
|
rule_sample_rate: nil,
|
|
@@ -98,7 +100,7 @@ module Datadog
|
|
|
98
100
|
@parent_span_id = parent_span_id
|
|
99
101
|
@sampled = sampled.nil? || sampled
|
|
100
102
|
@remote_parent = remote_parent
|
|
101
|
-
|
|
103
|
+
@span_links = span_links
|
|
102
104
|
# Tags
|
|
103
105
|
@agent_sample_rate = agent_sample_rate
|
|
104
106
|
@hostname = hostname
|
|
@@ -318,6 +320,7 @@ module Datadog
|
|
|
318
320
|
events: span_events,
|
|
319
321
|
on_error: on_error,
|
|
320
322
|
parent_id: parent_id,
|
|
323
|
+
links: (@root_span.nil? ? @span_links : nil),
|
|
321
324
|
resource: resource || op_name,
|
|
322
325
|
service: service,
|
|
323
326
|
start_time: start_time,
|