fair-ddtrace 0.8.2.a
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 +59 -0
- data/.rubocop.yml +61 -0
- data/.yardopts +5 -0
- data/Appraisals +136 -0
- data/Gemfile +3 -0
- data/LICENSE +24 -0
- data/README.md +156 -0
- data/Rakefile +176 -0
- data/circle.yml +61 -0
- data/ddtrace.gemspec +44 -0
- data/docker-compose.yml +42 -0
- data/docs/GettingStarted.md +735 -0
- data/gemfiles/contrib.gemfile +16 -0
- data/gemfiles/contrib_old.gemfile +15 -0
- data/gemfiles/rails30_postgres.gemfile +10 -0
- data/gemfiles/rails30_postgres_sidekiq.gemfile +11 -0
- data/gemfiles/rails32_mysql2.gemfile +11 -0
- data/gemfiles/rails32_postgres.gemfile +10 -0
- data/gemfiles/rails32_postgres_redis.gemfile +11 -0
- data/gemfiles/rails32_postgres_sidekiq.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/rails4_postgres_sidekiq.gemfile +11 -0
- data/gemfiles/rails5_mysql2.gemfile +8 -0
- data/gemfiles/rails5_postgres.gemfile +8 -0
- data/gemfiles/rails5_postgres_redis.gemfile +9 -0
- data/gemfiles/rails5_postgres_sidekiq.gemfile +10 -0
- data/lib/ddtrace.rb +73 -0
- data/lib/ddtrace/buffer.rb +52 -0
- data/lib/ddtrace/context.rb +145 -0
- data/lib/ddtrace/contrib/active_record/patcher.rb +94 -0
- data/lib/ddtrace/contrib/elasticsearch/patcher.rb +108 -0
- data/lib/ddtrace/contrib/elasticsearch/quantize.rb +22 -0
- data/lib/ddtrace/contrib/grape/endpoint.rb +164 -0
- data/lib/ddtrace/contrib/grape/patcher.rb +73 -0
- data/lib/ddtrace/contrib/http/patcher.rb +156 -0
- data/lib/ddtrace/contrib/rack/middlewares.rb +150 -0
- data/lib/ddtrace/contrib/rails/action_controller.rb +81 -0
- data/lib/ddtrace/contrib/rails/action_view.rb +110 -0
- data/lib/ddtrace/contrib/rails/active_record.rb +56 -0
- data/lib/ddtrace/contrib/rails/active_support.rb +113 -0
- data/lib/ddtrace/contrib/rails/core_extensions.rb +137 -0
- data/lib/ddtrace/contrib/rails/framework.rb +171 -0
- data/lib/ddtrace/contrib/rails/middlewares.rb +32 -0
- data/lib/ddtrace/contrib/rails/utils.rb +43 -0
- data/lib/ddtrace/contrib/redis/patcher.rb +118 -0
- data/lib/ddtrace/contrib/redis/quantize.rb +30 -0
- data/lib/ddtrace/contrib/redis/tags.rb +19 -0
- data/lib/ddtrace/contrib/sidekiq/tracer.rb +103 -0
- data/lib/ddtrace/contrib/sinatra/tracer.rb +169 -0
- data/lib/ddtrace/distributed.rb +38 -0
- data/lib/ddtrace/encoding.rb +65 -0
- data/lib/ddtrace/error.rb +37 -0
- data/lib/ddtrace/ext/app_types.rb +10 -0
- data/lib/ddtrace/ext/cache.rb +7 -0
- data/lib/ddtrace/ext/distributed.rb +10 -0
- data/lib/ddtrace/ext/errors.rb +10 -0
- data/lib/ddtrace/ext/http.rb +11 -0
- data/lib/ddtrace/ext/net.rb +8 -0
- data/lib/ddtrace/ext/redis.rb +11 -0
- data/lib/ddtrace/ext/sql.rb +8 -0
- data/lib/ddtrace/logger.rb +39 -0
- data/lib/ddtrace/monkey.rb +84 -0
- data/lib/ddtrace/pin.rb +63 -0
- data/lib/ddtrace/provider.rb +21 -0
- data/lib/ddtrace/sampler.rb +49 -0
- data/lib/ddtrace/span.rb +222 -0
- data/lib/ddtrace/tracer.rb +310 -0
- data/lib/ddtrace/transport.rb +162 -0
- data/lib/ddtrace/utils.rb +16 -0
- data/lib/ddtrace/version.rb +9 -0
- data/lib/ddtrace/workers.rb +108 -0
- data/lib/ddtrace/writer.rb +118 -0
- metadata +208 -0
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# This file was generated by Appraisal
|
|
2
|
+
|
|
3
|
+
source "https://rubygems.org"
|
|
4
|
+
|
|
5
|
+
gem "elasticsearch-transport"
|
|
6
|
+
gem "grape"
|
|
7
|
+
gem "rack"
|
|
8
|
+
gem "rack-test"
|
|
9
|
+
gem "redis"
|
|
10
|
+
gem "hiredis"
|
|
11
|
+
gem "sinatra"
|
|
12
|
+
gem "sqlite3"
|
|
13
|
+
gem "activerecord"
|
|
14
|
+
gem "sidekiq"
|
|
15
|
+
|
|
16
|
+
gemspec path: "../"
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# This file was generated by Appraisal
|
|
2
|
+
|
|
3
|
+
source "https://rubygems.org"
|
|
4
|
+
|
|
5
|
+
gem "elasticsearch-transport"
|
|
6
|
+
gem "redis", "< 4.0.0"
|
|
7
|
+
gem "hiredis"
|
|
8
|
+
gem "rack", "1.4.7"
|
|
9
|
+
gem "rack-test"
|
|
10
|
+
gem "sinatra", "1.4.5"
|
|
11
|
+
gem "sqlite3"
|
|
12
|
+
gem "activerecord", "3.2.22.5"
|
|
13
|
+
gem "sidekiq", "4.0.0"
|
|
14
|
+
|
|
15
|
+
gemspec path: "../"
|
|
@@ -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.0.20"
|
|
7
|
+
gem "pg", "0.15.1", platform: :ruby
|
|
8
|
+
gem "activerecord-jdbcpostgresql-adapter", platform: :jruby
|
|
9
|
+
gem "sidekiq", "4.0.0"
|
|
10
|
+
|
|
11
|
+
gemspec path: "../"
|
|
@@ -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 "mysql2", "0.3.21", platform: :ruby
|
|
8
|
+
gem "activerecord-mysql-adapter", platform: :ruby
|
|
9
|
+
gem "activerecord-jdbcmysql-adapter", platform: :jruby
|
|
10
|
+
|
|
11
|
+
gemspec path: "../"
|
|
@@ -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", "0.15.1", platform: :ruby
|
|
8
|
+
gem "activerecord-jdbcpostgresql-adapter", platform: :jruby
|
|
9
|
+
gem "redis-rails"
|
|
10
|
+
|
|
11
|
+
gemspec path: "../"
|
|
@@ -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", "0.15.1", platform: :ruby
|
|
8
|
+
gem "activerecord-jdbcpostgresql-adapter", platform: :jruby
|
|
9
|
+
gem "sidekiq", "4.0.0"
|
|
10
|
+
|
|
11
|
+
gemspec path: "../"
|
data/lib/ddtrace.rb
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
require 'ddtrace/monkey'
|
|
2
|
+
require 'ddtrace/pin'
|
|
3
|
+
require 'ddtrace/tracer'
|
|
4
|
+
require 'ddtrace/error'
|
|
5
|
+
|
|
6
|
+
# \Datadog global namespace that includes all tracing functionality for Tracer and Span classes.
|
|
7
|
+
module Datadog
|
|
8
|
+
@tracer = Datadog::Tracer.new()
|
|
9
|
+
|
|
10
|
+
# Default tracer that can be used as soon as +ddtrace+ is required:
|
|
11
|
+
#
|
|
12
|
+
# require 'ddtrace'
|
|
13
|
+
#
|
|
14
|
+
# span = Datadog.tracer.trace('web.request')
|
|
15
|
+
# span.finish()
|
|
16
|
+
#
|
|
17
|
+
# If you want to override the default tracer, the recommended way
|
|
18
|
+
# is to "pin" your own tracer onto your traced component:
|
|
19
|
+
#
|
|
20
|
+
# tracer = Datadog::Tracer.new
|
|
21
|
+
# pin = Datadog::Pin.get_from(mypatchcomponent)
|
|
22
|
+
# pin.tracer = tracer
|
|
23
|
+
|
|
24
|
+
def self.tracer
|
|
25
|
+
@tracer
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# Datadog auto instrumentation for frameworks
|
|
30
|
+
if defined?(Rails::VERSION)
|
|
31
|
+
if !ENV['DISABLE_DATADOG_RAILS']
|
|
32
|
+
if Rails::VERSION::MAJOR.to_i >= 3
|
|
33
|
+
require 'ddtrace/contrib/rails/framework'
|
|
34
|
+
require 'ddtrace/contrib/rails/middlewares'
|
|
35
|
+
|
|
36
|
+
module Datadog
|
|
37
|
+
# Railtie class initializes
|
|
38
|
+
class Railtie < Rails::Railtie
|
|
39
|
+
config.app_middleware.use(Datadog::Contrib::Rails::ExceptionMiddleware)
|
|
40
|
+
|
|
41
|
+
# auto instrument Rails and third party components after
|
|
42
|
+
# the framework initialization
|
|
43
|
+
options = {}
|
|
44
|
+
config.after_initialize do |app|
|
|
45
|
+
Datadog::Contrib::Rails::Framework.configure(config: app.config)
|
|
46
|
+
Datadog::Contrib::Rails::Framework.auto_instrument()
|
|
47
|
+
Datadog::Contrib::Rails::Framework.auto_instrument_redis()
|
|
48
|
+
Datadog::Contrib::Rails::Framework.auto_instrument_grape()
|
|
49
|
+
|
|
50
|
+
# override Rack Middleware configurations with Rails
|
|
51
|
+
options.update(::Rails.configuration.datadog_trace)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# Configure datadog settings before building the middleware stack.
|
|
55
|
+
# This is required because the middleware stack is frozen after
|
|
56
|
+
# the initialization and so it's too late to add our tracing
|
|
57
|
+
# functionalities.
|
|
58
|
+
initializer :datadog_config, before: :build_middleware_stack do |app|
|
|
59
|
+
app.config.middleware.insert_before(
|
|
60
|
+
0, Datadog::Contrib::Rack::TraceMiddleware, options
|
|
61
|
+
)
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
else
|
|
66
|
+
Datadog::Tracer.log.warn 'Detected a Rails version < 3.x.'\
|
|
67
|
+
'This version is not supported yet and the'\
|
|
68
|
+
'auto-instrumentation for core components will be disabled.'
|
|
69
|
+
end
|
|
70
|
+
else
|
|
71
|
+
Datadog::Tracer.log.info 'Skipping Rails auto-instrumentation, DISABLE_DATADOG_RAILS is set.'
|
|
72
|
+
end
|
|
73
|
+
end
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
require 'thread'
|
|
2
|
+
|
|
3
|
+
module Datadog
|
|
4
|
+
# Trace buffer that stores application traces. The buffer has a maximum size and when
|
|
5
|
+
# the buffer is full, a random trace is discarded. This class is thread-safe and is used
|
|
6
|
+
# automatically by the ``Tracer`` instance when a ``Span`` is finished.
|
|
7
|
+
class TraceBuffer
|
|
8
|
+
def initialize(max_size)
|
|
9
|
+
@max_size = max_size
|
|
10
|
+
|
|
11
|
+
@mutex = Mutex.new()
|
|
12
|
+
@traces = []
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# Add a new ``trace`` in the local queue. This method doesn't block the execution
|
|
16
|
+
# even if the buffer is full. In that case, a random trace is discarded.
|
|
17
|
+
def push(trace)
|
|
18
|
+
@mutex.synchronize do
|
|
19
|
+
len = @traces.length
|
|
20
|
+
if len < @max_size || @max_size <= 0
|
|
21
|
+
@traces << trace
|
|
22
|
+
else
|
|
23
|
+
# we should replace a random trace with the new one
|
|
24
|
+
@traces[rand(len)] = trace
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# Return the current number of stored traces.
|
|
30
|
+
def length
|
|
31
|
+
@mutex.synchronize do
|
|
32
|
+
return @traces.length
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# Return if the buffer is empty.
|
|
37
|
+
def empty?
|
|
38
|
+
@mutex.synchronize do
|
|
39
|
+
return @traces.empty?
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# Stored traces are returned and the local buffer is reset.
|
|
44
|
+
def pop
|
|
45
|
+
@mutex.synchronize do
|
|
46
|
+
traces = @traces
|
|
47
|
+
@traces = []
|
|
48
|
+
return traces
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
require 'thread'
|
|
2
|
+
|
|
3
|
+
module Datadog
|
|
4
|
+
# \Context is used to keep track of a hierarchy of spans for the current
|
|
5
|
+
# execution flow. During each logical execution, the same \Context is
|
|
6
|
+
# used to represent a single logical trace, even if the trace is built
|
|
7
|
+
# asynchronously.
|
|
8
|
+
#
|
|
9
|
+
# A single code execution may use multiple \Context if part of the execution
|
|
10
|
+
# must not be related to the current tracing. As example, a delayed job may
|
|
11
|
+
# compose a standalone trace instead of being related to the same trace that
|
|
12
|
+
# generates the job itself. On the other hand, if it's part of the same
|
|
13
|
+
# \Context, it will be related to the original trace.
|
|
14
|
+
#
|
|
15
|
+
# This data structure is thread-safe.
|
|
16
|
+
class Context
|
|
17
|
+
# Initialize a new thread-safe \Context.
|
|
18
|
+
def initialize
|
|
19
|
+
@mutex = Mutex.new
|
|
20
|
+
reset
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def reset
|
|
24
|
+
@trace = []
|
|
25
|
+
@sampled = false
|
|
26
|
+
@finished_spans = 0
|
|
27
|
+
@current_span = nil
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# Return the last active span that corresponds to the last inserted
|
|
31
|
+
# item in the trace list. This cannot be considered as the current active
|
|
32
|
+
# span in asynchronous environments, because some spans can be closed
|
|
33
|
+
# earlier while child spans still need to finish their traced execution.
|
|
34
|
+
def current_span
|
|
35
|
+
@mutex.synchronize do
|
|
36
|
+
return @current_span
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# Add a span to the context trace list, keeping it as the last active span.
|
|
41
|
+
def add_span(span)
|
|
42
|
+
@mutex.synchronize do
|
|
43
|
+
@current_span = span
|
|
44
|
+
@sampled = span.sampled
|
|
45
|
+
@trace << span
|
|
46
|
+
span.context = self
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# Mark a span as a finished, increasing the internal counter to prevent
|
|
51
|
+
# cycles inside _trace list.
|
|
52
|
+
def close_span(span)
|
|
53
|
+
@mutex.synchronize do
|
|
54
|
+
@finished_spans += 1
|
|
55
|
+
# Current span is only meaningful for linear tree-like traces,
|
|
56
|
+
# in other cases, this is just broken and one should rely
|
|
57
|
+
# on per-instrumentation code to retrieve handle parent/child relations.
|
|
58
|
+
@current_span = span.parent
|
|
59
|
+
return if span.tracer.nil?
|
|
60
|
+
return unless Datadog::Tracer.debug_logging
|
|
61
|
+
if span.parent.nil? && !check_finished_spans
|
|
62
|
+
opened_spans = @trace.length - @finished_spans
|
|
63
|
+
Datadog::Tracer.log.debug("root span #{span.name} closed but has #{opened_spans} unfinished spans:")
|
|
64
|
+
@trace.each do |s|
|
|
65
|
+
Datadog::Tracer.log.debug("unfinished span: #{s}") unless s.finished?
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
# Returns if the trace for the current Context is finished or not.
|
|
72
|
+
# Low-level internal function, not thread-safe.
|
|
73
|
+
def check_finished_spans
|
|
74
|
+
@finished_spans > 0 && @trace.length == @finished_spans
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
# Returns if the trace for the current Context is finished or not. A \Context
|
|
78
|
+
# is considered finished if all spans in this context are finished.
|
|
79
|
+
def finished?
|
|
80
|
+
@mutex.synchronize do
|
|
81
|
+
return check_finished_spans
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
# Returns true if the context is sampled, that is, if it should be kept
|
|
86
|
+
# and sent to the trace agent.
|
|
87
|
+
def sampled?
|
|
88
|
+
@mutex.synchronize do
|
|
89
|
+
return @sampled
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
# Returns both the trace list generated in the current context and
|
|
94
|
+
# if the context is sampled or not. It returns nil, nil if the ``Context`` is
|
|
95
|
+
# not finished. If a trace is returned, the \Context will be reset so that it
|
|
96
|
+
# can be re-used immediately.
|
|
97
|
+
#
|
|
98
|
+
# This operation is thread-safe.
|
|
99
|
+
def get
|
|
100
|
+
@mutex.synchronize do
|
|
101
|
+
return nil, nil unless check_finished_spans
|
|
102
|
+
|
|
103
|
+
trace = @trace
|
|
104
|
+
sampled = @sampled
|
|
105
|
+
reset
|
|
106
|
+
return trace, sampled
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
# Return a string representation of the context.
|
|
111
|
+
def to_s
|
|
112
|
+
@mutex.synchronize do
|
|
113
|
+
# rubocop:disable Metrics/LineLength
|
|
114
|
+
"Context(trace.length:#{@trace.length},sampled:#{@sampled},finished_spans:#{@finished_spans},current_span:#{@current_span})"
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
private :reset
|
|
119
|
+
private :check_finished_spans
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
# ThreadLocalContext can be used as a tracer global reference to create
|
|
123
|
+
# a different \Context for each thread. In synchronous tracer, this
|
|
124
|
+
# is required to prevent multiple threads sharing the same \Context
|
|
125
|
+
# in different executions.
|
|
126
|
+
class ThreadLocalContext
|
|
127
|
+
# ThreadLocalContext can be used as a tracer global reference to create
|
|
128
|
+
# a different \Context for each thread. In synchronous tracer, this
|
|
129
|
+
# is required to prevent multiple threads sharing the same \Context
|
|
130
|
+
# in different executions.
|
|
131
|
+
def initialize
|
|
132
|
+
self.local = Datadog::Context.new
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
# Override the thread-local context with a new context.
|
|
136
|
+
def local=(ctx)
|
|
137
|
+
Thread.current[:datadog_context] = ctx
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
# Return the thread-local context.
|
|
141
|
+
def local
|
|
142
|
+
Thread.current[:datadog_context] ||= Datadog::Context.new
|
|
143
|
+
end
|
|
144
|
+
end
|
|
145
|
+
end
|