ddtrace 1.4.1 → 1.6.1
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 +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
|
|