ddtrace 1.5.2 → 1.6.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 +44 -1
- 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 -2
- 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/contrib/rack/request_middleware.rb +4 -0
- data/lib/datadog/appsec/event.rb +6 -0
- data/lib/datadog/core/configuration/components.rb +20 -14
- data/lib/datadog/core/configuration/settings.rb +42 -4
- data/lib/datadog/core/diagnostics/environment_logger.rb +5 -1
- data/lib/datadog/core/utils/compression.rb +5 -1
- data/lib/datadog/core.rb +0 -54
- 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/exporter.rb +2 -4
- data/lib/datadog/profiling/http_transport.rb +1 -1
- data/lib/datadog/tracing/configuration/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/aws/instrumentation.rb +2 -0
- 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 -0
- 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 +6 -0
- data/lib/datadog/tracing/contrib/faraday/middleware.rb +2 -0
- 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 +34 -18
- 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/middlewares.rb +11 -5
- 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/patcher.rb +41 -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.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 +1 -1
- data/lib/datadog/tracing/metadata/ext.rb +8 -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_sampler.rb +10 -3
- data/lib/datadog/tracing/sampling/rule_sampler.rb +4 -3
- data/lib/datadog/tracing/sampling/span/ext.rb +0 -4
- data/lib/datadog/tracing/sampling/span/rule.rb +1 -1
- data/lib/datadog/tracing/sampling/span/sampler.rb +14 -3
- data/lib/datadog/tracing/trace_digest.rb +3 -0
- data/lib/datadog/tracing/trace_operation.rb +10 -0
- data/lib/datadog/tracing/trace_segment.rb +6 -0
- data/lib/datadog/tracing/tracer.rb +3 -1
- data/lib/datadog/tracing/writer.rb +7 -0
- data/lib/ddtrace/transport/trace_formatter.rb +7 -0
- data/lib/ddtrace/transport/traces.rb +1 -1
- data/lib/ddtrace/version.rb +2 -2
- metadata +18 -14
- 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
|
@@ -5,6 +5,9 @@ require_relative '../analytics'
|
|
|
5
5
|
require_relative '../ext'
|
|
6
6
|
require_relative 'ext'
|
|
7
7
|
|
|
8
|
+
require_relative '../propagation/sql_comment'
|
|
9
|
+
require_relative '../propagation/sql_comment/mode'
|
|
10
|
+
|
|
8
11
|
module Datadog
|
|
9
12
|
module Tracing
|
|
10
13
|
module Contrib
|
|
@@ -18,68 +21,77 @@ module Datadog
|
|
|
18
21
|
# PG::Connection patch methods
|
|
19
22
|
module InstanceMethods
|
|
20
23
|
def exec(sql, *args)
|
|
21
|
-
trace(Ext::SPAN_EXEC,
|
|
22
|
-
super(
|
|
24
|
+
trace(Ext::SPAN_EXEC, sql: sql) do |sql_statement|
|
|
25
|
+
super(sql_statement, *args)
|
|
23
26
|
end
|
|
24
27
|
end
|
|
25
28
|
|
|
26
29
|
def exec_params(sql, params, *args)
|
|
27
|
-
trace(Ext::SPAN_EXEC_PARAMS,
|
|
28
|
-
super(
|
|
30
|
+
trace(Ext::SPAN_EXEC_PARAMS, sql: sql) do |sql_statement|
|
|
31
|
+
super(sql_statement, params, *args)
|
|
29
32
|
end
|
|
30
33
|
end
|
|
31
34
|
|
|
32
35
|
def exec_prepared(statement_name, params, *args)
|
|
33
|
-
trace(Ext::SPAN_EXEC_PREPARED,
|
|
36
|
+
trace(Ext::SPAN_EXEC_PREPARED, statement_name: statement_name) do
|
|
34
37
|
super(statement_name, params, *args)
|
|
35
38
|
end
|
|
36
39
|
end
|
|
37
40
|
|
|
38
41
|
def async_exec(sql, *args)
|
|
39
|
-
trace(Ext::SPAN_ASYNC_EXEC,
|
|
40
|
-
super(
|
|
42
|
+
trace(Ext::SPAN_ASYNC_EXEC, sql: sql) do |sql_statement|
|
|
43
|
+
super(sql_statement, *args)
|
|
41
44
|
end
|
|
42
45
|
end
|
|
43
46
|
|
|
44
47
|
def async_exec_params(sql, params, *args)
|
|
45
|
-
trace(Ext::SPAN_ASYNC_EXEC_PARAMS,
|
|
46
|
-
super(
|
|
48
|
+
trace(Ext::SPAN_ASYNC_EXEC_PARAMS, sql: sql) do |sql_statement|
|
|
49
|
+
super(sql_statement, params, *args)
|
|
47
50
|
end
|
|
48
51
|
end
|
|
49
52
|
|
|
50
53
|
def async_exec_prepared(statement_name, params, *args)
|
|
51
|
-
trace(Ext::SPAN_ASYNC_EXEC_PREPARED,
|
|
54
|
+
trace(Ext::SPAN_ASYNC_EXEC_PREPARED, statement_name: statement_name) do
|
|
52
55
|
super(statement_name, params, *args)
|
|
53
56
|
end
|
|
54
57
|
end
|
|
55
58
|
|
|
56
59
|
def sync_exec(sql, *args)
|
|
57
|
-
trace(Ext::SPAN_SYNC_EXEC,
|
|
58
|
-
super(
|
|
60
|
+
trace(Ext::SPAN_SYNC_EXEC, sql: sql) do |sql_statement|
|
|
61
|
+
super(sql_statement, *args)
|
|
59
62
|
end
|
|
60
63
|
end
|
|
61
64
|
|
|
62
65
|
def sync_exec_params(sql, params, *args)
|
|
63
|
-
trace(Ext::SPAN_SYNC_EXEC_PARAMS,
|
|
64
|
-
super(
|
|
66
|
+
trace(Ext::SPAN_SYNC_EXEC_PARAMS, sql: sql) do |sql_statement|
|
|
67
|
+
super(sql_statement, params, *args)
|
|
65
68
|
end
|
|
66
69
|
end
|
|
67
70
|
|
|
68
71
|
def sync_exec_prepared(statement_name, params, *args)
|
|
69
|
-
trace(Ext::SPAN_SYNC_EXEC_PREPARED,
|
|
72
|
+
trace(Ext::SPAN_SYNC_EXEC_PREPARED, statement_name: statement_name) do
|
|
70
73
|
super(statement_name, params, *args)
|
|
71
74
|
end
|
|
72
75
|
end
|
|
73
76
|
|
|
74
77
|
private
|
|
75
78
|
|
|
76
|
-
def trace(name,
|
|
79
|
+
def trace(name, sql: nil, statement_name: nil)
|
|
77
80
|
service = Datadog.configuration_for(self, :service_name) || datadog_configuration[:service_name]
|
|
81
|
+
resource = statement_name || sql
|
|
82
|
+
|
|
78
83
|
Tracing.trace(name, service: service, resource: resource, type: Tracing::Metadata::Ext::SQL::TYPE) do |span|
|
|
79
84
|
annotate_span_with_query!(span, service)
|
|
80
85
|
# Set analytics sample rate
|
|
81
86
|
Contrib::Analytics.set_sample_rate(span, analytics_sample_rate) if analytics_enabled?
|
|
82
|
-
|
|
87
|
+
|
|
88
|
+
if sql
|
|
89
|
+
propagation_mode = Contrib::Propagation::SqlComment::Mode.new(comment_propagation)
|
|
90
|
+
Contrib::Propagation::SqlComment.annotate!(span, propagation_mode)
|
|
91
|
+
propagated_sql_statement = Contrib::Propagation::SqlComment.prepend_comment(sql, span, propagation_mode)
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
result = yield(propagated_sql_statement)
|
|
83
95
|
annotate_span_with_result!(span, result)
|
|
84
96
|
result
|
|
85
97
|
end
|
|
@@ -98,7 +110,7 @@ module Datadog
|
|
|
98
110
|
|
|
99
111
|
span.set_tag(Contrib::Ext::DB::TAG_INSTANCE, db)
|
|
100
112
|
span.set_tag(Contrib::Ext::DB::TAG_USER, user)
|
|
101
|
-
span.set_tag(Contrib::Ext::DB::TAG_SYSTEM, Ext::
|
|
113
|
+
span.set_tag(Contrib::Ext::DB::TAG_SYSTEM, Ext::TAG_SYSTEM)
|
|
102
114
|
|
|
103
115
|
span.set_tag(Tracing::Metadata::Ext::NET::TAG_TARGET_HOST, host)
|
|
104
116
|
span.set_tag(Tracing::Metadata::Ext::NET::TAG_TARGET_PORT, port)
|
|
@@ -121,6 +133,10 @@ module Datadog
|
|
|
121
133
|
def analytics_sample_rate
|
|
122
134
|
datadog_configuration[:analytics_sample_rate]
|
|
123
135
|
end
|
|
136
|
+
|
|
137
|
+
def comment_propagation
|
|
138
|
+
datadog_configuration[:comment_propagation]
|
|
139
|
+
end
|
|
124
140
|
end
|
|
125
141
|
end
|
|
126
142
|
end
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# typed: false
|
|
4
|
+
|
|
5
|
+
require 'erb'
|
|
6
|
+
|
|
7
|
+
module Datadog
|
|
8
|
+
module Tracing
|
|
9
|
+
module Contrib
|
|
10
|
+
module Propagation
|
|
11
|
+
module SqlComment
|
|
12
|
+
# To be prepended to a sql statement.
|
|
13
|
+
class Comment
|
|
14
|
+
def initialize(hash)
|
|
15
|
+
@hash = hash
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def to_s
|
|
19
|
+
@string ||= begin
|
|
20
|
+
ret = String.new
|
|
21
|
+
|
|
22
|
+
@hash.each do |key, value|
|
|
23
|
+
next if value.nil?
|
|
24
|
+
|
|
25
|
+
# Url encode
|
|
26
|
+
value = ERB::Util.url_encode(value)
|
|
27
|
+
|
|
28
|
+
# Escape SQL
|
|
29
|
+
ret << "#{key}='#{value}',"
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# Remove the last `,`
|
|
33
|
+
ret.chop!
|
|
34
|
+
|
|
35
|
+
"/*#{ret}*/"
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# typed: false
|
|
2
|
+
|
|
3
|
+
module Datadog
|
|
4
|
+
module Tracing
|
|
5
|
+
module Contrib
|
|
6
|
+
module Propagation
|
|
7
|
+
module SqlComment
|
|
8
|
+
module Ext
|
|
9
|
+
ENV_DBM_PROPAGATION_MODE = 'DD_DBM_PROPAGATION_MODE'.freeze
|
|
10
|
+
|
|
11
|
+
# The default mode for sql comment propagation
|
|
12
|
+
DISABLED = 'disabled'.freeze
|
|
13
|
+
|
|
14
|
+
# The `service` mode propagates service configuration
|
|
15
|
+
SERVICE = 'service'.freeze
|
|
16
|
+
|
|
17
|
+
# The `full` mode propagates service configuration + trace context
|
|
18
|
+
FULL = 'full'.freeze
|
|
19
|
+
|
|
20
|
+
# The value should be `true` when `full` mode
|
|
21
|
+
TAG_DBM_TRACE_INJECTED = '_dd.dbm_trace_injected'.freeze
|
|
22
|
+
|
|
23
|
+
KEY_DATABASE_SERVICE = 'dddbs'.freeze
|
|
24
|
+
KEY_ENVIRONMENT = 'dde'.freeze
|
|
25
|
+
KEY_PARENT_SERVICE = 'ddps'.freeze
|
|
26
|
+
KEY_VERSION = 'ddpv'.freeze
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# typed: false
|
|
2
|
+
|
|
3
|
+
require_relative 'ext'
|
|
4
|
+
|
|
5
|
+
module Datadog
|
|
6
|
+
module Tracing
|
|
7
|
+
module Contrib
|
|
8
|
+
module Propagation
|
|
9
|
+
# Implements sql comment propagation related contracts.
|
|
10
|
+
module SqlComment
|
|
11
|
+
Mode = Struct.new(:mode) do
|
|
12
|
+
def enabled?
|
|
13
|
+
service? || full?
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def service?
|
|
17
|
+
mode == Ext::SERVICE
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def full?
|
|
21
|
+
mode == Ext::FULL
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -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
|
|
@@ -56,16 +56,18 @@ module Datadog
|
|
|
56
56
|
# Find out if this is rack within rack
|
|
57
57
|
previous_request_span = env[Ext::RACK_ENV_REQUEST_SPAN]
|
|
58
58
|
|
|
59
|
+
return @app.call(env) if previous_request_span
|
|
60
|
+
|
|
59
61
|
# Extract distributed tracing context before creating any spans,
|
|
60
62
|
# so that all spans will be added to the distributed trace.
|
|
61
|
-
if configuration[:distributed_tracing]
|
|
63
|
+
if configuration[:distributed_tracing]
|
|
62
64
|
trace_digest = Tracing::Propagation::HTTP.extract(env)
|
|
63
65
|
Tracing.continue_trace!(trace_digest)
|
|
64
66
|
end
|
|
65
67
|
|
|
66
68
|
# Create a root Span to keep track of frontend web servers
|
|
67
69
|
# (i.e. Apache, nginx) if the header is properly set
|
|
68
|
-
frontend_span = compute_queue_time(env)
|
|
70
|
+
frontend_span = compute_queue_time(env)
|
|
69
71
|
|
|
70
72
|
trace_options = { span_type: Tracing::Metadata::Ext::HTTP::TYPE_INBOUND }
|
|
71
73
|
trace_options[:service] = configuration[:service_name] if configuration[:service_name]
|
|
@@ -127,6 +129,10 @@ module Datadog
|
|
|
127
129
|
request_headers_tags = parse_request_headers(request_header_collection)
|
|
128
130
|
response_headers_tags = parse_response_headers(headers || {})
|
|
129
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
|
+
|
|
130
136
|
# request_headers is subject to filtering and configuration so we
|
|
131
137
|
# get the user agent separately
|
|
132
138
|
user_agent = parse_user_agent_header(request_header_collection)
|
|
@@ -138,11 +144,11 @@ module Datadog
|
|
|
138
144
|
# 4. Fallback with verb + status, eq `GET 200`
|
|
139
145
|
request_span.resource ||=
|
|
140
146
|
if configuration[:middleware_names] && env['RESPONSE_MIDDLEWARE']
|
|
141
|
-
"#{env['RESPONSE_MIDDLEWARE']}##{
|
|
147
|
+
"#{env['RESPONSE_MIDDLEWARE']}##{original_request_method}"
|
|
142
148
|
elsif trace.resource_override?
|
|
143
149
|
trace.resource
|
|
144
150
|
else
|
|
145
|
-
"#{
|
|
151
|
+
"#{original_request_method} #{status}".strip
|
|
146
152
|
end
|
|
147
153
|
|
|
148
154
|
# Overrides the trace resource if it never been set
|
|
@@ -161,7 +167,7 @@ module Datadog
|
|
|
161
167
|
Contrib::Analytics.set_measured(request_span)
|
|
162
168
|
|
|
163
169
|
if request_span.get_tag(Tracing::Metadata::Ext::HTTP::TAG_METHOD).nil?
|
|
164
|
-
request_span.set_tag(Tracing::Metadata::Ext::HTTP::TAG_METHOD,
|
|
170
|
+
request_span.set_tag(Tracing::Metadata::Ext::HTTP::TAG_METHOD, original_request_method)
|
|
165
171
|
end
|
|
166
172
|
|
|
167
173
|
url = parse_url(env, original_env)
|
|
@@ -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)'
|
|
@@ -12,6 +12,42 @@ 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
|
+
def initialize(options = {})
|
|
24
|
+
options[:redis_instance] = self
|
|
25
|
+
|
|
26
|
+
super(options)
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# Patch for redis client
|
|
32
|
+
module ClientPatch
|
|
33
|
+
def self.included(base)
|
|
34
|
+
base.prepend(InstanceMethods)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# Instance method patch for redis client
|
|
38
|
+
module InstanceMethods
|
|
39
|
+
def initialize(options = {})
|
|
40
|
+
@redis_instance = options.delete(:redis_instance)
|
|
41
|
+
|
|
42
|
+
super(options)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
private
|
|
46
|
+
|
|
47
|
+
attr_reader :redis_instance
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
15
51
|
module_function
|
|
16
52
|
|
|
17
53
|
def target_version
|
|
@@ -26,6 +62,11 @@ module Datadog
|
|
|
26
62
|
require_relative 'quantize'
|
|
27
63
|
require_relative 'instrumentation'
|
|
28
64
|
|
|
65
|
+
# InstancePatch and ClientPatch allows the client object to access pin on redis instance
|
|
66
|
+
::Redis.include(InstancePatch)
|
|
67
|
+
::Redis::Client.include(ClientPatch)
|
|
68
|
+
|
|
69
|
+
# TODO: To support redis-rb 5.x, Redis::Client -> RedisClient
|
|
29
70
|
::Redis::Client.include(Instrumentation)
|
|
30
71
|
end
|
|
31
72
|
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
|
|
|
@@ -17,69 +17,12 @@ module Datadog
|
|
|
17
17
|
# Datadog::Tracing::Contrib::Sinatra::Tracer is a Sinatra extension which traces
|
|
18
18
|
# requests.
|
|
19
19
|
module Tracer
|
|
20
|
-
def route(verb, action, *)
|
|
21
|
-
# Keep track of the route name when the app is instantiated for an
|
|
22
|
-
# incoming request.
|
|
23
|
-
condition do
|
|
24
|
-
# If the option to prepend script names is enabled, then
|
|
25
|
-
# prepend the script name from the request onto the action.
|
|
26
|
-
#
|
|
27
|
-
# DEV: env['sinatra.route'] already exists with very similar information,
|
|
28
|
-
# DEV: but doesn't account for our `resource_script_names` logic.
|
|
29
|
-
#
|
|
30
|
-
@datadog_route = if Datadog.configuration.tracing[:sinatra][:resource_script_names]
|
|
31
|
-
"#{request.script_name}#{action}"
|
|
32
|
-
else
|
|
33
|
-
action
|
|
34
|
-
end
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
super
|
|
38
|
-
end
|
|
39
|
-
|
|
40
20
|
def self.registered(app)
|
|
41
21
|
app.use TracerMiddleware, app_instance: app
|
|
42
|
-
|
|
43
|
-
app.after do
|
|
44
|
-
next unless Tracing.enabled?
|
|
45
|
-
|
|
46
|
-
span = Sinatra::Env.datadog_span(env, app)
|
|
47
|
-
|
|
48
|
-
# TODO: `route` should *only* be populated if @datadog_route is defined.
|
|
49
|
-
# TODO: If @datadog_route is not defined, then this Sinatra app is not responsible
|
|
50
|
-
# TODO: for handling this request.
|
|
51
|
-
# TODO:
|
|
52
|
-
# TODO: This change would be BREAKING for any Sinatra app (classic or modular),
|
|
53
|
-
# TODO: as it affects the `resource` value for requests not handled by the Sinatra app.
|
|
54
|
-
# TODO: Currently we use "#{method} #{path}" in such aces, but `path` is the raw,
|
|
55
|
-
# TODO: high-cardinality HTTP path, and can contain PII.
|
|
56
|
-
# TODO:
|
|
57
|
-
# TODO: The value we should use as the `resource` when the Sinatra app is not
|
|
58
|
-
# TODO: responsible for the request is a tricky subject.
|
|
59
|
-
# TODO: The best option is a value that clearly communicates that this app did not
|
|
60
|
-
# TODO: handle this request. It's important to keep in mind that an unhandled request
|
|
61
|
-
# TODO: by this Sinatra app might still be handled by another Rack middleware (which can
|
|
62
|
-
# TODO: be a Sinatra app itself) or it might just 404 if not handled at all.
|
|
63
|
-
# TODO:
|
|
64
|
-
# TODO: A possible value for `resource` could set a high level description, e.g.
|
|
65
|
-
# TODO: `request.request_method`, given we don't have the response object available yet.
|
|
66
|
-
route = if defined?(@datadog_route)
|
|
67
|
-
@datadog_route
|
|
68
|
-
else
|
|
69
|
-
# Fallback in case no routes have matched
|
|
70
|
-
request.path
|
|
71
|
-
end
|
|
72
|
-
|
|
73
|
-
span.resource = "#{request.request_method} #{route}"
|
|
74
|
-
span.set_tag(Ext::TAG_ROUTE_PATH, route)
|
|
75
|
-
end
|
|
76
22
|
end
|
|
77
23
|
|
|
78
24
|
# Method overrides for Sinatra::Base
|
|
79
25
|
module Base
|
|
80
|
-
MISSING_REQUEST_SPAN_ONLY_ONCE = Core::Utils::OnlyOnce.new
|
|
81
|
-
private_constant :MISSING_REQUEST_SPAN_ONLY_ONCE
|
|
82
|
-
|
|
83
26
|
def render(engine, data, *)
|
|
84
27
|
return super unless Tracing.enabled?
|
|
85
28
|
|
|
@@ -102,19 +45,21 @@ module Datadog
|
|
|
102
45
|
|
|
103
46
|
# Invoked when a matching route is found.
|
|
104
47
|
# This method yields directly to user code.
|
|
105
|
-
# rubocop:disable Metrics/MethodLength
|
|
106
48
|
def route_eval
|
|
107
49
|
configuration = Datadog.configuration.tracing[:sinatra]
|
|
108
50
|
return super unless Tracing.enabled?
|
|
109
51
|
|
|
52
|
+
datadog_route = Sinatra::Env.route_path(env)
|
|
53
|
+
|
|
110
54
|
Tracing.trace(
|
|
111
55
|
Ext::SPAN_ROUTE,
|
|
112
56
|
service: configuration[:service_name],
|
|
113
57
|
span_type: Tracing::Metadata::Ext::HTTP::TYPE_INBOUND,
|
|
114
|
-
resource: "#{request.request_method} #{
|
|
58
|
+
resource: "#{request.request_method} #{datadog_route}",
|
|
115
59
|
) do |span, trace|
|
|
116
60
|
span.set_tag(Ext::TAG_APP_NAME, settings.name || settings.superclass.name)
|
|
117
|
-
span.set_tag(Ext::TAG_ROUTE_PATH,
|
|
61
|
+
span.set_tag(Ext::TAG_ROUTE_PATH, datadog_route)
|
|
62
|
+
|
|
118
63
|
if request.script_name && !request.script_name.empty?
|
|
119
64
|
span.set_tag(Ext::TAG_SCRIPT_NAME, request.script_name)
|
|
120
65
|
end
|
|
@@ -124,32 +69,15 @@ module Datadog
|
|
|
124
69
|
|
|
125
70
|
trace.resource = span.resource
|
|
126
71
|
|
|
127
|
-
sinatra_request_span =
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
else
|
|
131
|
-
Sinatra::Env.datadog_span(env, self.class)
|
|
132
|
-
end
|
|
133
|
-
if sinatra_request_span
|
|
134
|
-
sinatra_request_span.resource = span.resource
|
|
135
|
-
else
|
|
136
|
-
MISSING_REQUEST_SPAN_ONLY_ONCE.run do
|
|
137
|
-
Datadog.logger.warn do
|
|
138
|
-
'Sinatra integration is misconfigured, reported traces will be missing request metadata ' \
|
|
139
|
-
'such as path and HTTP status code. ' \
|
|
140
|
-
'Did you forget to add `register Datadog::Tracing::Contrib::Sinatra::Tracer` to your ' \
|
|
141
|
-
'`Sinatra::Base` subclass? ' \
|
|
142
|
-
'See <https://docs.datadoghq.com/tracing/setup_overview/setup/ruby/#sinatra> for more details.'
|
|
143
|
-
end
|
|
144
|
-
end
|
|
145
|
-
end
|
|
72
|
+
sinatra_request_span = Sinatra::Env.datadog_span(env)
|
|
73
|
+
|
|
74
|
+
sinatra_request_span.resource = span.resource
|
|
146
75
|
|
|
147
76
|
Contrib::Analytics.set_measured(span)
|
|
148
77
|
|
|
149
78
|
super
|
|
150
79
|
end
|
|
151
80
|
end
|
|
152
|
-
# rubocop:enable Metrics/MethodLength
|
|
153
81
|
end
|
|
154
82
|
end
|
|
155
83
|
end
|