ddtrace 0.30.1 → 0.31.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 +5 -5
- data/.circleci/config.yml +28 -0
- data/.circleci/images/primary/Dockerfile-2.7.0 +73 -0
- data/Appraisals +111 -2
- data/CHANGELOG.md +33 -1
- data/Rakefile +69 -1
- data/ddtrace.gemspec +1 -0
- data/docker-compose.yml +30 -0
- data/docs/GettingStarted.md +28 -3
- data/lib/ddtrace.rb +6 -0
- data/lib/ddtrace/buffer.rb +3 -3
- data/lib/ddtrace/configuration/base.rb +2 -1
- data/lib/ddtrace/configuration/settings.rb +15 -2
- data/lib/ddtrace/context.rb +62 -57
- data/lib/ddtrace/context_flush.rb +51 -114
- data/lib/ddtrace/context_provider.rb +45 -0
- data/lib/ddtrace/contrib/action_cable/configuration/settings.rb +25 -0
- data/lib/ddtrace/contrib/action_cable/event.rb +65 -0
- data/lib/ddtrace/contrib/action_cable/events.rb +33 -0
- data/lib/ddtrace/contrib/action_cable/events/broadcast.rb +49 -0
- data/lib/ddtrace/contrib/action_cable/events/perform_action.rb +52 -0
- data/lib/ddtrace/contrib/action_cable/events/transmit.rb +50 -0
- data/lib/ddtrace/contrib/action_cable/ext.rb +23 -0
- data/lib/ddtrace/contrib/action_cable/instrumentation.rb +31 -0
- data/lib/ddtrace/contrib/action_cable/integration.rb +36 -0
- data/lib/ddtrace/contrib/action_cable/patcher.rb +27 -0
- data/lib/ddtrace/contrib/action_pack/action_controller/instrumentation.rb +2 -2
- data/lib/ddtrace/contrib/action_view/events/render_partial.rb +5 -3
- data/lib/ddtrace/contrib/action_view/events/render_template.rb +5 -3
- data/lib/ddtrace/contrib/action_view/instrumentation/partial_renderer.rb +2 -1
- data/lib/ddtrace/contrib/action_view/instrumentation/template_renderer.rb +4 -2
- data/lib/ddtrace/contrib/action_view/patcher.rb +1 -1
- data/lib/ddtrace/contrib/active_record/events/instantiation.rb +1 -1
- data/lib/ddtrace/contrib/active_record/events/sql.rb +1 -1
- data/lib/ddtrace/contrib/active_support/cache/instrumentation.rb +2 -2
- data/lib/ddtrace/contrib/active_support/notifications/subscription.rb +2 -2
- data/lib/ddtrace/contrib/dalli/patcher.rb +1 -1
- data/lib/ddtrace/contrib/dalli/quantize.rb +1 -1
- data/lib/ddtrace/contrib/elasticsearch/patcher.rb +1 -1
- data/lib/ddtrace/contrib/excon/middleware.rb +3 -3
- data/lib/ddtrace/contrib/faraday/connection.rb +18 -0
- data/lib/ddtrace/contrib/faraday/integration.rb +1 -1
- data/lib/ddtrace/contrib/faraday/patcher.rb +3 -3
- data/lib/ddtrace/contrib/grape/endpoint.rb +5 -5
- data/lib/ddtrace/contrib/grape/patcher.rb +1 -1
- data/lib/ddtrace/contrib/grpc/datadog_interceptor/client.rb +1 -1
- data/lib/ddtrace/contrib/grpc/datadog_interceptor/server.rb +2 -2
- data/lib/ddtrace/contrib/grpc/patcher.rb +1 -1
- data/lib/ddtrace/contrib/http/instrumentation.rb +1 -1
- data/lib/ddtrace/contrib/mongodb/subscribers.rb +2 -2
- data/lib/ddtrace/contrib/patchable.rb +1 -1
- data/lib/ddtrace/contrib/patcher.rb +1 -1
- data/lib/ddtrace/contrib/rack/middlewares.rb +2 -2
- data/lib/ddtrace/contrib/rack/patcher.rb +2 -2
- data/lib/ddtrace/contrib/rack/request_queue.rb +1 -1
- data/lib/ddtrace/contrib/rails/configuration/settings.rb +1 -0
- data/lib/ddtrace/contrib/rails/framework.rb +12 -0
- data/lib/ddtrace/contrib/rake/instrumentation.rb +2 -2
- data/lib/ddtrace/contrib/redis/quantize.rb +1 -1
- data/lib/ddtrace/contrib/sinatra/tracer.rb +1 -1
- data/lib/ddtrace/ext/forced_tracing.rb +1 -1
- data/lib/ddtrace/ext/sampling.rb +3 -0
- data/lib/ddtrace/logger.rb +42 -0
- data/lib/ddtrace/metrics.rb +5 -5
- data/lib/ddtrace/monkey.rb +1 -1
- data/lib/ddtrace/pin.rb +1 -1
- data/lib/ddtrace/pipeline.rb +1 -1
- data/lib/ddtrace/propagation/http_propagator.rb +2 -2
- data/lib/ddtrace/runtime/cgroup.rb +1 -1
- data/lib/ddtrace/runtime/container.rb +1 -1
- data/lib/ddtrace/runtime/metrics.rb +1 -1
- data/lib/ddtrace/sampler.rb +1 -1
- data/lib/ddtrace/sampling/rule.rb +1 -1
- data/lib/ddtrace/sampling/rule_sampler.rb +4 -4
- data/lib/ddtrace/span.rb +24 -6
- data/lib/ddtrace/sync_writer.rb +4 -3
- data/lib/ddtrace/tracer.rb +37 -77
- data/lib/ddtrace/transport/http/client.rb +2 -2
- data/lib/ddtrace/utils.rb +1 -1
- data/lib/ddtrace/version.rb +2 -2
- data/lib/ddtrace/workers.rb +3 -3
- data/lib/ddtrace/writer.rb +3 -2
- metadata +44 -6
- data/lib/ddtrace/contrib/faraday/rack_builder.rb +0 -18
- data/lib/ddtrace/provider.rb +0 -21
@@ -30,7 +30,7 @@ module Datadog
|
|
30
30
|
rescue StandardError => e
|
31
31
|
# in case of an Exception we don't create a
|
32
32
|
# `request.queuing` span
|
33
|
-
Datadog::
|
33
|
+
Datadog::Logger.log.debug("[rack] unable to parse request queue headers: #{e}")
|
34
34
|
nil
|
35
35
|
end
|
36
36
|
end
|
@@ -67,6 +67,7 @@ module Datadog
|
|
67
67
|
option :tracer do |o|
|
68
68
|
o.delegate_to { Datadog.tracer }
|
69
69
|
o.on_set do |value|
|
70
|
+
Datadog.configuration[:action_cable][:tracer] = value
|
70
71
|
Datadog.configuration[:active_record][:tracer] = value
|
71
72
|
Datadog.configuration[:active_support][:tracer] = value
|
72
73
|
Datadog.configuration[:action_pack][:tracer] = value
|
@@ -3,6 +3,7 @@ require 'ddtrace/ext/app_types'
|
|
3
3
|
|
4
4
|
require 'ddtrace/contrib/active_record/integration'
|
5
5
|
require 'ddtrace/contrib/active_support/integration'
|
6
|
+
require 'ddtrace/contrib/action_cable/integration'
|
6
7
|
require 'ddtrace/contrib/action_pack/integration'
|
7
8
|
require 'ddtrace/contrib/action_view/integration'
|
8
9
|
require 'ddtrace/contrib/grape/endpoint'
|
@@ -23,6 +24,7 @@ module Datadog
|
|
23
24
|
config = config_with_defaults
|
24
25
|
|
25
26
|
activate_rack!(config)
|
27
|
+
activate_action_cable!(config)
|
26
28
|
activate_active_support!(config)
|
27
29
|
activate_action_pack!(config)
|
28
30
|
activate_action_view!(config)
|
@@ -65,6 +67,16 @@ module Datadog
|
|
65
67
|
)
|
66
68
|
end
|
67
69
|
|
70
|
+
def self.activate_action_cable!(config)
|
71
|
+
return unless defined?(::ActionCable)
|
72
|
+
|
73
|
+
Datadog.configuration.use(
|
74
|
+
:action_cable,
|
75
|
+
service_name: "#{config[:service_name]}-#{Contrib::ActionCable::Ext::SERVICE_NAME}",
|
76
|
+
tracer: config[:tracer]
|
77
|
+
)
|
78
|
+
end
|
79
|
+
|
68
80
|
def self.activate_action_pack!(config)
|
69
81
|
return unless defined?(::ActionPack)
|
70
82
|
|
@@ -47,14 +47,14 @@ module Datadog
|
|
47
47
|
span.set_tag(Ext::TAG_TASK_ARG_NAMES, arg_names)
|
48
48
|
span.set_tag(Ext::TAG_INVOKE_ARGS, quantize_args(args)) unless args.nil?
|
49
49
|
rescue StandardError => e
|
50
|
-
Datadog::
|
50
|
+
Datadog::Logger.log.debug("Error while tracing Rake invoke: #{e.message}")
|
51
51
|
end
|
52
52
|
|
53
53
|
def annotate_execute!(span, args)
|
54
54
|
span.resource = name
|
55
55
|
span.set_tag(Ext::TAG_EXECUTE_ARGS, quantize_args(args.to_hash)) unless args.nil?
|
56
56
|
rescue StandardError => e
|
57
|
-
Datadog::
|
57
|
+
Datadog::Logger.log.debug("Error while tracing Rake execute: #{e.message}")
|
58
58
|
end
|
59
59
|
|
60
60
|
def quantize_args(args)
|
@@ -15,7 +15,7 @@ module Datadog
|
|
15
15
|
str = Utils.utf8_encode(str, binary: true, placeholder: PLACEHOLDER)
|
16
16
|
Utils.truncate(str, VALUE_MAX_LEN, TOO_LONG_MARK)
|
17
17
|
rescue => e
|
18
|
-
Datadog::
|
18
|
+
Datadog::Logger.log.debug("non formattable Redis arg #{str}: #{e}")
|
19
19
|
PLACEHOLDER
|
20
20
|
end
|
21
21
|
|
@@ -12,7 +12,7 @@ module Datadog
|
|
12
12
|
|
13
13
|
# Only log each deprecation warning once (safeguard against log spam)
|
14
14
|
unless @deprecation_warning_shown
|
15
|
-
Datadog::
|
15
|
+
Datadog::Logger.log.warn(
|
16
16
|
'forced tracing: Datadog::Ext::ForcedTracing has been renamed to Datadog::Ext::ManualTracing'
|
17
17
|
)
|
18
18
|
@deprecation_warning_shown = true
|
data/lib/ddtrace/ext/sampling.rb
CHANGED
@@ -1,6 +1,9 @@
|
|
1
1
|
module Datadog
|
2
2
|
module Ext
|
3
3
|
module Sampling
|
4
|
+
ENV_SAMPLE_RATE = 'DD_TRACE_SAMPLE_RATE'.freeze
|
5
|
+
ENV_RATE_LIMIT = 'DD_TRACE_RATE_LIMIT'.freeze
|
6
|
+
|
4
7
|
# If rule sampling is applied to a span, set this metric the sample rate configured for that rule.
|
5
8
|
# This should be done regardless of sampling outcome.
|
6
9
|
RULE_SAMPLE_RATE = '_dd.rule_psr'.freeze
|
data/lib/ddtrace/logger.rb
CHANGED
@@ -7,6 +7,48 @@ module Datadog
|
|
7
7
|
# - progname defaults to ddtrace to clearly identify Datadog dd-trace-rb related messages
|
8
8
|
# - adds last caller stack-trace info to know where the message comes from
|
9
9
|
class Logger < ::Logger
|
10
|
+
# Global, memoized, lazy initialized instance of a logger that is used within the the Datadog
|
11
|
+
# namespace. This logger outputs to +STDOUT+ by default, and is considered thread-safe.
|
12
|
+
class << self
|
13
|
+
def log
|
14
|
+
unless defined? @logger
|
15
|
+
@logger = Datadog::Logger.new(STDOUT)
|
16
|
+
@logger.level = Logger::WARN
|
17
|
+
end
|
18
|
+
@logger
|
19
|
+
end
|
20
|
+
|
21
|
+
# Override the default logger with a custom one.
|
22
|
+
def log=(logger)
|
23
|
+
return unless logger
|
24
|
+
return unless logger.respond_to? :methods
|
25
|
+
return unless logger.respond_to? :error
|
26
|
+
if logger.respond_to? :methods
|
27
|
+
unimplemented = new(STDOUT).methods - logger.methods
|
28
|
+
unless unimplemented.empty?
|
29
|
+
logger.error("logger #{logger} does not implement #{unimplemented}")
|
30
|
+
return
|
31
|
+
end
|
32
|
+
end
|
33
|
+
@logger = logger
|
34
|
+
end
|
35
|
+
|
36
|
+
# Activate the debug mode providing more information related to tracer usage
|
37
|
+
# Default to Warn level unless using custom logger
|
38
|
+
def debug_logging=(value)
|
39
|
+
if value
|
40
|
+
log.level = Logger::DEBUG
|
41
|
+
elsif log.is_a?(Datadog::Logger)
|
42
|
+
log.level = Logger::WARN
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
# Return if the debug mode is activated or not
|
47
|
+
def debug_logging
|
48
|
+
log.level == Logger::DEBUG
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
10
52
|
def initialize(*args, &block)
|
11
53
|
super
|
12
54
|
self.progname = LOG_PREFIX
|
data/lib/ddtrace/metrics.rb
CHANGED
@@ -62,7 +62,7 @@ module Datadog
|
|
62
62
|
|
63
63
|
statsd.count(stat, value, metric_options(options))
|
64
64
|
rescue StandardError => e
|
65
|
-
Datadog::
|
65
|
+
Datadog::Logger.log.error("Failed to send count stat. Cause: #{e.message} Source: #{e.backtrace.first}")
|
66
66
|
end
|
67
67
|
|
68
68
|
def distribution(stat, value = nil, options = nil, &block)
|
@@ -72,7 +72,7 @@ module Datadog
|
|
72
72
|
|
73
73
|
statsd.distribution(stat, value, metric_options(options))
|
74
74
|
rescue StandardError => e
|
75
|
-
Datadog::
|
75
|
+
Datadog::Logger.log.error("Failed to send distribution stat. Cause: #{e.message} Source: #{e.backtrace.first}")
|
76
76
|
end
|
77
77
|
|
78
78
|
def increment(stat, options = nil)
|
@@ -81,7 +81,7 @@ module Datadog
|
|
81
81
|
|
82
82
|
statsd.increment(stat, metric_options(options))
|
83
83
|
rescue StandardError => e
|
84
|
-
Datadog::
|
84
|
+
Datadog::Logger.log.error("Failed to send increment stat. Cause: #{e.message} Source: #{e.backtrace.first}")
|
85
85
|
end
|
86
86
|
|
87
87
|
def gauge(stat, value = nil, options = nil, &block)
|
@@ -91,7 +91,7 @@ module Datadog
|
|
91
91
|
|
92
92
|
statsd.gauge(stat, value, metric_options(options))
|
93
93
|
rescue StandardError => e
|
94
|
-
Datadog::
|
94
|
+
Datadog::Logger.log.error("Failed to send gauge stat. Cause: #{e.message} Source: #{e.backtrace.first}")
|
95
95
|
end
|
96
96
|
|
97
97
|
def time(stat, options = nil)
|
@@ -107,7 +107,7 @@ module Datadog
|
|
107
107
|
distribution(stat, ((finished - start) * 1000), options)
|
108
108
|
end
|
109
109
|
rescue StandardError => e
|
110
|
-
Datadog::
|
110
|
+
Datadog::Logger.log.error("Failed to send time stat. Cause: #{e.message} Source: #{e.backtrace.first}")
|
111
111
|
end
|
112
112
|
end
|
113
113
|
|
data/lib/ddtrace/monkey.rb
CHANGED
data/lib/ddtrace/pin.rb
CHANGED
@@ -107,7 +107,7 @@ module Datadog
|
|
107
107
|
def log_deprecation_warning(method_name)
|
108
108
|
# Only log each deprecation warning once (safeguard against log spam)
|
109
109
|
do_once(method_name) do
|
110
|
-
Datadog::
|
110
|
+
Datadog::Logger.log.warn("#{method_name}:#{DEPRECATION_WARNING}")
|
111
111
|
end
|
112
112
|
end
|
113
113
|
end
|
data/lib/ddtrace/pipeline.rb
CHANGED
@@ -19,7 +19,7 @@ module Datadog
|
|
19
19
|
def self.inject!(context, env)
|
20
20
|
# Prevent propagation from being attempted if context provided is nil.
|
21
21
|
if context.nil?
|
22
|
-
::Datadog::
|
22
|
+
::Datadog::Logger.log.debug('Cannot inject context into env to propagate over HTTP: context is nil.'.freeze)
|
23
23
|
return
|
24
24
|
end
|
25
25
|
|
@@ -58,7 +58,7 @@ module Datadog
|
|
58
58
|
# Return an empty/new context if we have a mismatch in values extracted
|
59
59
|
msg = "#{context.trace_id} != #{extracted_context.trace_id} && " \
|
60
60
|
"#{context.span_id} != #{extracted_context.span_id}"
|
61
|
-
::Datadog::
|
61
|
+
::Datadog::Logger.log.debug("Cannot extract context from HTTP: extracted contexts differ, #{msg}".freeze)
|
62
62
|
# DEV: This will return from `self.extract` not this `each` block
|
63
63
|
return ::Datadog::Context.new
|
64
64
|
end
|
@@ -27,7 +27,7 @@ module Datadog
|
|
27
27
|
end
|
28
28
|
end
|
29
29
|
rescue StandardError => e
|
30
|
-
Datadog::
|
30
|
+
Datadog::Logger.log.error("Error while parsing cgroup. Cause: #{e.message} Location: #{e.backtrace.first}")
|
31
31
|
end
|
32
32
|
end
|
33
33
|
end
|
@@ -63,7 +63,7 @@ module Datadog
|
|
63
63
|
def try_flush
|
64
64
|
yield
|
65
65
|
rescue StandardError => e
|
66
|
-
Datadog::
|
66
|
+
Datadog::Logger.log.error("Error while sending runtime metric. Cause: #{e.message}")
|
67
67
|
end
|
68
68
|
|
69
69
|
def default_metric_options
|
data/lib/ddtrace/sampler.rb
CHANGED
@@ -48,7 +48,7 @@ module Datadog
|
|
48
48
|
# sampled.
|
49
49
|
def initialize(sample_rate = 1.0)
|
50
50
|
unless sample_rate > 0.0 && sample_rate <= 1.0
|
51
|
-
Datadog::
|
51
|
+
Datadog::Logger.log.error('sample rate is not between 0 and 1, disabling the sampler')
|
52
52
|
sample_rate = 1.0
|
53
53
|
end
|
54
54
|
|
@@ -28,7 +28,7 @@ module Datadog
|
|
28
28
|
def match?(span)
|
29
29
|
@matcher.match?(span)
|
30
30
|
rescue => e
|
31
|
-
Datadog::
|
31
|
+
Datadog::Logger.log.error("Matcher failed. Cause: #{e.message} Source: #{e.backtrace.first}")
|
32
32
|
nil
|
33
33
|
end
|
34
34
|
|
@@ -19,15 +19,15 @@ module Datadog
|
|
19
19
|
attr_reader :rules, :rate_limiter, :default_sampler
|
20
20
|
|
21
21
|
# @param rules [Array<Rule>] ordered list of rules to be applied to a span
|
22
|
-
# @param rate_limit [Float] number of traces per second, defaults to 100
|
22
|
+
# @param rate_limit [Float] number of traces per second, defaults to +100+
|
23
23
|
# @param rate_limiter [RateLimiter] limiter applied after rule matching
|
24
24
|
# @param default_sample_rate [Float] fallback sample rate when no rules apply to a span,
|
25
25
|
# between +[0,1]+, defaults to +1+
|
26
26
|
# @param default_sampler [Sample] fallback strategy when no rules apply to a span
|
27
27
|
def initialize(rules = [],
|
28
|
-
rate_limit:
|
28
|
+
rate_limit: Datadog.configuration.sampling.rate_limit,
|
29
29
|
rate_limiter: nil,
|
30
|
-
default_sample_rate:
|
30
|
+
default_sample_rate: Datadog.configuration.sampling.default_rate,
|
31
31
|
default_sampler: nil)
|
32
32
|
|
33
33
|
@rules = rules
|
@@ -95,7 +95,7 @@ module Datadog
|
|
95
95
|
set_limiter_metrics(span, rate_limiter.effective_rate)
|
96
96
|
end
|
97
97
|
rescue StandardError => e
|
98
|
-
Datadog::
|
98
|
+
Datadog::Logger.log.error("Rule sampling failed. Cause: #{e.message} Source: #{e.backtrace.first}")
|
99
99
|
yield(span)
|
100
100
|
end
|
101
101
|
|
data/lib/ddtrace/span.rb
CHANGED
@@ -31,6 +31,9 @@ module Datadog
|
|
31
31
|
# parsing 64-bit integers for distributed tracing since an upstream system may generate one
|
32
32
|
EXTERNAL_MAX_ID = 2**64
|
33
33
|
|
34
|
+
# This limit is for numeric tags because uint64 could end up rounded.
|
35
|
+
NUMERIC_TAG_SIZE_RANGE = (-2**53..2**53)
|
36
|
+
|
34
37
|
attr_accessor :name, :service, :resource, :span_type,
|
35
38
|
:start_time, :end_time,
|
36
39
|
:span_id, :trace_id, :parent_id,
|
@@ -80,9 +83,21 @@ module Datadog
|
|
80
83
|
#
|
81
84
|
# span.set_tag('http.method', request.method)
|
82
85
|
def set_tag(key, value = nil)
|
83
|
-
|
86
|
+
# Keys must be unique between tags and metrics
|
87
|
+
@metrics.delete(key)
|
88
|
+
|
89
|
+
# NOTE: Adding numeric tags as metrics is stop-gap support
|
90
|
+
# for numeric typed tags. Eventually they will become
|
91
|
+
# tags again.
|
92
|
+
# Any numeric that is not an integer greater than max size is logged as a metric.
|
93
|
+
# Everything else gets logged as a tag.
|
94
|
+
if value.is_a?(Numeric) && !(value.is_a?(Integer) && !NUMERIC_TAG_SIZE_RANGE.cover?(value))
|
95
|
+
set_metric(key, value)
|
96
|
+
else
|
97
|
+
@meta[key] = value.to_s
|
98
|
+
end
|
84
99
|
rescue StandardError => e
|
85
|
-
Datadog::
|
100
|
+
Datadog::Logger.log.debug("Unable to set the tag #{key}, ignoring it. Caused by: #{e}")
|
86
101
|
end
|
87
102
|
|
88
103
|
# This method removes a tag for the given key.
|
@@ -92,17 +107,20 @@ module Datadog
|
|
92
107
|
|
93
108
|
# Return the tag with the given key, nil if it doesn't exist.
|
94
109
|
def get_tag(key)
|
95
|
-
@meta[key]
|
110
|
+
@meta[key] || @metrics[key]
|
96
111
|
end
|
97
112
|
|
98
113
|
# This method sets a tag with a floating point value for the given key. It acts
|
99
114
|
# like `set_tag()` and it simply add a tag without further processing.
|
100
115
|
def set_metric(key, value)
|
116
|
+
# Keys must be unique between tags and metrics
|
117
|
+
@meta.delete(key)
|
118
|
+
|
101
119
|
# enforce that the value is a floating point number
|
102
120
|
value = Float(value)
|
103
121
|
@metrics[key] = value
|
104
122
|
rescue StandardError => e
|
105
|
-
Datadog::
|
123
|
+
Datadog::Logger.log.debug("Unable to set the metric #{key}, ignoring it. Caused by: #{e}")
|
106
124
|
end
|
107
125
|
|
108
126
|
# This method removes a metric for the given key. It acts like {#remove_tag}.
|
@@ -112,7 +130,7 @@ module Datadog
|
|
112
130
|
|
113
131
|
# Return the metric with the given key, nil if it doesn't exist.
|
114
132
|
def get_metric(key)
|
115
|
-
@metrics[key]
|
133
|
+
@metrics[key] || @meta[key]
|
116
134
|
end
|
117
135
|
|
118
136
|
# Mark the span with the given error.
|
@@ -154,7 +172,7 @@ module Datadog
|
|
154
172
|
@context.close_span(self)
|
155
173
|
@tracer.record(self)
|
156
174
|
rescue StandardError => e
|
157
|
-
Datadog::
|
175
|
+
Datadog::Logger.log.debug("error recording finished trace: #{e}")
|
158
176
|
Diagnostics::Health.metrics.error_span_finish(1, tags: ["error:#{e.class.name}"])
|
159
177
|
end
|
160
178
|
self
|
data/lib/ddtrace/sync_writer.rb
CHANGED
@@ -27,7 +27,7 @@ module Datadog
|
|
27
27
|
def write(trace, services = nil)
|
28
28
|
unless services.nil?
|
29
29
|
Datadog::Patcher.do_once('SyncWriter#write') do
|
30
|
-
Datadog::
|
30
|
+
Datadog::Logger.log.warn(%(
|
31
31
|
write: Writing services has been deprecated and no longer need to be provided.
|
32
32
|
write(traces, services) can be updted to write(traces)
|
33
33
|
))
|
@@ -38,7 +38,7 @@ module Datadog
|
|
38
38
|
proc { flush_trace(trace) }
|
39
39
|
)
|
40
40
|
rescue => e
|
41
|
-
|
41
|
+
Logger.log.debug(e)
|
42
42
|
end
|
43
43
|
|
44
44
|
private
|
@@ -49,8 +49,9 @@ module Datadog
|
|
49
49
|
|
50
50
|
def flush_trace(trace)
|
51
51
|
processed_traces = Pipeline.process!([trace])
|
52
|
+
return if processed_traces.empty?
|
52
53
|
inject_hostname!(processed_traces.first) if Datadog.configuration.report_hostname
|
53
|
-
transport.
|
54
|
+
transport.send_traces(processed_traces)
|
54
55
|
end
|
55
56
|
|
56
57
|
def inject_hostname!(trace)
|
data/lib/ddtrace/tracer.rb
CHANGED
@@ -5,8 +5,6 @@ require 'pathname'
|
|
5
5
|
|
6
6
|
require 'ddtrace/span'
|
7
7
|
require 'ddtrace/context'
|
8
|
-
require 'ddtrace/context_flush'
|
9
|
-
require 'ddtrace/provider'
|
10
8
|
require 'ddtrace/logger'
|
11
9
|
require 'ddtrace/writer'
|
12
10
|
require 'ddtrace/sampler'
|
@@ -21,57 +19,17 @@ module Datadog
|
|
21
19
|
# of these function calls and sub-requests would be encapsulated within a single trace.
|
22
20
|
# rubocop:disable Metrics/ClassLength
|
23
21
|
class Tracer
|
24
|
-
attr_reader :sampler, :tags, :provider
|
22
|
+
attr_reader :sampler, :tags, :provider, :context_flush
|
25
23
|
attr_accessor :enabled, :writer
|
26
24
|
attr_writer :default_service
|
27
25
|
|
28
26
|
ALLOWED_SPAN_OPTIONS = [:service, :resource, :span_type].freeze
|
29
27
|
DEFAULT_ON_ERROR = proc { |span, error| span.set_error(error) unless span.nil? }
|
30
28
|
|
31
|
-
# Global, memoized, lazy initialized instance of a logger that is used within the the Datadog
|
32
|
-
# namespace. This logger outputs to +STDOUT+ by default, and is considered thread-safe.
|
33
|
-
def self.log
|
34
|
-
unless defined? @logger
|
35
|
-
@logger = Datadog::Logger.new(STDOUT)
|
36
|
-
@logger.level = Logger::WARN
|
37
|
-
end
|
38
|
-
@logger
|
39
|
-
end
|
40
|
-
|
41
|
-
# Override the default logger with a custom one.
|
42
|
-
def self.log=(logger)
|
43
|
-
return unless logger
|
44
|
-
return unless logger.respond_to? :methods
|
45
|
-
return unless logger.respond_to? :error
|
46
|
-
if logger.respond_to? :methods
|
47
|
-
unimplemented = Logger.new(STDOUT).methods - logger.methods
|
48
|
-
unless unimplemented.empty?
|
49
|
-
logger.error("logger #{logger} does not implement #{unimplemented}")
|
50
|
-
return
|
51
|
-
end
|
52
|
-
end
|
53
|
-
@logger = logger
|
54
|
-
end
|
55
|
-
|
56
|
-
# Activate the debug mode providing more information related to tracer usage
|
57
|
-
# Default to Warn level unless using custom logger
|
58
|
-
def self.debug_logging=(value)
|
59
|
-
if value
|
60
|
-
log.level = Logger::DEBUG
|
61
|
-
elsif log.is_a?(Datadog::Logger)
|
62
|
-
log.level = Logger::WARN
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
|
-
# Return if the debug mode is activated or not
|
67
|
-
def self.debug_logging
|
68
|
-
log.level == Logger::DEBUG
|
69
|
-
end
|
70
|
-
|
71
29
|
def services
|
72
30
|
# Only log each deprecation warning once (safeguard against log spam)
|
73
31
|
Datadog::Patcher.do_once('Tracer#set_service_info') do
|
74
|
-
Datadog::
|
32
|
+
Datadog::Logger.log.warn('services: Usage of Tracer.services has been deprecated')
|
75
33
|
end
|
76
34
|
|
77
35
|
{}
|
@@ -90,8 +48,9 @@ module Datadog
|
|
90
48
|
# tracer.shutdown!
|
91
49
|
#
|
92
50
|
def shutdown!
|
93
|
-
return
|
94
|
-
|
51
|
+
return unless @enabled
|
52
|
+
|
53
|
+
@writer.stop unless @writer.nil?
|
95
54
|
end
|
96
55
|
|
97
56
|
# Return the current active \Context for this traced execution. This method is
|
@@ -117,7 +76,11 @@ module Datadog
|
|
117
76
|
@provider = options.fetch(:context_provider, Datadog::DefaultContextProvider.new)
|
118
77
|
@provider ||= Datadog::DefaultContextProvider.new # @provider should never be nil
|
119
78
|
|
120
|
-
@context_flush = options[:partial_flush]
|
79
|
+
@context_flush = if options[:partial_flush]
|
80
|
+
Datadog::ContextFlush::Partial.new(options)
|
81
|
+
else
|
82
|
+
Datadog::ContextFlush::Finished.new
|
83
|
+
end
|
121
84
|
|
122
85
|
@mutex = Mutex.new
|
123
86
|
@tags = {}
|
@@ -132,6 +95,7 @@ module Datadog
|
|
132
95
|
# * +enabled+: set if the tracer submits or not spans to the trace agent
|
133
96
|
# * +hostname+: change the location of the trace agent
|
134
97
|
# * +port+: change the port of the trace agent
|
98
|
+
# * +partial_flush+: enable partial trace flushing
|
135
99
|
#
|
136
100
|
# For instance, if the trace agent runs in a different location, just:
|
137
101
|
#
|
@@ -142,18 +106,17 @@ module Datadog
|
|
142
106
|
|
143
107
|
# Those are rare "power-user" options.
|
144
108
|
sampler = options.fetch(:sampler, nil)
|
145
|
-
max_spans_before_partial_flush = options.fetch(:max_spans_before_partial_flush, nil)
|
146
|
-
min_spans_before_partial_flush = options.fetch(:min_spans_before_partial_flush, nil)
|
147
|
-
partial_flush_timeout = options.fetch(:partial_flush_timeout, nil)
|
148
109
|
|
149
110
|
@enabled = enabled unless enabled.nil?
|
150
111
|
@sampler = sampler unless sampler.nil?
|
151
112
|
|
152
113
|
configure_writer(options)
|
153
114
|
|
154
|
-
@context_flush =
|
155
|
-
|
156
|
-
|
115
|
+
@context_flush = if options[:partial_flush]
|
116
|
+
Datadog::ContextFlush::Partial.new(options)
|
117
|
+
else
|
118
|
+
Datadog::ContextFlush::Finished.new
|
119
|
+
end
|
157
120
|
end
|
158
121
|
|
159
122
|
# Set the information about the given service. A valid example is:
|
@@ -164,7 +127,7 @@ module Datadog
|
|
164
127
|
def set_service_info(service, app, app_type)
|
165
128
|
# Only log each deprecation warning once (safeguard against log spam)
|
166
129
|
Datadog::Patcher.do_once('Tracer#set_service_info') do
|
167
|
-
Datadog::
|
130
|
+
Datadog::Logger.log.warn(%(
|
168
131
|
set_service_info: Usage of set_service_info has been deprecated,
|
169
132
|
service information no longer needs to be reported to the trace agent.
|
170
133
|
))
|
@@ -179,7 +142,7 @@ module Datadog
|
|
179
142
|
begin
|
180
143
|
@default_service = File.basename($PROGRAM_NAME, '.*')
|
181
144
|
rescue StandardError => e
|
182
|
-
Datadog::
|
145
|
+
Datadog::Logger.log.error("unable to guess default service: #{e}")
|
183
146
|
@default_service = 'ruby'.freeze
|
184
147
|
end
|
185
148
|
@default_service
|
@@ -302,7 +265,7 @@ module Datadog
|
|
302
265
|
span = start_span(name, options)
|
303
266
|
# rubocop:disable Lint/UselessAssignment
|
304
267
|
rescue StandardError => e
|
305
|
-
Datadog::
|
268
|
+
Datadog::Logger.log.debug('Failed to start span: #{e}')
|
306
269
|
ensure
|
307
270
|
return_value = yield(span)
|
308
271
|
end
|
@@ -332,24 +295,20 @@ module Datadog
|
|
332
295
|
def record(context)
|
333
296
|
context = context.context if context.is_a?(Datadog::Span)
|
334
297
|
return if context.nil?
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
else
|
350
|
-
ready = !trace.nil? && !trace.empty? && sampled
|
351
|
-
write(trace) if ready
|
352
|
-
end
|
298
|
+
|
299
|
+
record_context(context)
|
300
|
+
end
|
301
|
+
|
302
|
+
# Consume trace from +context+, according to +@context_flush+
|
303
|
+
# criteria.
|
304
|
+
#
|
305
|
+
# \ContextFlush#consume! can return nil or an empty list if the
|
306
|
+
# trace is not available to flush or if the trace has not been
|
307
|
+
# chosen to be sampled.
|
308
|
+
def record_context(context)
|
309
|
+
trace = @context_flush.consume!(context)
|
310
|
+
|
311
|
+
write(trace) if trace && !trace.empty?
|
353
312
|
end
|
354
313
|
|
355
314
|
# Return the current active span or +nil+.
|
@@ -372,11 +331,11 @@ module Datadog
|
|
372
331
|
def write(trace)
|
373
332
|
return if @writer.nil? || !@enabled
|
374
333
|
|
375
|
-
if Datadog::
|
376
|
-
Datadog::
|
334
|
+
if Datadog::Logger.debug_logging
|
335
|
+
Datadog::Logger.log.debug("Writing #{trace.length} spans (enabled: #{@enabled})")
|
377
336
|
str = String.new('')
|
378
337
|
PP.pp(trace, str)
|
379
|
-
Datadog::
|
338
|
+
Datadog::Logger.log.debug(str)
|
380
339
|
end
|
381
340
|
|
382
341
|
@writer.write(trace)
|
@@ -461,6 +420,7 @@ module Datadog
|
|
461
420
|
:configure_writer,
|
462
421
|
:deactivate_priority_sampling!,
|
463
422
|
:guess_context_and_parent,
|
423
|
+
:record_context,
|
464
424
|
:write
|
465
425
|
end
|
466
426
|
end
|