ddtrace 0.18.3 → 0.19.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: 690c74d7e00a2fabf4ad03e30b0b40656c8337e9
4
- data.tar.gz: dc9f24349943d09fd472b0e5cb9c3b1cff1685ca
3
+ metadata.gz: f812f568118b7998a52208ffdb4c90a253edfd67
4
+ data.tar.gz: 914ce035245993d7535152437c720c8c3cca3c2e
5
5
  SHA512:
6
- metadata.gz: e996f0517f9be72b1b81d36eeedf099f997e66b0d00da4ad4cd93e169a93b6dbcb7e5a8b7df466b11b6487a82236ecfb9c997c908b1337a336c34e07ac78a7be
7
- data.tar.gz: 6973e5ff265f3660a19836dd7b02fba398583429c5364e4140cf3231341b855c06596ef33a2a92376f70ead4545326f591a1275ff342f0aba043c1f9ef9dbe46
6
+ metadata.gz: '08f6d5fe32d68feb4c38ef89ef43908c76884d1b92b30929fc3edd7c50fad58674d21f7e00ff97e4731b008213e9e0584106691d52ed8b1feb16b0dbdac877a0'
7
+ data.tar.gz: 8b452ada6e2cfb91d1ee170600dc3fc7cd17c0b37042c6a3a746cc5739da038b37457204194f8ecdbc802a85d5afcdb4e79d13bf31293c2226aa0d62dcd0fa66
data/CHANGELOG.md CHANGED
@@ -4,6 +4,21 @@
4
4
 
5
5
  ## [Unreleased (beta)]
6
6
 
7
+ ## [0.19.0] - 2019-01-22
8
+
9
+ Release notes: https://github.com/DataDog/dd-trace-rb/releases/tag/v0.19.0
10
+
11
+ Git diff: https://github.com/DataDog/dd-trace-rb/compare/v0.18.3...v0.19.0
12
+
13
+ ### Added
14
+
15
+ - Tracer#active_correlation for adding correlation IDs to logs. (#660, #664, #673)
16
+ - Opt-in support for `event_sample_rate` tag for some integrations. (#665, #666)
17
+
18
+ ### Changed
19
+
20
+ - Priority sampling enabled by default. (#654)
21
+
7
22
  ## [0.18.3] - 2019-01-17
8
23
 
9
24
  Release notes: https://github.com/DataDog/dd-trace-rb/releases/tag/v0.18.3
@@ -627,8 +642,9 @@ Release notes: https://github.com/DataDog/dd-trace-rb/releases/tag/v0.3.1
627
642
 
628
643
  Git diff: https://github.com/DataDog/dd-trace-rb/compare/v0.3.0...v0.3.1
629
644
 
630
- [Unreleased (stable)]: https://github.com/DataDog/dd-trace-rb/compare/v0.18.3...master
631
- [Unreleased (beta)]: https://github.com/DataDog/dd-trace-rb/compare/v0.18.3...0.19-dev
645
+ [Unreleased (stable)]: https://github.com/DataDog/dd-trace-rb/compare/v0.19.0...master
646
+ [Unreleased (beta)]: https://github.com/DataDog/dd-trace-rb/compare/v0.19.0...0.20-dev
647
+ [0.19.0]: https://github.com/DataDog/dd-trace-rb/compare/v0.18.3...v0.19.0
632
648
  [0.18.3]: https://github.com/DataDog/dd-trace-rb/compare/v0.18.2...v0.18.3
633
649
  [0.18.2]: https://github.com/DataDog/dd-trace-rb/compare/v0.18.1...v0.18.2
634
650
  [0.18.1]: https://github.com/DataDog/dd-trace-rb/compare/v0.18.0...v0.18.1
data/Rakefile CHANGED
@@ -46,7 +46,7 @@ namespace :spec do
46
46
  end
47
47
 
48
48
  RSpec::Core::RakeTask.new(:contrib) do |t|
49
- t.pattern = 'spec/**/contrib/{configurable,integration,patchable,patcher,registerable,configuration/*}_spec.rb'
49
+ t.pattern = 'spec/**/contrib/{configurable,integration,patchable,patcher,registerable,sampling,configuration/*}_spec.rb'
50
50
  end
51
51
 
52
52
  [
@@ -62,6 +62,7 @@ For descriptions of terminology used in APM, take a look at the [official docume
62
62
  - [Processing pipeline](#processing-pipeline)
63
63
  - [Filtering](#filtering)
64
64
  - [Processing](#processing)
65
+ - [Trace correlation](#trace-correlation)
65
66
  - [OpenTracing](#opentracing)
66
67
 
67
68
  ## Compatibility
@@ -517,6 +518,7 @@ Where `options` is an optional `Hash` that accepts the following parameters:
517
518
 
518
519
  | Key | Description | Default |
519
520
  | --- | ----------- | ------- |
521
+ | `event_sample_rate` | Rate which spans should be sampled for search and analytics. | `nil` |
520
522
  | `service_name` | Service name used for `DelayedJob` instrumentation | `'delayed_job'` |
521
523
  | `tracer` | `Datadog::Tracer` used to perform instrumentation. Usually you don't need to set this. | `Datadog.tracer` |
522
524
 
@@ -865,6 +867,7 @@ Where `options` is an optional `Hash` that accepts the following parameters:
865
867
 
866
868
  | Key | Description | Default |
867
869
  | --- | ----------- | ------- |
870
+ | `event_sample_rate` | Rate which spans should be sampled for search and analytics. | `nil` |
868
871
  | `service_name` | Service name used for `racecar` instrumentation | `'racecar'` |
869
872
  | `tracer` | `Datadog::Tracer` used to perform instrumentation. Usually you don't need to set this. | `Datadog.tracer` |
870
873
 
@@ -897,6 +900,7 @@ Where `options` is an optional `Hash` that accepts the following parameters:
897
900
  | --- | ----------- | ------- |
898
901
  | `application` | Your Rack application. Required for `middleware_names`. | `nil` |
899
902
  | `distributed_tracing` | Enables [distributed tracing](#distributed-tracing) so that this service trace is connected with a trace of another service if tracing headers are received | `false` |
903
+ | `event_sample_rate` | Rate which spans should be sampled for search and analytics. | `nil` |
900
904
  | `headers` | Hash of HTTP request or response headers to add as tags to the `rack.request`. Accepts `request` and `response` keys with Array values e.g. `['Last-Modified']`. Adds `http.request.headers.*` and `http.response.headers.*` tags respectively. | `{ response: ['Content-Type', 'X-Request-ID'] }` |
901
905
  | `middleware_names` | Enable this if you want to use the middleware classes as the resource names for `rack` spans. Requires `application` option to use. | `false` |
902
906
  | `quantize` | Hash containing options for quantization. May include `:query` or `:fragment`. | `{}` |
@@ -1006,6 +1010,7 @@ Where `options` is an optional `Hash` that accepts the following parameters:
1006
1010
  | Key | Description | Default |
1007
1011
  | --- | ----------- | ------- |
1008
1012
  | `enabled` | Defines whether Rake tasks should be traced. Useful for temporarily disabling tracing. `true` or `false` | `true` |
1013
+ | `event_sample_rate` | Rate which spans should be sampled for search and analytics. | `nil` |
1009
1014
  | `quantize` | Hash containing options for quantization of task arguments. See below for more details and examples. | `{}` |
1010
1015
  | `service_name` | Service name used for `rake` instrumentation | `'rake'` |
1011
1016
  | `tracer` | `Datadog::Tracer` used to perform instrumentation. Usually you don't need to set this. | `Datadog.tracer` |
@@ -1107,6 +1112,7 @@ Where `options` is an optional `Hash` that accepts the following parameters:
1107
1112
 
1108
1113
  | Key | Description | Default |
1109
1114
  | --- | ----------- | ------- |
1115
+ | `event_sample_rate` | Rate which spans should be sampled for search and analytics. | `nil` |
1110
1116
  | `service_name` | Service name used for `resque` instrumentation | `'resque'` |
1111
1117
  | `tracer` | `Datadog::Tracer` used to perform instrumentation. Usually you don't need to set this. | `Datadog.tracer` |
1112
1118
  | `workers` | An array including all worker classes you want to trace (eg `[MyJob]`) | `[]` |
@@ -1198,6 +1204,7 @@ Where `options` is an optional `Hash` that accepts the following parameters:
1198
1204
 
1199
1205
  | Key | Description | Default |
1200
1206
  | --- | ----------- | ------- |
1207
+ | `event_sample_rate` | Rate which spans should be sampled for search and analytics. | `nil` |
1201
1208
  | `service_name` | Service name used for `shoryuken` instrumentation | `'shoryuken'` |
1202
1209
  | `tracer` | `Datadog::Tracer` used to perform instrumentation. Usually you don't need to set this. | `Datadog.tracer` |
1203
1210
 
@@ -1220,6 +1227,7 @@ Where `options` is an optional `Hash` that accepts the following parameters:
1220
1227
  | Key | Description | Default |
1221
1228
  | --- | ----------- | ------- |
1222
1229
  | `client_service_name` | Service name used for client-side `sidekiq` instrumentation | `'sidekiq-client'` |
1230
+ | `event_sample_rate` | Rate which spans should be sampled for search and analytics. | `nil` |
1223
1231
  | `service_name` | Service name used for server-side `sidekiq` instrumentation | `'sidekiq'` |
1224
1232
  | `tracer` | `Datadog::Tracer` used to perform instrumentation. Usually you don't need to set this. | `Datadog.tracer` |
1225
1233
 
@@ -1271,6 +1279,7 @@ Where `options` is an optional `Hash` that accepts the following parameters:
1271
1279
 
1272
1280
  | Key | Description | Default |
1273
1281
  | --- | ----------- | ------- |
1282
+ | `event_sample_rate` | Rate which spans should be sampled for search and analytics. | `nil` |
1274
1283
  | `service_name` | Service name used for `sucker_punch` instrumentation | `'sucker_punch'` |
1275
1284
  | `tracer` | `Datadog::Tracer` used to perform instrumentation. Usually you don't need to set this. | `Datadog.tracer` |
1276
1285
 
@@ -1356,15 +1365,7 @@ The sampler can set the priority to the following values:
1356
1365
  - `Datadog::Ext::Priority::AUTO_REJECT`: the sampler automatically decided to reject the trace.
1357
1366
  - `Datadog::Ext::Priority::AUTO_KEEP`: the sampler automatically decided to keep the trace.
1358
1367
 
1359
- For now, priority sampling is disabled by default. Enabling it ensures that your sampled distributed traces will be complete. To enable the priority sampling:
1360
-
1361
- ```ruby
1362
- Datadog.configure do |c|
1363
- c.tracer priority_sampling: true
1364
- end
1365
- ```
1366
-
1367
- Once enabled, the sampler will automatically assign a priority of 0 or 1 to traces, depending on their service and volume.
1368
+ Priority sampling is enabled by default. Enabling it ensures that your sampled distributed traces will be complete. Once enabled, the sampler will automatically assign a priority of 0 or 1 to traces, depending on their service and volume.
1368
1369
 
1369
1370
  You can also set this priority manually to either drop a non-interesting trace or to keep an important one. For that, set the `context#sampling_priority` to:
1370
1371
 
@@ -1613,6 +1614,77 @@ Datadog::Pipeline.before_flush(
1613
1614
  )
1614
1615
  ```
1615
1616
 
1617
+ ### Trace correlation
1618
+
1619
+ In many cases, such as logging, it may be useful to correlate trace IDs to other events or data streams, for easier cross referencing. The tracer can produce a correlation identifier for the currently active trace via `active_correlation`, which can be used to decorate these other data sources.
1620
+
1621
+ ```ruby
1622
+ # When a trace is active...
1623
+ Datadog.tracer.trace('correlation.example') do
1624
+ # Returns #<Datadog::Correlation::Identifier>
1625
+ correlation = Datadog.tracer.active_correlation
1626
+ correlation.trace_id # => 5963550561812073440
1627
+ correlation.span_id # => 2232727802607726424
1628
+ end
1629
+
1630
+ # When a trace isn't active...
1631
+ correlation = Datadog.tracer.active_correlation
1632
+ # Returns #<Datadog::Correlation::Identifier>
1633
+ correlation = Datadog.tracer.active_correlation
1634
+ correlation.trace_id # => 0
1635
+ correlation.span_id # => 0
1636
+ ```
1637
+
1638
+ #### For logging in Ruby applications
1639
+
1640
+ To add correlation IDs to your logger, add a log formatter which retrieves the correlation IDs with `Datadog.tracer.active_correlation`, then add them to the message.
1641
+
1642
+ To properly correlate with Datadog logging, be sure the following is present:
1643
+
1644
+ - `dd.trace_id=<TRACE_ID>`: Where `<TRACE_ID>` is equal to `Datadog.tracer.active_correlation.trace_id` or `0` if no trace is active.
1645
+ - `dd.span_id=<SPAN_ID>`: Where `<SPAN_ID>` is equal to `Datadog.tracer.active_correlation.span_id` or `0` if no trace is active.
1646
+
1647
+ By default, `Datadog::Correlation::Identifier#to_s` will return `dd.trace_id=<TRACE_ID> dd.span_id=<SPAN_ID>`.
1648
+
1649
+ An example of this in practice:
1650
+
1651
+ ```ruby
1652
+ require 'ddtrace'
1653
+ require 'logger'
1654
+
1655
+ logger = Logger.new(STDOUT)
1656
+ logger.progname = 'my_app'
1657
+ logger.formatter = proc do |severity, datetime, progname, msg|
1658
+ "[#{datetime}][#{progname}][#{severity}][#{Datadog.tracer.active_correlation}] #{msg}\n"
1659
+ end
1660
+
1661
+ # When no trace is active
1662
+ logger.warn('This is an untraced operation.')
1663
+ # [2019-01-16 18:38:41 +0000][my_app][WARN][dd.trace_id=0 dd.span_id=0] This is an untraced operation.
1664
+
1665
+ # When a trace is active
1666
+ Datadog.tracer.trace('my.operation') { logger.warn('This is a traced operation.') }
1667
+ # [2019-01-16 18:38:41 +0000][my_app][WARN][dd.trace_id=8545847825299552251 dd.span_id=3711755234730770098] This is a traced operation.
1668
+ ```
1669
+
1670
+ #### For logging in Rails applications
1671
+
1672
+ Rails applications which are configured with a `ActiveSupport::TaggedLogging` logger can append correlation IDs as tags to log output. The default Rails logger implements this tagged logging, making it easier to add correlation tags.
1673
+
1674
+ In your Rails environment configuration file, add the following:
1675
+
1676
+ ```ruby
1677
+ Rails.application.configure do
1678
+ config.log_tags = [proc { Datadog.tracer.active_correlation.to_s }]
1679
+ end
1680
+
1681
+ # Web requests will produce:
1682
+ # [dd.trace_id=7110975754844687674 dd.span_id=7518426836986654206] Started GET "/articles" for 172.22.0.1 at 2019-01-16 18:50:57 +0000
1683
+ # [dd.trace_id=7110975754844687674 dd.span_id=7518426836986654206] Processing by ArticlesController#index as */*
1684
+ # [dd.trace_id=7110975754844687674 dd.span_id=7518426836986654206] Article Load (0.5ms) SELECT "articles".* FROM "articles"
1685
+ # [dd.trace_id=7110975754844687674 dd.span_id=7518426836986654206] Completed 200 OK in 7ms (Views: 5.5ms | ActiveRecord: 0.5ms)
1686
+ ```
1687
+
1616
1688
  ### OpenTracing
1617
1689
 
1618
1690
  For setting up Datadog with OpenTracing, see out [Quickstart for OpenTracing](#quickstart-for-opentracing) section for details.
@@ -9,6 +9,7 @@ module Datadog
9
9
 
10
10
  option :service_name
11
11
  option :tracer, default: Datadog.tracer
12
+ option :event_sample_rate
12
13
 
13
14
  def initialize(options = {})
14
15
  configure(options)
@@ -1,4 +1,5 @@
1
1
  require 'delayed/plugin'
2
+ require 'ddtrace/contrib/sampling'
2
3
  require 'ddtrace/contrib/delayed_job/ext'
3
4
 
4
5
  module Datadog
@@ -18,6 +19,7 @@ module Datadog
18
19
  end
19
20
 
20
21
  tracer.trace(Ext::SPAN_JOB, service: configuration[:service_name], resource: job_name) do |span|
22
+ Contrib::Sampling.set_event_sample_rate(span, configuration[:event_sample_rate])
21
23
  span.set_tag(Ext::TAG_ID, job.id)
22
24
  span.set_tag(Ext::TAG_QUEUE, job.queue) if job.queue
23
25
  span.set_tag(Ext::TAG_PRIORITY, job.priority)
@@ -1,3 +1,4 @@
1
+ require 'ddtrace/contrib/sampling'
1
2
  require 'ddtrace/contrib/active_support/notifications/event'
2
3
  require 'ddtrace/contrib/racecar/ext'
3
4
 
@@ -36,6 +37,7 @@ module Datadog
36
37
  span.service = configuration[:service_name]
37
38
  span.resource = payload[:consumer_class]
38
39
 
40
+ Contrib::Sampling.set_event_sample_rate(span, configuration[:event_sample_rate])
39
41
  span.set_tag(Ext::TAG_TOPIC, payload[:topic])
40
42
  span.set_tag(Ext::TAG_CONSUMER, payload[:consumer_class])
41
43
  span.set_tag(Ext::TAG_PARTITION, payload[:partition])
@@ -1,6 +1,7 @@
1
1
  require 'ddtrace/ext/app_types'
2
2
  require 'ddtrace/ext/http'
3
3
  require 'ddtrace/propagation/http_propagator'
4
+ require 'ddtrace/contrib/sampling'
4
5
  require 'ddtrace/contrib/rack/ext'
5
6
  require 'ddtrace/contrib/rack/request_queue'
6
7
 
@@ -25,7 +26,7 @@ module Datadog
25
26
  end
26
27
 
27
28
  def compute_queue_time(env, tracer)
28
- return unless Datadog.configuration[:rack][:request_queuing]
29
+ return unless configuration[:request_queuing]
29
30
 
30
31
  # parse the request queue time
31
32
  request_start = Datadog::Contrib::Rack::QueueTime.get_request_start(env)
@@ -34,25 +35,25 @@ module Datadog
34
35
  tracer.trace(
35
36
  Ext::SPAN_HTTP_SERVER_QUEUE,
36
37
  start_time: request_start,
37
- service: Datadog.configuration[:rack][:web_service_name]
38
+ service: configuration[:web_service_name]
38
39
  )
39
40
  end
40
41
 
41
42
  def call(env)
42
43
  # retrieve integration settings
43
- tracer = Datadog.configuration[:rack][:tracer]
44
+ tracer = configuration[:tracer]
44
45
 
45
46
  # [experimental] create a root Span to keep track of frontend web servers
46
47
  # (i.e. Apache, nginx) if the header is properly set
47
48
  frontend_span = compute_queue_time(env, tracer)
48
49
 
49
50
  trace_options = {
50
- service: Datadog.configuration[:rack][:service_name],
51
+ service: configuration[:service_name],
51
52
  resource: nil,
52
53
  span_type: Datadog::Ext::HTTP::TYPE
53
54
  }
54
55
 
55
- if Datadog.configuration[:rack][:distributed_tracing]
56
+ if configuration[:distributed_tracing]
56
57
  context = HTTPPropagator.extract(env)
57
58
  tracer.provider.context = context if context.trace_id
58
59
  end
@@ -114,7 +115,7 @@ module Datadog
114
115
  end
115
116
 
116
117
  def resource_name_for(env, status)
117
- if Datadog.configuration[:rack][:middleware_names] && env['RESPONSE_MIDDLEWARE']
118
+ if configuration[:middleware_names] && env['RESPONSE_MIDDLEWARE']
118
119
  "#{env['RESPONSE_MIDDLEWARE']}##{env['REQUEST_METHOD']}"
119
120
  else
120
121
  "#{env['REQUEST_METHOD']} #{status}".strip
@@ -138,13 +139,19 @@ module Datadog
138
139
  response_headers = parse_response_headers(headers || {})
139
140
 
140
141
  request_span.resource ||= resource_name_for(env, status)
142
+
143
+ # Set event sample rate, if available.
144
+ Contrib::Sampling.set_event_sample_rate(request_span, configuration[:event_sample_rate])
145
+
141
146
  if request_span.get_tag(Datadog::Ext::HTTP::METHOD).nil?
142
147
  request_span.set_tag(Datadog::Ext::HTTP::METHOD, env['REQUEST_METHOD'])
143
148
  end
149
+
144
150
  if request_span.get_tag(Datadog::Ext::HTTP::URL).nil?
145
- options = Datadog.configuration[:rack][:quantize]
151
+ options = configuration[:quantize]
146
152
  request_span.set_tag(Datadog::Ext::HTTP::URL, Datadog::Quantization::HTTP.url(url, options))
147
153
  end
154
+
148
155
  if request_span.get_tag(Datadog::Ext::HTTP::BASE_URL).nil?
149
156
  request_obj = ::Rack::Request.new(env)
150
157
 
@@ -157,6 +164,7 @@ module Datadog
157
164
 
158
165
  request_span.set_tag(Datadog::Ext::HTTP::BASE_URL, base_url)
159
166
  end
167
+
160
168
  if request_span.get_tag(Datadog::Ext::HTTP::STATUS_CODE).nil? && status
161
169
  request_span.set_tag(Datadog::Ext::HTTP::STATUS_CODE, status)
162
170
  end
@@ -186,6 +194,10 @@ module Datadog
186
194
  If you need the Rack request span, try using `Datadog.tracer.active_span`.
187
195
  This key will be removed in version 1.0).freeze
188
196
 
197
+ def configuration
198
+ Datadog.configuration[:rack]
199
+ end
200
+
189
201
  def add_deprecation_warnings(env)
190
202
  env.instance_eval do
191
203
  unless instance_variable_defined?(:@patched_with_datadog_warnings)
@@ -225,7 +237,7 @@ module Datadog
225
237
 
226
238
  def parse_request_headers(env)
227
239
  {}.tap do |result|
228
- whitelist = Datadog.configuration[:rack][:headers][:request] || []
240
+ whitelist = configuration[:headers][:request] || []
229
241
  whitelist.each do |header|
230
242
  rack_header = header_to_rack_header(header)
231
243
  if env.key?(rack_header)
@@ -237,7 +249,7 @@ module Datadog
237
249
 
238
250
  def parse_response_headers(headers)
239
251
  {}.tap do |result|
240
- whitelist = Datadog.configuration[:rack][:headers][:response] || []
252
+ whitelist = configuration[:headers][:response] || []
241
253
  whitelist.each do |header|
242
254
  if headers.key?(header)
243
255
  result[Datadog::Ext::HTTP::ResponseHeaders.to_tag(header)] = headers[header]
@@ -1,3 +1,4 @@
1
+ require 'ddtrace/contrib/sampling'
1
2
  require 'ddtrace/contrib/rake/ext'
2
3
 
3
4
  module Datadog
@@ -41,6 +42,7 @@ module Datadog
41
42
 
42
43
  def annotate_invoke!(span, args)
43
44
  span.resource = name
45
+ Contrib::Sampling.set_event_sample_rate(span, configuration[:event_sample_rate])
44
46
  span.set_tag(Ext::TAG_TASK_ARG_NAMES, arg_names)
45
47
  span.set_tag(Ext::TAG_INVOKE_ARGS, quantize_args(args)) unless args.nil?
46
48
  rescue StandardError => e
@@ -19,7 +19,6 @@ module Datadog
19
19
  do_once(:resque) do
20
20
  begin
21
21
  require_relative 'resque_job'
22
- add_pin
23
22
  get_option(:workers).each { |worker| worker.extend(ResqueJob) }
24
23
  rescue StandardError => e
25
24
  Datadog::Tracer.log.error("Unable to apply Resque integration: #{e}")
@@ -27,15 +26,6 @@ module Datadog
27
26
  end
28
27
  end
29
28
 
30
- def add_pin
31
- Pin.new(
32
- get_option(:service_name),
33
- app: Ext::APP,
34
- app_type: Datadog::Ext::AppTypes::WORKER,
35
- tracer: get_option(:tracer)
36
- ).onto(::Resque)
37
- end
38
-
39
29
  def get_option(option)
40
30
  Datadog.configuration[:resque].get_option(option)
41
31
  end
@@ -1,5 +1,6 @@
1
1
  require 'ddtrace/ext/app_types'
2
2
  require 'ddtrace/sync_writer'
3
+ require 'ddtrace/contrib/sampling'
3
4
  require 'ddtrace/contrib/sidekiq/ext'
4
5
  require 'resque'
5
6
 
@@ -9,13 +10,13 @@ module Datadog
9
10
  # Uses Resque job hooks to create traces
10
11
  module ResqueJob
11
12
  def around_perform(*_)
12
- pin = Pin.get_from(::Resque)
13
- return yield unless pin && pin.tracer
14
- pin.tracer.trace(Ext::SPAN_JOB, service: pin.service) do |span|
13
+ return yield unless datadog_configuration && tracer
14
+
15
+ tracer.trace(Ext::SPAN_JOB, span_options) do |span|
15
16
  span.resource = name
16
- span.span_type = pin.app_type
17
+ span.span_type = Datadog::Ext::AppTypes::WORKER
18
+ Contrib::Sampling.set_event_sample_rate(span, datadog_configuration[:event_sample_rate])
17
19
  yield
18
- span.service = pin.service
19
20
  end
20
21
  end
21
22
 
@@ -28,8 +29,27 @@ module Datadog
28
29
  end
29
30
 
30
31
  def shutdown_tracer_when_forked!
31
- pin = Datadog::Pin.get_from(Resque)
32
- pin.tracer.shutdown! if pin && pin.tracer && pin.config && pin.config[:forked]
32
+ tracer.shutdown! if forked?
33
+ end
34
+
35
+ private
36
+
37
+ def forked?
38
+ pin = Datadog::Pin.get_from(::Resque)
39
+ return false unless pin
40
+ pin.config[:forked] == true
41
+ end
42
+
43
+ def span_options
44
+ { service: datadog_configuration[:service_name] }
45
+ end
46
+
47
+ def tracer
48
+ datadog_configuration.tracer
49
+ end
50
+
51
+ def datadog_configuration
52
+ Datadog.configuration[:resque]
33
53
  end
34
54
  end
35
55
  end
@@ -37,12 +57,17 @@ module Datadog
37
57
  end
38
58
 
39
59
  Resque.after_fork do
40
- # get the current tracer
41
- pin = Datadog::Pin.get_from(Resque)
42
- next unless pin && pin.tracer
43
- pin.config ||= {}
44
- pin.config[:forked] = true
45
-
46
- # clean the state so no CoW happens
47
- pin.tracer.provider.context = nil
60
+ configuration = Datadog.configuration[:resque]
61
+ next if configuration.nil?
62
+
63
+ # Add a pin, marking the job as forked.
64
+ # Used to trigger shutdown in forks for performance reasons.
65
+ Datadog::Pin.new(
66
+ configuration[:service_name],
67
+ config: { forked: true }
68
+ ).onto(::Resque)
69
+
70
+ # Clean the state so no CoW happens
71
+ next if configuration[:tracer].nil?
72
+ configuration[:tracer].provider.context = nil
48
73
  end
@@ -0,0 +1,14 @@
1
+ require 'ddtrace/ext/priority'
2
+
3
+ module Datadog
4
+ module Contrib
5
+ # Defines sampling behavior for integrations
6
+ module Sampling
7
+ module_function
8
+
9
+ def set_event_sample_rate(span, sample_rate)
10
+ span.set_metric(Datadog::Ext::Priority::TAG_EVENT_SAMPLE_RATE, sample_rate) unless sample_rate.nil?
11
+ end
12
+ end
13
+ end
14
+ end
@@ -1,16 +1,19 @@
1
+ require 'ddtrace/contrib/sampling'
2
+
1
3
  module Datadog
2
4
  module Contrib
3
5
  module Shoryuken
4
6
  # Tracer is a Shoryuken server-side middleware which traces executed jobs
5
7
  class Tracer
6
8
  def initialize(options = {})
7
- @tracer = options[:tracer] || Datadog.configuration[:shoryuken][:tracer]
8
- @shoryuken_service = options[:service_name] || Datadog.configuration[:shoryuken][:service_name]
9
+ @tracer = options[:tracer] || configuration[:tracer]
10
+ @shoryuken_service = options[:service_name] || configuration[:service_name]
9
11
  set_service_info(@shoryuken_service)
10
12
  end
11
13
 
12
14
  def call(worker_instance, queue, sqs_msg, body)
13
15
  @tracer.trace(Ext::SPAN_JOB, service: @shoryuken_service, span_type: Datadog::Ext::AppTypes::WORKER) do |span|
16
+ Contrib::Sampling.set_event_sample_rate(span, configuration[:event_sample_rate])
14
17
  span.resource = resource(worker_instance, body)
15
18
  span.set_tag(Ext::TAG_JOB_ID, sqs_msg.message_id)
16
19
  span.set_tag(Ext::TAG_JOB_QUEUE, queue)
@@ -31,8 +34,12 @@ module Datadog
31
34
  job_class || worker_instance.class.name
32
35
  end
33
36
 
37
+ def configuration
38
+ Datadog.configuration[:shoryuken]
39
+ end
40
+
34
41
  def set_service_info(service)
35
- return if @tracer.services[service]
42
+ return if @tracer.nil? || @tracer.services[service]
36
43
  @tracer.set_service_info(
37
44
  service,
38
45
  Ext::APP,
@@ -1,4 +1,5 @@
1
1
  require 'ddtrace/contrib/sidekiq/tracing'
2
+ require 'ddtrace/contrib/sampling'
2
3
 
3
4
  module Datadog
4
5
  module Contrib
@@ -9,19 +10,18 @@ module Datadog
9
10
 
10
11
  def initialize(options = {})
11
12
  super
12
- @sidekiq_service = options[:client_service_name] || Datadog.configuration[:sidekiq][:client_service_name]
13
+ @sidekiq_service = options[:client_service_name] || configuration[:client_service_name]
14
+ set_service_info(@sidekiq_service)
13
15
  end
14
16
 
15
17
  # Client middleware arguments are documented here:
16
18
  # https://github.com/mperham/sidekiq/wiki/Middleware#client-middleware
17
19
  def call(worker_class, job, queue, redis_pool)
18
- service = @sidekiq_service
19
- set_service_info(service)
20
-
21
20
  resource = job_resource(job)
22
21
 
23
- @tracer.trace(Ext::SPAN_PUSH, service: service) do |span|
22
+ @tracer.trace(Ext::SPAN_PUSH, service: @sidekiq_service) do |span|
24
23
  span.resource = resource
24
+ Contrib::Sampling.set_event_sample_rate(span, configuration[:event_sample_rate])
25
25
  span.set_tag(Ext::TAG_JOB_ID, job['jid'])
26
26
  span.set_tag(Ext::TAG_JOB_QUEUE, job['queue'])
27
27
  span.set_tag(Ext::TAG_JOB_WRAPPER, job['class']) if job['wrapped']
@@ -29,6 +29,12 @@ module Datadog
29
29
  yield
30
30
  end
31
31
  end
32
+
33
+ private
34
+
35
+ def configuration
36
+ Datadog.configuration[:sidekiq]
37
+ end
32
38
  end
33
39
  end
34
40
  end
@@ -1,4 +1,5 @@
1
1
  require 'ddtrace/contrib/sidekiq/tracing'
2
+ require 'ddtrace/contrib/sampling'
2
3
 
3
4
  module Datadog
4
5
  module Contrib
@@ -9,7 +10,7 @@ module Datadog
9
10
 
10
11
  def initialize(options = {})
11
12
  super
12
- @sidekiq_service = options[:service_name] || Datadog.configuration[:sidekiq][:service_name]
13
+ @sidekiq_service = options[:service_name] || configuration[:service_name]
13
14
  end
14
15
 
15
16
  def call(worker, job, queue)
@@ -20,6 +21,7 @@ module Datadog
20
21
 
21
22
  @tracer.trace(Ext::SPAN_JOB, service: service, span_type: Datadog::Ext::AppTypes::WORKER) do |span|
22
23
  span.resource = resource
24
+ Contrib::Sampling.set_event_sample_rate(span, configuration[:event_sample_rate])
23
25
  span.set_tag(Ext::TAG_JOB_ID, job['jid'])
24
26
  span.set_tag(Ext::TAG_JOB_RETRY, job['retry'])
25
27
  span.set_tag(Ext::TAG_JOB_QUEUE, job['queue'])
@@ -32,6 +34,10 @@ module Datadog
32
34
 
33
35
  private
34
36
 
37
+ def configuration
38
+ Datadog.configuration[:sidekiq]
39
+ end
40
+
35
41
  def service_from_worker_config(resource)
36
42
  # Try to get the Ruby class from the resource name.
37
43
  worker_klass = begin
@@ -1,4 +1,5 @@
1
1
  require 'sucker_punch'
2
+ require 'ddtrace/contrib/sampling'
2
3
  require 'ddtrace/contrib/sucker_punch/ext'
3
4
 
4
5
  module Datadog
@@ -18,6 +19,7 @@ module Datadog
18
19
 
19
20
  __with_instrumentation(Ext::SPAN_PERFORM) do |span|
20
21
  span.resource = "PROCESS #{self}"
22
+ Contrib::Sampling.set_event_sample_rate(span, datadog_configuration[:event_sample_rate])
21
23
  __run_perform_without_datadog(*args)
22
24
  end
23
25
  rescue => e
@@ -43,6 +45,10 @@ module Datadog
43
45
 
44
46
  private
45
47
 
48
+ def datadog_configuration
49
+ Datadog.configuration[:sucker_punch]
50
+ end
51
+
46
52
  def __with_instrumentation(name)
47
53
  pin = Datadog::Pin.get_from(::SuckerPunch)
48
54
 
@@ -0,0 +1,32 @@
1
+ module Datadog
2
+ # Contains behavior for managing correlations with tracing
3
+ # e.g. Retrieve a correlation to the current trace for logging, etc.
4
+ module Correlation
5
+ # Struct representing correlation
6
+ Identifier = Struct.new(:trace_id, :span_id).tap do |struct|
7
+ # Do this #class_eval here for Ruby 1.9.3 support.
8
+ # Ruby 2.0+ supports passing a block to Struct::new instead.
9
+ struct.class_eval do
10
+ def initialize(*args)
11
+ super
12
+ self.trace_id = trace_id || 0
13
+ self.span_id = span_id || 0
14
+ end
15
+
16
+ def to_s
17
+ "dd.trace_id=#{trace_id} dd.span_id=#{span_id}"
18
+ end
19
+ end
20
+ end.freeze
21
+
22
+ NULL_IDENTIFIER = Identifier.new.freeze
23
+
24
+ module_function
25
+
26
+ # Produces a CorrelationIdentifier from the Context provided
27
+ def identifier_from_context(context)
28
+ return NULL_IDENTIFIER if context.nil?
29
+ Identifier.new(context.trace_id, context.span_id).freeze
30
+ end
31
+ end
32
+ end
@@ -3,6 +3,8 @@ module Datadog
3
3
  # Priority is a hint given to the backend so that it knows which traces to reject or kept.
4
4
  # In a distributed context, it should be set before any context propagation (fork, RPC calls) to be effective.
5
5
  module Priority
6
+ # Tag for span sample rate; used by agent to determine whether event is emitted.
7
+ TAG_EVENT_SAMPLE_RATE = '_dd1.sr.eausr'.freeze
6
8
  # Use this to explicitely inform the backend that a trace should be rejected and not stored.
7
9
  USER_REJECT = -1
8
10
  # Used by the builtin sampler to inform the backend that a trace should be rejected and not stored.
@@ -10,6 +10,7 @@ require 'ddtrace/provider'
10
10
  require 'ddtrace/logger'
11
11
  require 'ddtrace/writer'
12
12
  require 'ddtrace/sampler'
13
+ require 'ddtrace/correlation'
13
14
 
14
15
  # \Datadog global namespace that includes all tracing functionality for Tracer and Span classes.
15
16
  module Datadog
@@ -126,7 +127,7 @@ module Datadog
126
127
 
127
128
  # Those are rare "power-user" options.
128
129
  sampler = options.fetch(:sampler, nil)
129
- priority_sampling = options[:priority_sampling]
130
+ priority_sampling = options.fetch(:priority_sampling, nil)
130
131
  max_spans_before_partial_flush = options.fetch(:max_spans_before_partial_flush, nil)
131
132
  min_spans_before_partial_flush = options.fetch(:min_spans_before_partial_flush, nil)
132
133
  partial_flush_timeout = options.fetch(:partial_flush_timeout, nil)
@@ -134,9 +135,15 @@ module Datadog
134
135
  @enabled = enabled unless enabled.nil?
135
136
  @sampler = sampler unless sampler.nil?
136
137
 
137
- if priority_sampling
138
+ # Re-build the sampler and writer if priority sampling is enabled,
139
+ # but neither are configured. Verify the sampler isn't already a
140
+ # priority sampler too, so we don't wrap one with another.
141
+ if priority_sampling != false && !@sampler.is_a?(PrioritySampler)
138
142
  @sampler = PrioritySampler.new(base_sampler: @sampler)
139
143
  @writer = Writer.new(priority_sampler: @sampler)
144
+ elsif priority_sampling == false
145
+ @sampler = sampler || Datadog::AllSampler.new if @sampler.is_a?(PrioritySampler)
146
+ @writer = Writer.new
140
147
  end
141
148
 
142
149
  @writer.transport.hostname = hostname unless hostname.nil?
@@ -351,6 +358,11 @@ module Datadog
351
358
  call_context.current_root_span
352
359
  end
353
360
 
361
+ # Return a CorrelationIdentifier for active span
362
+ def active_correlation
363
+ Datadog::Correlation.identifier_from_context(call_context)
364
+ end
365
+
354
366
  # Send the trace to the writer to enqueue the spans list in the agent
355
367
  # sending queue.
356
368
  def write(trace)
@@ -1,8 +1,8 @@
1
1
  module Datadog
2
2
  module VERSION
3
3
  MAJOR = 0
4
- MINOR = 18
5
- PATCH = 3
4
+ MINOR = 19
5
+ PATCH = 0
6
6
  PRE = nil
7
7
 
8
8
  STRING = [MAJOR, MINOR, PATCH, PRE].compact.join('.')
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.18.3
4
+ version: 0.19.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: 2019-01-17 00:00:00.000000000 Z
11
+ date: 2019-01-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: msgpack
@@ -449,6 +449,7 @@ files:
449
449
  - lib/ddtrace/contrib/rest_client/integration.rb
450
450
  - lib/ddtrace/contrib/rest_client/patcher.rb
451
451
  - lib/ddtrace/contrib/rest_client/request_patch.rb
452
+ - lib/ddtrace/contrib/sampling.rb
452
453
  - lib/ddtrace/contrib/sequel/configuration/settings.rb
453
454
  - lib/ddtrace/contrib/sequel/database.rb
454
455
  - lib/ddtrace/contrib/sequel/dataset.rb
@@ -482,6 +483,7 @@ files:
482
483
  - lib/ddtrace/contrib/sucker_punch/instrumentation.rb
483
484
  - lib/ddtrace/contrib/sucker_punch/integration.rb
484
485
  - lib/ddtrace/contrib/sucker_punch/patcher.rb
486
+ - lib/ddtrace/correlation.rb
485
487
  - lib/ddtrace/encoding.rb
486
488
  - lib/ddtrace/error.rb
487
489
  - lib/ddtrace/ext/app_types.rb