ddtrace 0.13.0 → 0.14.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 +88 -6
- data/.rubocop.yml +10 -0
- data/Appraisals +24 -0
- data/CHANGELOG.md +108 -2
- data/Gemfile +1 -0
- data/Rakefile +32 -2
- data/benchmarks/postgres_database.yml +9 -0
- data/benchmarks/sidekiq_test.rb +154 -0
- data/ddtrace.gemspec +3 -0
- data/docs/GettingStarted.md +127 -6
- data/lib/ddtrace/configuration.rb +19 -7
- data/lib/ddtrace/context.rb +8 -0
- data/lib/ddtrace/contrib/active_record/configuration/resolver.rb +46 -0
- data/lib/ddtrace/contrib/active_record/configuration/settings.rb +28 -0
- data/lib/ddtrace/contrib/active_record/events/sql.rb +11 -7
- data/lib/ddtrace/contrib/active_record/integration.rb +44 -0
- data/lib/ddtrace/contrib/active_record/patcher.rb +4 -28
- data/lib/ddtrace/contrib/active_record/utils.rb +5 -11
- data/lib/ddtrace/contrib/active_support/notifications/subscription.rb +2 -1
- data/lib/ddtrace/contrib/base.rb +4 -3
- data/lib/ddtrace/contrib/configurable.rb +55 -0
- data/lib/ddtrace/contrib/configuration/option.rb +33 -0
- data/lib/ddtrace/contrib/configuration/option_definition.rb +29 -0
- data/lib/ddtrace/contrib/configuration/option_definition_set.rb +20 -0
- data/lib/ddtrace/contrib/configuration/option_set.rb +8 -0
- data/lib/ddtrace/contrib/configuration/options.rb +95 -0
- data/lib/ddtrace/contrib/configuration/resolver.rb +12 -0
- data/lib/ddtrace/contrib/configuration/settings.rb +35 -0
- data/lib/ddtrace/contrib/delayed_job/patcher.rb +41 -0
- data/lib/ddtrace/contrib/delayed_job/plugin.rb +43 -0
- data/lib/ddtrace/contrib/integration.rb +16 -0
- data/lib/ddtrace/contrib/patchable.rb +38 -0
- data/lib/ddtrace/contrib/patcher.rb +28 -0
- data/lib/ddtrace/contrib/rack/middlewares.rb +34 -15
- data/lib/ddtrace/contrib/rake/instrumentation.rb +15 -3
- data/lib/ddtrace/contrib/registerable.rb +33 -0
- data/lib/ddtrace/contrib/resque/resque_job.rb +2 -10
- data/lib/ddtrace/contrib/rest_client/configuration/settings.rb +22 -0
- data/lib/ddtrace/contrib/rest_client/integration.rb +27 -0
- data/lib/ddtrace/contrib/rest_client/patcher.rb +25 -0
- data/lib/ddtrace/contrib/rest_client/request_patch.rb +90 -0
- data/lib/ddtrace/contrib/sequel/configuration/settings.rb +13 -0
- data/lib/ddtrace/contrib/sequel/database.rb +1 -1
- data/lib/ddtrace/contrib/sequel/integration.rb +38 -0
- data/lib/ddtrace/contrib/sequel/patcher.rb +4 -20
- data/lib/ddtrace/monkey.rb +0 -7
- data/lib/ddtrace/patcher.rb +5 -0
- data/lib/ddtrace/pin.rb +1 -1
- data/lib/ddtrace/propagation/http_propagator.rb +6 -0
- data/lib/ddtrace/span.rb +0 -1
- data/lib/ddtrace/tracer.rb +22 -5
- data/lib/ddtrace/vendor/active_record/connection_specification.rb +301 -0
- data/lib/ddtrace/version.rb +1 -1
- data/lib/ddtrace/workers.rb +6 -4
- data/lib/ddtrace/writer.rb +4 -5
- data/lib/ddtrace.rb +7 -15
- metadata +57 -3
|
@@ -15,23 +15,31 @@ module Datadog
|
|
|
15
15
|
def invoke(*args)
|
|
16
16
|
return super unless enabled?
|
|
17
17
|
|
|
18
|
-
tracer.trace(SPAN_NAME_INVOKE) do |span|
|
|
18
|
+
tracer.trace(SPAN_NAME_INVOKE, span_options) do |span|
|
|
19
19
|
super
|
|
20
20
|
annotate_invoke!(span, args)
|
|
21
21
|
end
|
|
22
|
+
ensure
|
|
23
|
+
shutdown_tracer!
|
|
22
24
|
end
|
|
23
25
|
|
|
24
26
|
def execute(args = nil)
|
|
25
27
|
return super unless enabled?
|
|
26
28
|
|
|
27
|
-
tracer.trace(SPAN_NAME_EXECUTE) do |span|
|
|
29
|
+
tracer.trace(SPAN_NAME_EXECUTE, span_options) do |span|
|
|
28
30
|
super
|
|
29
31
|
annotate_execute!(span, args)
|
|
30
32
|
end
|
|
33
|
+
ensure
|
|
34
|
+
shutdown_tracer!
|
|
31
35
|
end
|
|
32
36
|
|
|
33
37
|
private
|
|
34
38
|
|
|
39
|
+
def shutdown_tracer!
|
|
40
|
+
tracer.shutdown! if tracer.active_span.nil? && ::Rake.application.top_level_tasks.include?(name)
|
|
41
|
+
end
|
|
42
|
+
|
|
35
43
|
def annotate_invoke!(span, args)
|
|
36
44
|
span.resource = name
|
|
37
45
|
span.set_tag('rake.task.arg_names', arg_names)
|
|
@@ -48,7 +56,7 @@ module Datadog
|
|
|
48
56
|
end
|
|
49
57
|
|
|
50
58
|
def quantize_args(args)
|
|
51
|
-
quantize_options =
|
|
59
|
+
quantize_options = configuration[:quantize][:args]
|
|
52
60
|
Datadog::Quantization::Hash.format(args, quantize_options)
|
|
53
61
|
end
|
|
54
62
|
|
|
@@ -60,6 +68,10 @@ module Datadog
|
|
|
60
68
|
configuration[:tracer]
|
|
61
69
|
end
|
|
62
70
|
|
|
71
|
+
def span_options
|
|
72
|
+
{ service: configuration[:service_name] }
|
|
73
|
+
end
|
|
74
|
+
|
|
63
75
|
def configuration
|
|
64
76
|
Datadog.configuration[:rake]
|
|
65
77
|
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
require 'ddtrace/registry'
|
|
2
|
+
|
|
3
|
+
module Datadog
|
|
4
|
+
module Contrib
|
|
5
|
+
# Defines registerable behavior for integrations
|
|
6
|
+
module Registerable
|
|
7
|
+
def self.included(base)
|
|
8
|
+
base.send(:extend, ClassMethods)
|
|
9
|
+
base.send(:include, InstanceMethods)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
# Class methods for registerable behavior
|
|
13
|
+
module ClassMethods
|
|
14
|
+
def register_as(name, options = {})
|
|
15
|
+
registry = options.fetch(:registry, Datadog.registry)
|
|
16
|
+
auto_patch = options.fetch(:auto_patch, false)
|
|
17
|
+
|
|
18
|
+
registry.add(name, new(name, options), auto_patch)
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# Instance methods for registerable behavior
|
|
23
|
+
module InstanceMethods
|
|
24
|
+
attr_reader \
|
|
25
|
+
:name
|
|
26
|
+
|
|
27
|
+
def initialize(name, options = {})
|
|
28
|
+
@name = name
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -16,26 +16,18 @@ module Datadog
|
|
|
16
16
|
yield
|
|
17
17
|
span.service = pin.service
|
|
18
18
|
end
|
|
19
|
+
ensure
|
|
20
|
+
pin.tracer.shutdown! if pin && pin.tracer
|
|
19
21
|
end
|
|
20
22
|
end
|
|
21
23
|
end
|
|
22
24
|
end
|
|
23
25
|
end
|
|
24
26
|
|
|
25
|
-
Resque.before_first_fork do
|
|
26
|
-
pin = Datadog::Pin.get_from(Resque)
|
|
27
|
-
next unless pin && pin.tracer
|
|
28
|
-
|
|
29
|
-
# Create SyncWriter instance before forking
|
|
30
|
-
sync_writer = Datadog::SyncWriter.new(transport: pin.tracer.writer.transport)
|
|
31
|
-
Datadog::Contrib::Resque.sync_writer = sync_writer
|
|
32
|
-
end
|
|
33
|
-
|
|
34
27
|
Resque.after_fork do
|
|
35
28
|
# get the current tracer
|
|
36
29
|
pin = Datadog::Pin.get_from(Resque)
|
|
37
30
|
next unless pin && pin.tracer
|
|
38
31
|
# clean the state so no CoW happens
|
|
39
32
|
pin.tracer.provider.context = nil
|
|
40
|
-
pin.tracer.writer = Datadog::Contrib::Resque.sync_writer
|
|
41
33
|
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
require 'ddtrace/contrib/configuration/settings'
|
|
2
|
+
require 'ddtrace/contrib/active_record/utils'
|
|
3
|
+
|
|
4
|
+
module Datadog
|
|
5
|
+
module Contrib
|
|
6
|
+
module RestClient
|
|
7
|
+
module Configuration
|
|
8
|
+
# Unique settings for RestClient
|
|
9
|
+
class Settings < Contrib::Configuration::Settings
|
|
10
|
+
NAME = 'rest_client'.freeze
|
|
11
|
+
|
|
12
|
+
option :service_name, default: NAME, depends_on: [:tracer] do |value|
|
|
13
|
+
get_option(:tracer).set_service_info(value, NAME, Ext::AppTypes::DB)
|
|
14
|
+
value
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
option :distributed_tracing, default: false
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
require 'ddtrace/contrib/integration'
|
|
2
|
+
require 'ddtrace/contrib/rest_client/configuration/settings'
|
|
3
|
+
require 'ddtrace/contrib/rest_client/patcher'
|
|
4
|
+
|
|
5
|
+
module Datadog
|
|
6
|
+
module Contrib
|
|
7
|
+
module RestClient
|
|
8
|
+
# Description of RestClient integration
|
|
9
|
+
class Integration
|
|
10
|
+
include Contrib::Integration
|
|
11
|
+
register_as :rest_client
|
|
12
|
+
|
|
13
|
+
def self.compatible?
|
|
14
|
+
RUBY_VERSION >= '1.9.3' && defined?(::RestClient::Request)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def default_configuration
|
|
18
|
+
Configuration::Settings.new
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def patcher
|
|
22
|
+
Patcher
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
module Datadog
|
|
2
|
+
module Contrib
|
|
3
|
+
module RestClient
|
|
4
|
+
# RestClient integration
|
|
5
|
+
module Patcher
|
|
6
|
+
include Contrib::Patcher
|
|
7
|
+
|
|
8
|
+
module_function
|
|
9
|
+
|
|
10
|
+
def patched?
|
|
11
|
+
done?(:rest_client)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def patch
|
|
15
|
+
do_once(:rest_client) do
|
|
16
|
+
require 'ddtrace/ext/app_types'
|
|
17
|
+
require 'ddtrace/contrib/rest_client/request_patch'
|
|
18
|
+
|
|
19
|
+
::RestClient::Request.send(:include, RequestPatch)
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
require 'ddtrace/ext/net'
|
|
2
|
+
require 'ddtrace/ext/distributed'
|
|
3
|
+
require 'ddtrace/propagation/http_propagator'
|
|
4
|
+
|
|
5
|
+
module Datadog
|
|
6
|
+
module Contrib
|
|
7
|
+
module RestClient
|
|
8
|
+
# RestClient RequestPatch
|
|
9
|
+
module RequestPatch
|
|
10
|
+
REQUEST_TRACE_NAME = 'rest_client.request'.freeze
|
|
11
|
+
|
|
12
|
+
def self.included(base)
|
|
13
|
+
if Gem::Version.new(RUBY_VERSION) < Gem::Version.new('2.0.0')
|
|
14
|
+
base.class_eval do
|
|
15
|
+
alias_method :execute_without_datadog, :execute
|
|
16
|
+
remove_method :execute
|
|
17
|
+
include InstanceMethods
|
|
18
|
+
end
|
|
19
|
+
else
|
|
20
|
+
base.send(:prepend, InstanceMethods)
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# Compatibility shim for Rubies not supporting `.prepend`
|
|
25
|
+
module InstanceMethodsCompatibility
|
|
26
|
+
def execute(&block)
|
|
27
|
+
execute_without_datadog(&block)
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# InstanceMethods - implementing instrumentation
|
|
32
|
+
module InstanceMethods
|
|
33
|
+
include InstanceMethodsCompatibility unless Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('2.0.0')
|
|
34
|
+
|
|
35
|
+
def execute(&block)
|
|
36
|
+
uri = URI.parse(url)
|
|
37
|
+
|
|
38
|
+
return super(&block) unless datadog_configuration[:tracer].enabled
|
|
39
|
+
|
|
40
|
+
datadog_trace_request(uri) do |span|
|
|
41
|
+
if datadog_configuration[:distributed_tracing]
|
|
42
|
+
Datadog::HTTPPropagator.inject!(span.context, processed_headers)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
super(&block)
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def datadog_tag_request(uri, span)
|
|
50
|
+
span.resource = method.to_s.upcase
|
|
51
|
+
span.set_tag(Ext::HTTP::URL, uri.path)
|
|
52
|
+
span.set_tag(Ext::HTTP::METHOD, method.to_s.upcase)
|
|
53
|
+
span.set_tag(Ext::NET::TARGET_HOST, uri.host)
|
|
54
|
+
span.set_tag(Ext::NET::TARGET_PORT, uri.port)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def datadog_trace_request(uri)
|
|
58
|
+
span = datadog_configuration[:tracer].trace(REQUEST_TRACE_NAME,
|
|
59
|
+
service: datadog_configuration[:service_name],
|
|
60
|
+
span_type: Datadog::Ext::AppTypes::WEB)
|
|
61
|
+
|
|
62
|
+
datadog_tag_request(uri, span)
|
|
63
|
+
|
|
64
|
+
response = yield(span)
|
|
65
|
+
|
|
66
|
+
span.set_tag(Ext::HTTP::STATUS_CODE, response.code)
|
|
67
|
+
response
|
|
68
|
+
rescue ::RestClient::ExceptionWithResponse => e
|
|
69
|
+
span.set_error(e) if Ext::HTTP::ERROR_RANGE.cover?(e.http_code)
|
|
70
|
+
span.set_tag(Ext::HTTP::STATUS_CODE, e.http_code)
|
|
71
|
+
|
|
72
|
+
raise e
|
|
73
|
+
# rubocop:disable Lint/RescueException
|
|
74
|
+
rescue Exception => e
|
|
75
|
+
# rubocop:enable Lint/RescueException
|
|
76
|
+
span.set_error(e)
|
|
77
|
+
|
|
78
|
+
raise e
|
|
79
|
+
ensure
|
|
80
|
+
span.finish
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def datadog_configuration
|
|
84
|
+
Datadog.configuration[:rest_client]
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
require 'ddtrace/contrib/configuration/settings'
|
|
2
|
+
|
|
3
|
+
module Datadog
|
|
4
|
+
module Contrib
|
|
5
|
+
module Sequel
|
|
6
|
+
module Configuration
|
|
7
|
+
class Settings < Contrib::Configuration::Settings
|
|
8
|
+
# Add any custom Sequel settings or behavior here.
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -31,7 +31,7 @@ module Datadog
|
|
|
31
31
|
def datadog_pin
|
|
32
32
|
@pin ||= Datadog::Pin.new(
|
|
33
33
|
Datadog.configuration[:sequel][:service_name] || adapter_name,
|
|
34
|
-
app:
|
|
34
|
+
app: Integration::APP,
|
|
35
35
|
app_type: Datadog::Ext::AppTypes::DB,
|
|
36
36
|
tracer: Datadog.configuration[:sequel][:tracer] || Datadog.tracer
|
|
37
37
|
)
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
require 'ddtrace/contrib/integration'
|
|
2
|
+
require 'ddtrace/contrib/sequel/configuration/settings'
|
|
3
|
+
require 'ddtrace/contrib/sequel/patcher'
|
|
4
|
+
|
|
5
|
+
module Datadog
|
|
6
|
+
module Contrib
|
|
7
|
+
module Sequel
|
|
8
|
+
# Description of Sequel integration
|
|
9
|
+
class Integration
|
|
10
|
+
include Contrib::Integration
|
|
11
|
+
|
|
12
|
+
APP = 'sequel'.freeze
|
|
13
|
+
|
|
14
|
+
register_as :sequel, auto_patch: false
|
|
15
|
+
|
|
16
|
+
def self.version
|
|
17
|
+
Gem.loaded_specs['sequel'] && Gem.loaded_specs['sequel'].version
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def self.present?
|
|
21
|
+
super && defined?(::Sequel)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def self.compatible?
|
|
25
|
+
super && RUBY_VERSION >= '2.0.0'
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def default_configuration
|
|
29
|
+
Configuration::Settings.new
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def patcher
|
|
33
|
+
Patcher
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
require 'ddtrace/contrib/patcher'
|
|
1
2
|
require 'ddtrace/contrib/sequel/database'
|
|
2
3
|
require 'ddtrace/contrib/sequel/dataset'
|
|
3
4
|
|
|
@@ -7,40 +8,23 @@ module Datadog
|
|
|
7
8
|
# Patcher enables patching of 'sequel' module.
|
|
8
9
|
# This is used in monkey.rb to manually apply patches
|
|
9
10
|
module Patcher
|
|
10
|
-
include
|
|
11
|
-
|
|
12
|
-
APP = 'sequel'.freeze
|
|
13
|
-
|
|
14
|
-
register_as :sequel, auto_patch: false
|
|
15
|
-
option :service_name
|
|
16
|
-
option :tracer, default: Datadog.tracer
|
|
17
|
-
|
|
18
|
-
@patched = false
|
|
11
|
+
include Contrib::Patcher
|
|
19
12
|
|
|
20
13
|
module_function
|
|
21
14
|
|
|
22
|
-
# patched? tells whether patch has been successfully applied
|
|
23
15
|
def patched?
|
|
24
|
-
|
|
16
|
+
done?(:sequel)
|
|
25
17
|
end
|
|
26
18
|
|
|
27
19
|
def patch
|
|
28
|
-
|
|
20
|
+
do_once(:sequel) do
|
|
29
21
|
begin
|
|
30
22
|
patch_sequel_database
|
|
31
23
|
patch_sequel_dataset
|
|
32
|
-
|
|
33
|
-
@patched = true
|
|
34
24
|
rescue StandardError => e
|
|
35
25
|
Datadog::Tracer.log.error("Unable to apply Sequel integration: #{e}")
|
|
36
26
|
end
|
|
37
27
|
end
|
|
38
|
-
|
|
39
|
-
@patched
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
def compatible?
|
|
43
|
-
RUBY_VERSION >= '2.0.0' && defined?(::Sequel)
|
|
44
28
|
end
|
|
45
29
|
|
|
46
30
|
def patch_sequel_database
|
data/lib/ddtrace/monkey.rb
CHANGED
|
@@ -15,8 +15,6 @@ module Datadog
|
|
|
15
15
|
|
|
16
16
|
module_function
|
|
17
17
|
|
|
18
|
-
attr_writer :registry
|
|
19
|
-
|
|
20
18
|
def registry
|
|
21
19
|
log_deprecation_warning('Monkey#registry')
|
|
22
20
|
@registry
|
|
@@ -54,11 +52,6 @@ module Datadog
|
|
|
54
52
|
end
|
|
55
53
|
|
|
56
54
|
class << self
|
|
57
|
-
def registry
|
|
58
|
-
log_deprecation_warning('Monkey#registry')
|
|
59
|
-
@registry
|
|
60
|
-
end
|
|
61
|
-
|
|
62
55
|
attr_writer :registry
|
|
63
56
|
end
|
|
64
57
|
end
|
data/lib/ddtrace/patcher.rb
CHANGED
|
@@ -32,6 +32,11 @@ module Datadog
|
|
|
32
32
|
@done_once[key] = true
|
|
33
33
|
end
|
|
34
34
|
end
|
|
35
|
+
|
|
36
|
+
def done?(key)
|
|
37
|
+
return false unless instance_variable_defined?(:@done_once)
|
|
38
|
+
!@done_once.nil? && @done_once.key?(key)
|
|
39
|
+
end
|
|
35
40
|
end
|
|
36
41
|
|
|
37
42
|
# Extend the common methods so they're available as a module function.
|
data/lib/ddtrace/pin.rb
CHANGED
|
@@ -9,6 +9,12 @@ module Datadog
|
|
|
9
9
|
|
|
10
10
|
# inject! popolates the env with span ID, trace ID and sampling priority
|
|
11
11
|
def self.inject!(context, env)
|
|
12
|
+
# Prevent propagation from being attempted if context provided is nil.
|
|
13
|
+
if context.nil?
|
|
14
|
+
Datadog::Tracer.log.debug('Cannot inject context into env to propagate over HTTP: context is nil.'.freeze)
|
|
15
|
+
return
|
|
16
|
+
end
|
|
17
|
+
|
|
12
18
|
env[HTTP_HEADER_TRACE_ID] = context.trace_id.to_s
|
|
13
19
|
env[HTTP_HEADER_PARENT_ID] = context.span_id.to_s
|
|
14
20
|
env[HTTP_HEADER_SAMPLING_PRIORITY] = context.sampling_priority.to_s
|
data/lib/ddtrace/span.rb
CHANGED
data/lib/ddtrace/tracer.rb
CHANGED
|
@@ -24,6 +24,7 @@ module Datadog
|
|
|
24
24
|
attr_writer :default_service
|
|
25
25
|
|
|
26
26
|
ALLOWED_SPAN_OPTIONS = [:service, :resource, :span_type].freeze
|
|
27
|
+
DEFAULT_ON_ERROR = proc { |span, error| span.set_error(error) unless span.nil? }
|
|
27
28
|
|
|
28
29
|
# Global, memoized, lazy initialized instance of a logger that is used within the the Datadog
|
|
29
30
|
# namespace. This logger outputs to +STDOUT+ by default, and is considered thread-safe.
|
|
@@ -277,14 +278,23 @@ module Datadog
|
|
|
277
278
|
# * +tags+: extra tags which should be added to the span.
|
|
278
279
|
def trace(name, options = {})
|
|
279
280
|
options[:child_of] = call_context
|
|
280
|
-
span = start_span(name, options)
|
|
281
281
|
|
|
282
282
|
# call the finish only if a block is given; this ensures
|
|
283
283
|
# that a call to tracer.trace() without a block, returns
|
|
284
284
|
# a span that should be manually finished.
|
|
285
285
|
if block_given?
|
|
286
|
+
span = nil
|
|
287
|
+
return_value = nil
|
|
288
|
+
|
|
286
289
|
begin
|
|
287
|
-
|
|
290
|
+
begin
|
|
291
|
+
span = start_span(name, options)
|
|
292
|
+
# rubocop:disable Lint/UselessAssignment
|
|
293
|
+
rescue StandardError => e
|
|
294
|
+
Datadog::Tracer.log.debug('Failed to start span: #{e}')
|
|
295
|
+
ensure
|
|
296
|
+
return_value = yield(span)
|
|
297
|
+
end
|
|
288
298
|
# rubocop:disable Lint/RescueException
|
|
289
299
|
# Here we really want to catch *any* exception, not only StandardError,
|
|
290
300
|
# as we really have no clue of what is in the block,
|
|
@@ -292,13 +302,15 @@ module Datadog
|
|
|
292
302
|
# It's not a problem since we re-raise it afterwards so for example a
|
|
293
303
|
# SignalException::Interrupt would still bubble up.
|
|
294
304
|
rescue Exception => e
|
|
295
|
-
|
|
305
|
+
(options[:on_error] || DEFAULT_ON_ERROR).call(span, e)
|
|
296
306
|
raise e
|
|
297
307
|
ensure
|
|
298
|
-
span.finish
|
|
308
|
+
span.finish unless span.nil?
|
|
299
309
|
end
|
|
310
|
+
|
|
311
|
+
return_value
|
|
300
312
|
else
|
|
301
|
-
|
|
313
|
+
start_span(name, options)
|
|
302
314
|
end
|
|
303
315
|
end
|
|
304
316
|
|
|
@@ -334,6 +346,11 @@ module Datadog
|
|
|
334
346
|
call_context.current_span
|
|
335
347
|
end
|
|
336
348
|
|
|
349
|
+
# Return the current active root span or +nil+.
|
|
350
|
+
def active_root_span
|
|
351
|
+
call_context.current_root_span
|
|
352
|
+
end
|
|
353
|
+
|
|
337
354
|
# Send the trace to the writer to enqueue the spans list in the agent
|
|
338
355
|
# sending queue.
|
|
339
356
|
def write(trace)
|