ddtrace 0.30.1 → 0.31.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|