ddtrace 1.4.1 → 1.6.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +144 -1
- data/LICENSE-3rdparty.csv +1 -0
- data/ext/ddtrace_profiling_loader/ddtrace_profiling_loader.c +9 -2
- data/ext/ddtrace_profiling_loader/extconf.rb +17 -0
- data/ext/ddtrace_profiling_native_extension/NativeExtensionDesign.md +38 -2
- data/ext/ddtrace_profiling_native_extension/clock_id.h +1 -0
- data/ext/ddtrace_profiling_native_extension/clock_id_from_pthread.c +1 -0
- data/ext/ddtrace_profiling_native_extension/collectors_cpu_and_wall_time.c +517 -42
- data/ext/ddtrace_profiling_native_extension/collectors_cpu_and_wall_time.h +3 -0
- data/ext/ddtrace_profiling_native_extension/collectors_cpu_and_wall_time_worker.c +208 -30
- data/ext/ddtrace_profiling_native_extension/collectors_stack.c +156 -46
- data/ext/ddtrace_profiling_native_extension/collectors_stack.h +11 -2
- data/ext/ddtrace_profiling_native_extension/extconf.rb +11 -1
- data/ext/ddtrace_profiling_native_extension/http_transport.c +83 -64
- data/ext/ddtrace_profiling_native_extension/libdatadog_helpers.h +4 -4
- data/ext/ddtrace_profiling_native_extension/native_extension_helpers.rb +3 -4
- data/ext/ddtrace_profiling_native_extension/private_vm_api_access.c +59 -0
- data/ext/ddtrace_profiling_native_extension/private_vm_api_access.h +3 -0
- data/ext/ddtrace_profiling_native_extension/profiling.c +10 -0
- data/ext/ddtrace_profiling_native_extension/ruby_helpers.c +0 -1
- data/ext/ddtrace_profiling_native_extension/ruby_helpers.h +4 -2
- data/ext/ddtrace_profiling_native_extension/stack_recorder.c +45 -29
- data/ext/ddtrace_profiling_native_extension/stack_recorder.h +7 -7
- data/lib/datadog/appsec/assets/waf_rules/recommended.json +1169 -275
- data/lib/datadog/appsec/assets/waf_rules/risky.json +78 -78
- data/lib/datadog/appsec/assets/waf_rules/strict.json +278 -88
- data/lib/datadog/appsec/configuration/settings.rb +0 -2
- data/lib/datadog/appsec/contrib/rack/gateway/watcher.rb +25 -20
- data/lib/datadog/appsec/contrib/rack/reactive/request.rb +11 -11
- data/lib/datadog/appsec/contrib/rack/reactive/request_body.rb +11 -11
- data/lib/datadog/appsec/contrib/rack/reactive/response.rb +11 -11
- data/lib/datadog/appsec/contrib/rack/request.rb +3 -0
- data/lib/datadog/appsec/contrib/rack/request_middleware.rb +46 -19
- data/lib/datadog/appsec/contrib/rails/gateway/watcher.rb +7 -6
- data/lib/datadog/appsec/contrib/rails/integration.rb +1 -1
- data/lib/datadog/appsec/contrib/rails/reactive/action.rb +11 -11
- data/lib/datadog/appsec/contrib/rails/request.rb +3 -0
- data/lib/datadog/appsec/contrib/sinatra/gateway/watcher.rb +14 -12
- data/lib/datadog/appsec/contrib/sinatra/reactive/routed.rb +11 -11
- data/lib/datadog/appsec/event.rb +6 -10
- data/lib/datadog/appsec/instrumentation/gateway.rb +16 -2
- data/lib/datadog/appsec/processor.rb +18 -2
- data/lib/datadog/ci/ext/environment.rb +16 -4
- data/lib/datadog/core/configuration/agent_settings_resolver.rb +0 -3
- data/lib/datadog/core/configuration/components.rb +28 -16
- data/lib/datadog/core/configuration/settings.rb +127 -8
- data/lib/datadog/core/configuration.rb +1 -1
- data/lib/datadog/core/diagnostics/environment_logger.rb +5 -1
- data/lib/datadog/core/header_collection.rb +41 -0
- data/lib/datadog/core/telemetry/collector.rb +0 -2
- data/lib/datadog/core/utils/compression.rb +5 -1
- data/lib/datadog/core/workers/async.rb +0 -2
- data/lib/datadog/core.rb +0 -54
- data/lib/datadog/opentracer/tracer.rb +4 -6
- data/lib/datadog/profiling/collectors/cpu_and_wall_time.rb +12 -2
- data/lib/datadog/profiling/collectors/cpu_and_wall_time_worker.rb +5 -3
- data/lib/datadog/profiling/collectors/old_stack.rb +1 -1
- data/lib/datadog/profiling/exporter.rb +2 -4
- data/lib/datadog/profiling/http_transport.rb +1 -1
- data/lib/datadog/profiling.rb +1 -1
- data/lib/datadog/tracing/client_ip.rb +164 -0
- data/lib/datadog/tracing/configuration/ext.rb +14 -0
- data/lib/datadog/tracing/contrib/aws/instrumentation.rb +2 -0
- data/lib/datadog/tracing/contrib/aws/services.rb +0 -2
- data/lib/datadog/tracing/contrib/dalli/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/dalli/instrumentation.rb +4 -0
- data/lib/datadog/tracing/contrib/elasticsearch/ext.rb +2 -0
- data/lib/datadog/tracing/contrib/elasticsearch/patcher.rb +3 -0
- data/lib/datadog/tracing/contrib/ethon/easy_patch.rb +2 -2
- data/lib/datadog/tracing/contrib/ethon/multi_patch.rb +2 -0
- data/lib/datadog/tracing/contrib/excon/middleware.rb +2 -0
- data/lib/datadog/tracing/contrib/ext.rb +25 -0
- data/lib/datadog/tracing/contrib/faraday/middleware.rb +3 -2
- data/lib/datadog/tracing/contrib/grape/endpoint.rb +0 -2
- data/lib/datadog/tracing/contrib/graphql/configuration/settings.rb +1 -1
- data/lib/datadog/tracing/contrib/grpc/datadog_interceptor/client.rb +5 -0
- data/lib/datadog/tracing/contrib/grpc/datadog_interceptor/server.rb +7 -1
- data/lib/datadog/tracing/contrib/grpc/ext.rb +2 -0
- data/lib/datadog/tracing/contrib/hanami/action_tracer.rb +47 -0
- data/lib/datadog/tracing/contrib/hanami/configuration/settings.rb +22 -0
- data/lib/datadog/tracing/contrib/hanami/ext.rb +24 -0
- data/lib/datadog/tracing/contrib/hanami/integration.rb +44 -0
- data/lib/datadog/tracing/contrib/hanami/patcher.rb +33 -0
- data/lib/datadog/tracing/contrib/hanami/plugin.rb +23 -0
- data/lib/datadog/tracing/contrib/hanami/renderer_policy_tracing.rb +41 -0
- data/lib/datadog/tracing/contrib/hanami/router_tracing.rb +44 -0
- data/lib/datadog/tracing/contrib/http/instrumentation.rb +2 -0
- data/lib/datadog/tracing/contrib/httpclient/instrumentation.rb +2 -0
- data/lib/datadog/tracing/contrib/httprb/instrumentation.rb +2 -0
- data/lib/datadog/tracing/contrib/mongodb/ext.rb +7 -0
- data/lib/datadog/tracing/contrib/mongodb/subscribers.rb +4 -0
- data/lib/datadog/tracing/contrib/mysql2/configuration/settings.rb +12 -0
- data/lib/datadog/tracing/contrib/mysql2/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/mysql2/instrumentation.rb +16 -0
- data/lib/datadog/tracing/contrib/pg/configuration/settings.rb +12 -0
- data/lib/datadog/tracing/contrib/pg/ext.rb +2 -1
- data/lib/datadog/tracing/contrib/pg/instrumentation.rb +38 -21
- data/lib/datadog/tracing/contrib/propagation/sql_comment/comment.rb +43 -0
- data/lib/datadog/tracing/contrib/propagation/sql_comment/ext.rb +32 -0
- data/lib/datadog/tracing/contrib/propagation/sql_comment/mode.rb +28 -0
- data/lib/datadog/tracing/contrib/propagation/sql_comment.rb +49 -0
- data/lib/datadog/tracing/contrib/rack/header_collection.rb +35 -0
- data/lib/datadog/tracing/contrib/rack/middlewares.rb +105 -43
- data/lib/datadog/tracing/contrib/redis/ext.rb +2 -0
- data/lib/datadog/tracing/contrib/redis/instrumentation.rb +4 -2
- data/lib/datadog/tracing/contrib/redis/integration.rb +2 -1
- data/lib/datadog/tracing/contrib/redis/patcher.rb +40 -0
- data/lib/datadog/tracing/contrib/redis/tags.rb +5 -0
- data/lib/datadog/tracing/contrib/rest_client/request_patch.rb +2 -0
- data/lib/datadog/tracing/contrib/sinatra/env.rb +12 -23
- data/lib/datadog/tracing/contrib/sinatra/ext.rb +7 -3
- data/lib/datadog/tracing/contrib/sinatra/patcher.rb +2 -2
- data/lib/datadog/tracing/contrib/sinatra/tracer.rb +8 -80
- data/lib/datadog/tracing/contrib/sinatra/tracer_middleware.rb +14 -9
- data/lib/datadog/tracing/contrib/utils/quantization/http.rb +92 -10
- data/lib/datadog/tracing/contrib.rb +1 -0
- data/lib/datadog/tracing/distributed/datadog_tags_codec.rb +84 -0
- data/lib/datadog/tracing/distributed/headers/datadog.rb +122 -30
- data/lib/datadog/tracing/distributed/headers/ext.rb +2 -0
- data/lib/datadog/tracing/flush.rb +57 -35
- data/lib/datadog/tracing/metadata/ext.rb +11 -9
- data/lib/datadog/tracing/metadata/tagging.rb +9 -0
- data/lib/datadog/tracing/propagation/http.rb +9 -1
- data/lib/datadog/tracing/sampling/ext.rb +31 -0
- data/lib/datadog/tracing/sampling/priority_sampler.rb +46 -4
- data/lib/datadog/tracing/sampling/rate_by_key_sampler.rb +8 -9
- data/lib/datadog/tracing/sampling/rate_by_service_sampler.rb +29 -5
- data/lib/datadog/tracing/sampling/rate_limiter.rb +3 -0
- data/lib/datadog/tracing/sampling/rate_sampler.rb +20 -3
- data/lib/datadog/tracing/sampling/rule_sampler.rb +4 -3
- data/lib/datadog/tracing/sampling/span/ext.rb +25 -0
- data/lib/datadog/tracing/sampling/span/matcher.rb +9 -0
- data/lib/datadog/tracing/sampling/span/rule.rb +82 -0
- data/lib/datadog/tracing/sampling/span/rule_parser.rb +104 -0
- data/lib/datadog/tracing/sampling/span/sampler.rb +75 -0
- data/lib/datadog/tracing/span_operation.rb +0 -2
- data/lib/datadog/tracing/trace_digest.rb +3 -0
- data/lib/datadog/tracing/trace_operation.rb +32 -3
- data/lib/datadog/tracing/trace_segment.rb +7 -2
- data/lib/datadog/tracing/tracer.rb +34 -6
- data/lib/datadog/tracing/writer.rb +7 -0
- data/lib/ddtrace/transport/trace_formatter.rb +7 -0
- data/lib/ddtrace/transport/traces.rb +3 -1
- data/lib/ddtrace/version.rb +1 -1
- metadata +36 -18
- data/lib/datadog/profiling/old_ext.rb +0 -42
- data/lib/datadog/profiling/transport/http/api/endpoint.rb +0 -85
- data/lib/datadog/profiling/transport/http/api/instance.rb +0 -38
- data/lib/datadog/profiling/transport/http/api/spec.rb +0 -42
- data/lib/datadog/profiling/transport/http/api.rb +0 -45
- data/lib/datadog/profiling/transport/http/builder.rb +0 -30
- data/lib/datadog/profiling/transport/http/client.rb +0 -37
- data/lib/datadog/profiling/transport/http/response.rb +0 -21
- data/lib/datadog/profiling/transport/http.rb +0 -118
@@ -0,0 +1,49 @@
|
|
1
|
+
# typed: false
|
2
|
+
|
3
|
+
require_relative 'sql_comment/comment'
|
4
|
+
require_relative 'sql_comment/ext'
|
5
|
+
|
6
|
+
module Datadog
|
7
|
+
module Tracing
|
8
|
+
module Contrib
|
9
|
+
module Propagation
|
10
|
+
# Implements sql comment propagation related contracts.
|
11
|
+
module SqlComment
|
12
|
+
def self.annotate!(span_op, mode)
|
13
|
+
return unless mode.enabled?
|
14
|
+
|
15
|
+
# PENDING: Until `traceparent`` implementation in `full` mode
|
16
|
+
# span_op.set_tag(Ext::TAG_DBM_TRACE_INJECTED, true) if mode.full?
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.prepend_comment(sql, span_op, mode)
|
20
|
+
return sql unless mode.enabled?
|
21
|
+
|
22
|
+
tags = {
|
23
|
+
Ext::KEY_DATABASE_SERVICE => span_op.service,
|
24
|
+
Ext::KEY_ENVIRONMENT => datadog_configuration.env,
|
25
|
+
Ext::KEY_PARENT_SERVICE => datadog_configuration.service,
|
26
|
+
Ext::KEY_VERSION => datadog_configuration.version
|
27
|
+
}
|
28
|
+
|
29
|
+
# PENDING: Until `traceparent`` implementation in `full` mode
|
30
|
+
# tags.merge!(trace_context(span_op)) if mode.full?
|
31
|
+
|
32
|
+
"#{Comment.new(tags)} #{sql}"
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.datadog_configuration
|
36
|
+
Datadog.configuration
|
37
|
+
end
|
38
|
+
|
39
|
+
# TODO: Derive from trace
|
40
|
+
def self.trace_context(_)
|
41
|
+
{
|
42
|
+
# traceparent: '00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01'
|
43
|
+
}.freeze
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require_relative '../../../core/header_collection'
|
2
|
+
|
3
|
+
module Datadog
|
4
|
+
module Tracing
|
5
|
+
module Contrib
|
6
|
+
module Rack
|
7
|
+
# Classes and utilities for handling headers in Rack.
|
8
|
+
module Header
|
9
|
+
# An implementation of a header collection that looks up headers from a Rack environment.
|
10
|
+
class RequestHeaderCollection < Datadog::Core::HeaderCollection
|
11
|
+
# Creates a header collection from a rack environment.
|
12
|
+
def initialize(env)
|
13
|
+
super()
|
14
|
+
@env = env
|
15
|
+
end
|
16
|
+
|
17
|
+
# Gets the value of the header with the given name.
|
18
|
+
def get(header_name)
|
19
|
+
@env[Header.to_rack_header(header_name)]
|
20
|
+
end
|
21
|
+
|
22
|
+
# Tests whether a header with the given name exists in the environment.
|
23
|
+
def key?(header_name)
|
24
|
+
@env.key?(Header.to_rack_header(header_name))
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.to_rack_header(name)
|
29
|
+
"HTTP_#{name.to_s.upcase.gsub(/[-\s]/, '_')}"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -3,12 +3,14 @@
|
|
3
3
|
require 'date'
|
4
4
|
|
5
5
|
require_relative '../../../core/environment/variable_helpers'
|
6
|
+
require_relative '../../client_ip'
|
6
7
|
require_relative '../../metadata/ext'
|
7
8
|
require_relative '../../propagation/http'
|
8
9
|
require_relative '../analytics'
|
10
|
+
require_relative '../utils/quantization/http'
|
9
11
|
require_relative 'ext'
|
12
|
+
require_relative 'header_collection'
|
10
13
|
require_relative 'request_queue'
|
11
|
-
require_relative '../utils/quantization/http'
|
12
14
|
|
13
15
|
module Datadog
|
14
16
|
module Tracing
|
@@ -54,16 +56,18 @@ module Datadog
|
|
54
56
|
# Find out if this is rack within rack
|
55
57
|
previous_request_span = env[Ext::RACK_ENV_REQUEST_SPAN]
|
56
58
|
|
59
|
+
return @app.call(env) if previous_request_span
|
60
|
+
|
57
61
|
# Extract distributed tracing context before creating any spans,
|
58
62
|
# so that all spans will be added to the distributed trace.
|
59
|
-
if configuration[:distributed_tracing]
|
63
|
+
if configuration[:distributed_tracing]
|
60
64
|
trace_digest = Tracing::Propagation::HTTP.extract(env)
|
61
65
|
Tracing.continue_trace!(trace_digest)
|
62
66
|
end
|
63
67
|
|
64
68
|
# Create a root Span to keep track of frontend web servers
|
65
69
|
# (i.e. Apache, nginx) if the header is properly set
|
66
|
-
frontend_span = compute_queue_time(env)
|
70
|
+
frontend_span = compute_queue_time(env)
|
67
71
|
|
68
72
|
trace_options = { span_type: Tracing::Metadata::Ext::HTTP::TYPE_INBOUND }
|
69
73
|
trace_options[:service] = configuration[:service_name] if configuration[:service_name]
|
@@ -121,20 +125,17 @@ module Datadog
|
|
121
125
|
# rubocop:disable Metrics/PerceivedComplexity
|
122
126
|
# rubocop:disable Metrics/MethodLength
|
123
127
|
def set_request_tags!(trace, request_span, env, status, headers, response, original_env)
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
#
|
129
|
-
#
|
130
|
-
|
131
|
-
|
132
|
-
#
|
133
|
-
#
|
134
|
-
|
135
|
-
url = env['REQUEST_URI'] || original_env['PATH_INFO']
|
136
|
-
request_headers = parse_request_headers(env)
|
137
|
-
response_headers = parse_response_headers(headers || {})
|
128
|
+
request_header_collection = Header::RequestHeaderCollection.new(env)
|
129
|
+
request_headers_tags = parse_request_headers(request_header_collection)
|
130
|
+
response_headers_tags = parse_response_headers(headers || {})
|
131
|
+
|
132
|
+
# Since it could be mutated, it would be more accurate to fetch from the original env,
|
133
|
+
# e.g. ActionDispatch::ShowExceptions middleware with Rails exceptions_app configuration
|
134
|
+
original_request_method = original_env['REQUEST_METHOD']
|
135
|
+
|
136
|
+
# request_headers is subject to filtering and configuration so we
|
137
|
+
# get the user agent separately
|
138
|
+
user_agent = parse_user_agent_header(request_header_collection)
|
138
139
|
|
139
140
|
# The priority
|
140
141
|
# 1. User overrides span.resource
|
@@ -143,11 +144,11 @@ module Datadog
|
|
143
144
|
# 4. Fallback with verb + status, eq `GET 200`
|
144
145
|
request_span.resource ||=
|
145
146
|
if configuration[:middleware_names] && env['RESPONSE_MIDDLEWARE']
|
146
|
-
"#{env['RESPONSE_MIDDLEWARE']}##{
|
147
|
+
"#{env['RESPONSE_MIDDLEWARE']}##{original_request_method}"
|
147
148
|
elsif trace.resource_override?
|
148
149
|
trace.resource
|
149
150
|
else
|
150
|
-
"#{
|
151
|
+
"#{original_request_method} #{status}".strip
|
151
152
|
end
|
152
153
|
|
153
154
|
# Overrides the trace resource if it never been set
|
@@ -166,11 +167,17 @@ module Datadog
|
|
166
167
|
Contrib::Analytics.set_measured(request_span)
|
167
168
|
|
168
169
|
if request_span.get_tag(Tracing::Metadata::Ext::HTTP::TAG_METHOD).nil?
|
169
|
-
request_span.set_tag(Tracing::Metadata::Ext::HTTP::TAG_METHOD,
|
170
|
+
request_span.set_tag(Tracing::Metadata::Ext::HTTP::TAG_METHOD, original_request_method)
|
170
171
|
end
|
171
172
|
|
173
|
+
url = parse_url(env, original_env)
|
174
|
+
|
172
175
|
if request_span.get_tag(Tracing::Metadata::Ext::HTTP::TAG_URL).nil?
|
173
|
-
options = configuration[:quantize]
|
176
|
+
options = configuration[:quantize] || {}
|
177
|
+
|
178
|
+
# Quantization::HTTP.url base defaults to :show, but we are transitioning
|
179
|
+
options[:base] ||= :exclude
|
180
|
+
|
174
181
|
request_span.set_tag(
|
175
182
|
Tracing::Metadata::Ext::HTTP::TAG_URL,
|
176
183
|
Contrib::Utils::Quantization::HTTP.url(url, options)
|
@@ -178,29 +185,43 @@ module Datadog
|
|
178
185
|
end
|
179
186
|
|
180
187
|
if request_span.get_tag(Tracing::Metadata::Ext::HTTP::TAG_BASE_URL).nil?
|
181
|
-
|
188
|
+
options = configuration[:quantize]
|
189
|
+
|
190
|
+
unless options[:base] == :show
|
191
|
+
base_url = Contrib::Utils::Quantization::HTTP.base_url(url)
|
182
192
|
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
193
|
+
unless base_url.empty?
|
194
|
+
request_span.set_tag(
|
195
|
+
Tracing::Metadata::Ext::HTTP::TAG_BASE_URL,
|
196
|
+
base_url
|
197
|
+
)
|
198
|
+
end
|
199
|
+
end
|
200
|
+
end
|
189
201
|
|
190
|
-
|
202
|
+
if request_span.get_tag(Tracing::Metadata::Ext::HTTP::TAG_CLIENT_IP).nil?
|
203
|
+
Tracing::ClientIp.set_client_ip_tag(
|
204
|
+
request_span,
|
205
|
+
headers: request_header_collection,
|
206
|
+
remote_ip: env['REMOTE_ADDR']
|
207
|
+
)
|
191
208
|
end
|
192
209
|
|
193
210
|
if request_span.get_tag(Tracing::Metadata::Ext::HTTP::TAG_STATUS_CODE).nil? && status
|
194
211
|
request_span.set_tag(Tracing::Metadata::Ext::HTTP::TAG_STATUS_CODE, status)
|
195
212
|
end
|
196
213
|
|
214
|
+
if request_span.get_tag(Tracing::Metadata::Ext::HTTP::TAG_USER_AGENT).nil? && user_agent
|
215
|
+
request_span.set_tag(Tracing::Metadata::Ext::HTTP::TAG_USER_AGENT, user_agent)
|
216
|
+
end
|
217
|
+
|
197
218
|
# Request headers
|
198
|
-
|
219
|
+
request_headers_tags.each do |name, value|
|
199
220
|
request_span.set_tag(name, value) if request_span.get_tag(name).nil?
|
200
221
|
end
|
201
222
|
|
202
223
|
# Response headers
|
203
|
-
|
224
|
+
response_headers_tags.each do |name, value|
|
204
225
|
request_span.set_tag(name, value) if request_span.get_tag(name).nil?
|
205
226
|
end
|
206
227
|
|
@@ -219,14 +240,59 @@ module Datadog
|
|
219
240
|
Datadog.configuration.tracing[:rack]
|
220
241
|
end
|
221
242
|
|
222
|
-
def
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
243
|
+
def parse_url(env, original_env)
|
244
|
+
request_obj = ::Rack::Request.new(env)
|
245
|
+
|
246
|
+
# scheme, host, and port
|
247
|
+
base_url = if request_obj.respond_to?(:base_url)
|
248
|
+
request_obj.base_url
|
249
|
+
else
|
250
|
+
# Compatibility for older Rack versions
|
251
|
+
request_obj.url.chomp(request_obj.fullpath)
|
252
|
+
end
|
253
|
+
|
254
|
+
# https://github.com/rack/rack/blob/main/SPEC.rdoc
|
255
|
+
#
|
256
|
+
# The source of truth in Rack is the PATH_INFO key that holds the
|
257
|
+
# URL for the current request; but some frameworks may override that
|
258
|
+
# value, especially during exception handling.
|
259
|
+
#
|
260
|
+
# Because of this, we prefer to use REQUEST_URI, if available, which is the
|
261
|
+
# relative path + query string, and doesn't mutate.
|
262
|
+
#
|
263
|
+
# REQUEST_URI is only available depending on what web server is running though.
|
264
|
+
# So when its not available, we want the original, unmutated PATH_INFO, which
|
265
|
+
# is just the relative path without query strings.
|
266
|
+
#
|
267
|
+
# SCRIPT_NAME is the first part of the request URL path, so that
|
268
|
+
# the application can know its virtual location. It should be
|
269
|
+
# prepended to PATH_INFO to reflect the correct user visible path.
|
270
|
+
request_uri = env['REQUEST_URI'].to_s
|
271
|
+
fullpath = if request_uri.empty?
|
272
|
+
query_string = original_env['QUERY_STRING'].to_s
|
273
|
+
path = original_env['SCRIPT_NAME'].to_s + original_env['PATH_INFO'].to_s
|
274
|
+
|
275
|
+
query_string.empty? ? path : "#{path}?#{query_string}"
|
276
|
+
else
|
277
|
+
# normally REQUEST_URI starts at the path, but it
|
278
|
+
# might contain the full URL in some cases (e.g WEBrick)
|
279
|
+
request_uri.sub(/^#{base_url}/, '')
|
280
|
+
end
|
281
|
+
|
282
|
+
base_url + fullpath
|
283
|
+
end
|
284
|
+
|
285
|
+
def parse_user_agent_header(headers)
|
286
|
+
headers.get(Tracing::Metadata::Ext::HTTP::HEADER_USER_AGENT)
|
287
|
+
end
|
288
|
+
|
289
|
+
def parse_request_headers(headers)
|
290
|
+
whitelist = configuration[:headers][:request] || []
|
291
|
+
whitelist.each_with_object({}) do |header, result|
|
292
|
+
header_value = headers.get(header)
|
293
|
+
unless header_value.nil?
|
294
|
+
header_tag = Tracing::Metadata::Ext::HTTP::RequestHeaders.to_tag(header)
|
295
|
+
result[header_tag] = header_value
|
230
296
|
end
|
231
297
|
end
|
232
298
|
end
|
@@ -248,10 +314,6 @@ module Datadog
|
|
248
314
|
end
|
249
315
|
end
|
250
316
|
end
|
251
|
-
|
252
|
-
def header_to_rack_header(name)
|
253
|
-
"HTTP_#{name.to_s.upcase.gsub(/[-\s]/, '_')}"
|
254
|
-
end
|
255
317
|
end
|
256
318
|
end
|
257
319
|
end
|
@@ -21,7 +21,8 @@ module Datadog
|
|
21
21
|
def call(*args, &block)
|
22
22
|
response = nil
|
23
23
|
Tracing.trace(Contrib::Redis::Ext::SPAN_COMMAND) do |span|
|
24
|
-
span.service = Datadog.configuration_for(
|
24
|
+
span.service = Datadog.configuration_for(redis_instance, :service_name) ||
|
25
|
+
datadog_configuration[:service_name]
|
25
26
|
span.span_type = Contrib::Redis::Ext::TYPE
|
26
27
|
span.resource = get_command(args)
|
27
28
|
Contrib::Redis::Tags.set_common_tags(self, span)
|
@@ -35,7 +36,8 @@ module Datadog
|
|
35
36
|
def call_pipeline(*args, &block)
|
36
37
|
response = nil
|
37
38
|
Tracing.trace(Contrib::Redis::Ext::SPAN_COMMAND) do |span|
|
38
|
-
span.service = Datadog.configuration_for(
|
39
|
+
span.service = Datadog.configuration_for(redis_instance, :service_name) ||
|
40
|
+
datadog_configuration[:service_name]
|
39
41
|
span.span_type = Contrib::Redis::Ext::TYPE
|
40
42
|
commands = get_pipeline_commands(args)
|
41
43
|
span.resource = commands.any? ? commands.join("\n") : '(none)'
|
@@ -13,6 +13,7 @@ module Datadog
|
|
13
13
|
include Contrib::Integration
|
14
14
|
|
15
15
|
MINIMUM_VERSION = Gem::Version.new('3.2')
|
16
|
+
MAX_VERSION = Gem::Version.new('5')
|
16
17
|
|
17
18
|
# @public_api Changing the integration name or integration options can cause breaking changes
|
18
19
|
register_as :redis, auto_patch: true
|
@@ -26,7 +27,7 @@ module Datadog
|
|
26
27
|
end
|
27
28
|
|
28
29
|
def self.compatible?
|
29
|
-
super && version >= MINIMUM_VERSION
|
30
|
+
super && version >= MINIMUM_VERSION && version < MAX_VERSION
|
30
31
|
end
|
31
32
|
|
32
33
|
def new_configuration
|
@@ -12,6 +12,41 @@ module Datadog
|
|
12
12
|
module Patcher
|
13
13
|
include Contrib::Patcher
|
14
14
|
|
15
|
+
# Patch for redis instance
|
16
|
+
module InstancePatch
|
17
|
+
def self.included(base)
|
18
|
+
base.prepend(InstanceMethods)
|
19
|
+
end
|
20
|
+
|
21
|
+
# Instance method patch for redis instance
|
22
|
+
module InstanceMethods
|
23
|
+
# `options` could be frozen
|
24
|
+
def initialize(options = {})
|
25
|
+
super(options.merge(redis_instance: self))
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
# Patch for redis client
|
31
|
+
module ClientPatch
|
32
|
+
def self.included(base)
|
33
|
+
base.prepend(InstanceMethods)
|
34
|
+
end
|
35
|
+
|
36
|
+
# Instance method patch for redis client
|
37
|
+
module InstanceMethods
|
38
|
+
def initialize(options = {})
|
39
|
+
@redis_instance = options.delete(:redis_instance)
|
40
|
+
|
41
|
+
super(options)
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
attr_reader :redis_instance
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
15
50
|
module_function
|
16
51
|
|
17
52
|
def target_version
|
@@ -26,6 +61,11 @@ module Datadog
|
|
26
61
|
require_relative 'quantize'
|
27
62
|
require_relative 'instrumentation'
|
28
63
|
|
64
|
+
# InstancePatch and ClientPatch allows the client object to access pin on redis instance
|
65
|
+
::Redis.include(InstancePatch)
|
66
|
+
::Redis::Client.include(ClientPatch)
|
67
|
+
|
68
|
+
# TODO: To support redis-rb 5.x, Redis::Client -> RedisClient
|
29
69
|
::Redis::Client.include(Instrumentation)
|
30
70
|
end
|
31
71
|
end
|
@@ -3,6 +3,7 @@
|
|
3
3
|
require_relative '../../metadata/ext'
|
4
4
|
require_relative '../analytics'
|
5
5
|
require_relative 'ext'
|
6
|
+
require_relative '../ext'
|
6
7
|
|
7
8
|
module Datadog
|
8
9
|
module Tracing
|
@@ -22,8 +23,12 @@ module Datadog
|
|
22
23
|
# Set analytics sample rate
|
23
24
|
Contrib::Analytics.set_sample_rate(span, analytics_sample_rate) if analytics_enabled?
|
24
25
|
|
26
|
+
span.set_tag Contrib::Ext::DB::TAG_SYSTEM, Ext::TAG_SYSTEM
|
27
|
+
|
25
28
|
span.set_tag Tracing::Metadata::Ext::NET::TAG_TARGET_HOST, client.host
|
26
29
|
span.set_tag Tracing::Metadata::Ext::NET::TAG_TARGET_PORT, client.port
|
30
|
+
|
31
|
+
span.set_tag Ext::TAG_DATABASE_INDEX, client.db.to_s
|
27
32
|
span.set_tag Ext::TAG_DB, client.db
|
28
33
|
span.set_tag Ext::TAG_RAW_COMMAND, span.resource if show_command_args?
|
29
34
|
end
|
@@ -34,6 +34,8 @@ module Datadog
|
|
34
34
|
def datadog_tag_request(uri, span)
|
35
35
|
span.resource = method.to_s.upcase
|
36
36
|
|
37
|
+
span.set_tag(Tracing::Metadata::Ext::TAG_KIND, Tracing::Metadata::Ext::SpanKind::TAG_CLIENT)
|
38
|
+
|
37
39
|
span.set_tag(Tracing::Metadata::Ext::TAG_COMPONENT, Ext::TAG_COMPONENT)
|
38
40
|
span.set_tag(Tracing::Metadata::Ext::TAG_OPERATION, Ext::TAG_OPERATION_REQUEST)
|
39
41
|
|
@@ -13,14 +13,12 @@ module Datadog
|
|
13
13
|
module Env
|
14
14
|
module_function
|
15
15
|
|
16
|
-
def datadog_span(env
|
17
|
-
|
18
|
-
request_span && request_span[app]
|
16
|
+
def datadog_span(env)
|
17
|
+
env[Ext::RACK_ENV_SINATRA_REQUEST_SPAN]
|
19
18
|
end
|
20
19
|
|
21
|
-
def set_datadog_span(env,
|
22
|
-
|
23
|
-
hash[app] = span
|
20
|
+
def set_datadog_span(env, span)
|
21
|
+
env[Ext::RACK_ENV_SINATRA_REQUEST_SPAN] = span
|
24
22
|
end
|
25
23
|
|
26
24
|
def request_header_tags(env, headers)
|
@@ -40,24 +38,15 @@ module Datadog
|
|
40
38
|
"HTTP_#{name.to_s.upcase.gsub(/[-\s]/, '_')}"
|
41
39
|
end
|
42
40
|
|
43
|
-
|
44
|
-
|
45
|
-
# middlewares that don't match the request at hand.
|
46
|
-
def middleware_traced?(env)
|
47
|
-
env[Ext::RACK_ENV_MIDDLEWARE_TRACED]
|
48
|
-
end
|
49
|
-
|
50
|
-
def set_middleware_traced(env, bool)
|
51
|
-
env[Ext::RACK_ENV_MIDDLEWARE_TRACED] = bool
|
52
|
-
end
|
41
|
+
def route_path(env, use_script_names: Datadog.configuration.tracing[:sinatra][:resource_script_names])
|
42
|
+
return unless env['sinatra.route']
|
53
43
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
env[Ext::RACK_ENV_MIDDLEWARE_START_TIME] = time
|
44
|
+
_, path = env['sinatra.route'].split(' ', 2)
|
45
|
+
if use_script_names
|
46
|
+
env['SCRIPT_NAME'].to_s + path
|
47
|
+
else
|
48
|
+
path
|
49
|
+
end
|
61
50
|
end
|
62
51
|
end
|
63
52
|
end
|
@@ -10,9 +10,7 @@ module Datadog
|
|
10
10
|
ENV_ENABLED = 'DD_TRACE_SINATRA_ENABLED'.freeze
|
11
11
|
ENV_ANALYTICS_ENABLED = 'DD_TRACE_SINATRA_ANALYTICS_ENABLED'.freeze
|
12
12
|
ENV_ANALYTICS_SAMPLE_RATE = 'DD_TRACE_SINATRA_ANALYTICS_SAMPLE_RATE'.freeze
|
13
|
-
|
14
|
-
RACK_ENV_MIDDLEWARE_START_TIME = 'datadog.sinatra_middleware_start_time'.freeze
|
15
|
-
RACK_ENV_MIDDLEWARE_TRACED = 'datadog.sinatra_middleware_traced'.freeze
|
13
|
+
RACK_ENV_SINATRA_REQUEST_SPAN = 'datadog.sinatra_request_span'.freeze
|
16
14
|
SPAN_RENDER_TEMPLATE = 'sinatra.render_template'.freeze
|
17
15
|
SPAN_REQUEST = 'sinatra.request'.freeze
|
18
16
|
SPAN_ROUTE = 'sinatra.route'.freeze
|
@@ -25,6 +23,12 @@ module Datadog
|
|
25
23
|
TAG_SCRIPT_NAME = 'sinatra.script_name'.freeze
|
26
24
|
TAG_TEMPLATE_ENGINE = 'sinatra.template_engine'.freeze
|
27
25
|
TAG_TEMPLATE_NAME = 'sinatra.template_name'.freeze
|
26
|
+
|
27
|
+
# === Deprecated: To be removed ===
|
28
|
+
RACK_ENV_REQUEST_SPAN = 'datadog.sinatra_request_span'.freeze
|
29
|
+
RACK_ENV_MIDDLEWARE_START_TIME = 'datadog.sinatra_middleware_start_time'.freeze
|
30
|
+
RACK_ENV_MIDDLEWARE_TRACED = 'datadog.sinatra_middleware_traced'.freeze
|
31
|
+
# === Deprecated: To be removed ===
|
28
32
|
end
|
29
33
|
end
|
30
34
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
# typed:
|
1
|
+
# typed: false
|
2
2
|
|
3
3
|
require_relative '../../../core/utils/only_once'
|
4
4
|
require_relative '../patcher'
|
@@ -58,7 +58,7 @@ module Datadog
|
|
58
58
|
end
|
59
59
|
|
60
60
|
def register_tracer
|
61
|
-
::Sinatra.
|
61
|
+
::Sinatra::Base.register(Contrib::Sinatra::Tracer)
|
62
62
|
::Sinatra::Base.prepend(Sinatra::Tracer::Base)
|
63
63
|
end
|
64
64
|
|