ddtrace 0.13.2 → 0.14.0.beta1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +10 -0
- data/Appraisals +12 -0
- data/CHANGELOG.md +16 -5
- data/Rakefile +18 -1
- data/docs/GettingStarted.md +63 -0
- data/lib/ddtrace.rb +3 -1
- data/lib/ddtrace/configuration.rb +18 -6
- 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/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/rake/instrumentation.rb +3 -15
- data/lib/ddtrace/contrib/registerable.rb +33 -0
- data/lib/ddtrace/contrib/resque/resque_job.rb +2 -10
- 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/patcher.rb +5 -0
- data/lib/ddtrace/propagation/http_propagator.rb +0 -6
- data/lib/ddtrace/tracer.rb +17 -5
- data/lib/ddtrace/vendor/active_record/connection_specification.rb +301 -0
- data/lib/ddtrace/version.rb +3 -3
- metadata +24 -4
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'ddtrace/contrib/configuration/options'
|
2
|
+
|
3
|
+
module Datadog
|
4
|
+
module Contrib
|
5
|
+
module Configuration
|
6
|
+
# Common settings for all integrations
|
7
|
+
class Settings
|
8
|
+
include Options
|
9
|
+
|
10
|
+
option :service_name
|
11
|
+
option :tracer, default: Datadog.tracer
|
12
|
+
|
13
|
+
def initialize(options = {})
|
14
|
+
configure(options)
|
15
|
+
end
|
16
|
+
|
17
|
+
def configure(options = {})
|
18
|
+
self.class.options.dependency_order.each do |name|
|
19
|
+
self[name] = options.fetch(name, self[name])
|
20
|
+
end
|
21
|
+
|
22
|
+
yield(self) if block_given?
|
23
|
+
end
|
24
|
+
|
25
|
+
def [](name)
|
26
|
+
respond_to?(name) ? send(name) : get_option(name)
|
27
|
+
end
|
28
|
+
|
29
|
+
def []=(name, value)
|
30
|
+
respond_to?("#{name}=") ? send("#{name}=", value) : set_option(name, value)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module Datadog
|
2
|
+
module Contrib
|
3
|
+
module DelayedJob
|
4
|
+
# DelayedJob integration
|
5
|
+
module Patcher
|
6
|
+
include Base
|
7
|
+
register_as :delayed_job
|
8
|
+
|
9
|
+
option :service_name, default: 'delayed_job'.freeze
|
10
|
+
option :tracer, default: Datadog.tracer
|
11
|
+
|
12
|
+
@patched = false
|
13
|
+
|
14
|
+
class << self
|
15
|
+
def patch
|
16
|
+
return @patched if patched? || !defined?(::Delayed)
|
17
|
+
|
18
|
+
require 'ddtrace/ext/app_types'
|
19
|
+
require_relative 'plugin'
|
20
|
+
|
21
|
+
add_instrumentation(::Delayed::Worker)
|
22
|
+
@patched = true
|
23
|
+
rescue => e
|
24
|
+
Tracer.log.error("Unable to apply DelayedJob integration: #{e}")
|
25
|
+
@patched
|
26
|
+
end
|
27
|
+
|
28
|
+
def patched?
|
29
|
+
@patched
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def add_instrumentation(klass)
|
35
|
+
klass.plugins << Plugin
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'delayed/plugin'
|
2
|
+
|
3
|
+
module Datadog
|
4
|
+
module Contrib
|
5
|
+
module DelayedJob
|
6
|
+
# DelayedJob plugin that instruments invoke_job hook
|
7
|
+
class Plugin < Delayed::Plugin
|
8
|
+
def self.instrument(job, &block)
|
9
|
+
return block.call(job) unless tracer && tracer.enabled
|
10
|
+
|
11
|
+
tracer.trace('delayed_job'.freeze, service: configuration[:service_name], resource: job.name) do |span|
|
12
|
+
span.set_tag('delayed_job.id'.freeze, job.id)
|
13
|
+
span.set_tag('delayed_job.queue'.freeze, job.queue) if job.queue
|
14
|
+
span.set_tag('delayed_job.priority'.freeze, job.priority)
|
15
|
+
span.set_tag('delayed_job.attempts'.freeze, job.attempts)
|
16
|
+
span.span_type = Ext::AppTypes::WORKER
|
17
|
+
|
18
|
+
yield job
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.flush(worker, &block)
|
23
|
+
yield worker
|
24
|
+
|
25
|
+
tracer.shutdown! if tracer && tracer.enabled
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.configuration
|
29
|
+
Datadog.configuration[:delayed_job]
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.tracer
|
33
|
+
configuration[:tracer]
|
34
|
+
end
|
35
|
+
|
36
|
+
callbacks do |lifecycle|
|
37
|
+
lifecycle.around(:invoke_job, &method(:instrument))
|
38
|
+
lifecycle.around(:execute, &method(:flush))
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'ddtrace/contrib/configurable'
|
2
|
+
require 'ddtrace/contrib/patchable'
|
3
|
+
require 'ddtrace/contrib/registerable'
|
4
|
+
|
5
|
+
module Datadog
|
6
|
+
module Contrib
|
7
|
+
# Base provides features that are shared across all integrations
|
8
|
+
module Integration
|
9
|
+
def self.included(base)
|
10
|
+
base.send(:include, Configurable)
|
11
|
+
base.send(:include, Patchable)
|
12
|
+
base.send(:include, Registerable)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module Datadog
|
2
|
+
module Contrib
|
3
|
+
# Base provides features that are shared across all integrations
|
4
|
+
module Patchable
|
5
|
+
def self.included(base)
|
6
|
+
base.send(:extend, ClassMethods)
|
7
|
+
base.send(:include, InstanceMethods)
|
8
|
+
end
|
9
|
+
|
10
|
+
# Class methods for integrations
|
11
|
+
module ClassMethods
|
12
|
+
def version
|
13
|
+
nil
|
14
|
+
end
|
15
|
+
|
16
|
+
def present?
|
17
|
+
!version.nil?
|
18
|
+
end
|
19
|
+
|
20
|
+
def compatible?
|
21
|
+
RUBY_VERSION >= '1.9.3' && present?
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
# Instance methods for integrations
|
26
|
+
module InstanceMethods
|
27
|
+
def patcher
|
28
|
+
nil
|
29
|
+
end
|
30
|
+
|
31
|
+
def patch
|
32
|
+
return if !self.class.compatible? || patcher.nil?
|
33
|
+
patcher.patch
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'ddtrace/patcher'
|
2
|
+
|
3
|
+
module Datadog
|
4
|
+
module Contrib
|
5
|
+
# Common behavior for patcher modules
|
6
|
+
module Patcher
|
7
|
+
def self.included(base)
|
8
|
+
base.send(:include, Datadog::Patcher)
|
9
|
+
base.send(:extend, InstanceMethods)
|
10
|
+
base.send(:include, InstanceMethods)
|
11
|
+
end
|
12
|
+
|
13
|
+
# Class methods for patchers
|
14
|
+
module ClassMethods
|
15
|
+
def patch
|
16
|
+
raise NotImplementedError, '#patch not implemented for Patcher!'
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
# Instance methods for patchers
|
21
|
+
module InstanceMethods
|
22
|
+
def patch
|
23
|
+
raise NotImplementedError, '#patch not implemented for Patcher!'
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -15,31 +15,23 @@ module Datadog
|
|
15
15
|
def invoke(*args)
|
16
16
|
return super unless enabled?
|
17
17
|
|
18
|
-
tracer.trace(SPAN_NAME_INVOKE
|
18
|
+
tracer.trace(SPAN_NAME_INVOKE) do |span|
|
19
19
|
super
|
20
20
|
annotate_invoke!(span, args)
|
21
21
|
end
|
22
|
-
ensure
|
23
|
-
shutdown_tracer!
|
24
22
|
end
|
25
23
|
|
26
24
|
def execute(args = nil)
|
27
25
|
return super unless enabled?
|
28
26
|
|
29
|
-
tracer.trace(SPAN_NAME_EXECUTE
|
27
|
+
tracer.trace(SPAN_NAME_EXECUTE) do |span|
|
30
28
|
super
|
31
29
|
annotate_execute!(span, args)
|
32
30
|
end
|
33
|
-
ensure
|
34
|
-
shutdown_tracer!
|
35
31
|
end
|
36
32
|
|
37
33
|
private
|
38
34
|
|
39
|
-
def shutdown_tracer!
|
40
|
-
tracer.shutdown! if tracer.active_span.nil? && ::Rake.application.top_level_tasks.include?(name)
|
41
|
-
end
|
42
|
-
|
43
35
|
def annotate_invoke!(span, args)
|
44
36
|
span.resource = name
|
45
37
|
span.set_tag('rake.task.arg_names', arg_names)
|
@@ -56,7 +48,7 @@ module Datadog
|
|
56
48
|
end
|
57
49
|
|
58
50
|
def quantize_args(args)
|
59
|
-
quantize_options = configuration[:quantize][:args]
|
51
|
+
quantize_options = Datadog.configuration[:rake][:quantize][:args]
|
60
52
|
Datadog::Quantization::Hash.format(args, quantize_options)
|
61
53
|
end
|
62
54
|
|
@@ -68,10 +60,6 @@ module Datadog
|
|
68
60
|
configuration[:tracer]
|
69
61
|
end
|
70
62
|
|
71
|
-
def span_options
|
72
|
-
{ service: configuration[:service_name] }
|
73
|
-
end
|
74
|
-
|
75
63
|
def configuration
|
76
64
|
Datadog.configuration[:rake]
|
77
65
|
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,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/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.
|