datadog 2.32.0 → 2.34.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 +30 -1
- data/ext/datadog_profiling_native_extension/clock_id.h +9 -1
- data/ext/datadog_profiling_native_extension/clock_id_from_mach.c +73 -0
- data/ext/datadog_profiling_native_extension/clock_id_from_pthread.c +1 -1
- data/ext/datadog_profiling_native_extension/collectors_cpu_and_wall_time_worker.c +20 -0
- data/ext/datadog_profiling_native_extension/collectors_thread_context.c +5 -1
- data/ext/datadog_profiling_native_extension/extconf.rb +3 -0
- data/ext/datadog_profiling_native_extension/macos_sampler_thread.h +55 -0
- data/ext/datadog_profiling_native_extension/stack_recorder.c +3 -9
- data/ext/datadog_profiling_native_extension/time_helpers.h +1 -0
- data/ext/libdatadog_api/crashtracker.c +2 -0
- data/ext/libdatadog_extconf_helpers.rb +1 -1
- data/lib/datadog/ai_guard/autoload.rb +10 -0
- data/lib/datadog/ai_guard/component.rb +1 -1
- data/lib/datadog/ai_guard/contrib/auto_instrument.rb +24 -0
- data/lib/datadog/ai_guard/contrib/rack/integration.rb +42 -0
- data/lib/datadog/ai_guard/contrib/rack/patcher.rb +26 -0
- data/lib/datadog/ai_guard/contrib/rack/request_middleware.rb +83 -0
- data/lib/datadog/ai_guard/contrib/rails/integration.rb +41 -0
- data/lib/datadog/ai_guard/contrib/rails/patcher.rb +97 -0
- data/lib/datadog/ai_guard/evaluation.rb +1 -0
- data/lib/datadog/ai_guard/ext.rb +1 -0
- data/lib/datadog/ai_guard.rb +8 -0
- data/lib/datadog/appsec/component.rb +4 -1
- data/lib/datadog/appsec/compressed_json.rb +2 -2
- data/lib/datadog/appsec/contrib/aws_lambda/gateway/watcher.rb +75 -0
- data/lib/datadog/appsec/contrib/aws_lambda/integration.rb +39 -0
- data/lib/datadog/appsec/contrib/aws_lambda/patcher.rb +30 -0
- data/lib/datadog/appsec/contrib/aws_lambda/waf_addresses.rb +111 -0
- data/lib/datadog/appsec/contrib/rack/ext.rb +1 -1
- data/lib/datadog/appsec.rb +1 -0
- data/lib/datadog/core/configuration/components.rb +8 -1
- data/lib/datadog/core/configuration/settings.rb +16 -1
- data/lib/datadog/core/configuration/supported_configurations.rb +12 -0
- data/lib/datadog/core/environment/ext.rb +5 -0
- data/lib/datadog/core/environment/identity.rb +15 -1
- data/lib/datadog/core/environment/process.rb +48 -27
- data/lib/datadog/core/environment/socket.rb +13 -0
- data/lib/datadog/core/remote/client/capabilities.rb +11 -2
- data/lib/datadog/core/remote/transport/http/config.rb +5 -5
- data/lib/datadog/core/telemetry/request.rb +0 -2
- data/lib/datadog/core/transport/response.rb +1 -1
- data/lib/datadog/core/utils/{base64.rb → base64_codec.rb} +3 -2
- data/lib/datadog/core/utils/hash.rb +0 -23
- data/lib/datadog/core/utils/spawn_monkey_patch.rb +46 -16
- data/lib/datadog/data_streams/pathway_context.rb +3 -3
- data/lib/datadog/di/code_tracker.rb +43 -22
- data/lib/datadog/di/contrib/active_record.rb +6 -2
- data/lib/datadog/di/instrumenter.rb +24 -4
- data/lib/datadog/di/probe_notification_builder.rb +1 -1
- data/lib/datadog/di/remote.rb +4 -4
- data/lib/datadog/di/serializer.rb +5 -5
- data/lib/datadog/di/utils.rb +42 -14
- data/lib/datadog/opentelemetry/configuration/settings.rb +65 -0
- data/lib/datadog/opentelemetry/ext.rb +9 -0
- data/lib/datadog/opentelemetry/logs.rb +98 -0
- data/lib/datadog/opentelemetry/metrics.rb +10 -37
- data/lib/datadog/opentelemetry/sdk/configurator.rb +40 -0
- data/lib/datadog/opentelemetry/sdk/id_generator.rb +16 -10
- data/lib/datadog/opentelemetry/sdk/logs_exporter.rb +37 -0
- data/lib/datadog/opentelemetry/signal_configuration.rb +53 -0
- data/lib/datadog/opentelemetry.rb +1 -0
- data/lib/datadog/profiling/component.rb +0 -1
- data/lib/datadog/profiling/stack_recorder.rb +0 -4
- data/lib/datadog/symbol_database/component.rb +409 -0
- data/lib/datadog/symbol_database/configuration.rb +2 -2
- data/lib/datadog/symbol_database/extractor.rb +45 -26
- data/lib/datadog/symbol_database/remote.rb +175 -0
- data/lib/datadog/symbol_database/scope.rb +16 -12
- data/lib/datadog/symbol_database/scope_batcher.rb +288 -0
- data/lib/datadog/symbol_database/service_version.rb +15 -6
- data/lib/datadog/symbol_database/symbol.rb +6 -3
- data/lib/datadog/symbol_database/uploader.rb +65 -8
- data/lib/datadog/tracing/contrib/action_pack/action_dispatch/instrumentation.rb +8 -0
- data/lib/datadog/tracing/contrib/active_record/events/sql.rb +0 -4
- data/lib/datadog/tracing/contrib/active_support/cache/events/cache.rb +0 -4
- data/lib/datadog/tracing/contrib/active_support/cache/instrumentation.rb +0 -4
- data/lib/datadog/tracing/contrib/aws/instrumentation.rb +0 -5
- data/lib/datadog/tracing/contrib/dalli/instrumentation.rb +0 -5
- data/lib/datadog/tracing/contrib/elasticsearch/patcher.rb +0 -5
- data/lib/datadog/tracing/contrib/ethon/easy_patch.rb +0 -5
- data/lib/datadog/tracing/contrib/ethon/multi_patch.rb +0 -8
- data/lib/datadog/tracing/contrib/excon/middleware.rb +0 -5
- data/lib/datadog/tracing/contrib/ext.rb +2 -3
- data/lib/datadog/tracing/contrib/faraday/middleware.rb +0 -5
- data/lib/datadog/tracing/contrib/grpc/datadog_interceptor/client.rb +0 -5
- data/lib/datadog/tracing/contrib/grpc/datadog_interceptor/server.rb +0 -5
- data/lib/datadog/tracing/contrib/http/instrumentation.rb +0 -5
- data/lib/datadog/tracing/contrib/httpclient/instrumentation.rb +0 -5
- data/lib/datadog/tracing/contrib/httprb/instrumentation.rb +0 -5
- data/lib/datadog/tracing/contrib/mongodb/subscribers.rb +0 -5
- data/lib/datadog/tracing/contrib/mysql2/instrumentation.rb +0 -5
- data/lib/datadog/tracing/contrib/opensearch/patcher.rb +0 -5
- data/lib/datadog/tracing/contrib/pg/instrumentation.rb +0 -5
- data/lib/datadog/tracing/contrib/presto/instrumentation.rb +0 -5
- data/lib/datadog/tracing/contrib/racecar/event.rb +0 -5
- data/lib/datadog/tracing/contrib/rack/configuration/settings.rb +6 -0
- data/lib/datadog/tracing/contrib/rack/ext.rb +27 -0
- data/lib/datadog/tracing/contrib/rack/trace_proxy_middleware.rb +117 -1
- data/lib/datadog/tracing/contrib/redis/tags.rb +0 -5
- data/lib/datadog/tracing/contrib/rest_client/request_patch.rb +0 -5
- data/lib/datadog/tracing/contrib/sequel/utils.rb +0 -5
- data/lib/datadog/tracing/contrib/trilogy/instrumentation.rb +0 -5
- data/lib/datadog/tracing/distributed/datadog_tags_codec.rb +0 -13
- data/lib/datadog/tracing/distributed/trace_context.rb +0 -28
- data/lib/datadog/tracing/metadata/ext.rb +3 -0
- data/lib/datadog/tracing/span_operation.rb +13 -0
- data/lib/datadog/tracing/trace_operation.rb +22 -0
- data/lib/datadog/tracing/tracer.rb +7 -3
- data/lib/datadog/version.rb +1 -1
- metadata +27 -8
- data/ext/datadog_profiling_native_extension/clock_id_noop.c +0 -21
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require 'json'
|
|
4
|
+
require 'securerandom'
|
|
4
5
|
require 'zlib'
|
|
5
6
|
require 'stringio'
|
|
6
7
|
require_relative '../core/environment/identity'
|
|
@@ -45,6 +46,12 @@ module Datadog
|
|
|
45
46
|
agent_settings: agent_settings,
|
|
46
47
|
logger: @logger,
|
|
47
48
|
)
|
|
49
|
+
|
|
50
|
+
# Protects the lazy initialization of @upload_pid/@upload_id and the
|
|
51
|
+
# @batch_num increment in next_upload_metadata. ScopeBatcher calls
|
|
52
|
+
# upload_scopes outside its own mutex, so two threads (e.g. a size-
|
|
53
|
+
# triggered flush and the timer/shutdown path) can race here.
|
|
54
|
+
@metadata_mutex = Mutex.new
|
|
48
55
|
end
|
|
49
56
|
|
|
50
57
|
# Upload a batch of scopes to the agent.
|
|
@@ -56,9 +63,13 @@ module Datadog
|
|
|
56
63
|
def upload_scopes(scopes)
|
|
57
64
|
return if scopes.empty?
|
|
58
65
|
|
|
59
|
-
|
|
66
|
+
upload_id, batch_num = next_upload_metadata
|
|
67
|
+
json_data = build_symbol_payload(scopes, upload_id: upload_id, batch_num: batch_num)
|
|
60
68
|
compressed_data = Zlib.gzip(json_data)
|
|
61
69
|
|
|
70
|
+
# Emitted unconditionally so the rare oversized case is observable.
|
|
71
|
+
@telemetry&.distribution('tracers', 'symbol_database.payload_size', compressed_data.bytesize)
|
|
72
|
+
|
|
62
73
|
# Symbols for very large applications (>50MB after gzip) are dropped:
|
|
63
74
|
# the upload is skipped and the customer sees no autocomplete /
|
|
64
75
|
# symbol probe results for those classes. Java handles the same case
|
|
@@ -69,7 +80,7 @@ module Datadog
|
|
|
69
80
|
return
|
|
70
81
|
end
|
|
71
82
|
|
|
72
|
-
perform_http_upload(compressed_data, scopes.size)
|
|
83
|
+
perform_http_upload(compressed_data, scopes.size, upload_id: upload_id, batch_num: batch_num)
|
|
73
84
|
rescue => e
|
|
74
85
|
@logger.debug { "symdb: upload failed: #{e.class}: #{e.message}" }
|
|
75
86
|
@telemetry&.report(e, description: 'symdb: upload failed')
|
|
@@ -79,31 +90,44 @@ module Datadog
|
|
|
79
90
|
|
|
80
91
|
# Build JSON payload from scopes.
|
|
81
92
|
# @param scopes [Array<Scope>] Scopes to serialize
|
|
93
|
+
# @param upload_id [String] UUID identifying the logical upload
|
|
94
|
+
# @param batch_num [Integer] 1-indexed batch number within the upload
|
|
82
95
|
# @return [String] JSON string
|
|
83
|
-
def build_symbol_payload(scopes)
|
|
96
|
+
def build_symbol_payload(scopes, upload_id:, batch_num:)
|
|
84
97
|
ServiceVersion.new(
|
|
85
98
|
service: @settings.service,
|
|
86
99
|
env: @settings.env,
|
|
87
100
|
version: @settings.version,
|
|
88
101
|
scopes: scopes,
|
|
102
|
+
upload_id: upload_id,
|
|
103
|
+
batch_num: batch_num,
|
|
104
|
+
# Always false: the Ruby tracer continuously uploads new code
|
|
105
|
+
# as files are loaded; there is no defined end-of-upload point.
|
|
106
|
+
final: false,
|
|
89
107
|
).to_json
|
|
90
108
|
end
|
|
91
109
|
|
|
92
110
|
# Perform HTTP POST with multipart form-data via transport layer.
|
|
93
111
|
# @param compressed_data [String] GZIP compressed JSON payload
|
|
94
112
|
# @param scope_count [Integer] Number of scopes (for logging)
|
|
113
|
+
# @param upload_id [String] UUID identifying the logical upload
|
|
114
|
+
# @param batch_num [Integer] 1-indexed batch number within the upload
|
|
95
115
|
# @return [void]
|
|
96
|
-
def perform_http_upload(compressed_data, scope_count)
|
|
97
|
-
form = build_multipart_form(compressed_data)
|
|
116
|
+
def perform_http_upload(compressed_data, scope_count, upload_id:, batch_num:)
|
|
117
|
+
form = build_multipart_form(compressed_data, upload_id: upload_id, batch_num: batch_num)
|
|
98
118
|
response = @transport.send_symbols(form)
|
|
99
119
|
handle_response(response, scope_count)
|
|
100
120
|
end
|
|
101
121
|
|
|
102
122
|
# Build multipart form-data with event metadata and compressed symbols.
|
|
103
123
|
# @param compressed_data [String] GZIP compressed JSON payload
|
|
124
|
+
# @param upload_id [String] UUID identifying the logical upload
|
|
125
|
+
# @param batch_num [Integer] 1-indexed batch number within the upload
|
|
104
126
|
# @return [Hash] Form data hash with UploadIO objects
|
|
105
|
-
def build_multipart_form(compressed_data)
|
|
106
|
-
event_io = StringIO.new(
|
|
127
|
+
def build_multipart_form(compressed_data, upload_id:, batch_num:)
|
|
128
|
+
event_io = StringIO.new(
|
|
129
|
+
build_event_metadata(compressed_data.bytesize, upload_id: upload_id, batch_num: batch_num),
|
|
130
|
+
)
|
|
107
131
|
file_io = StringIO.new(compressed_data)
|
|
108
132
|
|
|
109
133
|
event_upload = Datadog::Core::Vendor::Multipart::Post::UploadIO.new(
|
|
@@ -125,17 +149,50 @@ module Datadog
|
|
|
125
149
|
end
|
|
126
150
|
|
|
127
151
|
# Build event.json metadata part.
|
|
152
|
+
# @param attachment_size [Integer] Size of the compressed attachment in bytes
|
|
153
|
+
# @param upload_id [String] UUID identifying the logical upload
|
|
154
|
+
# @param batch_num [Integer] 1-indexed batch number within the upload
|
|
128
155
|
# @return [String] JSON string for event metadata
|
|
129
|
-
def build_event_metadata
|
|
156
|
+
def build_event_metadata(attachment_size, upload_id:, batch_num:)
|
|
130
157
|
JSON.generate(
|
|
131
158
|
ddsource: 'ruby',
|
|
132
159
|
service: @settings.service,
|
|
160
|
+
version: @settings.version,
|
|
161
|
+
language: 'ruby',
|
|
133
162
|
runtimeId: Datadog::Core::Environment::Identity.id,
|
|
134
163
|
parentId: nil, # Fork tracking deferred for MVP
|
|
135
164
|
type: 'symdb',
|
|
165
|
+
uploadId: upload_id,
|
|
166
|
+
batchNum: batch_num,
|
|
167
|
+
# Always false: the Ruby tracer continuously uploads new code
|
|
168
|
+
# as files are loaded; there is no defined end-of-upload point.
|
|
169
|
+
final: false,
|
|
170
|
+
attachmentSize: attachment_size,
|
|
136
171
|
)
|
|
137
172
|
end
|
|
138
173
|
|
|
174
|
+
# Return [upload_id, batch_num] for the current process. upload_id is
|
|
175
|
+
# generated lazily on first use and shared by all batches uploaded from
|
|
176
|
+
# the process. A forked child observes a different Process.pid and
|
|
177
|
+
# therefore gets a fresh upload_id and batch counter.
|
|
178
|
+
# Synchronized: ScopeBatcher releases its mutex before calling
|
|
179
|
+
# upload_scopes, so this can be entered concurrently.
|
|
180
|
+
# @return [Array<(String, Integer)>]
|
|
181
|
+
def next_upload_metadata
|
|
182
|
+
@metadata_mutex.synchronize do
|
|
183
|
+
if @upload_pid != Process.pid
|
|
184
|
+
@upload_pid = Process.pid
|
|
185
|
+
@upload_id = SecureRandom.uuid.freeze
|
|
186
|
+
@batch_num = 0
|
|
187
|
+
end
|
|
188
|
+
@batch_num += 1 # steep:ignore NoMethod
|
|
189
|
+
# @upload_id and @batch_num are non-nil after the branch above; refine for Steep.
|
|
190
|
+
upload_id = @upload_id or raise('unreachable: @upload_id should be set')
|
|
191
|
+
batch_num = @batch_num or raise('unreachable: @batch_num should be set')
|
|
192
|
+
[upload_id, batch_num]
|
|
193
|
+
end
|
|
194
|
+
end
|
|
195
|
+
|
|
139
196
|
# Handle HTTP response and track metrics.
|
|
140
197
|
# @param response [Core::Transport::Response] HTTP response from agent
|
|
141
198
|
# @param scope_count [Integer] Number of scopes uploaded
|
|
@@ -11,6 +11,8 @@ module Datadog
|
|
|
11
11
|
module Instrumentation
|
|
12
12
|
SCRIPT_NAME_KEY = 'SCRIPT_NAME'
|
|
13
13
|
FORMAT_SUFFIX = '(.:format)'
|
|
14
|
+
# NOTE: Rails 8.1.1+ natively provides the same object via 'action_dispatch.route'.
|
|
15
|
+
DATADOG_RAILS_ROUTE_ENV_KEY = 'datadog.action_dispatch.route'
|
|
14
16
|
|
|
15
17
|
module_function
|
|
16
18
|
|
|
@@ -48,6 +50,8 @@ module Datadog
|
|
|
48
50
|
result.each do |_, _, route|
|
|
49
51
|
next unless Instrumentation.dispatcher_route?(route)
|
|
50
52
|
|
|
53
|
+
req.env[DATADOG_RAILS_ROUTE_ENV_KEY] = route
|
|
54
|
+
|
|
51
55
|
http_route = route.path.spec.to_s
|
|
52
56
|
http_route.delete_suffix!(FORMAT_SUFFIX)
|
|
53
57
|
|
|
@@ -66,6 +70,8 @@ module Datadog
|
|
|
66
70
|
def find_routes(req)
|
|
67
71
|
super do |match, parameters, route|
|
|
68
72
|
if Instrumentation.dispatcher_route?(route)
|
|
73
|
+
req.env[DATADOG_RAILS_ROUTE_ENV_KEY] = route
|
|
74
|
+
|
|
69
75
|
http_route = route.path.spec.to_s
|
|
70
76
|
http_route.delete_suffix!(FORMAT_SUFFIX)
|
|
71
77
|
|
|
@@ -86,6 +92,8 @@ module Datadog
|
|
|
86
92
|
|
|
87
93
|
super do |route, parameters|
|
|
88
94
|
if Instrumentation.dispatcher_route?(route)
|
|
95
|
+
req.env[DATADOG_RAILS_ROUTE_ENV_KEY] = route
|
|
96
|
+
|
|
89
97
|
http_route = route.path.spec.to_s
|
|
90
98
|
http_route = http_route.delete_suffix(FORMAT_SUFFIX)
|
|
91
99
|
|
|
@@ -48,10 +48,6 @@ module Datadog
|
|
|
48
48
|
span.set_tag(Tracing::Metadata::Ext::TAG_COMPONENT, Ext::TAG_COMPONENT)
|
|
49
49
|
span.set_tag(Tracing::Metadata::Ext::TAG_OPERATION, Ext::TAG_OPERATION_SQL)
|
|
50
50
|
|
|
51
|
-
if service_name != Datadog.configuration.service
|
|
52
|
-
span.set_tag(Tracing::Contrib::Ext::Metadata::TAG_BASE_SERVICE, Datadog.configuration.service)
|
|
53
|
-
end
|
|
54
|
-
|
|
55
51
|
# Set analytics sample rate
|
|
56
52
|
if Contrib::Analytics.enabled?(configuration[:analytics_enabled])
|
|
57
53
|
Contrib::Analytics.set_sample_rate(span, configuration[:analytics_sample_rate])
|
|
@@ -82,10 +82,6 @@ module Datadog
|
|
|
82
82
|
span.set_tag(Tracing::Metadata::Ext::TAG_COMPONENT, Ext::TAG_COMPONENT)
|
|
83
83
|
span.set_tag(Tracing::Metadata::Ext::TAG_OPERATION, Ext::TAG_OPERATION_CACHE)
|
|
84
84
|
|
|
85
|
-
if span.service != Datadog.configuration.service
|
|
86
|
-
span.set_tag(Tracing::Contrib::Ext::Metadata::TAG_BASE_SERVICE, Datadog.configuration.service)
|
|
87
|
-
end
|
|
88
|
-
|
|
89
85
|
span.set_tag(Ext::TAG_CACHE_BACKEND, cache_backend(store))
|
|
90
86
|
|
|
91
87
|
span.set_tag('EVENT', event)
|
|
@@ -54,10 +54,6 @@ module Datadog
|
|
|
54
54
|
span.set_tag(Tracing::Metadata::Ext::TAG_COMPONENT, Ext::TAG_COMPONENT)
|
|
55
55
|
span.set_tag(Tracing::Metadata::Ext::TAG_OPERATION, Ext::TAG_OPERATION_CACHE)
|
|
56
56
|
|
|
57
|
-
if span.service != Datadog.configuration.service
|
|
58
|
-
span.set_tag(Tracing::Contrib::Ext::Metadata::TAG_BASE_SERVICE, Datadog.configuration.service)
|
|
59
|
-
end
|
|
60
|
-
|
|
61
57
|
span.set_tag(Ext::TAG_CACHE_BACKEND, store) if store
|
|
62
58
|
|
|
63
59
|
set_cache_key(span, key, multi_key) if Datadog.configuration.tracing[:active_support][:cache_key].enabled
|
|
@@ -61,11 +61,6 @@ module Datadog
|
|
|
61
61
|
)
|
|
62
62
|
end
|
|
63
63
|
|
|
64
|
-
# Tag original global service name if not used
|
|
65
|
-
if span.service != Datadog.configuration.service
|
|
66
|
-
span.set_tag(Tracing::Contrib::Ext::Metadata::TAG_BASE_SERVICE, Datadog.configuration.service)
|
|
67
|
-
end
|
|
68
|
-
|
|
69
64
|
span.set_tag(Tracing::Metadata::Ext::TAG_KIND, Tracing::Metadata::Ext::SpanKind::TAG_CLIENT)
|
|
70
65
|
|
|
71
66
|
span.set_tag(Tracing::Metadata::Ext::TAG_COMPONENT, Ext::TAG_COMPONENT)
|
|
@@ -31,11 +31,6 @@ module Datadog
|
|
|
31
31
|
)
|
|
32
32
|
end
|
|
33
33
|
|
|
34
|
-
# Tag original global service name if not used
|
|
35
|
-
if span.service != Datadog.configuration.service
|
|
36
|
-
span.set_tag(Tracing::Contrib::Ext::Metadata::TAG_BASE_SERVICE, Datadog.configuration.service)
|
|
37
|
-
end
|
|
38
|
-
|
|
39
34
|
span.set_tag(Tracing::Metadata::Ext::TAG_KIND, Tracing::Metadata::Ext::SpanKind::TAG_CLIENT)
|
|
40
35
|
|
|
41
36
|
span.set_tag(Tracing::Metadata::Ext::TAG_COMPONENT, Ext::TAG_COMPONENT)
|
|
@@ -66,11 +66,6 @@ module Datadog
|
|
|
66
66
|
)
|
|
67
67
|
end
|
|
68
68
|
|
|
69
|
-
# Tag original global service name if not used
|
|
70
|
-
if span.service != Datadog.configuration.service
|
|
71
|
-
span.set_tag(Tracing::Contrib::Ext::Metadata::TAG_BASE_SERVICE, Datadog.configuration.service)
|
|
72
|
-
end
|
|
73
|
-
|
|
74
69
|
span.type = Datadog::Tracing::Contrib::Elasticsearch::Ext::SPAN_TYPE_QUERY
|
|
75
70
|
|
|
76
71
|
span.set_tag(Tracing::Metadata::Ext::TAG_COMPONENT, Ext::TAG_COMPONENT)
|
|
@@ -144,11 +144,6 @@ module Datadog
|
|
|
144
144
|
)
|
|
145
145
|
end
|
|
146
146
|
|
|
147
|
-
# Tag original global service name if not used
|
|
148
|
-
if span.service != Datadog.configuration.service
|
|
149
|
-
span.set_tag(Tracing::Contrib::Ext::Metadata::TAG_BASE_SERVICE, Datadog.configuration.service)
|
|
150
|
-
end
|
|
151
|
-
|
|
152
147
|
# Set analytics sample rate
|
|
153
148
|
Contrib::Analytics.set_sample_rate(span, analytics_sample_rate) if analytics_enabled?
|
|
154
149
|
|
|
@@ -69,14 +69,6 @@ module Datadog
|
|
|
69
69
|
|
|
70
70
|
@datadog_multi_span.set_tag(Tracing::Metadata::Ext::TAG_KIND, Tracing::Metadata::Ext::SpanKind::TAG_CLIENT)
|
|
71
71
|
|
|
72
|
-
# Tag original global service name if not used
|
|
73
|
-
if @datadog_multi_span.service != Datadog.configuration.service
|
|
74
|
-
@datadog_multi_span.set_tag(
|
|
75
|
-
Tracing::Contrib::Ext::Metadata::TAG_BASE_SERVICE,
|
|
76
|
-
Datadog.configuration.service
|
|
77
|
-
)
|
|
78
|
-
end
|
|
79
|
-
|
|
80
72
|
# Set analytics sample rate
|
|
81
73
|
Contrib::Analytics.set_sample_rate(@datadog_multi_span, analytics_sample_rate) if analytics_enabled?
|
|
82
74
|
|
|
@@ -128,11 +128,6 @@ module Datadog
|
|
|
128
128
|
)
|
|
129
129
|
end
|
|
130
130
|
|
|
131
|
-
# Tag original global service name if not used
|
|
132
|
-
if span.service != Datadog.configuration.service
|
|
133
|
-
span.set_tag(Tracing::Contrib::Ext::Metadata::TAG_BASE_SERVICE, Datadog.configuration.service)
|
|
134
|
-
end
|
|
135
|
-
|
|
136
131
|
span.set_tag(Tracing::Metadata::Ext::TAG_KIND, Tracing::Metadata::Ext::SpanKind::TAG_CLIENT)
|
|
137
132
|
|
|
138
133
|
span.set_tag(Tracing::Metadata::Ext::TAG_COMPONENT, Ext::TAG_COMPONENT)
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require_relative '../metadata/ext'
|
|
4
|
+
|
|
3
5
|
module Datadog
|
|
4
6
|
module Tracing
|
|
5
7
|
module Contrib
|
|
@@ -60,9 +62,6 @@ module Datadog
|
|
|
60
62
|
|
|
61
63
|
# Value of tag from which peer.service value was remapped from
|
|
62
64
|
TAG_PEER_SERVICE_REMAP = '_dd.peer.service.remapped_from'
|
|
63
|
-
|
|
64
|
-
# Set equal to the global service when contrib span.service is overriden
|
|
65
|
-
TAG_BASE_SERVICE = '_dd.base_service'
|
|
66
65
|
end
|
|
67
66
|
end
|
|
68
67
|
end
|
|
@@ -56,11 +56,6 @@ module Datadog
|
|
|
56
56
|
)
|
|
57
57
|
end
|
|
58
58
|
|
|
59
|
-
# Tag original global service name if not used
|
|
60
|
-
if span.service != Datadog.configuration.service
|
|
61
|
-
span.set_tag(Tracing::Contrib::Ext::Metadata::TAG_BASE_SERVICE, Datadog.configuration.service)
|
|
62
|
-
end
|
|
63
|
-
|
|
64
59
|
span.set_tag(Tracing::Metadata::Ext::TAG_KIND, Tracing::Metadata::Ext::SpanKind::TAG_CLIENT)
|
|
65
60
|
|
|
66
61
|
span.set_tag(Tracing::Metadata::Ext::TAG_COMPONENT, Ext::TAG_COMPONENT)
|
|
@@ -59,11 +59,6 @@ module Datadog
|
|
|
59
59
|
)
|
|
60
60
|
end
|
|
61
61
|
|
|
62
|
-
# Tag original global service name if not used
|
|
63
|
-
if span.service != Datadog.configuration.service
|
|
64
|
-
span.set_tag(Tracing::Contrib::Ext::Metadata::TAG_BASE_SERVICE, Datadog.configuration.service)
|
|
65
|
-
end
|
|
66
|
-
|
|
67
62
|
span.set_tag(Tracing::Metadata::Ext::TAG_KIND, Tracing::Metadata::Ext::SpanKind::TAG_CLIENT)
|
|
68
63
|
span.set_tag(Tracing::Metadata::Ext::TAG_COMPONENT, Ext::TAG_COMPONENT)
|
|
69
64
|
span.set_tag(Tracing::Metadata::Ext::TAG_OPERATION, Ext::TAG_OPERATION_CLIENT)
|
|
@@ -66,11 +66,6 @@ module Datadog
|
|
|
66
66
|
span.set_tag(header, value)
|
|
67
67
|
end
|
|
68
68
|
|
|
69
|
-
# Tag original global service name if not used
|
|
70
|
-
if span.service != Datadog.configuration.service
|
|
71
|
-
span.set_tag(Tracing::Contrib::Ext::Metadata::TAG_BASE_SERVICE, Datadog.configuration.service)
|
|
72
|
-
end
|
|
73
|
-
|
|
74
69
|
span.set_tag(Tracing::Metadata::Ext::TAG_KIND, Tracing::Metadata::Ext::SpanKind::TAG_SERVER)
|
|
75
70
|
span.set_tag(Tracing::Metadata::Ext::TAG_COMPONENT, Ext::TAG_COMPONENT)
|
|
76
71
|
span.set_tag(Tracing::Metadata::Ext::TAG_OPERATION, Ext::TAG_OPERATION_SERVICE)
|
|
@@ -63,11 +63,6 @@ module Datadog
|
|
|
63
63
|
)
|
|
64
64
|
end
|
|
65
65
|
|
|
66
|
-
# Tag original global service name if not used
|
|
67
|
-
if span.service != Datadog.configuration.service
|
|
68
|
-
span.set_tag(Tracing::Contrib::Ext::Metadata::TAG_BASE_SERVICE, Datadog.configuration.service)
|
|
69
|
-
end
|
|
70
|
-
|
|
71
66
|
span.set_tag(Tracing::Metadata::Ext::TAG_KIND, Tracing::Metadata::Ext::SpanKind::TAG_CLIENT)
|
|
72
67
|
|
|
73
68
|
span.set_tag(Tracing::Metadata::Ext::TAG_COMPONENT, Ext::TAG_COMPONENT)
|
|
@@ -68,11 +68,6 @@ module Datadog
|
|
|
68
68
|
)
|
|
69
69
|
end
|
|
70
70
|
|
|
71
|
-
# Tag original global service name if not used
|
|
72
|
-
if span.service != Datadog.configuration.service
|
|
73
|
-
span.set_tag(Tracing::Contrib::Ext::Metadata::TAG_BASE_SERVICE, Datadog.configuration.service)
|
|
74
|
-
end
|
|
75
|
-
|
|
76
71
|
span.set_tag(Tracing::Metadata::Ext::TAG_COMPONENT, Ext::TAG_COMPONENT)
|
|
77
72
|
span.set_tag(Tracing::Metadata::Ext::TAG_OPERATION, Ext::TAG_OPERATION_REQUEST)
|
|
78
73
|
|
|
@@ -66,11 +66,6 @@ module Datadog
|
|
|
66
66
|
)
|
|
67
67
|
end
|
|
68
68
|
|
|
69
|
-
# Tag original global service name if not used
|
|
70
|
-
if span.service != Datadog.configuration.service
|
|
71
|
-
span.set_tag(Tracing::Contrib::Ext::Metadata::TAG_BASE_SERVICE, Datadog.configuration.service)
|
|
72
|
-
end
|
|
73
|
-
|
|
74
69
|
span.set_tag(Tracing::Metadata::Ext::TAG_COMPONENT, Ext::TAG_COMPONENT)
|
|
75
70
|
span.set_tag(Tracing::Metadata::Ext::TAG_OPERATION, Ext::TAG_OPERATION_REQUEST)
|
|
76
71
|
|
|
@@ -41,11 +41,6 @@ module Datadog
|
|
|
41
41
|
)
|
|
42
42
|
end
|
|
43
43
|
|
|
44
|
-
# Tag original global service name if not used
|
|
45
|
-
if span.service != Datadog.configuration.service
|
|
46
|
-
span.set_tag(Tracing::Contrib::Ext::Metadata::TAG_BASE_SERVICE, Datadog.configuration.service)
|
|
47
|
-
end
|
|
48
|
-
|
|
49
44
|
span.set_tag(Contrib::Ext::DB::TAG_SYSTEM, Ext::TAG_SYSTEM)
|
|
50
45
|
|
|
51
46
|
span.set_tag(Tracing::Metadata::Ext::TAG_KIND, Tracing::Metadata::Ext::SpanKind::TAG_CLIENT)
|
|
@@ -34,11 +34,6 @@ module Datadog
|
|
|
34
34
|
)
|
|
35
35
|
end
|
|
36
36
|
|
|
37
|
-
# Tag original global service name if not used
|
|
38
|
-
if span.service != Datadog.configuration.service
|
|
39
|
-
span.set_tag(Tracing::Contrib::Ext::Metadata::TAG_BASE_SERVICE, Datadog.configuration.service)
|
|
40
|
-
end
|
|
41
|
-
|
|
42
37
|
span.set_tag(Contrib::Ext::DB::TAG_SYSTEM, Ext::TAG_SYSTEM)
|
|
43
38
|
span.set_tag(Tracing::Metadata::Ext::TAG_KIND, Tracing::Metadata::Ext::SpanKind::TAG_CLIENT)
|
|
44
39
|
|
|
@@ -62,11 +62,6 @@ module Datadog
|
|
|
62
62
|
)
|
|
63
63
|
end
|
|
64
64
|
|
|
65
|
-
# Tag original global service name if not used
|
|
66
|
-
if span.service != Datadog.configuration.service
|
|
67
|
-
span.set_tag(Tracing::Contrib::Ext::Metadata::TAG_BASE_SERVICE, Datadog.configuration.service)
|
|
68
|
-
end
|
|
69
|
-
|
|
70
65
|
# Set url tags
|
|
71
66
|
span.set_tag(OpenSearch::Ext::TAG_URL, url)
|
|
72
67
|
span.set_tag(OpenSearch::Ext::TAG_HOST, host)
|
|
@@ -160,11 +160,6 @@ module Datadog
|
|
|
160
160
|
)
|
|
161
161
|
end
|
|
162
162
|
|
|
163
|
-
# Tag original global service name if not used
|
|
164
|
-
if span.service != Datadog.configuration.service
|
|
165
|
-
span.set_tag(Tracing::Contrib::Ext::Metadata::TAG_BASE_SERVICE, Datadog.configuration.service)
|
|
166
|
-
end
|
|
167
|
-
|
|
168
163
|
span.set_tag(Tracing::Metadata::Ext::TAG_COMPONENT, Ext::TAG_COMPONENT)
|
|
169
164
|
span.set_tag(Tracing::Metadata::Ext::TAG_OPERATION, Ext::TAG_OPERATION_QUERY)
|
|
170
165
|
span.set_tag(Tracing::Metadata::Ext::TAG_KIND, Tracing::Metadata::Ext::SpanKind::TAG_CLIENT)
|
|
@@ -92,11 +92,6 @@ module Datadog
|
|
|
92
92
|
)
|
|
93
93
|
end
|
|
94
94
|
|
|
95
|
-
# Tag original global service name if not used
|
|
96
|
-
if span.service != Datadog.configuration.service
|
|
97
|
-
span.set_tag(Tracing::Contrib::Ext::Metadata::TAG_BASE_SERVICE, Datadog.configuration.service)
|
|
98
|
-
end
|
|
99
|
-
|
|
100
95
|
if (host_port = @options[:server])
|
|
101
96
|
host, port = Core::Utils.extract_host_port(host_port)
|
|
102
97
|
if host && port
|
|
@@ -48,11 +48,6 @@ module Datadog
|
|
|
48
48
|
# Measure service stats
|
|
49
49
|
Contrib::Analytics.set_measured(span)
|
|
50
50
|
|
|
51
|
-
# Tag original global service name if not used
|
|
52
|
-
if span.service != Datadog.configuration.service
|
|
53
|
-
span.set_tag(Tracing::Contrib::Ext::Metadata::TAG_BASE_SERVICE, Datadog.configuration.service)
|
|
54
|
-
end
|
|
55
|
-
|
|
56
51
|
span.set_tag(Ext::TAG_TOPIC, payload[:topic])
|
|
57
52
|
span.set_tag(Ext::TAG_CONSUMER, payload[:consumer_class])
|
|
58
53
|
span.set_tag(Ext::TAG_PARTITION, payload[:partition])
|
|
@@ -54,6 +54,12 @@ module Datadog
|
|
|
54
54
|
o.type :string, nilable: true
|
|
55
55
|
end
|
|
56
56
|
|
|
57
|
+
option :inferred_proxy_enabled do |o|
|
|
58
|
+
o.type :bool
|
|
59
|
+
o.env Ext::ENV_INFERRED_PROXY_ENABLED
|
|
60
|
+
o.default false
|
|
61
|
+
end
|
|
62
|
+
|
|
57
63
|
option :web_service_name, default: Ext::DEFAULT_PEER_WEBSERVER_SERVICE_NAME, type: :string
|
|
58
64
|
end
|
|
59
65
|
end
|
|
@@ -9,6 +9,7 @@ module Datadog
|
|
|
9
9
|
module Ext
|
|
10
10
|
ENV_ENABLED = 'DD_TRACE_RACK_ENABLED'
|
|
11
11
|
ENV_DISTRIBUTED_TRACING = 'DD_TRACE_RACK_DISTRIBUTED_TRACING'
|
|
12
|
+
ENV_INFERRED_PROXY_ENABLED = 'DD_TRACE_INFERRED_PROXY_SERVICES_ENABLED'
|
|
12
13
|
# @!visibility private
|
|
13
14
|
ENV_ANALYTICS_ENABLED = 'DD_TRACE_RACK_ANALYTICS_ENABLED'
|
|
14
15
|
ENV_ANALYTICS_SAMPLE_RATE = 'DD_TRACE_RACK_ANALYTICS_SAMPLE_RATE'
|
|
@@ -24,6 +25,32 @@ module Datadog
|
|
|
24
25
|
TAG_OPERATION_HTTP_SERVER_QUEUE = 'queue'
|
|
25
26
|
WEBSERVER_APP = 'webserver'
|
|
26
27
|
DEFAULT_PEER_WEBSERVER_SERVICE_NAME = 'web-server'
|
|
28
|
+
|
|
29
|
+
# @!visibility private
|
|
30
|
+
HEADER_X_DD_PROXY = 'HTTP_X_DD_PROXY'
|
|
31
|
+
HEADER_X_DD_PROXY_REQUEST_TIME_MS = 'HTTP_X_DD_PROXY_REQUEST_TIME_MS'
|
|
32
|
+
HEADER_X_DD_PROXY_PATH = 'HTTP_X_DD_PROXY_PATH'
|
|
33
|
+
HEADER_X_DD_PROXY_RESOURCE_PATH = 'HTTP_X_DD_PROXY_RESOURCE_PATH'
|
|
34
|
+
HEADER_X_DD_PROXY_HTTPMETHOD = 'HTTP_X_DD_PROXY_HTTPMETHOD'
|
|
35
|
+
HEADER_X_DD_PROXY_DOMAIN_NAME = 'HTTP_X_DD_PROXY_DOMAIN_NAME'
|
|
36
|
+
HEADER_X_DD_PROXY_STAGE = 'HTTP_X_DD_PROXY_STAGE'
|
|
37
|
+
HEADER_X_DD_PROXY_ACCOUNT_ID = 'HTTP_X_DD_PROXY_ACCOUNT_ID'
|
|
38
|
+
HEADER_X_DD_PROXY_API_ID = 'HTTP_X_DD_PROXY_API_ID'
|
|
39
|
+
HEADER_X_DD_PROXY_REGION = 'HTTP_X_DD_PROXY_REGION'
|
|
40
|
+
HEADER_X_DD_PROXY_USER = 'HTTP_X_DD_PROXY_USER'
|
|
41
|
+
|
|
42
|
+
PROXY_AWS_APIGATEWAY = 'aws-apigateway'
|
|
43
|
+
PROXY_AWS_HTTPAPI = 'aws-httpapi'
|
|
44
|
+
|
|
45
|
+
SPAN_AWS_APIGATEWAY = 'aws.apigateway'
|
|
46
|
+
SPAN_AWS_HTTPAPI = 'aws.httpapi'
|
|
47
|
+
|
|
48
|
+
PROXY_SPAN_NAMES = {
|
|
49
|
+
PROXY_AWS_APIGATEWAY => SPAN_AWS_APIGATEWAY,
|
|
50
|
+
PROXY_AWS_HTTPAPI => SPAN_AWS_HTTPAPI,
|
|
51
|
+
}.freeze
|
|
52
|
+
|
|
53
|
+
TAG_INFERRED_SPAN = '_dd.inferred_span'
|
|
27
54
|
end
|
|
28
55
|
end
|
|
29
56
|
end
|
|
@@ -13,7 +13,11 @@ module Datadog
|
|
|
13
13
|
module TraceProxyMiddleware
|
|
14
14
|
module_function
|
|
15
15
|
|
|
16
|
-
def call(env, configuration)
|
|
16
|
+
def call(env, configuration, &block)
|
|
17
|
+
if configuration[:inferred_proxy_enabled] &&
|
|
18
|
+
(proxy_type = env[Ext::HEADER_X_DD_PROXY]) && !proxy_type.empty?
|
|
19
|
+
return call_with_inferred_proxy(env, proxy_type, &block)
|
|
20
|
+
end
|
|
17
21
|
return yield unless configuration[:request_queuing]
|
|
18
22
|
|
|
19
23
|
# parse the request queue time
|
|
@@ -51,6 +55,118 @@ module Datadog
|
|
|
51
55
|
queue_span&.finish
|
|
52
56
|
request_span&.finish
|
|
53
57
|
end
|
|
58
|
+
|
|
59
|
+
# Creates a virtual parent span representing the upstream proxy
|
|
60
|
+
# that wraps the actual request processing.
|
|
61
|
+
#
|
|
62
|
+
# rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
63
|
+
def call_with_inferred_proxy(env, proxy_type)
|
|
64
|
+
span_name = Ext::PROXY_SPAN_NAMES[proxy_type]
|
|
65
|
+
return yield unless span_name
|
|
66
|
+
|
|
67
|
+
request_time_ms = env[Ext::HEADER_X_DD_PROXY_REQUEST_TIME_MS].to_f
|
|
68
|
+
return yield unless request_time_ms.positive?
|
|
69
|
+
|
|
70
|
+
path = env[Ext::HEADER_X_DD_PROXY_PATH]
|
|
71
|
+
stage = env[Ext::HEADER_X_DD_PROXY_STAGE]
|
|
72
|
+
domain = env[Ext::HEADER_X_DD_PROXY_DOMAIN_NAME]
|
|
73
|
+
http_method = env[Ext::HEADER_X_DD_PROXY_HTTPMETHOD]
|
|
74
|
+
resource_path = env[Ext::HEADER_X_DD_PROXY_RESOURCE_PATH]
|
|
75
|
+
|
|
76
|
+
# NOTE: resource_path is the parameterized route (e.g. /users/{id}) vs literal path
|
|
77
|
+
resource = "#{http_method} #{resource_path || path}" if http_method
|
|
78
|
+
|
|
79
|
+
inferred_span = Tracing.trace(
|
|
80
|
+
span_name,
|
|
81
|
+
service: domain,
|
|
82
|
+
type: Tracing::Metadata::Ext::AppTypes::TYPE_WEB,
|
|
83
|
+
start_time: Time.at(request_time_ms / 1_000),
|
|
84
|
+
)
|
|
85
|
+
inferred_span.resource = resource if resource
|
|
86
|
+
inferred_span.set_tag(Tracing::Metadata::Ext::TAG_COMPONENT, proxy_type)
|
|
87
|
+
inferred_span.set_tag(Tracing::Metadata::Ext::TAG_KIND, Tracing::Metadata::Ext::SpanKind::TAG_SERVER)
|
|
88
|
+
inferred_span.set_tag('stage', stage) if stage
|
|
89
|
+
inferred_span.set_tag(Tracing::Metadata::Ext::HTTP::TAG_METHOD, http_method) if http_method
|
|
90
|
+
inferred_span.set_tag(Tracing::Metadata::Ext::HTTP::TAG_URL, "https://#{domain}#{path}") if domain && path
|
|
91
|
+
inferred_span.set_tag(Tracing::Metadata::Ext::HTTP::TAG_ROUTE, resource_path) if resource_path
|
|
92
|
+
inferred_span.set_metric(Ext::TAG_INFERRED_SPAN, 1)
|
|
93
|
+
|
|
94
|
+
set_optional_tags(inferred_span, env: env, proxy_type: proxy_type)
|
|
95
|
+
|
|
96
|
+
yield
|
|
97
|
+
# NOTE: The underlying {Rack::TraceMiddleware} rescues {Exception}
|
|
98
|
+
# to tag the request span with error details.
|
|
99
|
+
# We must propagate errors to the inferred proxy parent span.
|
|
100
|
+
rescue Exception => e # rubocop:disable Lint/RescueException
|
|
101
|
+
inferred_span&.set_error(e)
|
|
102
|
+
raise
|
|
103
|
+
ensure
|
|
104
|
+
if inferred_span
|
|
105
|
+
propagate_request_span_tags(inferred_span, env: env)
|
|
106
|
+
|
|
107
|
+
if (trace = Tracing.active_trace) && resource
|
|
108
|
+
trace.resource = resource
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
inferred_span.finish
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
# rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
115
|
+
|
|
116
|
+
# Sets cloud provider metadata and constructs the resource ARN.
|
|
117
|
+
#
|
|
118
|
+
# rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
119
|
+
def set_optional_tags(span, env:, proxy_type:)
|
|
120
|
+
api_id = env[Ext::HEADER_X_DD_PROXY_API_ID]
|
|
121
|
+
region = env[Ext::HEADER_X_DD_PROXY_REGION]
|
|
122
|
+
|
|
123
|
+
# API Gateway v1 sends region as a single-quoted string
|
|
124
|
+
region = region.delete("'") if region
|
|
125
|
+
|
|
126
|
+
span.set_tag('apiid', api_id) if api_id
|
|
127
|
+
span.set_tag('region', region) if region
|
|
128
|
+
|
|
129
|
+
if (account_id = env[Ext::HEADER_X_DD_PROXY_ACCOUNT_ID])
|
|
130
|
+
span.set_tag('account_id', account_id)
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
if (user = env[Ext::HEADER_X_DD_PROXY_USER])
|
|
134
|
+
span.set_tag('aws_user', user)
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
if api_id && region
|
|
138
|
+
# NOTE: Update this when adding non-AWS proxy types.
|
|
139
|
+
restapi_prefix = (proxy_type == Ext::PROXY_AWS_APIGATEWAY) ? 'restapis' : 'apis'
|
|
140
|
+
span.set_tag('dd_resource_key', "arn:aws:apigateway:#{region}::/#{restapi_prefix}/#{api_id}")
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
# rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
144
|
+
|
|
145
|
+
# Propagates response-level and security tags from the request span to
|
|
146
|
+
# the inferred parent.
|
|
147
|
+
def propagate_request_span_tags(span, env:)
|
|
148
|
+
rack_span = env[Ext::RACK_ENV_REQUEST_SPAN]
|
|
149
|
+
return unless rack_span
|
|
150
|
+
|
|
151
|
+
if (status_code = rack_span.get_tag(Tracing::Metadata::Ext::HTTP::TAG_STATUS_CODE))
|
|
152
|
+
span.set_tag(Tracing::Metadata::Ext::HTTP::TAG_STATUS_CODE, status_code)
|
|
153
|
+
span.status = rack_span.status
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
if (user_agent = rack_span.get_tag(Tracing::Metadata::Ext::HTTP::TAG_USER_AGENT))
|
|
157
|
+
span.set_tag(Tracing::Metadata::Ext::HTTP::TAG_USER_AGENT, user_agent)
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
# NOTE: Tracing shouldn't know about AppSec tags.
|
|
161
|
+
if (appsec_enabled = rack_span.get_metric('_dd.appsec.enabled'))
|
|
162
|
+
span.set_metric('_dd.appsec.enabled', appsec_enabled)
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
# NOTE: Tracing shouldn't know about AppSec tags.
|
|
166
|
+
if (appsec_json = rack_span.get_tag('_dd.appsec.json'))
|
|
167
|
+
span.set_tag('_dd.appsec.json', appsec_json)
|
|
168
|
+
end
|
|
169
|
+
end
|
|
54
170
|
end
|
|
55
171
|
end
|
|
56
172
|
end
|