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
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
require 'ddtrace/
|
|
2
|
-
require 'ddtrace/ext/app_types'
|
|
3
|
-
require 'ddtrace/contrib/active_record/utils'
|
|
1
|
+
require 'ddtrace/contrib/patcher'
|
|
4
2
|
require 'ddtrace/contrib/active_record/events'
|
|
5
3
|
|
|
6
4
|
module Datadog
|
|
@@ -8,44 +6,22 @@ module Datadog
|
|
|
8
6
|
module ActiveRecord
|
|
9
7
|
# Patcher enables patching of 'active_record' module.
|
|
10
8
|
module Patcher
|
|
11
|
-
include
|
|
12
|
-
|
|
13
|
-
register_as :active_record, auto_patch: false
|
|
14
|
-
option :service_name, depends_on: [:tracer] do |value|
|
|
15
|
-
(value || Utils.adapter_name).tap do |v|
|
|
16
|
-
get_option(:tracer).set_service_info(v, 'active_record', Ext::AppTypes::DB)
|
|
17
|
-
end
|
|
18
|
-
end
|
|
19
|
-
option :orm_service_name
|
|
20
|
-
option :tracer, default: Datadog.tracer do |value|
|
|
21
|
-
(value || Datadog.tracer).tap do |v|
|
|
22
|
-
# Make sure to update tracers of all subscriptions
|
|
23
|
-
Events.subscriptions.each do |subscription|
|
|
24
|
-
subscription.tracer = v
|
|
25
|
-
end
|
|
26
|
-
end
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
@patched = false
|
|
9
|
+
include Contrib::Patcher
|
|
30
10
|
|
|
31
11
|
module_function
|
|
32
12
|
|
|
33
|
-
# patched? tells whether patch has been successfully applied
|
|
34
13
|
def patched?
|
|
35
|
-
|
|
14
|
+
done?(:active_record)
|
|
36
15
|
end
|
|
37
16
|
|
|
38
17
|
def patch
|
|
39
|
-
|
|
18
|
+
do_once(:active_record) do
|
|
40
19
|
begin
|
|
41
20
|
Events.subscribe!
|
|
42
|
-
@patched = true
|
|
43
21
|
rescue StandardError => e
|
|
44
22
|
Datadog::Tracer.log.error("Unable to apply Active Record integration: #{e}")
|
|
45
23
|
end
|
|
46
24
|
end
|
|
47
|
-
|
|
48
|
-
@patched
|
|
49
25
|
end
|
|
50
26
|
end
|
|
51
27
|
end
|
|
@@ -4,29 +4,23 @@ module Datadog
|
|
|
4
4
|
# Common utilities for Rails
|
|
5
5
|
module Utils
|
|
6
6
|
def self.adapter_name
|
|
7
|
-
connection_config[:
|
|
7
|
+
Datadog::Utils::Database.normalize_vendor(connection_config[:adapter])
|
|
8
8
|
end
|
|
9
9
|
|
|
10
10
|
def self.database_name
|
|
11
|
-
connection_config[:
|
|
11
|
+
connection_config[:database]
|
|
12
12
|
end
|
|
13
13
|
|
|
14
14
|
def self.adapter_host
|
|
15
|
-
connection_config[:
|
|
15
|
+
connection_config[:host]
|
|
16
16
|
end
|
|
17
17
|
|
|
18
18
|
def self.adapter_port
|
|
19
|
-
connection_config[:
|
|
19
|
+
connection_config[:port]
|
|
20
20
|
end
|
|
21
21
|
|
|
22
22
|
def self.connection_config(object_id = nil)
|
|
23
|
-
|
|
24
|
-
{
|
|
25
|
-
adapter_name: Datadog::Utils::Database.normalize_vendor(config[:adapter]),
|
|
26
|
-
adapter_host: config[:host],
|
|
27
|
-
adapter_port: config[:port],
|
|
28
|
-
database_name: config[:database]
|
|
29
|
-
}
|
|
23
|
+
object_id.nil? ? default_connection_config : connection_config_by_id(object_id)
|
|
30
24
|
end
|
|
31
25
|
|
|
32
26
|
# Attempt to retrieve the connection from an object ID.
|
|
@@ -75,11 +75,12 @@ module Datadog
|
|
|
75
75
|
tracer.trace(@span_name, @options).tap do |span|
|
|
76
76
|
# Assign start time if provided
|
|
77
77
|
span.start_time = start unless start.nil?
|
|
78
|
+
payload[:datadog_span] = span
|
|
78
79
|
end
|
|
79
80
|
end
|
|
80
81
|
|
|
81
82
|
def finish_span(name, id, payload, finish = nil)
|
|
82
|
-
|
|
83
|
+
payload[:datadog_span].tap do |span|
|
|
83
84
|
# If no active span, return.
|
|
84
85
|
return nil if span.nil?
|
|
85
86
|
|
data/lib/ddtrace/contrib/base.rb
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
require 'ddtrace/registry'
|
|
2
1
|
require 'ddtrace/configurable'
|
|
2
|
+
require 'ddtrace/patcher'
|
|
3
|
+
require 'ddtrace/registry/registerable'
|
|
3
4
|
|
|
4
5
|
module Datadog
|
|
5
6
|
module Contrib
|
|
@@ -7,8 +8,8 @@ module Datadog
|
|
|
7
8
|
module Base
|
|
8
9
|
def self.included(base)
|
|
9
10
|
base.send(:include, Registry::Registerable)
|
|
10
|
-
base.send(:include, Configurable)
|
|
11
|
-
base.send(:include, Patcher)
|
|
11
|
+
base.send(:include, Datadog::Configurable)
|
|
12
|
+
base.send(:include, Datadog::Patcher)
|
|
12
13
|
end
|
|
13
14
|
end
|
|
14
15
|
end
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
require 'ddtrace/contrib/configuration/resolver'
|
|
2
|
+
require 'ddtrace/contrib/configuration/settings'
|
|
3
|
+
|
|
4
|
+
module Datadog
|
|
5
|
+
module Contrib
|
|
6
|
+
# Defines configurable behavior for integrations
|
|
7
|
+
module Configurable
|
|
8
|
+
def self.included(base)
|
|
9
|
+
base.send(:include, InstanceMethods)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
# Configurable instance behavior for integrations
|
|
13
|
+
module InstanceMethods
|
|
14
|
+
def default_configuration
|
|
15
|
+
Configuration::Settings.new
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def reset_configuration!
|
|
19
|
+
@configurations = nil
|
|
20
|
+
@resolver = nil
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def configuration(name = :default)
|
|
24
|
+
name = :default if name.nil?
|
|
25
|
+
name = resolver.resolve(name)
|
|
26
|
+
return nil unless configurations.key?(name)
|
|
27
|
+
configurations[name]
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def configurations
|
|
31
|
+
@configurations ||= Hash.new { default_configuration }.tap do |configs|
|
|
32
|
+
configs[:default] = default_configuration
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def configure(name, options = {}, &block)
|
|
37
|
+
name = resolver.resolve(name || :default)
|
|
38
|
+
|
|
39
|
+
configurations[name].tap do |settings|
|
|
40
|
+
settings.configure(options, &block)
|
|
41
|
+
configurations[name] = settings
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
protected
|
|
46
|
+
|
|
47
|
+
attr_writer :resolver
|
|
48
|
+
|
|
49
|
+
def resolver
|
|
50
|
+
@resolver ||= Configuration::Resolver.new
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
module Datadog
|
|
2
|
+
module Contrib
|
|
3
|
+
module Configuration
|
|
4
|
+
# Represents an instance of an integration configuration option
|
|
5
|
+
class Option
|
|
6
|
+
attr_reader \
|
|
7
|
+
:definition
|
|
8
|
+
|
|
9
|
+
def initialize(definition, context)
|
|
10
|
+
@definition = definition
|
|
11
|
+
@context = context
|
|
12
|
+
@value = nil
|
|
13
|
+
@is_set = false
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def set(value)
|
|
17
|
+
@value = @context.instance_exec(value, &definition.setter).tap do
|
|
18
|
+
@is_set = true
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def get
|
|
23
|
+
return definition.default_value unless @is_set
|
|
24
|
+
@value
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def reset
|
|
28
|
+
set(definition.default_value)
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
module Datadog
|
|
2
|
+
module Contrib
|
|
3
|
+
module Configuration
|
|
4
|
+
# Represents a definition for an integration configuration option
|
|
5
|
+
class OptionDefinition
|
|
6
|
+
IDENTITY = ->(x) { x }
|
|
7
|
+
|
|
8
|
+
attr_reader \
|
|
9
|
+
:default,
|
|
10
|
+
:depends_on,
|
|
11
|
+
:lazy,
|
|
12
|
+
:name,
|
|
13
|
+
:setter
|
|
14
|
+
|
|
15
|
+
def initialize(name, meta = {}, &block)
|
|
16
|
+
@default = meta[:default]
|
|
17
|
+
@depends_on = meta[:depends_on] || []
|
|
18
|
+
@lazy = meta[:lazy] || false
|
|
19
|
+
@name = name.to_sym
|
|
20
|
+
@setter = meta[:setter] || block || IDENTITY
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def default_value
|
|
24
|
+
lazy ? @default.call : @default
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
require 'ddtrace/configuration/resolver'
|
|
2
|
+
|
|
3
|
+
module Datadog
|
|
4
|
+
module Contrib
|
|
5
|
+
module Configuration
|
|
6
|
+
# Represents a set of configuration option definitions for an integration
|
|
7
|
+
class OptionDefinitionSet < Hash
|
|
8
|
+
def dependency_order
|
|
9
|
+
Datadog::Configuration::Resolver.new(dependency_graph).call
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def dependency_graph
|
|
13
|
+
each_with_object({}) do |(name, option), graph|
|
|
14
|
+
graph[name] = option.depends_on
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
require 'ddtrace/contrib/configuration/option'
|
|
2
|
+
require 'ddtrace/contrib/configuration/option_set'
|
|
3
|
+
require 'ddtrace/contrib/configuration/option_definition'
|
|
4
|
+
require 'ddtrace/contrib/configuration/option_definition_set'
|
|
5
|
+
|
|
6
|
+
module Datadog
|
|
7
|
+
module Contrib
|
|
8
|
+
module Configuration
|
|
9
|
+
# Behavior for a configuration object that has options
|
|
10
|
+
module Options
|
|
11
|
+
def self.included(base)
|
|
12
|
+
base.send(:extend, ClassMethods)
|
|
13
|
+
base.send(:include, InstanceMethods)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# Class behavior for a configuration object with options
|
|
17
|
+
module ClassMethods
|
|
18
|
+
def options
|
|
19
|
+
@options ||= begin
|
|
20
|
+
# Allows for class inheritance of option definitions
|
|
21
|
+
superclass <= Options ? superclass.options.dup : OptionDefinitionSet.new
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
protected
|
|
26
|
+
|
|
27
|
+
def option(name, meta = {}, &block)
|
|
28
|
+
options[name] = OptionDefinition.new(name, meta, &block).tap do
|
|
29
|
+
define_option_accessors(name)
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
private
|
|
34
|
+
|
|
35
|
+
def define_option_accessors(name)
|
|
36
|
+
option_name = name
|
|
37
|
+
|
|
38
|
+
define_method(option_name) do
|
|
39
|
+
get_option(option_name)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
define_method("#{option_name}=") do |value|
|
|
43
|
+
set_option(option_name, value)
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# Instance behavior for a configuration object with options
|
|
49
|
+
module InstanceMethods
|
|
50
|
+
def options
|
|
51
|
+
@options ||= OptionSet.new
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def set_option(name, value)
|
|
55
|
+
add_option(name) unless options.key?(name)
|
|
56
|
+
options[name].set(value)
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def get_option(name)
|
|
60
|
+
add_option(name) unless options.key?(name)
|
|
61
|
+
options[name].get
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def to_h
|
|
65
|
+
options.each_with_object({}) do |(key, _), hash|
|
|
66
|
+
hash[key] = get_option(key)
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def reset_options!
|
|
71
|
+
options.values.each(&:reset)
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
private
|
|
75
|
+
|
|
76
|
+
def add_option(name)
|
|
77
|
+
assert_valid_option!(name)
|
|
78
|
+
definition = self.class.options[name]
|
|
79
|
+
Option.new(definition, self).tap do |option|
|
|
80
|
+
options[name] = option
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def assert_valid_option!(name)
|
|
85
|
+
unless self.class.options.key?(name)
|
|
86
|
+
raise(InvalidOptionError, "#{self.class.name} doesn't define the option: #{name}")
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
InvalidOptionError = Class.new(StandardError)
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
end
|
|
@@ -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
|
|
@@ -13,6 +13,7 @@ module Datadog
|
|
|
13
13
|
# in the Rack environment so that it can be retrieved by the underlying
|
|
14
14
|
# application. If request tags are not set by the app, they will be set using
|
|
15
15
|
# information available at the Rack level.
|
|
16
|
+
# rubocop:disable Metrics/ClassLength
|
|
16
17
|
class TraceMiddleware
|
|
17
18
|
RACK_REQUEST_SPAN = 'datadog.rack_request_span'.freeze
|
|
18
19
|
|
|
@@ -58,11 +59,12 @@ module Datadog
|
|
|
58
59
|
request_span = tracer.trace('rack.request', trace_options)
|
|
59
60
|
env[RACK_REQUEST_SPAN] = request_span
|
|
60
61
|
|
|
61
|
-
# TODO: For backwards compatibility; this attribute is deprecated.
|
|
62
|
-
env[:datadog_rack_request_span] = env[RACK_REQUEST_SPAN]
|
|
63
|
-
|
|
64
62
|
# Add deprecation warnings
|
|
65
63
|
add_deprecation_warnings(env)
|
|
64
|
+
env.without_datadog_warnings do
|
|
65
|
+
# TODO: For backwards compatibility; this attribute is deprecated.
|
|
66
|
+
env[:datadog_rack_request_span] = env[RACK_REQUEST_SPAN]
|
|
67
|
+
end
|
|
66
68
|
|
|
67
69
|
# Copy the original env, before the rest of the stack executes.
|
|
68
70
|
# Values may change; we want values before that happens.
|
|
@@ -175,24 +177,41 @@ module Datadog
|
|
|
175
177
|
:datadog_rack_request_span is considered an internal symbol in the Rack env,
|
|
176
178
|
and has been been DEPRECATED. Public support for its usage is discontinued.
|
|
177
179
|
If you need the Rack request span, try using `Datadog.tracer.active_span`.
|
|
178
|
-
This key will be removed in version
|
|
180
|
+
This key will be removed in version 1.0).freeze
|
|
179
181
|
|
|
180
182
|
def add_deprecation_warnings(env)
|
|
181
183
|
env.instance_eval do
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
184
|
+
unless instance_variable_defined?(:@patched_with_datadog_warnings)
|
|
185
|
+
@patched_with_datadog_warnings = true
|
|
186
|
+
@datadog_deprecation_warnings = true
|
|
187
|
+
@datadog_span_warning = true
|
|
188
|
+
|
|
189
|
+
def [](key)
|
|
190
|
+
if key == :datadog_rack_request_span \
|
|
191
|
+
&& @datadog_span_warning \
|
|
192
|
+
&& @datadog_deprecation_warnings
|
|
193
|
+
Datadog::Tracer.log.warn(REQUEST_SPAN_DEPRECATION_WARNING)
|
|
194
|
+
@datadog_span_warning = true
|
|
195
|
+
end
|
|
196
|
+
super
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
def []=(key, value)
|
|
200
|
+
if key == :datadog_rack_request_span \
|
|
201
|
+
&& @datadog_span_warning \
|
|
202
|
+
&& @datadog_deprecation_warnings
|
|
203
|
+
Datadog::Tracer.log.warn(REQUEST_SPAN_DEPRECATION_WARNING)
|
|
204
|
+
@datadog_span_warning = true
|
|
205
|
+
end
|
|
206
|
+
super
|
|
186
207
|
end
|
|
187
|
-
super
|
|
188
|
-
end
|
|
189
208
|
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
209
|
+
def without_datadog_warnings
|
|
210
|
+
@datadog_deprecation_warnings = false
|
|
211
|
+
yield
|
|
212
|
+
ensure
|
|
213
|
+
@datadog_deprecation_warnings = true
|
|
194
214
|
end
|
|
195
|
-
super
|
|
196
215
|
end
|
|
197
216
|
end
|
|
198
217
|
end
|