ddtrace 0.4.3 → 0.5.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9dc26d3b7ce6a1750bd273655bfb068604249878
4
- data.tar.gz: 9c431f39db93b20c1d3c854e8efa1cb3b8d030b4
3
+ metadata.gz: 80f9cffb7ec1f57e9215784dd53d859b6a9ffae7
4
+ data.tar.gz: 348d67544886fa8762b2c2125dd8033a766d5f62
5
5
  SHA512:
6
- metadata.gz: 044bc1ebc2a9e74f66754fbe3514563a8f8ad735e3547bcdc7ca61e508cbd3fac52a7f16d451d719c5402f05272a5f3ea7951b57a7c155fcc27b897cae063a62
7
- data.tar.gz: 29ce52bf23933396a5d45b2467d43c0a9b1642769f6119fe22c8f38b544b2c796cf309366de063498f3ad07e4026dd48d18ac03179f24952cf31d96fb5b7597c
6
+ metadata.gz: e6795138d773ce92ba5123d9fbbe42a84c49a66800a9ab2a487f5c73900059b5197dbae0768e055fd11b9990fed3e1c812cf5f0637c87de7f7b56fa0ec1ba242
7
+ data.tar.gz: 1658c85972eb0be8ecc6941382558623d2ba54407e3d28874efe5c6e0936510e108512ee6314cf8d483796a903e71af77a4b47057441d2ff25e35e3174c4dfc5
@@ -34,7 +34,7 @@ Style/NumericLiterals:
34
34
  Enabled: false
35
35
 
36
36
  Metrics/ClassLength:
37
- Max: 120
37
+ Max: 140
38
38
 
39
39
  Metrics/BlockLength:
40
40
  Max: 42
@@ -47,3 +47,6 @@ Metrics/CyclomaticComplexity:
47
47
 
48
48
  Metrics/PerceivedComplexity:
49
49
  Max: 15
50
+
51
+ Lint/UnusedMethodArgument:
52
+ Enabled: false
data/Appraisals CHANGED
@@ -40,6 +40,20 @@ if RUBY_VERSION < "2.4.0"
40
40
  gem 'activerecord-jdbcpostgresql-adapter', platform: :jruby
41
41
  gem "redis-rails"
42
42
  end
43
+ appraise "rails3-postgres-sidekiq" do
44
+ gem "test-unit"
45
+ gem "rails", "3.2.22.5"
46
+ gem "pg", platform: :ruby
47
+ gem 'activerecord-jdbcpostgresql-adapter', platform: :jruby
48
+ gem "sidekiq"
49
+ end
50
+
51
+ appraise "rails4-postgres-sidekiq" do
52
+ gem "rails", "4.2.7.1"
53
+ gem "pg", platform: :ruby
54
+ gem 'activerecord-jdbcpostgresql-adapter', platform: :jruby
55
+ gem "sidekiq"
56
+ end
43
57
 
44
58
  if RUBY_VERSION >= "2.2.2" && RUBY_PLATFORM != "java"
45
59
  appraise "rails5-postgres" do
@@ -57,6 +71,12 @@ if RUBY_VERSION < "2.4.0"
57
71
  gem "pg", platform: :ruby
58
72
  gem "redis-rails"
59
73
  end
74
+
75
+ appraise "rails5-postgres-sidekiq" do
76
+ gem "rails", "5.0.1"
77
+ gem "pg", platform: :ruby
78
+ gem "sidekiq"
79
+ end
60
80
  end
61
81
  end
62
82
 
@@ -66,4 +86,5 @@ appraise "contrib" do
66
86
  gem "hiredis"
67
87
  gem "rack-test"
68
88
  gem "sinatra"
89
+ gem "sidekiq"
69
90
  end
data/Rakefile CHANGED
@@ -6,7 +6,7 @@ require 'appraisal'
6
6
  require 'yard'
7
7
 
8
8
  namespace :test do
9
- task all: [:main, :rails, :railsredis, :elasticsearch, :http, :redis, :sinatra, :monkey]
9
+ task all: [:main, :rails, :railsredis, :elasticsearch, :http, :redis, :sidekiq, :sinatra, :monkey]
10
10
 
11
11
  Rake::TestTask.new(:main) do |t|
12
12
  t.libs << %w(test lib)
@@ -21,7 +21,8 @@ namespace :test do
21
21
  Rake::TestTask.new(:rails) do |t|
22
22
  t.libs << %w(test lib)
23
23
  t.test_files = FileList['test/contrib/rails/**/*_test.rb'].reject do |path|
24
- path.include?('redis')
24
+ path.include?('redis') ||
25
+ path.include?('sidekiq')
25
26
  end
26
27
  end
27
28
 
@@ -30,7 +31,12 @@ namespace :test do
30
31
  t.test_files = FileList['test/contrib/rails/**/*redis*_test.rb']
31
32
  end
32
33
 
33
- [:elasticsearch, :http, :redis, :sinatra].each do |contrib|
34
+ Rake::TestTask.new(:railssidekiq) do |t|
35
+ t.libs << %w(test lib)
36
+ t.test_files = FileList['test/contrib/rails/**/*sidekiq*_test.rb']
37
+ end
38
+
39
+ [:elasticsearch, :http, :redis, :sinatra, :sidekiq].each do |contrib|
34
40
  Rake::TestTask.new(contrib) do |t|
35
41
  t.libs << %w(test lib)
36
42
  t.test_files = FileList["test/contrib/#{contrib}/*_test.rb"]
@@ -49,6 +55,7 @@ Rake::TestTask.new(:benchmark) do |t|
49
55
  end
50
56
 
51
57
  RuboCop::RakeTask.new(:rubocop) do |t|
58
+ t.options << ['-D']
52
59
  t.patterns = ['lib/**/*.rb', 'test/**/*.rb', 'Gemfile', 'Rakefile']
53
60
  end
54
61
 
@@ -114,6 +121,10 @@ task :ci do
114
121
  sh 'rvm $MRI_VERSIONS --verbose do appraisal contrib rake test:http'
115
122
  sh 'rvm $MRI_VERSIONS --verbose do appraisal contrib rake test:redis'
116
123
  sh 'rvm $MRI_VERSIONS --verbose do appraisal contrib rake test:sinatra'
124
+ sh 'rvm $MRI_VERSIONS --verbose do appraisal contrib rake test:sidekiq'
125
+ sh 'rvm $RAILS_VERSIONS --verbose do appraisal rails3-postgres-sidekiq rake test:railssidekiq'
126
+ sh 'rvm $RAILS_VERSIONS --verbose do appraisal rails4-postgres-sidekiq rake test:railssidekiq'
127
+ sh 'rvm $RAILS5_VERSIONS --verbose do appraisal rails5-postgres-sidekiq rake test:railssidekiq'
117
128
  when 2
118
129
  sh 'rvm $RAILS_VERSIONS --verbose do appraisal rails3-postgres rake test:rails'
119
130
  sh 'rvm $RAILS_VERSIONS --verbose do appraisal rails3-mysql2 rake test:rails'
data/circle.yml CHANGED
@@ -28,8 +28,6 @@ dependencies:
28
28
  # configure Ruby interpreters
29
29
  - rvm get head
30
30
  - rvm install $MRI_VERSIONS
31
- # run the agent
32
- - docker run -d -e DD_API_KEY=invalid_key_but_this_is_fine -e DD_BIND_HOST=0.0.0.0 -e DD_APM_ENABLED=true -p 127.0.0.1:8126:8126 -p 127.0.0.1:7777:7777 datadog/docker-dd-agent
33
31
  override:
34
32
  - rvm $MRI_VERSIONS --verbose do gem update --system
35
33
  - rvm $MRI_VERSIONS --verbose do gem install bundler
@@ -31,3 +31,12 @@ redis:
31
31
  image: redis:3.0
32
32
  ports:
33
33
  - "127.0.0.1:${TEST_REDIS_PORT}:6379"
34
+
35
+ ddagent:
36
+ image: datadog/docker-dd-agent
37
+ environment:
38
+ - DD_APM_ENABLED=true
39
+ - DD_BIND_HOST=0.0.0.0
40
+ - DD_API_KEY=invalid_key_but_this_is_fine
41
+ ports:
42
+ - "127.0.0.1:8126:8126"
@@ -64,7 +64,7 @@ of the Datadog tracer, you can override the following defaults:
64
64
  tracer: Datadog.tracer,
65
65
  debug: false,
66
66
  trace_agent_hostname: 'localhost',
67
- trace_agent_port: 7777
67
+ trace_agent_port: 8126
68
68
  }
69
69
 
70
70
  Available settings are:
@@ -175,6 +175,59 @@ Net::HTTP module.
175
175
 
176
176
  content = Net::HTTP.get(URI('http://127.0.0.1/index.html'))
177
177
 
178
+ ### Sidekiq
179
+
180
+ The Sidekiq integration is a server-side middleware which will trace job
181
+ executions. It can be added as any other Sidekiq middleware:
182
+
183
+ require 'sidekiq'
184
+ require 'ddtrace'
185
+ require 'ddtrace/contrib/sidekiq/tracer'
186
+
187
+ Sidekiq.configure_server do |config|
188
+ config.server_middleware do |chain|
189
+ chain.add(Datadog::Contrib::Sidekiq::Tracer)
190
+ end
191
+ end
192
+
193
+ #### Configure the tracer middleware
194
+
195
+ To modify the default configuration, simply pass arguments to the middleware.
196
+ For example, to change the default service name:
197
+
198
+ Sidekiq.configure_server do |config|
199
+ config.server_middleware do |chain|
200
+ chain.add(
201
+ Datadog::Contrib::Sidekiq::Tracer,
202
+ sidekiq_service: 'sidekiq-notifications'
203
+ )
204
+ end
205
+ end
206
+
207
+ Available settings are:
208
+
209
+ * ``enabled``: define if the ``tracer`` is enabled or not. If set to
210
+ ``false``, the code is still instrumented but no spans are sent to the local
211
+ trace agent.
212
+ * ``sidekiq_service``: set the service name used when tracing application
213
+ requests. Defaults to ``sidekiq``.
214
+ * ``tracer``: set the tracer to use. Usually you don't need to change that
215
+ value unless you're already using a different initialized tracer somewhere
216
+ else.
217
+ * ``debug``: set to ``true`` to enable debug logging.
218
+ * ``trace_agent_hostname``: set the hostname of the trace agent.
219
+ * ``trace_agent_port``: set the port the trace agent is listening on.
220
+
221
+ If you're using Sidekiq along with [Ruby on Rails](#label-Ruby+on+Rails) auto-instrumentation,
222
+ the Sidekiq middleware will re-use the Rails configuration defined in the initializer file before
223
+ giving precedence to the middleware settings. Inherited configurations are:
224
+
225
+ * ``enabled``
226
+ * ``tracer``
227
+ * ``debug``
228
+ * ``trace_agent_hostname``
229
+ * ``trace_agent_port``
230
+
178
231
  ## Advanced usage
179
232
 
180
233
  ### Manual Instrumentation
@@ -195,13 +248,16 @@ to trace requests to the home page:
195
248
  # set some span metadata
196
249
  span.service = 'my-web-site'
197
250
  span.resource = '/'
198
- span.set_tag('http.method', request.request_method)
199
251
 
200
252
  # trace the activerecord call
201
253
  tracer.trace('posts.fetch') do
202
254
  @posts = Posts.order(created_at: :desc).limit(10)
203
255
  end
204
256
 
257
+ # add some attributes and metrics
258
+ span.set_tag('http.method', request.request_method)
259
+ span.set_metric('posts.count', len(@posts))
260
+
205
261
  # trace the template rendering
206
262
  tracer.trace('template.render') do
207
263
  erb :index
@@ -329,6 +385,18 @@ for the first time:
329
385
  Remember that the debug mode may affect your application performance and so it must not be used
330
386
  in a production environment.
331
387
 
388
+ ### Sampling
389
+
390
+ `ddtrace` can perform trace sampling. While the trace agent already samples
391
+ traces to reduce bandwidth usage, client sampling reduces performance
392
+ overhead.
393
+
394
+ `Datadog::RateSampler` samples a ratio of the traces. For example:
395
+
396
+ # Sample rate is between 0 (nothing sampled) to 1 (everything sampled).
397
+ sampler = Datadog::RateSampler.new(0.5) # sample 50% of the traces
398
+ Datadog.tracer.configure(sampler: sampler)
399
+
332
400
  ### Supported Versions
333
401
 
334
402
  #### Ruby interpreters
@@ -360,6 +428,10 @@ The currently supported web server are:
360
428
 
361
429
  Currently we are supporting Sinatra >= 1.4.0.
362
430
 
431
+ #### Sidekiq versions
432
+
433
+ Currently we are supporting Sidekiq >= 4.0.0.
434
+
363
435
  ### Glossary
364
436
 
365
437
  * ``Service``: The name of a set of processes that do the same job. Some examples are ``datadog-web-app`` or ``datadog-metrics-db``.
@@ -7,5 +7,6 @@ gem "redis"
7
7
  gem "hiredis"
8
8
  gem "rack-test"
9
9
  gem "sinatra"
10
+ gem "sidekiq"
10
11
 
11
12
  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", :platform => :ruby
8
+ gem "activerecord-jdbcpostgresql-adapter", :platform => :jruby
9
+ gem "sidekiq"
10
+
11
+ gemspec :path => "../"
@@ -0,0 +1,10 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "rails", "4.2.7.1"
6
+ gem "pg", :platform => :ruby
7
+ gem "activerecord-jdbcpostgresql-adapter", :platform => :jruby
8
+ gem "sidekiq"
9
+
10
+ gemspec :path => "../"
@@ -0,0 +1,9 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "rails", "5.0.1"
6
+ gem "pg", :platform => :ruby
7
+ gem "sidekiq"
8
+
9
+ gemspec :path => "../"
@@ -31,24 +31,9 @@ if defined?(Rails::VERSION)
31
31
  require 'ddtrace/contrib/rails/framework'
32
32
 
33
33
  module Datadog
34
- # Run the auto instrumentation directly after the initialization of the application and
35
- # after the application initializers in config/initializers are run
34
+ # Run the auto instrumentation directly after initializers in
35
+ # `config/initializers` are executed
36
36
  class Railtie < Rails::Railtie
37
- config.before_configuration do
38
- begin
39
- # We include 'redis-rails' here if it's available, doing it later
40
- # (typically in initialize callback) does not work, it does not
41
- # get loaded in the right context.
42
- require 'redis-rails'
43
- Datadog::Tracer.log.debug("'redis-rails' module found, Datadog 'redis-rails' integration is available")
44
- rescue LoadError
45
- Datadog::Tracer.log.debug("'redis-rails' module not found, Datadog 'redis-rails' integration is disabled")
46
- end
47
-
48
- Datadog::Monkey.patch_module(:redis)
49
- end
50
-
51
- # we do actions
52
37
  config.after_initialize do |app|
53
38
  Datadog::Contrib::Rails::Framework.configure(config: app.config)
54
39
  Datadog::Contrib::Rails::Framework.auto_instrument()
@@ -80,21 +80,32 @@ module Datadog
80
80
  end
81
81
 
82
82
  def self.auto_instrument_redis
83
- # configure Redis PIN
84
- return unless (defined? ::Rails.cache) && ::Rails.cache.respond_to?(:data)
85
- pin = Datadog::Pin.get_from(::Rails.cache.data)
86
- return unless pin
83
+ return unless ::Rails.configuration.datadog_trace[:auto_instrument_redis]
84
+ Datadog::Tracer.log.debug('Enabling auto-instrumentation for Redis client')
87
85
 
88
- # enable Redis instrumentation if activated
89
- pin.tracer = nil unless ::Rails.configuration.datadog_trace[:auto_instrument_redis]
90
- return unless pin.tracer
91
- Datadog::Tracer.log.debug("'redis' module found, Datadog 'redis' integration is available")
86
+ # patch the Redis library and reload the CacheStore if it was using Redis
87
+ Datadog::Monkey.patch_module(:redis)
88
+
89
+ # reload the cache store if it's available and it's using Redis
90
+ return unless defined?(::ActiveSupport::Cache::RedisStore) &&
91
+ defined?(::Rails.cache) &&
92
+ ::Rails.cache.is_a?(::ActiveSupport::Cache::RedisStore)
93
+ Datadog::Tracer.log.debug('Enabling auto-instrumentation for redis-rails connector')
94
+
95
+ # backward compatibility: Rails 3.x doesn't have `cache=` method
96
+ cache_store = ::Rails.configuration.cache_store
97
+ cache_instance = ::ActiveSupport::Cache.lookup_store(cache_store)
98
+ if ::Rails::VERSION::MAJOR.to_i == 3
99
+ silence_warnings { Object.const_set 'RAILS_CACHE', cache_instance }
100
+ elsif ::Rails::VERSION::MAJOR.to_i > 3
101
+ ::Rails.cache = cache_instance
102
+ end
92
103
  end
93
104
 
94
105
  # automatically instrument all Rails component
95
106
  def self.auto_instrument
96
107
  return unless ::Rails.configuration.datadog_trace[:auto_instrument]
97
- Datadog::Tracer.log.info('Detected Rails >= 3.x. Enabling auto-instrumentation for core components')
108
+ Datadog::Tracer.log.debug('Enabling auto-instrumentation for core components')
98
109
 
99
110
  # instrumenting Rails framework
100
111
  Datadog::Contrib::Rails::ActionController.instrument()
@@ -0,0 +1,67 @@
1
+ require 'sidekiq/api'
2
+
3
+ require 'ddtrace/ext/app_types'
4
+
5
+ sidekiq_vs = Gem::Version.new(Sidekiq::VERSION)
6
+ sidekiq_min_vs = Gem::Version.new('4.0.0')
7
+ if sidekiq_vs < sidekiq_min_vs
8
+ raise "sidekiq version #{sidekiq_vs} is not supported yet " \
9
+ + "(supporting versions >=#{sidekiq_min_vs})"
10
+ end
11
+
12
+ Datadog::Tracer.log.debug("Activating instrumentation for Sidekiq '#{sidekiq_vs}'")
13
+
14
+ module Datadog
15
+ module Contrib
16
+ module Sidekiq
17
+ DEFAULT_CONFIG = {
18
+ enabled: true,
19
+ sidekiq_service: 'sidekiq',
20
+ tracer: Datadog.tracer,
21
+ debug: false,
22
+ trace_agent_hostname: Datadog::Writer::HOSTNAME,
23
+ trace_agent_port: Datadog::Writer::PORT
24
+ }.freeze
25
+
26
+ # Middleware is a Sidekiq server-side middleware which traces executed jobs
27
+ class Tracer
28
+ def initialize(options)
29
+ # check if Rails configuration is available and use it to override
30
+ # Sidekiq defaults
31
+ rails_config = ::Rails.configuration.datadog_trace rescue {}
32
+ base_config = DEFAULT_CONFIG.merge(rails_config)
33
+ user_config = base_config.merge(options)
34
+ @tracer = user_config[:tracer]
35
+ @sidekiq_service = user_config[:sidekiq_service]
36
+
37
+ # set Tracer status
38
+ @tracer.enabled = user_config[:enabled]
39
+ Datadog::Tracer.debug_logging = user_config[:debug]
40
+
41
+ # configure the Tracer instance
42
+ @tracer.configure(
43
+ hostname: user_config[:trace_agent_hostname],
44
+ port: user_config[:trace_agent_port]
45
+ )
46
+
47
+ # configure Sidekiq service
48
+ @tracer.set_service_info(
49
+ @sidekiq_service,
50
+ 'sidekiq',
51
+ Datadog::Ext::AppTypes::WORKER
52
+ )
53
+ end
54
+
55
+ def call(worker, job, queue)
56
+ @tracer.trace('sidekiq.job', service: @sidekiq_service, span_type: 'job') do |span|
57
+ span.resource = job['class']
58
+ span.set_tag('sidekiq.job.id', job['jid'])
59
+ span.set_tag('sidekiq.job.retry', job['retry'])
60
+ span.set_tag('sidekiq.job.queue', job['queue'])
61
+ yield
62
+ end
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
@@ -4,6 +4,7 @@ module Datadog
4
4
  WEB = 'web'.freeze
5
5
  DB = 'db'.freeze
6
6
  CACHE = 'cache'.freeze
7
+ WORKER = 'worker'.freeze
7
8
  end
8
9
  end
9
10
  end
@@ -0,0 +1,49 @@
1
+ module Datadog
2
+ # \Sampler performs client-side trace sampling.
3
+ class Sampler
4
+ def sample(_span)
5
+ raise NotImplementedError, 'samplers have to implement the sample() method'
6
+ end
7
+ end
8
+
9
+ # \AllSampler samples all the traces.
10
+ class AllSampler < Sampler
11
+ def sample(span)
12
+ span.sampled = true
13
+ end
14
+ end
15
+
16
+ # \RateSampler is based on a sample rate.
17
+ class RateSampler < Sampler
18
+ KNUTH_FACTOR = 1111111111111111111
19
+ SAMPLE_RATE_METRIC_KEY = '_sample_rate'.freeze()
20
+
21
+ attr_reader :sample_rate
22
+
23
+ # Initialize a \RateSampler.
24
+ # This sampler keeps a random subset of the traces. Its main purpose is to
25
+ # reduce the instrumentation footprint.
26
+ #
27
+ # * +sample_rate+: the sample rate as a \Float between 0.0 and 1.0. 0.0
28
+ # means that no trace will be sampled; 1.0 means that all traces will be
29
+ # sampled.
30
+ def initialize(sample_rate = 1.0)
31
+ unless sample_rate > 0.0 && sample_rate <= 1.0
32
+ Datadog::Tracer.log.error('sample rate is not between 0 and 1, disabling the sampler')
33
+ sample_rate = 1.0
34
+ end
35
+
36
+ self.sample_rate = sample_rate
37
+ end
38
+
39
+ def sample_rate=(sample_rate)
40
+ @sample_rate = sample_rate
41
+ @sampling_id_threshold = sample_rate * Span::MAX_ID
42
+ end
43
+
44
+ def sample(span)
45
+ span.sampled = ((span.trace_id * KNUTH_FACTOR) % Datadog::Span::MAX_ID) <= @sampling_id_threshold
46
+ span.set_metric(SAMPLE_RATE_METRIC_KEY, @sample_rate)
47
+ end
48
+ end
49
+ end
@@ -16,7 +16,7 @@ module Datadog
16
16
  attr_accessor :name, :service, :resource, :span_type,
17
17
  :start_time, :end_time,
18
18
  :span_id, :trace_id, :parent_id,
19
- :status, :parent
19
+ :status, :parent, :sampled
20
20
 
21
21
  # Create a new span linked to the given tracer. Call the <tt>finish()</tt> method once the
22
22
  # tracer operation is over or use the <tt>finish_at(time)</tt> helper to close the span with the
@@ -40,9 +40,11 @@ module Datadog
40
40
  @trace_id = options.fetch(:trace_id, @span_id)
41
41
 
42
42
  @meta = {}
43
+ @metrics = {}
43
44
  @status = 0
44
45
 
45
46
  @parent = nil
47
+ @sampled = true
46
48
 
47
49
  @start_time = Time.now.utc
48
50
  @end_time = nil
@@ -55,14 +57,29 @@ module Datadog
55
57
  def set_tag(key, value)
56
58
  @meta[key] = value.to_s
57
59
  rescue StandardError => e
58
- Datadog::Tracer.log.error("Unable to set the tag #{key}, ignoring it. Caused by: #{e}")
60
+ Datadog::Tracer.log.debug("Unable to set the tag #{key}, ignoring it. Caused by: #{e}")
59
61
  end
60
62
 
61
- # Return the tag wth the given key, nil if it doesn't exist.
63
+ # Return the tag with the given key, nil if it doesn't exist.
62
64
  def get_tag(key)
63
65
  @meta[key]
64
66
  end
65
67
 
68
+ # Set the given key / value metric pair on the span. Keys must be string.
69
+ # Values must be floating point numbers.
70
+ def set_metric(key, value)
71
+ # enforce that the value is a floating point number
72
+ value = Float(value)
73
+ @metrics[key] = value
74
+ rescue StandardError => e
75
+ Datadog::Tracer.log.debug("Unable to set the metric #{key}, ignoring it. Caused by: #{e}")
76
+ end
77
+
78
+ # Return the metric with the given key, nil if it doesn't exist.
79
+ def get_metric(key)
80
+ @metrics[key]
81
+ end
82
+
66
83
  # Mark the span with the given error.
67
84
  def set_error(e)
68
85
  return if e.nil?
@@ -122,6 +139,7 @@ module Datadog
122
139
  resource: @resource,
123
140
  type: @span_type,
124
141
  meta: @meta,
142
+ metrics: @metrics,
125
143
  error: @status
126
144
  }
127
145
 
@@ -151,12 +169,18 @@ module Datadog
151
169
  q.text "Start: #{start_time}\n"
152
170
  q.text "End: #{end_time}\n"
153
171
  q.text "Duration: #{duration}\n"
154
- q.group(2, 'Tags: [', ']') do
172
+ q.group(2, 'Tags: [', "]\n") do
155
173
  q.breakable
156
174
  q.seplist @meta.each do |key, value|
157
175
  q.text "#{key} => #{value}"
158
176
  end
159
177
  end
178
+ q.group(2, 'Metrics: [', ']') do
179
+ q.breakable
180
+ q.seplist @metrics.each do |key, value|
181
+ q.text "#{key} => #{value}"
182
+ end
183
+ end
160
184
  end
161
185
  end
162
186
  end
@@ -5,6 +5,7 @@ require 'logger'
5
5
  require 'ddtrace/span'
6
6
  require 'ddtrace/buffer'
7
7
  require 'ddtrace/writer'
8
+ require 'ddtrace/sampler'
8
9
 
9
10
  # \Datadog global namespace that includes all tracing functionality for Tracer and Span classes.
10
11
  module Datadog
@@ -13,7 +14,7 @@ module Datadog
13
14
  # Even though the request may require multiple resources and machines to handle the request, all
14
15
  # of these function calls and sub-requests would be encapsulated within a single trace.
15
16
  class Tracer
16
- attr_reader :writer, :services
17
+ attr_reader :writer, :sampler, :services
17
18
  attr_accessor :enabled
18
19
 
19
20
  # Global, memoized, lazy initialized instance of a logger that is used within the the Datadog
@@ -44,6 +45,8 @@ module Datadog
44
45
  def initialize(options = {})
45
46
  @enabled = options.fetch(:enabled, true)
46
47
  @writer = options.fetch(:writer, Datadog::Writer.new)
48
+ @sampler = options.fetch(:sampler, Datadog::AllSampler.new)
49
+
47
50
  @buffer = Datadog::SpanBuffer.new()
48
51
 
49
52
  @mutex = Mutex.new
@@ -66,10 +69,12 @@ module Datadog
66
69
  enabled = options.fetch(:enabled, nil)
67
70
  hostname = options.fetch(:hostname, nil)
68
71
  port = options.fetch(:port, nil)
72
+ sampler = options.fetch(:sampler, nil)
69
73
 
70
74
  @enabled = enabled unless enabled.nil?
71
75
  @writer.transport.hostname = hostname unless hostname.nil?
72
76
  @writer.transport.port = port unless port.nil?
77
+ @sampler = sampler unless sampler.nil?
73
78
  end
74
79
 
75
80
  # Set the information about the given service. A valid example is:
@@ -121,6 +126,13 @@ module Datadog
121
126
  span.set_parent(parent)
122
127
  @buffer.set(span)
123
128
 
129
+ # sampling
130
+ if parent.nil?
131
+ @sampler.sample(span)
132
+ else
133
+ span.sampled = span.parent.sampled
134
+ end
135
+
124
136
  # call the finish only if a block is given; this ensures
125
137
  # that a call to tracer.trace() without a block, returns
126
138
  # a span that should be manually finished.
@@ -155,7 +167,7 @@ module Datadog
155
167
  @spans = []
156
168
  end
157
169
 
158
- return if spans.empty?
170
+ return if spans.empty? || !span.sampled
159
171
  write(spans)
160
172
  end
161
173
 
@@ -1,8 +1,8 @@
1
1
  module Datadog
2
2
  module VERSION
3
3
  MAJOR = 0
4
- MINOR = 4
5
- PATCH = 3
4
+ MINOR = 5
5
+ PATCH = 0
6
6
 
7
7
  STRING = [MAJOR, MINOR, PATCH].compact.join('.')
8
8
  end
@@ -9,7 +9,7 @@ module Datadog
9
9
  attr_reader :transport
10
10
 
11
11
  HOSTNAME = 'localhost'.freeze
12
- PORT = '7777'.freeze
12
+ PORT = '8126'.freeze
13
13
 
14
14
  def initialize(options = {})
15
15
  # writer and transport parameters
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ddtrace
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.3
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Datadog, Inc.
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-02-17 00:00:00.000000000 Z
11
+ date: 2017-03-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: msgpack
@@ -121,12 +121,15 @@ files:
121
121
  - gemfiles/rails3_mysql2.gemfile
122
122
  - gemfiles/rails3_postgres.gemfile
123
123
  - gemfiles/rails3_postgres_redis.gemfile
124
+ - gemfiles/rails3_postgres_sidekiq.gemfile
124
125
  - gemfiles/rails4_mysql2.gemfile
125
126
  - gemfiles/rails4_postgres.gemfile
126
127
  - gemfiles/rails4_postgres_redis.gemfile
128
+ - gemfiles/rails4_postgres_sidekiq.gemfile
127
129
  - gemfiles/rails5_mysql2.gemfile
128
130
  - gemfiles/rails5_postgres.gemfile
129
131
  - gemfiles/rails5_postgres_redis.gemfile
132
+ - gemfiles/rails5_postgres_sidekiq.gemfile
130
133
  - lib/ddtrace.rb
131
134
  - lib/ddtrace/buffer.rb
132
135
  - lib/ddtrace/contrib/elasticsearch/core.rb
@@ -143,6 +146,7 @@ files:
143
146
  - lib/ddtrace/contrib/redis/patcher.rb
144
147
  - lib/ddtrace/contrib/redis/quantize.rb
145
148
  - lib/ddtrace/contrib/redis/tags.rb
149
+ - lib/ddtrace/contrib/sidekiq/tracer.rb
146
150
  - lib/ddtrace/contrib/sinatra/tracer.rb
147
151
  - lib/ddtrace/encoding.rb
148
152
  - lib/ddtrace/ext/app_types.rb
@@ -154,6 +158,7 @@ files:
154
158
  - lib/ddtrace/ext/sql.rb
155
159
  - lib/ddtrace/monkey.rb
156
160
  - lib/ddtrace/pin.rb
161
+ - lib/ddtrace/sampler.rb
157
162
  - lib/ddtrace/span.rb
158
163
  - lib/ddtrace/tracer.rb
159
164
  - lib/ddtrace/transport.rb
@@ -182,7 +187,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
182
187
  version: '0'
183
188
  requirements: []
184
189
  rubyforge_project:
185
- rubygems_version: 2.6.9
190
+ rubygems_version: 2.5.1
186
191
  signing_key:
187
192
  specification_version: 4
188
193
  summary: Datadog tracing code for your Ruby applications