ddtrace 0.4.3 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
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