ddtrace 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.env +11 -0
- data/.gitignore +56 -0
- data/.rubocop.yml +43 -0
- data/Appraisals +65 -0
- data/Gemfile +3 -0
- data/LICENSE +24 -0
- data/README.md +119 -0
- data/Rakefile +103 -0
- data/circle.yml +68 -0
- data/ddtrace.gemspec +41 -0
- data/docker-compose.yml +33 -0
- data/docs/GettingStarted +352 -0
- data/gemfiles/contrib.gemfile +9 -0
- data/gemfiles/rails3_mysql2.gemfile +11 -0
- data/gemfiles/rails3_postgres.gemfile +10 -0
- data/gemfiles/rails3_postgres_redis.gemfile +11 -0
- data/gemfiles/rails4_mysql2.gemfile +9 -0
- data/gemfiles/rails4_postgres.gemfile +9 -0
- data/gemfiles/rails4_postgres_redis.gemfile +10 -0
- data/gemfiles/rails5_mysql2.gemfile +8 -0
- data/gemfiles/rails5_postgres.gemfile +8 -0
- data/gemfiles/rails5_postgres_redis.gemfile +9 -0
- data/lib/ddtrace.rb +63 -0
- data/lib/ddtrace/buffer.rb +77 -0
- data/lib/ddtrace/contrib/elasticsearch/core.rb +56 -0
- data/lib/ddtrace/contrib/elasticsearch/patcher.rb +35 -0
- data/lib/ddtrace/contrib/elasticsearch/quantize.rb +22 -0
- data/lib/ddtrace/contrib/rails/action_controller.rb +75 -0
- data/lib/ddtrace/contrib/rails/action_view.rb +121 -0
- data/lib/ddtrace/contrib/rails/active_record.rb +44 -0
- data/lib/ddtrace/contrib/rails/active_support.rb +115 -0
- data/lib/ddtrace/contrib/rails/core_extensions.rb +89 -0
- data/lib/ddtrace/contrib/rails/framework.rb +107 -0
- data/lib/ddtrace/contrib/rails/utils.rb +42 -0
- data/lib/ddtrace/contrib/redis/core.rb +72 -0
- data/lib/ddtrace/contrib/redis/patcher.rb +36 -0
- data/lib/ddtrace/contrib/redis/quantize.rb +30 -0
- data/lib/ddtrace/contrib/redis/tags.rb +19 -0
- data/lib/ddtrace/encoding.rb +65 -0
- data/lib/ddtrace/ext/app_types.rb +9 -0
- data/lib/ddtrace/ext/cache.rb +7 -0
- data/lib/ddtrace/ext/errors.rb +9 -0
- data/lib/ddtrace/ext/http.rb +11 -0
- data/lib/ddtrace/ext/net.rb +8 -0
- data/lib/ddtrace/ext/redis.rb +16 -0
- data/lib/ddtrace/ext/sql.rb +8 -0
- data/lib/ddtrace/monkey.rb +60 -0
- data/lib/ddtrace/pin.rb +62 -0
- data/lib/ddtrace/span.rb +163 -0
- data/lib/ddtrace/tracer.rb +180 -0
- data/lib/ddtrace/transport.rb +149 -0
- data/lib/ddtrace/utils.rb +9 -0
- data/lib/ddtrace/version.rb +9 -0
- data/lib/ddtrace/workers.rb +109 -0
- data/lib/ddtrace/writer.rb +119 -0
- metadata +187 -0
@@ -0,0 +1,11 @@
|
|
1
|
+
# This file was generated by Appraisal
|
2
|
+
|
3
|
+
source "https://rubygems.org"
|
4
|
+
|
5
|
+
gem "test-unit"
|
6
|
+
gem "rails", "3.2.22.5"
|
7
|
+
gem "pg", :platform => :ruby
|
8
|
+
gem "activerecord-jdbcpostgresql-adapter", :platform => :jruby
|
9
|
+
gem "redis-rails"
|
10
|
+
|
11
|
+
gemspec :path => "../"
|
data/lib/ddtrace.rb
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
require 'ddtrace/monkey'
|
2
|
+
require 'ddtrace/pin'
|
3
|
+
require 'ddtrace/tracer'
|
4
|
+
|
5
|
+
# \Datadog global namespace that includes all tracing functionality for Tracer and Span classes.
|
6
|
+
module Datadog
|
7
|
+
@tracer = Datadog::Tracer.new()
|
8
|
+
|
9
|
+
# Default tracer that can be used as soon as +ddtrace+ is required:
|
10
|
+
#
|
11
|
+
# require 'ddtrace'
|
12
|
+
#
|
13
|
+
# span = Datadog.tracer.trace('web.request')
|
14
|
+
# span.finish()
|
15
|
+
#
|
16
|
+
# If you want to override the default tracer, the recommended way
|
17
|
+
# is to "pin" your own tracer onto your traced component:
|
18
|
+
#
|
19
|
+
# tracer = Datadog::Tracer.new
|
20
|
+
# pin = Datadog::Pin.get_from(mypatchcomponent)
|
21
|
+
# pin.tracer = tracer
|
22
|
+
|
23
|
+
def self.tracer
|
24
|
+
@tracer
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
# Datadog auto instrumentation for frameworks
|
29
|
+
if defined?(Rails::VERSION)
|
30
|
+
if Rails::VERSION::MAJOR.to_i >= 3
|
31
|
+
begin
|
32
|
+
# We include 'redis-rails' here if it's available, doing it later
|
33
|
+
# (typically in initialize callback) does not work, it does not
|
34
|
+
# get loaded in the right context.
|
35
|
+
require 'redis-rails'
|
36
|
+
Datadog::Tracer.log.info("'redis-rails' module found, datadog redis integration is available")
|
37
|
+
rescue LoadError
|
38
|
+
Datadog::Tracer.log.info("no 'redis-rails' module found, datadog redis integration is not available")
|
39
|
+
end
|
40
|
+
require 'ddtrace/contrib/rails/framework'
|
41
|
+
|
42
|
+
Datadog::Monkey.patch_module(:redis) # does nothing if redis is not loaded
|
43
|
+
Datadog::RailsPatcher.patch_renderer()
|
44
|
+
Datadog::RailsPatcher.patch_cache_store()
|
45
|
+
|
46
|
+
module Datadog
|
47
|
+
# Run the auto instrumentation directly after the initialization of the application and
|
48
|
+
# after the application initializers in config/initializers are run
|
49
|
+
class Railtie < Rails::Railtie
|
50
|
+
config.after_initialize do |app|
|
51
|
+
Datadog::Contrib::Rails::Framework.configure(config: app.config)
|
52
|
+
Datadog::Contrib::Rails::Framework.auto_instrument()
|
53
|
+
Datadog::Contrib::Rails::Framework.auto_instrument_redis()
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
else
|
58
|
+
logger = Logger.new(STDOUT)
|
59
|
+
logger.warn 'Detected a Rails version < 3.x.'\
|
60
|
+
'This version is not supported yet and the'\
|
61
|
+
'auto-instrumentation for core components will be disabled.'
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
require 'thread'
|
2
|
+
|
3
|
+
module Datadog
|
4
|
+
# Buffer used to store active spans
|
5
|
+
class SpanBuffer
|
6
|
+
# ensure that a new SpanBuffer clears the thread spans
|
7
|
+
def initialize
|
8
|
+
Thread.current[:datadog_span] = nil
|
9
|
+
end
|
10
|
+
|
11
|
+
# Set the current active span.
|
12
|
+
def set(span)
|
13
|
+
Thread.current[:datadog_span] = span
|
14
|
+
end
|
15
|
+
|
16
|
+
# Return the current active span or nil.
|
17
|
+
def get
|
18
|
+
Thread.current[:datadog_span]
|
19
|
+
end
|
20
|
+
|
21
|
+
# Pop the current active span.
|
22
|
+
def pop
|
23
|
+
span = get()
|
24
|
+
set(nil)
|
25
|
+
span
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
# Trace buffer that stores application traces. The buffer has a maximum size and when
|
30
|
+
# the buffer is full, a random trace is discarded. This class is thread-safe and is used
|
31
|
+
# automatically by the ``Tracer`` instance when a ``Span`` is finished.
|
32
|
+
class TraceBuffer
|
33
|
+
def initialize(max_size)
|
34
|
+
@max_size = max_size
|
35
|
+
|
36
|
+
@mutex = Mutex.new()
|
37
|
+
@traces = []
|
38
|
+
end
|
39
|
+
|
40
|
+
# Add a new ``trace`` in the local queue. This method doesn't block the execution
|
41
|
+
# even if the buffer is full. In that case, a random trace is discarded.
|
42
|
+
def push(trace)
|
43
|
+
@mutex.synchronize do
|
44
|
+
len = @traces.length
|
45
|
+
if len < @max_size || @max_size <= 0
|
46
|
+
@traces << trace
|
47
|
+
else
|
48
|
+
# we should replace a random trace with the new one
|
49
|
+
@traces[rand(len)] = trace
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
# Return the current number of stored traces.
|
55
|
+
def length
|
56
|
+
@mutex.synchronize do
|
57
|
+
return @traces.length
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
# Return if the buffer is empty.
|
62
|
+
def empty?
|
63
|
+
@mutex.synchronize do
|
64
|
+
return @traces.empty?
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
# Stored traces are returned and the local buffer is reset
|
69
|
+
def pop
|
70
|
+
@mutex.synchronize do
|
71
|
+
traces = @traces
|
72
|
+
@traces = []
|
73
|
+
return traces
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'uri'
|
2
|
+
require 'ddtrace/pin'
|
3
|
+
require 'ddtrace/ext/app_types'
|
4
|
+
require 'json'
|
5
|
+
require 'ddtrace/contrib/elasticsearch/quantize'
|
6
|
+
|
7
|
+
module Datadog
|
8
|
+
module Contrib
|
9
|
+
module Elasticsearch
|
10
|
+
URL = 'elasticsearch.url'.freeze
|
11
|
+
METHOD = 'elasticsearch.method'.freeze
|
12
|
+
PARAMS = 'elasticsearch.params'.freeze
|
13
|
+
BODY = 'elasticsearch.body'.freeze
|
14
|
+
|
15
|
+
SERVICE = 'elasticsearch'.freeze
|
16
|
+
SPAN_TYPE = 'elasticsearch'.freeze
|
17
|
+
|
18
|
+
# Datadog APM Elastic Search integration.
|
19
|
+
module TracedClient
|
20
|
+
def initialize(*args)
|
21
|
+
pin = Datadog::Pin.new(SERVICE, app: 'elasticsearch', app_type: Datadog::Ext::AppTypes::DB)
|
22
|
+
pin.onto(self)
|
23
|
+
super(*args)
|
24
|
+
end
|
25
|
+
|
26
|
+
def perform_request(*args)
|
27
|
+
pin = Datadog::Pin.get_from(self)
|
28
|
+
method = args[0]
|
29
|
+
path = args[1]
|
30
|
+
params = args[2]
|
31
|
+
body = args[3]
|
32
|
+
full_url = URI.parse(path)
|
33
|
+
|
34
|
+
url = full_url.path
|
35
|
+
response = nil
|
36
|
+
pin.tracer.trace('elasticsearch.query') do |span|
|
37
|
+
span.service = pin.service
|
38
|
+
span.span_type = SPAN_TYPE
|
39
|
+
|
40
|
+
span.set_tag(METHOD, method)
|
41
|
+
span.set_tag(URL, url)
|
42
|
+
span.set_tag(PARAMS, JSON.generate(params)) if params
|
43
|
+
span.set_tag(BODY, JSON.generate(body)) if body
|
44
|
+
|
45
|
+
quantized_url = Datadog::Contrib::Elasticsearch::Quantize.format_url(url)
|
46
|
+
span.resource = "#{method} #{quantized_url}"
|
47
|
+
|
48
|
+
response = super(*args)
|
49
|
+
end
|
50
|
+
|
51
|
+
response
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# requirements should be kept minimal as Patcher is a shared requirement.
|
2
|
+
|
3
|
+
module Datadog
|
4
|
+
module Contrib
|
5
|
+
module Elasticsearch
|
6
|
+
# Patcher enables patching of 'elasticsearch/transport' module.
|
7
|
+
# This is used in monkey.rb to automatically apply patches
|
8
|
+
module Patcher
|
9
|
+
@patched = false
|
10
|
+
|
11
|
+
module_function
|
12
|
+
|
13
|
+
# patch applies our patch if needed
|
14
|
+
def patch
|
15
|
+
if !@patched && (defined?(::Elasticsearch::Transport::VERSION) && \
|
16
|
+
Gem::Version.new(::Elasticsearch::Transport::VERSION) >= Gem::Version.new('1.0.0'))
|
17
|
+
begin
|
18
|
+
require 'ddtrace/contrib/elasticsearch/core'
|
19
|
+
::Elasticsearch::Transport::Client.prepend Datadog::Contrib::Elasticsearch::TracedClient
|
20
|
+
@patched = true
|
21
|
+
rescue StandardError => e
|
22
|
+
Datadog::Tracer.log.error("Unable to apply Elastic Search integration: #{e}")
|
23
|
+
end
|
24
|
+
end
|
25
|
+
@patched
|
26
|
+
end
|
27
|
+
|
28
|
+
# patched? tells wether patch has been successfully applied
|
29
|
+
def patched?
|
30
|
+
@patched
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Datadog
|
2
|
+
module Contrib
|
3
|
+
module Elasticsearch
|
4
|
+
# Quantize contains ES-specific resource quantization tools.
|
5
|
+
module Quantize
|
6
|
+
ID_REGEXP = %r{\/([0-9]+)([\/\?]|$)}
|
7
|
+
ID_PLACEHOLDER = '/?\2'.freeze
|
8
|
+
|
9
|
+
INDEX_REGEXP = /[0-9]{2,}/
|
10
|
+
INDEX_PLACEHOLDER = '?'.freeze
|
11
|
+
|
12
|
+
module_function
|
13
|
+
|
14
|
+
# Very basic quantization, complex processing should be done in the agent
|
15
|
+
def format_url(url)
|
16
|
+
quantized_url = url.gsub(ID_REGEXP, ID_PLACEHOLDER)
|
17
|
+
quantized_url.gsub(INDEX_REGEXP, INDEX_PLACEHOLDER)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
require 'ddtrace/ext/http'
|
2
|
+
require 'ddtrace/ext/errors'
|
3
|
+
|
4
|
+
module Datadog
|
5
|
+
module Contrib
|
6
|
+
module Rails
|
7
|
+
# TODO[manu]: write docs
|
8
|
+
module ActionController
|
9
|
+
KEY = 'datadog_actioncontroller'.freeze
|
10
|
+
|
11
|
+
def self.instrument
|
12
|
+
# subscribe when the request processing starts
|
13
|
+
::ActiveSupport::Notifications.subscribe('start_processing.action_controller') do |*args|
|
14
|
+
start_processing(*args)
|
15
|
+
end
|
16
|
+
|
17
|
+
# subscribe when the request processing has been completed
|
18
|
+
::ActiveSupport::Notifications.subscribe('process_action.action_controller') do |*args|
|
19
|
+
process_action(*args)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.start_processing(*)
|
24
|
+
return if Thread.current[KEY]
|
25
|
+
|
26
|
+
tracer = ::Rails.configuration.datadog_trace.fetch(:tracer)
|
27
|
+
service = ::Rails.configuration.datadog_trace.fetch(:default_service)
|
28
|
+
type = Datadog::Ext::HTTP::TYPE
|
29
|
+
tracer.trace('rails.request', service: service, span_type: type)
|
30
|
+
|
31
|
+
Thread.current[KEY] = true
|
32
|
+
rescue StandardError => e
|
33
|
+
Datadog::Tracer.log.error(e.message)
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.process_action(_name, start, finish, _id, payload)
|
37
|
+
return unless Thread.current[KEY]
|
38
|
+
Thread.current[KEY] = false
|
39
|
+
|
40
|
+
tracer = ::Rails.configuration.datadog_trace.fetch(:tracer)
|
41
|
+
span = tracer.active_span()
|
42
|
+
return unless span
|
43
|
+
|
44
|
+
begin
|
45
|
+
span.resource = "#{payload.fetch(:controller)}##{payload.fetch(:action)}"
|
46
|
+
span.set_tag(Datadog::Ext::HTTP::URL, payload.fetch(:path))
|
47
|
+
span.set_tag(Datadog::Ext::HTTP::METHOD, payload.fetch(:method))
|
48
|
+
span.set_tag('rails.route.action', payload.fetch(:action))
|
49
|
+
span.set_tag('rails.route.controller', payload.fetch(:controller))
|
50
|
+
|
51
|
+
if payload[:exception].nil?
|
52
|
+
# [christian] in some cases :status is not defined,
|
53
|
+
# rather than firing an error, simply acknowledge we don't know it.
|
54
|
+
span.set_tag(Datadog::Ext::HTTP::STATUS_CODE, payload.fetch(:status, '?').to_s)
|
55
|
+
else
|
56
|
+
error = payload[:exception]
|
57
|
+
# TODO[manu]: it's right to have a 500? there are cases in Rails that let
|
58
|
+
# user to recover the error after this point?
|
59
|
+
span.status = 1
|
60
|
+
span.set_tag(Datadog::Ext::Errors::TYPE, error[0])
|
61
|
+
span.set_tag(Datadog::Ext::Errors::MSG, error[1])
|
62
|
+
span.set_tag(Datadog::Ext::HTTP::STATUS_CODE, '500')
|
63
|
+
end
|
64
|
+
|
65
|
+
ensure
|
66
|
+
span.start_time = start
|
67
|
+
span.finish_at(finish)
|
68
|
+
end
|
69
|
+
rescue StandardError => e
|
70
|
+
Datadog::Tracer.log.error(e.message)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,121 @@
|
|
1
|
+
require 'ddtrace/contrib/rails/utils'
|
2
|
+
|
3
|
+
module Datadog
|
4
|
+
module Contrib
|
5
|
+
module Rails
|
6
|
+
# TODO[manu]: write docs
|
7
|
+
module ActionView
|
8
|
+
def self.instrument
|
9
|
+
# subscribe when the template rendering starts
|
10
|
+
::ActiveSupport::Notifications.subscribe('start_render_template.action_view') do |*args|
|
11
|
+
start_render_template(*args)
|
12
|
+
end
|
13
|
+
|
14
|
+
# subscribe when the partial rendering starts
|
15
|
+
::ActiveSupport::Notifications.subscribe('start_render_partial.action_view') do |*args|
|
16
|
+
start_render_partial(*args)
|
17
|
+
end
|
18
|
+
|
19
|
+
# subscribe when the template rendering has been processed
|
20
|
+
::ActiveSupport::Notifications.subscribe('render_template.action_view') do |*args|
|
21
|
+
render_template(*args)
|
22
|
+
end
|
23
|
+
|
24
|
+
# subscribe when the partial rendering has been processed
|
25
|
+
::ActiveSupport::Notifications.subscribe('render_partial.action_view') do |*args|
|
26
|
+
render_partial(*args)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.get_key(f)
|
31
|
+
'datadog_actionview_' + f
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.start_render_template(*)
|
35
|
+
key = get_key('render_template')
|
36
|
+
return if Thread.current[key]
|
37
|
+
|
38
|
+
tracer = ::Rails.configuration.datadog_trace.fetch(:tracer)
|
39
|
+
type = Datadog::Ext::HTTP::TEMPLATE
|
40
|
+
tracer.trace('rails.render_template', span_type: type)
|
41
|
+
|
42
|
+
Thread.current[key] = true
|
43
|
+
rescue StandardError => e
|
44
|
+
Datadog::Tracer.log.error(e.message)
|
45
|
+
end
|
46
|
+
|
47
|
+
def self.start_render_partial(*)
|
48
|
+
key = get_key('render_partial')
|
49
|
+
return if Thread.current[key]
|
50
|
+
|
51
|
+
tracer = ::Rails.configuration.datadog_trace.fetch(:tracer)
|
52
|
+
type = Datadog::Ext::HTTP::TEMPLATE
|
53
|
+
tracer.trace('rails.render_partial', span_type: type)
|
54
|
+
|
55
|
+
Thread.current[key] = true
|
56
|
+
rescue StandardError => e
|
57
|
+
Datadog::Tracer.log.error(e.message)
|
58
|
+
end
|
59
|
+
|
60
|
+
def self.render_template(_name, start, finish, _id, payload)
|
61
|
+
key = get_key('render_template')
|
62
|
+
return unless Thread.current[key]
|
63
|
+
Thread.current[key] = false
|
64
|
+
|
65
|
+
# finish the tracing and update the execution time
|
66
|
+
tracer = ::Rails.configuration.datadog_trace.fetch(:tracer)
|
67
|
+
span = tracer.active_span()
|
68
|
+
return unless span
|
69
|
+
|
70
|
+
begin
|
71
|
+
template_name = Datadog::Contrib::Rails::Utils.normalize_template_name(payload.fetch(:identifier))
|
72
|
+
span.set_tag('rails.template_name', template_name)
|
73
|
+
span.set_tag('rails.layout', payload.fetch(:layout))
|
74
|
+
|
75
|
+
if payload[:exception]
|
76
|
+
error = payload[:exception]
|
77
|
+
span.status = 1
|
78
|
+
span.set_tag(Datadog::Ext::Errors::TYPE, error[0])
|
79
|
+
span.set_tag(Datadog::Ext::Errors::MSG, error[1])
|
80
|
+
end
|
81
|
+
|
82
|
+
ensure
|
83
|
+
span.start_time = start
|
84
|
+
span.finish_at(finish)
|
85
|
+
end
|
86
|
+
rescue StandardError => e
|
87
|
+
Datadog::Tracer.log.error(e.message)
|
88
|
+
end
|
89
|
+
|
90
|
+
def self.render_partial(_name, start, finish, _id, payload)
|
91
|
+
key = get_key('render_partial')
|
92
|
+
return unless Thread.current[key]
|
93
|
+
Thread.current[key] = false
|
94
|
+
|
95
|
+
# finish the tracing and update the execution time
|
96
|
+
tracer = ::Rails.configuration.datadog_trace.fetch(:tracer)
|
97
|
+
span = tracer.active_span()
|
98
|
+
return unless span
|
99
|
+
|
100
|
+
begin
|
101
|
+
template_name = Datadog::Contrib::Rails::Utils.normalize_template_name(payload.fetch(:identifier))
|
102
|
+
span.set_tag('rails.template_name', template_name)
|
103
|
+
|
104
|
+
if payload[:exception]
|
105
|
+
error = payload[:exception]
|
106
|
+
span.status = 1
|
107
|
+
span.set_tag(Datadog::Ext::Errors::TYPE, error[0])
|
108
|
+
span.set_tag(Datadog::Ext::Errors::MSG, error[1])
|
109
|
+
end
|
110
|
+
|
111
|
+
ensure
|
112
|
+
span.start_time = start
|
113
|
+
span.finish_at(finish)
|
114
|
+
end
|
115
|
+
rescue StandardError => e
|
116
|
+
Datadog::Tracer.log.error(e.message)
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|