ddtrace 0.12.0.beta2 → 0.12.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) hide show
  1. checksums.yaml +4 -4
  2. data/Appraisals +8 -8
  3. data/CHANGELOG.md +293 -0
  4. data/README.md +11 -114
  5. data/Rakefile +26 -18
  6. data/docs/GettingStarted.md +704 -453
  7. data/gemfiles/contrib.gemfile +2 -2
  8. data/gemfiles/rails4_mysql2.gemfile +1 -1
  9. data/gemfiles/rails5_mysql2.gemfile +2 -2
  10. data/gemfiles/rails5_postgres.gemfile +1 -1
  11. data/gemfiles/rails5_postgres_redis.gemfile +1 -1
  12. data/gemfiles/rails5_postgres_sidekiq.gemfile +1 -1
  13. data/lib/ddtrace.rb +1 -0
  14. data/lib/ddtrace/context.rb +96 -34
  15. data/lib/ddtrace/context_flush.rb +132 -0
  16. data/lib/ddtrace/contrib/active_record/patcher.rb +55 -70
  17. data/lib/ddtrace/contrib/active_record/utils.rb +83 -0
  18. data/lib/ddtrace/contrib/active_support/notifications/subscriber.rb +66 -0
  19. data/lib/ddtrace/contrib/active_support/notifications/subscription.rb +155 -0
  20. data/lib/ddtrace/contrib/elasticsearch/patcher.rb +6 -1
  21. data/lib/ddtrace/contrib/elasticsearch/quantize.rb +89 -0
  22. data/lib/ddtrace/contrib/grape/endpoint.rb +1 -1
  23. data/lib/ddtrace/contrib/racecar/patcher.rb +43 -19
  24. data/lib/ddtrace/contrib/rack/middlewares.rb +58 -11
  25. data/lib/ddtrace/contrib/rack/patcher.rb +18 -11
  26. data/lib/ddtrace/contrib/rails/action_controller.rb +9 -11
  27. data/lib/ddtrace/contrib/rails/action_view.rb +5 -1
  28. data/lib/ddtrace/contrib/rails/active_support.rb +6 -2
  29. data/lib/ddtrace/contrib/rails/core_extensions.rb +280 -215
  30. data/lib/ddtrace/contrib/rails/framework.rb +38 -23
  31. data/lib/ddtrace/contrib/rails/middlewares.rb +7 -2
  32. data/lib/ddtrace/contrib/rails/patcher.rb +9 -6
  33. data/lib/ddtrace/contrib/rails/railtie.rb +4 -2
  34. data/lib/ddtrace/contrib/rails/utils.rb +9 -40
  35. data/lib/ddtrace/patcher.rb +32 -10
  36. data/lib/ddtrace/quantization/http.rb +86 -0
  37. data/lib/ddtrace/tracer.rb +29 -2
  38. data/lib/ddtrace/transport.rb +33 -20
  39. data/lib/ddtrace/version.rb +1 -1
  40. data/lib/ddtrace/writer.rb +11 -5
  41. metadata +8 -3
  42. data/lib/ddtrace/contrib/rails/active_record.rb +0 -80
data/Rakefile CHANGED
@@ -40,25 +40,26 @@ namespace :spec do
40
40
  end
41
41
 
42
42
  [
43
+ :active_record,
44
+ :active_support,
45
+ :aws,
46
+ :dalli,
43
47
  :elasticsearch,
44
- :http,
45
- :redis,
46
- :sinatra,
47
- :sidekiq,
48
- :rack,
49
48
  :faraday,
50
49
  :grape,
51
50
  :graphql,
52
- :aws,
53
- :sucker_punch,
51
+ :http,
54
52
  :mongodb,
55
53
  :racecar,
54
+ :rack,
55
+ :redis,
56
56
  :resque,
57
- :active_record,
58
- :dalli
57
+ :sidekiq,
58
+ :sinatra,
59
+ :sucker_punch
59
60
  ].each do |contrib|
60
61
  RSpec::Core::RakeTask.new(contrib) do |t|
61
- t.pattern = "spec/ddtrace/contrib/#{contrib}/*_spec.rb"
62
+ t.pattern = "spec/ddtrace/contrib/#{contrib}/**/*_spec.rb"
62
63
  end
63
64
  end
64
65
  end
@@ -66,7 +67,7 @@ end
66
67
  namespace :test do
67
68
  task all: [:main,
68
69
  :rails, :railsredis, :railssidekiq, :railsactivejob,
69
- :elasticsearch, :http, :redis, :sidekiq, :sinatra, :monkey]
70
+ :elasticsearch, :http, :sidekiq, :sinatra, :monkey]
70
71
 
71
72
  Rake::TestTask.new(:main) do |t|
72
73
  t.libs << %w[test lib]
@@ -111,13 +112,11 @@ namespace :test do
111
112
  [
112
113
  :aws,
113
114
  :elasticsearch,
114
- :faraday,
115
115
  :grape,
116
116
  :http,
117
117
  :mongodb,
118
118
  :resque,
119
119
  :rack,
120
- :redis,
121
120
  :resque,
122
121
  :sidekiq,
123
122
  :sinatra,
@@ -209,11 +208,9 @@ task :ci do
209
208
  when 1
210
209
  sh 'rvm $MRI_VERSIONS --verbose do appraisal contrib rake test:elasticsearch'
211
210
  sh 'rvm $MRI_VERSIONS --verbose do appraisal contrib rake test:http'
212
- sh 'rvm $MRI_VERSIONS --verbose do appraisal contrib rake test:redis'
213
211
  sh 'rvm $MRI_VERSIONS --verbose do appraisal contrib rake test:sinatra'
214
212
  sh 'rvm $MRI_VERSIONS --verbose do appraisal contrib rake test:rack'
215
213
  sh 'rvm $MRI_VERSIONS --verbose do appraisal contrib rake test:grape'
216
- sh 'rvm $MRI_VERSIONS --verbose do appraisal contrib rake test:faraday'
217
214
  sh 'rvm $MRI_VERSIONS --verbose do appraisal contrib rake test:aws'
218
215
  sh 'rvm $MRI_VERSIONS --verbose do appraisal contrib rake test:mongodb'
219
216
  sh 'rvm $MRI_VERSIONS --verbose do appraisal contrib rake test:sucker_punch'
@@ -221,21 +218,25 @@ task :ci do
221
218
  sh 'rvm $MRI_OLD_VERSIONS --verbose do appraisal contrib-old rake test:monkey'
222
219
  sh 'rvm $MRI_OLD_VERSIONS --verbose do appraisal contrib-old rake test:elasticsearch'
223
220
  sh 'rvm $MRI_OLD_VERSIONS --verbose do appraisal contrib-old rake test:http'
224
- sh 'rvm $MRI_OLD_VERSIONS --verbose do appraisal contrib-old rake test:redis'
225
221
  sh 'rvm $MRI_OLD_VERSIONS --verbose do appraisal contrib-old rake test:sinatra'
226
222
  sh 'rvm $MRI_OLD_VERSIONS --verbose do appraisal contrib-old rake test:rack'
227
- sh 'rvm $MRI_OLD_VERSIONS --verbose do appraisal contrib-old rake test:faraday'
228
223
  sh 'rvm $MRI_OLD_VERSIONS --verbose do appraisal contrib-old rake test:aws'
229
224
  sh 'rvm $MRI_OLD_VERSIONS --verbose do appraisal contrib-old rake test:mongodb'
230
225
  sh 'rvm $MRI_OLD_VERSIONS --verbose do appraisal contrib-old rake test:sucker_punch'
231
226
  sh 'rvm $MRI_OLD_VERSIONS --verbose do appraisal contrib-old rake test:resque'
232
227
  # RSpec
233
228
  sh 'rvm $MRI_VERSIONS --verbose do appraisal contrib rake spec:active_record'
229
+ sh 'rvm $MRI_VERSIONS --verbose do appraisal contrib rake spec:active_support'
234
230
  sh 'rvm $MRI_VERSIONS --verbose do appraisal contrib rake spec:dalli'
231
+ sh 'rvm $MRI_VERSIONS --verbose do appraisal contrib rake spec:faraday'
235
232
  sh 'rvm $MRI_VERSIONS --verbose do appraisal contrib rake spec:graphql'
236
233
  sh 'rvm $MRI_VERSIONS --verbose do appraisal contrib rake spec:racecar'
237
- sh 'rvm $MRI_OLD_VERSIONS --verbose do appraisal contrib-old rake spec:dalli'
234
+ sh 'rvm $MRI_VERSIONS --verbose do appraisal contrib rake spec:redis'
238
235
  sh 'rvm $MRI_OLD_VERSIONS --verbose do appraisal contrib-old rake spec:active_record'
236
+ sh 'rvm $MRI_OLD_VERSIONS --verbose do appraisal contrib-old rake spec:active_support'
237
+ sh 'rvm $MRI_OLD_VERSIONS --verbose do appraisal contrib-old rake spec:dalli'
238
+ sh 'rvm $MRI_OLD_VERSIONS --verbose do appraisal contrib-old rake spec:faraday'
239
+ sh 'rvm $MRI_OLD_VERSIONS --verbose do appraisal contrib-old rake spec:redis'
239
240
  when 2
240
241
  sh 'rvm $MRI_VERSIONS --verbose do appraisal contrib rake test:sidekiq'
241
242
  sh 'rvm $SIDEKIQ_OLD_VERSIONS --verbose do appraisal contrib-old rake test:sidekiq'
@@ -261,6 +262,13 @@ task :ci do
261
262
  sh 'rvm $RAILS5_VERSIONS --verbose do appraisal rails5-postgres rake test:railsdisableenv'
262
263
  # RSpec
263
264
  sh 'rvm $LAST_STABLE --verbose do rake benchmark'
265
+ sh 'rvm $RAILS3_VERSIONS --verbose do appraisal rails30-postgres rake spec:rails'
266
+ sh 'rvm $RAILS3_VERSIONS --verbose do appraisal rails32-mysql2 rake spec:rails'
267
+ sh 'rvm $RAILS3_VERSIONS --verbose do appraisal rails32-postgres rake spec:rails'
268
+ sh 'rvm $RAILS4_VERSIONS --verbose do appraisal rails4-mysql2 rake spec:rails'
269
+ sh 'rvm $RAILS4_VERSIONS --verbose do appraisal rails4-postgres rake spec:rails'
270
+ sh 'rvm $RAILS5_VERSIONS --verbose do appraisal rails5-mysql2 rake spec:rails'
271
+ sh 'rvm $RAILS5_VERSIONS --verbose do appraisal rails5-postgres rake spec:rails'
264
272
  else
265
273
  puts 'Too many workers than parallel tasks'
266
274
  end
@@ -3,297 +3,486 @@
3
3
  ``ddtrace`` is Datadog’s tracing client for Ruby. It is used to trace requests as they flow across web servers,
4
4
  databases and microservices so that developers have great visiblity into bottlenecks and troublesome requests.
5
5
 
6
- ## Install the gem
7
-
8
- Install the tracing client, adding the following gem in your ``Gemfile``:
9
-
6
+ ## Getting started
7
+
8
+ For a basic product overview, check out our [setup documentation][setup docs].
9
+
10
+ For details about contributing, check out the [development guide][development docs].
11
+
12
+ For descriptions of terminology used in APM, take a look at the [official documentation][visualization docs].
13
+
14
+ [setup docs]: https://docs.datadoghq.com/tracing/setup/ruby/
15
+ [development docs]: https://github.com/DataDog/dd-trace-rb/blob/master/README.md#development
16
+ [visualization docs]: https://docs.datadoghq.com/tracing/visualization/
17
+
18
+ ## Table of Contents
19
+
20
+ - [Compatibility](#compatibility)
21
+ - [Installation](#installation)
22
+ - [Quickstart for Rails applications](#quickstart-for-rails-applications)
23
+ - [Quickstart for Ruby applications](#quickstart-for-ruby-applications)
24
+ - [Manual instrumentation](#manual-instrumentation)
25
+ - [Integration instrumentation](#integration-instrumentation)
26
+ - [Active Record](#active-record)
27
+ - [AWS](#aws)
28
+ - [Dalli](#dalli)
29
+ - [Elastic Search](#elastic-search)
30
+ - [Faraday](#faraday)
31
+ - [Grape](#grape)
32
+ - [GraphQL](#graphql)
33
+ - [MongoDB](#mongodb)
34
+ - [Net/HTTP](#nethttp)
35
+ - [Racecar](#racecar)
36
+ - [Rack](#rack)
37
+ - [Rails](#rails)
38
+ - [Redis](#redis)
39
+ - [Resque](#resque)
40
+ - [Sidekiq](#sidekiq)
41
+ - [Sinatra](#sinatra)
42
+ - [Sucker Punch](#sucker-punch)
43
+ - [Advanced configuration](#advanced-configuration)
44
+ - [Tracer settings](#tracer-settings)
45
+ - [Custom logging](#custom-logging)
46
+ - [Environment and tags](#environment-and-tags)
47
+ - [Sampling](#sampling)
48
+ - [Priority sampling](#priority-sampling)
49
+ - [Distributed tracing](#distributed-tracing)
50
+ - [Processing pipeline](#processing-pipeline)
51
+ - [Filtering](#filtering)
52
+ - [Processing](#processing)
53
+
54
+ ## Compatibility
55
+
56
+ **Supported Ruby interpreters**:
57
+
58
+ | Type | Documentation | Version | Support type |
59
+ | ----- | -------------------------- | ----- | ------------ |
60
+ | MRI | https://www.ruby-lang.org/ | 1.9.1 | Experimental |
61
+ | | | 1.9.3 | Full |
62
+ | | | 2.0 | Full |
63
+ | | | 2.1 | Full |
64
+ | | | 2.2 | Full |
65
+ | | | 2.3 | Full |
66
+ | | | 2.4 | Full |
67
+ | JRuby | http://jruby.org/ | 9.1.5 | Experimental |
68
+
69
+ *Full* support indicates all tracer features are available.
70
+
71
+ *Experimental* indicates most features should be available, but unverified.
72
+
73
+ **Supported web servers**:
74
+
75
+ | Type | Documentation | Version | Support type |
76
+ | --------- | --------------------------------- | ------------ | ------------ |
77
+ | Puma | http://puma.io/ | 2.16+ / 3.6+ | Full |
78
+ | Unicorn | https://bogomips.org/unicorn/ | 4.8+ / 5.1+ | Full |
79
+ | Passenger | https://www.phusionpassenger.com/ | 5.0+ | Full |
80
+
81
+ ## Installation
82
+
83
+ The following steps will help you quickly start tracing your Ruby application.
84
+
85
+ ### Setup the Datadog Agent
86
+
87
+ The Ruby APM tracer sends trace data through the Datadog Agent.
88
+
89
+ [Install and configure the Datadog Agent](https://docs.datadoghq.com/tracing/setup), see additional documentation for [tracing Docker applications](https://docs.datadoghq.com/tracing/setup/docker/).
90
+
91
+ ### Quickstart for Rails applications
92
+
93
+ 1. Add the `ddtrace` gem to your Gemfile:
94
+
95
+ ```ruby
10
96
  source 'https://rubygems.org'
11
-
12
- # tracing gem
13
97
  gem 'ddtrace'
98
+ ```
14
99
 
15
- If you're not using ``Bundler`` to manage your dependencies, you can install ``ddtrace`` with:
100
+ 2. Install the gem with `bundle install`
101
+ 3. Create a `config/initializers/datadog.rb` file containing:
16
102
 
17
- gem install ddtrace
18
-
19
- We strongly suggest pinning the version of the library you deploy.
103
+ ```ruby
104
+ Datadog.configure do |c|
105
+ # This will activate auto-instrumentation for Rails
106
+ c.use :rails
107
+ end
108
+ ```
20
109
 
21
- ## Quickstart
110
+ You can also activate additional integrations here (see [Integration instrumentation](#integration-instrumentation))
22
111
 
23
- The easiest way to get started with the tracing client is to instrument your web application.
24
- All configuration is done through ``Datadog.configure`` method. As an
25
- example, below is a setup that enables auto instrumentation for Rails, Redis and
26
- Grape, and sets a custom endpoint for the trace agent:
112
+ ### Quickstart for Ruby applications
27
113
 
28
- # config/initializers/datadog-tracer.rb
114
+ 1. Install the gem with `gem install ddtrace`
115
+ 2. Add a configuration block to your Ruby application:
29
116
 
117
+ ```ruby
118
+ require 'ddtrace'
30
119
  Datadog.configure do |c|
31
- c.tracer hostname: 'trace-agent.local'
32
- c.use :rails
33
- c.use :grape
34
- c.use :redis, service_name: 'cache'
120
+ # Configure the tracer here.
121
+ # Activate integrations, change tracer settings, etc...
122
+ # By default without additional configuration, nothing will be traced.
35
123
  end
124
+ ```
36
125
 
37
- For further details and options, check our integrations list.
126
+ 3. Add or activate instrumentation by doing either of the following:
127
+ 1. Activate integration instrumentation (see [Integration instrumentation](#integration-instrumentation))
128
+ 2. Add manual instrumentation around your code (see [Manual instrumentation](#manual-instrumentation))
38
129
 
39
- ## Available Integrations
130
+ ### Final steps for installation
40
131
 
41
- * [Ruby on Rails](#Ruby_on_Rails)
42
- * [Sinatra](#Sinatra)
43
- * [Rack](#Rack)
44
- * [GraphQL](#GraphQL)
45
- * [Grape](#Grape)
46
- * [Active Record](#Active_Record)
47
- * [Elastic Search](#Elastic_Search)
48
- * [MongoDB](#MongoDB)
49
- * [Sidekiq](#Sidekiq)
50
- * [Resque](#Resque)
51
- * [SuckerPunch](#SuckerPunch)
52
- * [Net/HTTP](#Net_HTTP)
53
- * [Faraday](#Faraday)
54
- * [Dalli](#Dalli)
55
- * [Redis](#Redis)
132
+ After setting up, your services will appear on the [APM services page](https://app.datadoghq.com/apm/services) within a few minutes. Learn more about [using the APM UI][visualization docs].
56
133
 
57
- ## Web Frameworks
134
+ ## Manual Instrumentation
58
135
 
59
- ### Ruby on Rails
136
+ If you aren't using a supported framework instrumentation, you may want to to manually instrument your code.
60
137
 
61
- The Rails integration will trace requests, database calls, templates rendering and cache read/write/delete
62
- operations. The integration makes use of the Active Support Instrumentation, listening to the Notification API
63
- so that any operation instrumented by the API is traced.
138
+ To trace any Ruby code, you can use the `Datadog.tracer.trace` method:
64
139
 
65
- To enable the Rails auto instrumentation, create an initializer file in your ``config/`` folder:
140
+ ```ruby
141
+ Datadog.tracer.trace(name, options) do |span|
142
+ # Wrap this block around the code you want to instrument
143
+ # Additionally, you can modify the span here.
144
+ # e.g. Change the resource name, set tags, etc...
145
+ end
146
+ ```
66
147
 
67
- # config/initializers/datadog-tracer.rb
148
+ Where `name` should be a `String` that describes the generic kind of operation being done (e.g. `'web.request'`, or `'request.parse'`)
68
149
 
69
- Datadog.configure do |c|
70
- c.use :rails, options
150
+ And `options` is an optional `Hash` that accepts the following parameters:
151
+
152
+ | Key | Type | Description | Default |
153
+ | --- | --- | --- | --- |
154
+ | ``service`` | `String` | The service name which this span belongs (e.g. `'my-web-service'`) | Tracer `default-service`, `$PROGRAM_NAME` or `'ruby'` |
155
+ | ``resource`` | `String` | Name of the resource or action being operated on. Traces with the same resource value will be grouped together for the purpose of metrics (but still independently viewable.) Usually domain specific, such as a URL, query, request, etc. (e.g. `'Article#submit'`, `http://example.com/articles/list`.) | `name` of Span. |
156
+ | ``span_type`` | `String` | The type of the span (such as `'http'`, `'db'`, etc.) | `nil` |
157
+ | ``child_of`` | `Datadog::Span` / `Datadog::Context` | Parent for this span. If not provided, will automatically become current active span. | `nil` |
158
+ | ``start_time`` | `Integer` | When the span actually starts. Useful when tracing events that have already happened. | `Time.now.utc` |
159
+ | ``tags`` | `Hash` | Extra tags which should be added to the span. | `{}` |
160
+
161
+ It's highly recommended you set both `service` and `resource` at a minimum. Spans without a `service` or `resource` as `nil` will be discarded by the Datadog agent.
162
+
163
+ Example of manual instrumentation in action:
164
+
165
+ ```ruby
166
+ get '/posts' do
167
+ Datadog.tracer.trace('web.request', service: 'my-blog', resource: 'GET /posts') do |span|
168
+ # Trace the activerecord call
169
+ Datadog.tracer.trace('posts.fetch') do
170
+ @posts = Posts.order(created_at: :desc).limit(10)
71
171
  end
72
172
 
73
- Where `options` is an optional `Hash` that accepts the following parameters:
173
+ # Add some APM tags
174
+ span.set_tag('http.method', request.request_method)
175
+ span.set_tag('posts.count', @posts.length)
74
176
 
177
+ # Trace the template rendering
178
+ Datadog.tracer.trace('template.render') do
179
+ erb :index
180
+ end
181
+ end
182
+ end
183
+ ```
75
184
 
76
- | Key | Description | Default |
77
- | --- | --- | --- |
78
- | ``service_name`` | Service name used when tracing application requests (on the `rack` level) | ``<app_name>`` (inferred from your Rails application namespace) |
79
- | ``controller_service`` | Service name used when tracing a Rails action controller | ``<app_name>-controller`` |
80
- | ``cache_service`` | Cache service name used when tracing cache activity | ``<app_name>-cache`` |
81
- | ``database_service`` | Database service name used when tracing database activity | ``<app_name>-<adapter_name>`` |
82
- | ``exception_controller`` | Class or Module which identifies a custom exception controller class. Tracer provides improved error behavior when it can identify custom exception controllers. By default, without this option, it 'guesses' what a custom exception controller looks like. Providing this option aids this identification. | ``nil`` |
83
- | ``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` |
84
- | ``template_base_path`` | Used when the template name is parsed. If you don't store your templates in the ``views/`` folder, you may need to change this value | ``views/`` |
85
- | ``tracer`` | A ``Datadog::Tracer`` instance used to instrument the application. Usually you don't need to set that. | ``Datadog.tracer`` |
185
+ **Asynchronous tracing**
86
186
 
87
- ### Sinatra
187
+ It might not always be possible to wrap `Datadog.tracer.trace` around a block of code. Some event or notification based instrumentation might only notify you when an event begins or ends.
88
188
 
89
- The Sinatra integration traces requests and template rendering.
189
+ To trace these operations, you can trace code asynchronously by calling `Datadog.tracer.trace` without a block:
90
190
 
91
- To start using the tracing client, make sure you import ``ddtrace`` and ``ddtrace/contrib/sinatra/tracer`` after
92
- either ``sinatra`` or ``sinatra/base``:
191
+ ```ruby
192
+ # Some instrumentation framework calls this after an event began and finished...
193
+ def db_query(start, finish, query)
194
+ span = Datadog.tracer.trace('database.query')
195
+ span.resource = query
196
+ span.start_time = start
197
+ span.finish(finish)
198
+ end
199
+ ```
93
200
 
94
- require 'sinatra'
95
- require 'ddtrace'
96
- require 'ddtrace/contrib/sinatra/tracer'
201
+ Calling `Datadog.tracer.trace` without a block will cause the function to return a `Datadog::Span` that is started, but not finished. You can then modify this span however you wish, then close it `finish`.
97
202
 
98
- Datadog.configure do |c|
99
- c.use :sinatra, options
100
- end
203
+ *You must not leave any unfinished spans.* If any spans are left open when the trace completes, the trace will be discarded. You can [activate debug mode](#tracer-settings) to check for warnings if you suspect this might be happening.
101
204
 
102
- get '/' do
103
- 'Hello world!'
104
- end
205
+ To avoid this scenario when handling start/finish events, you can use `Datadog.tracer.active_span` to get the current active span.
105
206
 
106
- Where `options` is an optional `Hash` that accepts the following parameters:
207
+ ```ruby
208
+ # e.g. ActiveSupport::Notifications calls this when an event starts
209
+ def start(name, id, payload)
210
+ # Start a span
211
+ Datadog.tracer.trace(name)
212
+ end
107
213
 
108
- | Key | Description | Default |
109
- | --- | --- | --- |
110
- | ``service_name`` | Service name used for `sinatra` instrumentation | sinatra |
111
- | ``resource_script_names`` | Prepend resource names with script name | ``false`` |
112
- | ``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` |
113
- | ``tracer`` | A ``Datadog::Tracer`` instance used to instrument the application. Usually you don't need to set that. | ``Datadog.tracer`` |
214
+ # e.g. ActiveSupport::Notifications calls this when an event finishes
215
+ def finish(name, id, payload)
216
+ # Retrieve current active span (thread-safe)
217
+ current_span = Datadog.tracer.active_span
218
+ unless current_span.nil?
219
+ current_span.resource = payload[:query]
220
+ current_span.finish
221
+ end
222
+ end
223
+ ```
114
224
 
115
- ### Rack
225
+ ## Integration instrumentation
116
226
 
117
- The Rack integration provides a middleware that traces all requests before they reach the underlying framework
118
- or application. It responds to the Rack minimal interface, providing reasonable values that can be
119
- retrieved at the Rack level. This integration is automatically activated with web frameworks like Rails.
120
- If you're using a plain Rack application, just enable the integration it to your ``config.ru``:
227
+ Many popular libraries and frameworks are supported out-of-the-box, which can be auto-instrumented. Although they are not activated automatically, they can be easily activated and configured by using the `Datadog.configure` API:
121
228
 
122
- # config.ru example
123
- require 'ddtrace'
229
+ ```ruby
230
+ Datadog.configure do |c|
231
+ # Activates and configures an integration
232
+ c.use :integration_name, options
233
+ end
234
+ ```
124
235
 
125
- Datadog.configure do |c|
126
- c.use :rack, options
127
- end
236
+ `options` is a `Hash` of integration-specific configuration settings.
237
+
238
+ For a list of available integrations, and their configuration options, please refer to the following:
239
+
240
+ | Name | Key | Versions Supported | How to configure | Gem source |
241
+ | -------------- | --------------- | ---------------------- | ------------------------- | ------------------------------------------------------------------------------ |
242
+ | Active Record | `active_record` | `>= 3.2, < 5.2` | *[Link](#active-record)* | *[Link](https://github.com/rails/rails/tree/master/activerecord)* |
243
+ | AWS | `aws` | `>= 2.0` | *[Link](#aws)* | *[Link](https://github.com/aws/aws-sdk-ruby)* |
244
+ | Dalli | `dalli` | `>= 2.7` | *[Link](#dalli)* | *[Link](https://github.com/petergoldstein/dalli)* |
245
+ | Elastic Search | `elasticsearch` | `>= 6.0` | *[Link](#elastic-search)* | *[Link](https://github.com/elastic/elasticsearch-ruby)* |
246
+ | Faraday | `faraday` | `>= 0.14` | *[Link](#faraday)* | *[Link](https://github.com/lostisland/faraday)* |
247
+ | Grape | `grape` | `>= 1.0` | *[Link](#grape)* | *[Link](https://github.com/ruby-grape/grape)* |
248
+ | GraphQL | `graphql` | `>= 1.7.9` | *[Link](#graphql)* | *[Link](https://github.com/rmosolgo/graphql-ruby)* |
249
+ | MongoDB | `mongo` | `>= 2.0, < 2.5` | *[Link](#mongodb)* | *[Link](https://github.com/mongodb/mongo-ruby-driver)* |
250
+ | Net/HTTP | `http` | *(Any supported Ruby)* | *[Link](#nethttp)* | *[Link](https://ruby-doc.org/stdlib-2.4.0/libdoc/net/http/rdoc/Net/HTTP.html)* |
251
+ | Racecar | `racecar` | `>= 0.3.5` | *[Link](#racecar)* | *[Link](https://github.com/zendesk/racecar)* |
252
+ | Rack | `rack` | `>= 1.4.7` | *[Link](#rack)* | *[Link](https://github.com/rack/rack)* |
253
+ | Rails | `rails` | `>= 3.2, < 5.2` | *[Link](#rails)* | *[Link](https://github.com/rails/rails)* |
254
+ | Redis | `redis` | `>= 3.2, < 4.0` | *[Link](#redis)* | *[Link](https://github.com/redis/redis-rb)* |
255
+ | Resque | `resque` | `>= 1.0, < 2.0` | *[Link](#resque)* | *[Link](https://github.com/resque/resque)* |
256
+ | Sidekiq | `sidekiq` | `>= 4.0` | *[Link](#sidekiq)* | *[Link](https://github.com/mperham/sidekiq)* |
257
+ | Sinatra | `sinatra` | `>= 1.4.5` | *[Link](#sinatra)* | *[Link](https://github.com/sinatra/sinatra)* |
258
+ | Sucker Punch | `sucker_punch` | `>= 2.0` | *[Link](#sucker-punch)* | *[Link](https://github.com/brandonhilkert/sucker_punch)* |
128
259
 
129
- use Datadog::Contrib::Rack::TraceMiddleware
260
+ ### Active Record
130
261
 
131
- app = proc do |env|
132
- [ 200, {'Content-Type' => 'text/plain'}, ['OK'] ]
133
- end
262
+ Most of the time, Active Record is set up as part of a web framework (Rails, Sinatra...) however it can be set up alone:
134
263
 
135
- run app
264
+ ```ruby
265
+ require 'tmpdir'
266
+ require 'sqlite3'
267
+ require 'active_record'
268
+ require 'ddtrace'
269
+
270
+ Datadog.configure do |c|
271
+ c.use :active_record, options
272
+ end
273
+
274
+ Dir::Tmpname.create(['test', '.sqlite']) do |db|
275
+ conn = ActiveRecord::Base.establish_connection(adapter: 'sqlite3',
276
+ database: db)
277
+ conn.connection.execute('SELECT 42') # traced!
278
+ end
279
+ ```
136
280
 
137
281
  Where `options` is an optional `Hash` that accepts the following parameters:
138
282
 
139
283
  | Key | Description | Default |
140
284
  | --- | --- | --- |
141
- | ``service_name`` | Service name used when tracing application requests | rack |
142
- | ``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` |
143
- | ``middleware_names`` | Enable this if you want to use the middleware classes as the resource names for `rack` spans | ``false`` |
144
- | ``tracer`` | A ``Datadog::Tracer`` instance used to instrument the application. Usually you don't need to set that. | ``Datadog.tracer`` |
145
-
146
- ## Other libraries
285
+ | ``service_name`` | Service name used for database portion of `active_record` instrumentation. | Name of database adapter (e.g. `mysql2`) |
286
+ | ``orm_service_name`` | Service name used for the Ruby ORM portion of `active_record` instrumentation. Overrides service name for ORM spans if explicitly set, which otherwise inherit their service from their parent. | ``active_record`` |
147
287
 
148
- ### GraphQL
288
+ ### AWS
149
289
 
150
- *Version 1.7.9+ supported*
290
+ The AWS integration will trace every interaction (e.g. API calls) with AWS services (S3, ElastiCache etc.).
151
291
 
152
- The GraphQL integration activates instrumentation for GraphQL queries. To activate your integration, use the ``Datadog.configure`` method:
292
+ ```ruby
293
+ require 'aws-sdk'
294
+ require 'ddtrace'
153
295
 
154
- # Inside Rails initializer or equivalent
155
- Datadog.configure do |c|
156
- c.use :graphql,
157
- service_name: 'graphql',
158
- schemas: [YourSchema]
159
- end
296
+ Datadog.configure do |c|
297
+ c.use :aws, options
298
+ end
160
299
 
161
- # Then run a GraphQL query
162
- YourSchema.execute(query, variables: {}, context: {}, operation_name: nil)
300
+ Aws::S3::Client.new.list_buckets # traced call
301
+ ```
163
302
 
164
- The `use :graphql` method accepts the following parameters:
303
+ Where `options` is an optional `Hash` that accepts the following parameters:
165
304
 
166
305
  | Key | Description | Default |
167
306
  | --- | --- | --- |
168
- | ``service_name`` | Service name used for `graphql` instrumentation | ``ruby-graphql`` |
169
- | ``schemas`` | Required. Array of `GraphQL::Schema` objects which to trace. Tracing will be added to all the schemas listed, using the options provided to this configuration. If you do not provide any, then tracing will not be activated. | ``[]`` |
170
- | ``tracer`` | A ``Datadog::Tracer`` instance used to instrument the application. Usually you don't need to set that. | ``Datadog.tracer`` |
307
+ | ``service_name`` | Service name used for `aws` instrumentation | aws |
171
308
 
172
- ##### Manually configuring GraphQL schemas
309
+ ### Dalli
173
310
 
174
- If you prefer to individually configure the tracer settings for a schema (e.g. you have multiple schemas with different service names),
175
- in the schema definition, you can add the following [using the GraphQL API](http://graphql-ruby.org/queries/tracing.html):
311
+ Dalli integration will trace all calls to your ``memcached`` server:
176
312
 
177
- ```
178
- YourSchema = GraphQL::Schema.define do
179
- use(
180
- GraphQL::Tracing::DataDogTracing,
181
- service: 'graphql'
182
- )
313
+ ```ruby
314
+ require 'dalli'
315
+ require 'ddtrace'
316
+
317
+ Datadog.configure do |c|
318
+ c.use :dalli, service_name: 'dalli'
183
319
  end
320
+
321
+ client = Dalli::Client.new('localhost:11211', options)
322
+ client.set('abc', 123)
184
323
  ```
185
324
 
186
- Or you can modify an already defined schema:
325
+ Where `options` is an optional `Hash` that accepts the following parameters:
187
326
 
188
- ```
189
- YourSchema.define do
190
- use(
191
- GraphQL::Tracing::DataDogTracing,
192
- service: 'graphql'
193
- )
327
+ | Key | Description | Default |
328
+ | --- | --- | --- |
329
+ | ``service_name`` | Service name used for `dalli` instrumentation | memcached |
330
+
331
+ ### Elastic Search
332
+
333
+ The Elasticsearch integration will trace any call to ``perform_request`` in the ``Client`` object:
334
+
335
+ ```ruby
336
+ require 'elasticsearch/transport'
337
+ require 'ddtrace'
338
+
339
+ Datadog.configure do |c|
340
+ c.use :elasticsearch, options
194
341
  end
342
+
343
+ # now do your Elastic Search stuff, eg:
344
+ client = Elasticsearch::Client.new url: 'http://127.0.0.1:9200'
345
+ response = client.perform_request 'GET', '_cluster/health'
195
346
  ```
196
347
 
197
- Do *not* `use :graphql` in `Datadog.configure` if you choose to configure manually, as to avoid double tracing. These two means of configuring GraphQL tracing are considered mutually exclusive.
348
+ Where `options` is an optional `Hash` that accepts the following parameters:
198
349
 
199
- ### Grape
350
+ | Key | Description | Default |
351
+ | --- | --- | --- |
352
+ | ``service_name`` | Service name used for `elasticsearch` instrumentation | elasticsearch |
353
+ | ``quantize`` | Hash containing options for quantization. May include `:show` with an Array of keys to not quantize (or `:all` to skip quantization), or `:exclude` with Array of keys to exclude entirely. | {} |
200
354
 
201
- The Grape integration adds the instrumentation to Grape endpoints and filters. This integration can work side by side
202
- with other integrations like Rack and Rails. To activate your integration, use the ``Datadog.configure`` method before
203
- defining your Grape application:
355
+ ### Faraday
204
356
 
205
- # api.rb
206
- require 'grape'
207
- require 'ddtrace'
357
+ The `faraday` integration is available through the `ddtrace` middleware:
208
358
 
209
- Datadog.configure do |c|
210
- c.use :grape, options
211
- end
359
+ ```ruby
360
+ require 'faraday'
361
+ require 'ddtrace'
212
362
 
213
- # then define your application
214
- class RackTestingAPI < Grape::API
215
- desc 'main endpoint'
216
- get :success do
217
- 'Hello world!'
218
- end
219
- end
363
+ Datadog.configure do |c|
364
+ c.use :faraday, service_name: 'faraday' # global service name
365
+ end
366
+
367
+ connection = Faraday.new('https://example.com') do |builder|
368
+ builder.use(:ddtrace, options)
369
+ builder.adapter Faraday.default_adapter
370
+ end
371
+
372
+ connection.get('/foo')
373
+ ```
220
374
 
221
375
  Where `options` is an optional `Hash` that accepts the following parameters:
222
376
 
223
- | Key | Description | Default |
377
+ | Key | Default | Description |
224
378
  | --- | --- | --- |
225
- | ``service_name`` | Service name used for `grape` instrumentation | grape |
379
+ | `service_name` | Global service name (default: `faraday`) | Service name for this specific connection object. |
380
+ | `split_by_domain` | `false` | Uses the request domain as the service name when set to `true`. |
381
+ | `distributed_tracing` | `false` | Propagates tracing context along the HTTP request when set to `true`. |
382
+ | `error_handler` | ``5xx`` evaluated as errors | A callable object that receives a single argument – the request environment. If it evaluates to a *truthy* value, the trace span is marked as an error. |
226
383
 
227
- ### Active Record
384
+ ### Grape
228
385
 
229
- Most of the time, Active Record is set up as part of a web framework (Rails, Sinatra...)
230
- however it can be set up alone:
386
+ The Grape integration adds the instrumentation to Grape endpoints and filters. This integration can work side by side with other integrations like Rack and Rails.
231
387
 
232
- require 'tmpdir'
233
- require 'sqlite3'
234
- require 'active_record'
235
- require 'ddtrace'
388
+ To activate your integration, use the ``Datadog.configure`` method before defining your Grape application:
236
389
 
237
- Datadog.configure do |c|
238
- c.use :active_record, options
239
- end
390
+ ```ruby
391
+ # api.rb
392
+ require 'grape'
393
+ require 'ddtrace'
240
394
 
241
- Dir::Tmpname.create(['test', '.sqlite']) do |db|
242
- conn = ActiveRecord::Base.establish_connection(adapter: 'sqlite3',
243
- database: db)
244
- conn.connection.execute('SELECT 42') # traced!
245
- end
395
+ Datadog.configure do |c|
396
+ c.use :grape, options
397
+ end
398
+
399
+ # then define your application
400
+ class RackTestingAPI < Grape::API
401
+ desc 'main endpoint'
402
+ get :success do
403
+ 'Hello world!'
404
+ end
405
+ end
406
+ ```
246
407
 
247
408
  Where `options` is an optional `Hash` that accepts the following parameters:
248
409
 
249
410
  | Key | Description | Default |
250
411
  | --- | --- | --- |
251
- | ``service_name`` | Service name used for database portion of `active_record` instrumentation. | Name of database adapter (e.g. `mysql2`) |
252
- | ``orm_service_name`` | Service name used for the Ruby ORM portion of `active_record` instrumentation. Overrides service name for ORM spans if explicitly set, which otherwise inherit their service from their parent. | ``active_record`` |
412
+ | ``service_name`` | Service name used for `grape` instrumentation | grape |
253
413
 
254
- ### Elastic Search
414
+ ### GraphQL
255
415
 
256
- The Elasticsearch integration will trace any call to ``perform_request``
257
- in the ``Client`` object:
416
+ The GraphQL integration activates instrumentation for GraphQL queries.
258
417
 
259
- require 'elasticsearch/transport'
260
- require 'ddtrace'
418
+ To activate your integration, use the ``Datadog.configure`` method:
261
419
 
262
- Datadog.configure do |c|
263
- c.use :elasticsearch, options
264
- end
420
+ ```ruby
421
+ # Inside Rails initializer or equivalent
422
+ Datadog.configure do |c|
423
+ c.use :graphql,
424
+ service_name: 'graphql',
425
+ schemas: [YourSchema]
426
+ end
265
427
 
266
- # now do your Elastic Search stuff, eg:
267
- client = Elasticsearch::Client.new url: 'http://127.0.0.1:9200'
268
- response = client.perform_request 'GET', '_cluster/health'
428
+ # Then run a GraphQL query
429
+ YourSchema.execute(query, variables: {}, context: {}, operation_name: nil)
430
+ ```
269
431
 
270
- Where `options` is an optional `Hash` that accepts the following parameters:
432
+ The `use :graphql` method accepts the following parameters:
271
433
 
272
434
  | Key | Description | Default |
273
435
  | --- | --- | --- |
274
- | ``service_name`` | Service name used for `elasticsearch` instrumentation | elasticsearch |
436
+ | ``service_name`` | Service name used for `graphql` instrumentation | ``ruby-graphql`` |
437
+ | ``schemas`` | Required. Array of `GraphQL::Schema` objects which to trace. Tracing will be added to all the schemas listed, using the options provided to this configuration. If you do not provide any, then tracing will not be activated. | ``[]`` |
438
+ | ``tracer`` | A ``Datadog::Tracer`` instance used to instrument the application. Usually you don't need to set that. | ``Datadog.tracer`` |
439
+
440
+ **Manually configuring GraphQL schemas**
441
+
442
+ If you prefer to individually configure the tracer settings for a schema (e.g. you have multiple schemas with different service names), in the schema definition, you can add the following [using the GraphQL API](http://graphql-ruby.org/queries/tracing.html):
443
+
444
+ ```ruby
445
+ YourSchema = GraphQL::Schema.define do
446
+ use(
447
+ GraphQL::Tracing::DataDogTracing,
448
+ service: 'graphql'
449
+ )
450
+ end
451
+ ```
452
+
453
+ Or you can modify an already defined schema:
454
+
455
+ ```ruby
456
+ YourSchema.define do
457
+ use(
458
+ GraphQL::Tracing::DataDogTracing,
459
+ service: 'graphql'
460
+ )
461
+ end
462
+ ```
463
+
464
+ Do *not* `use :graphql` in `Datadog.configure` if you choose to configure manually, as to avoid double tracing. These two means of configuring GraphQL tracing are considered mutually exclusive.
275
465
 
276
466
  ### MongoDB
277
467
 
278
- The integration traces any `Command` that is sent from the
279
- [MongoDB Ruby Driver](https://github.com/mongodb/mongo-ruby-driver) to a MongoDB cluster.
280
- By extension, Object Document Mappers (ODM) such as Mongoid are automatically instrumented
281
- if they use the official Ruby driver. To activate the integration, simply:
468
+ The integration traces any `Command` that is sent from the [MongoDB Ruby Driver](https://github.com/mongodb/mongo-ruby-driver) to a MongoDB cluster. By extension, Object Document Mappers (ODM) such as Mongoid are automatically instrumented if they use the official Ruby driver. To activate the integration, simply:
282
469
 
283
- require 'mongo'
284
- require 'ddtrace'
470
+ ```ruby
471
+ require 'mongo'
472
+ require 'ddtrace'
285
473
 
286
- Datadog.configure do |c|
287
- c.use :mongo, options
288
- end
474
+ Datadog.configure do |c|
475
+ c.use :mongo, options
476
+ end
289
477
 
290
- # now create a MongoDB client and use it as usual:
291
- client = Mongo::Client.new([ '127.0.0.1:27017' ], :database => 'artists')
292
- collection = client[:people]
293
- collection.insert_one({ name: 'Steve' })
478
+ # now create a MongoDB client and use it as usual:
479
+ client = Mongo::Client.new([ '127.0.0.1:27017' ], :database => 'artists')
480
+ collection = client[:people]
481
+ collection.insert_one({ name: 'Steve' })
294
482
 
295
- # In case you want to override the global configuration for a certain client instance
296
- Datadog.configure(client, service_name: 'mongodb-primary')
483
+ # In case you want to override the global configuration for a certain client instance
484
+ Datadog.configure(client, service_name: 'mongodb-primary')
485
+ ```
297
486
 
298
487
  Where `options` is an optional `Hash` that accepts the following parameters:
299
488
 
@@ -303,22 +492,23 @@ Where `options` is an optional `Hash` that accepts the following parameters:
303
492
 
304
493
  ### Net/HTTP
305
494
 
306
- The Net/HTTP integration will trace any HTTP call using the standard lib
307
- Net::HTTP module.
495
+ The Net/HTTP integration will trace any HTTP call using the standard lib Net::HTTP module.
308
496
 
309
- require 'net/http'
310
- require 'ddtrace'
497
+ ```ruby
498
+ require 'net/http'
499
+ require 'ddtrace'
311
500
 
312
- Datadog.configure do |c|
313
- c.use :http, options
314
- end
501
+ Datadog.configure do |c|
502
+ c.use :http, options
503
+ end
315
504
 
316
- Net::HTTP.start('127.0.0.1', 8080) do |http|
317
- request = Net::HTTP::Get.new '/index'
318
- response = http.request request
319
- end
505
+ Net::HTTP.start('127.0.0.1', 8080) do |http|
506
+ request = Net::HTTP::Get.new '/index'
507
+ response = http.request request
508
+ end
320
509
 
321
- content = Net::HTTP.get(URI('http://127.0.0.1/index.html'))
510
+ content = Net::HTTP.get(URI('http://127.0.0.1/index.html'))
511
+ ```
322
512
 
323
513
  Where `options` is an optional `Hash` that accepts the following parameters:
324
514
 
@@ -329,90 +519,144 @@ Where `options` is an optional `Hash` that accepts the following parameters:
329
519
 
330
520
  If you wish to configure each connection object individually, you may use the ``Datadog.configure`` as it follows:
331
521
 
332
- client = Net::HTTP.new(host, port)
333
- Datadog.configure(client, options)
334
-
335
- ### Faraday
522
+ ```ruby
523
+ client = Net::HTTP.new(host, port)
524
+ Datadog.configure(client, options)
525
+ ```
336
526
 
337
- The `faraday` integration is available through the `ddtrace` middleware:
527
+ ### Racecar
338
528
 
339
- require 'faraday'
340
- require 'ddtrace'
529
+ The Racecar integration provides tracing for Racecar jobs.
341
530
 
342
- Datadog.configure do |c|
343
- c.use :faraday, service_name: 'faraday' # global service name
344
- end
531
+ You can enable it through `Datadog.configure`:
345
532
 
346
- connection = Faraday.new('https://example.com') do |builder|
347
- builder.use(:ddtrace, options)
348
- builder.adapter Faraday.default_adapter
349
- end
533
+ ```ruby
534
+ require 'ddtrace'
350
535
 
351
- connection.get('/foo')
536
+ Datadog.configure do |c|
537
+ c.use :racecar, options
538
+ end
539
+ ```
352
540
 
353
541
  Where `options` is an optional `Hash` that accepts the following parameters:
354
542
 
355
- | Key | Default | Description |
543
+ | Key | Description | Default |
356
544
  | --- | --- | --- |
357
- | `service_name` | Global service name (default: `faraday`) | Service name for this specific connection object. |
358
- | `split_by_domain` | `false` | Uses the request domain as the service name when set to `true`. |
359
- | `distributed_tracing` | `false` | Propagates tracing context along the HTTP request when set to `true`. |
360
- | `error_handler` | ``5xx`` evaluated as errors | A callable object that receives a single argument – the request environment. If it evaluates to a *truthy* value, the trace span is marked as an error. |
545
+ | ``service_name`` | Service name used for `racecar` instrumentation | racecar |
546
+ | ``tracer`` | A ``Datadog::Tracer`` instance used to instrument the application. Usually you don't need to set that. | ``Datadog.tracer`` |
361
547
 
362
- ### AWS
548
+ ### Rack
363
549
 
364
- The AWS integration will trace every interaction (e.g. API calls) with AWS
365
- services (S3, ElastiCache etc.).
550
+ The Rack integration provides a middleware that traces all requests before they reach the underlying framework or application. It responds to the Rack minimal interface, providing reasonable values that can be retrieved at the Rack level.
366
551
 
367
- require 'aws-sdk'
368
- require 'ddtrace'
552
+ This integration is automatically activated with web frameworks like Rails. If you're using a plain Rack application, just enable the integration it to your ``config.ru``:
369
553
 
370
- Datadog.configure do |c|
371
- c.use :aws, options
372
- end
554
+ ```ruby
555
+ # config.ru example
556
+ require 'ddtrace'
373
557
 
374
- Aws::S3::Client.new.list_buckets # traced call
558
+ Datadog.configure do |c|
559
+ c.use :rack, options
560
+ end
561
+
562
+ use Datadog::Contrib::Rack::TraceMiddleware
563
+
564
+ app = proc do |env|
565
+ [ 200, {'Content-Type' => 'text/plain'}, ['OK'] ]
566
+ end
567
+
568
+ run app
569
+ ```
375
570
 
376
571
  Where `options` is an optional `Hash` that accepts the following parameters:
377
572
 
378
573
  | Key | Description | Default |
379
574
  | --- | --- | --- |
380
- | ``service_name`` | Service name used for `aws` instrumentation | aws |
575
+ | ``service_name`` | Service name used when tracing application requests | rack |
576
+ | ``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` |
577
+ | ``middleware_names`` | Enable this if you want to use the middleware classes as the resource names for `rack` spans. Must provide the ``application`` option with it. | ``false`` |
578
+ | ``quantize`` | Hash containing options for quantization. May include `:query` or `:fragment`. | {} |
579
+ | ``quantize.query`` | Hash containing options for query portion of URL quantization. May include `:show` or `:exclude`. See options below. Option must be nested inside the `quantize` option. | {} |
580
+ | ``quantize.query.show`` | Defines which values should always be shown. Shows no values by default. May be an Array of strings, or `:all` to show all values. Option must be nested inside the `query` option. | ``nil`` |
581
+ | ``quantize.query.exclude`` | Defines which values should be removed entirely. Excludes nothing by default. May be an Array of strings, or `:all` to remove the query string entirely. Option must be nested inside the `query` option. | ``nil`` |
582
+ | ``quantize.fragment`` | Defines behavior for URL fragments. Removes fragments by default. May be `:show` to show URL fragments. Option must be nested inside the `quantize` option. | ``nil`` |
583
+ | ``application`` | Your Rack application. Necessary for enabling middleware resource names. | ``nil`` |
584
+ | ``tracer`` | A ``Datadog::Tracer`` instance used to instrument the application. Usually you don't need to set that. | ``Datadog.tracer`` |
381
585
 
382
- ### Dalli
586
+ **Configuring URL quantization behavior**
383
587
 
384
- Dalli integration will trace all calls to your ``memcached`` server:
588
+ ```ruby
589
+ Datadog.configure do |c|
590
+ # Default behavior: all values are quantized, fragment is removed.
591
+ # http://example.com/path?category_id=1&sort_by=asc#featured --> http://example.com/path?category_id&sort_by
592
+ # http://example.com/path?categories[]=1&categories[]=2 --> http://example.com/path?categories[]
385
593
 
386
- require 'dalli'
387
- require 'ddtrace'
594
+ # Show values for any query string parameter matching 'category_id' exactly
595
+ # http://example.com/path?category_id=1&sort_by=asc#featured --> http://example.com/path?category_id=1&sort_by
596
+ c.use :rack, quantize: { query: { show: ['category_id'] } }
388
597
 
389
- Datadog.configure do |c|
390
- c.use :dalli, service_name: 'dalli'
391
- end
598
+ # Show all values for all query string parameters
599
+ # http://example.com/path?category_id=1&sort_by=asc#featured --> http://example.com/path?category_id=1&sort_by=asc
600
+ c.use :rack, quantize: { query: { show: :all } }
601
+
602
+ # Totally exclude any query string parameter matching 'sort_by' exactly
603
+ # http://example.com/path?category_id=1&sort_by=asc#featured --> http://example.com/path?category_id
604
+ c.use :rack, quantize: { query: { exclude: ['sort_by'] } }
392
605
 
393
- client = Dalli::Client.new('localhost:11211', options)
394
- client.set('abc', 123)
606
+ # Remove the query string entirely
607
+ # http://example.com/path?category_id=1&sort_by=asc#featured --> http://example.com/path
608
+ c.use :rack, quantize: { query: { exclude: :all } }
609
+
610
+ # Show URL fragments
611
+ # http://example.com/path?category_id=1&sort_by=asc#featured --> http://example.com/path?category_id&sort_by#featured
612
+ c.use :rack, quantize: { fragment: :show }
613
+ end
614
+ ```
615
+
616
+ ### Rails
617
+
618
+ The Rails integration will trace requests, database calls, templates rendering and cache read/write/delete operations. The integration makes use of the Active Support Instrumentation, listening to the Notification API so that any operation instrumented by the API is traced.
619
+
620
+ To enable the Rails auto instrumentation, create an initializer file in your ``config/initializers`` folder:
621
+
622
+ ```ruby
623
+ # config/initializers/datadog-tracer.rb
624
+
625
+ Datadog.configure do |c|
626
+ c.use :rails, options
627
+ end
628
+ ```
395
629
 
396
630
  Where `options` is an optional `Hash` that accepts the following parameters:
397
631
 
398
632
  | Key | Description | Default |
399
633
  | --- | --- | --- |
400
- | ``service_name`` | Service name used for `dalli` instrumentation | memcached |
634
+ | ``service_name`` | Service name used when tracing application requests (on the `rack` level) | ``<app_name>`` (inferred from your Rails application namespace) |
635
+ | ``controller_service`` | Service name used when tracing a Rails action controller | ``<app_name>-controller`` |
636
+ | ``cache_service`` | Cache service name used when tracing cache activity | ``<app_name>-cache`` |
637
+ | ``database_service`` | Database service name used when tracing database activity | ``<app_name>-<adapter_name>`` |
638
+ | ``exception_controller`` | Class or Module which identifies a custom exception controller class. Tracer provides improved error behavior when it can identify custom exception controllers. By default, without this option, it 'guesses' what a custom exception controller looks like. Providing this option aids this identification. | ``nil`` |
639
+ | ``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` |
640
+ | ``middleware_names`` | Enables any short-circuited middleware requests to display the middleware name as resource for the trace. | `false` |
641
+ | ``template_base_path`` | Used when the template name is parsed. If you don't store your templates in the ``views/`` folder, you may need to change this value | ``views/`` |
642
+ | ``tracer`` | A ``Datadog::Tracer`` instance used to instrument the application. Usually you don't need to set that. | ``Datadog.tracer`` |
401
643
 
402
644
  ### Redis
403
645
 
404
646
  The Redis integration will trace simple calls as well as pipelines.
405
647
 
406
- require 'redis'
407
- require 'ddtrace'
648
+ ```ruby
649
+ require 'redis'
650
+ require 'ddtrace'
408
651
 
409
- Datadog.configure do |c|
410
- c.use :redis, service_name: 'redis'
411
- end
652
+ Datadog.configure do |c|
653
+ c.use :redis, service_name: 'redis'
654
+ end
412
655
 
413
- # now do your Redis stuff, eg:
414
- redis = Redis.new
415
- redis.set 'foo', 'bar' # traced!
656
+ # now do your Redis stuff, eg:
657
+ redis = Redis.new
658
+ redis.set 'foo', 'bar' # traced!
659
+ ```
416
660
 
417
661
  Where `options` is an optional `Hash` that accepts the following parameters:
418
662
 
@@ -422,25 +666,56 @@ Where `options` is an optional `Hash` that accepts the following parameters:
422
666
 
423
667
  You can also set *per-instance* configuration as it follows:
424
668
 
425
- customer_cache = Redis.new
426
- invoice_cache = Redis.new
669
+ ```ruby
670
+ customer_cache = Redis.new
671
+ invoice_cache = Redis.new
672
+
673
+ Datadog.configure(customer_cache, service_name: 'customer-cache')
674
+ Datadog.configure(invoice_cache, service_name: invoice-cache')
675
+
676
+ customer_cache.get(...) # traced call will belong to `customer-cache` service
677
+ invoice_cache.get(...) # traced call will belong to `invoice-cache` service
678
+ ```
679
+
680
+ ### Resque
681
+
682
+ The Resque integration uses Resque hooks that wraps the ``perform`` method.
683
+ To add tracing to a Resque job, simply do as follows:
684
+
685
+ ```ruby
686
+ require 'ddtrace'
427
687
 
428
- Datadog.configure(customer_cache, service_name: 'customer-cache')
429
- Datadog.configure(invoice_cache, service_name: invoice-cache')
688
+ class MyJob
689
+ def self.perform(*args)
690
+ # do_something
691
+ end
692
+ end
693
+
694
+ Datadog.configure do |c|
695
+ c.use :resque, options
696
+ end
697
+ ```
698
+
699
+ Where `options` is an optional `Hash` that accepts the following parameters:
430
700
 
431
- customer_cache.get(...) # traced call will belong to `customer-cache` service
432
- invoice_cache.get(...) # traced call will belong to `invoice-cache` service
701
+ | Key | Description | Default |
702
+ | --- | --- | --- |
703
+ | ``service_name`` | Service name used for `resque` instrumentation | resque |
704
+ | ``workers`` | An array including all worker classes you want to trace (eg ``[MyJob]``) | ``[]`` |
433
705
 
434
706
  ### Sidekiq
435
707
 
436
- The Sidekiq integration is a server-side middleware which will trace job
437
- executions. You can enable it through `Datadog.configure`:
708
+ The Sidekiq integration is a server-side middleware which will trace job executions.
438
709
 
439
- require 'ddtrace'
710
+ You can enable it through `Datadog.configure`:
440
711
 
441
- Datadog.configure do |c|
442
- c.use :sidekiq, options
443
- end
712
+ ```ruby
713
+ require 'ddtrace'
714
+
715
+ Datadog.configure do |c|
716
+ c.use :sidekiq, options
717
+ end
718
+ ```
444
719
 
445
720
  Where `options` is an optional `Hash` that accepts the following parameters:
446
721
 
@@ -448,42 +723,50 @@ Where `options` is an optional `Hash` that accepts the following parameters:
448
723
  | --- | --- | --- |
449
724
  | ``service_name`` | Service name used for `sidekiq` instrumentation | sidekiq |
450
725
 
451
- ### Resque
726
+ ### Sinatra
452
727
 
453
- The Resque integration uses Resque hooks that wraps the ``perform`` method.
454
- To add tracing to a Resque job, simply do as follows:
728
+ The Sinatra integration traces requests and template rendering.
455
729
 
456
- require 'ddtrace'
730
+ To start using the tracing client, make sure you import ``ddtrace`` and ``ddtrace/contrib/sinatra/tracer`` after
731
+ either ``sinatra`` or ``sinatra/base``:
457
732
 
458
- class MyJob
459
- def self.perform(*args)
460
- # do_something
461
- end
462
- end
733
+ ```ruby
734
+ require 'sinatra'
735
+ require 'ddtrace'
736
+ require 'ddtrace/contrib/sinatra/tracer'
463
737
 
464
- Datadog.configure do |c|
465
- c.use :resque, options
466
- end
738
+ Datadog.configure do |c|
739
+ c.use :sinatra, options
740
+ end
741
+
742
+ get '/' do
743
+ 'Hello world!'
744
+ end
745
+ ```
467
746
 
468
747
  Where `options` is an optional `Hash` that accepts the following parameters:
469
748
 
470
749
  | Key | Description | Default |
471
750
  | --- | --- | --- |
472
- | ``service_name`` | Service name used for `resque` instrumentation | resque |
473
- | ``workers`` | An array including all worker classes you want to trace (eg ``[MyJob]``) | ``[]`` |
751
+ | ``service_name`` | Service name used for `sinatra` instrumentation | sinatra |
752
+ | ``resource_script_names`` | Prepend resource names with script name | ``false`` |
753
+ | ``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` |
754
+ | ``tracer`` | A ``Datadog::Tracer`` instance used to instrument the application. Usually you don't need to set that. | ``Datadog.tracer`` |
474
755
 
475
- ### SuckerPunch
756
+ ### Sucker Punch
476
757
 
477
758
  The `sucker_punch` integration traces all scheduled jobs:
478
759
 
479
- require 'ddtrace'
760
+ ```ruby
761
+ require 'ddtrace'
480
762
 
481
- Datadog.configure do |c|
482
- c.use :sucker_punch, options
483
- end
763
+ Datadog.configure do |c|
764
+ c.use :sucker_punch, options
765
+ end
484
766
 
485
- # the execution of this job is traced
486
- LogJob.perform_async('login')
767
+ # the execution of this job is traced
768
+ LogJob.perform_async('login')
769
+ ```
487
770
 
488
771
  Where `options` is an optional `Hash` that accepts the following parameters:
489
772
 
@@ -491,113 +774,78 @@ Where `options` is an optional `Hash` that accepts the following parameters:
491
774
  | --- | --- | --- |
492
775
  | ``service_name`` | Service name used for `sucker_punch` instrumentation | sucker_punch |
493
776
 
494
- ## Advanced usage
777
+ ## Advanced configuration
495
778
 
496
- ### Configure the tracer
779
+ ### Tracer settings
497
780
 
498
781
  To change the default behavior of the Datadog tracer, you can provide custom options inside the `Datadog.configure` block as in:
499
782
 
500
- # config/initializers/datadog-tracer.rb
783
+ ```ruby
784
+ # config/initializers/datadog-tracer.rb
501
785
 
502
- Datadog.configure do |c|
503
- c.tracer option_name: option_value, ...
504
- end
786
+ Datadog.configure do |c|
787
+ c.tracer option_name: option_value, ...
788
+ end
789
+ ```
505
790
 
506
791
  Available options are:
507
792
 
508
- * ``enabled``: defines if the ``tracer`` is enabled or not. If set to ``false`` the code could be still instrumented
793
+ - ``enabled``: defines if the ``tracer`` is enabled or not. If set to ``false`` the code could be still instrumented
509
794
  because of other settings, but no spans are sent to the local trace agent.
510
- * ``debug``: set to true to enable debug logging.
511
- * ``hostname``: set the hostname of the trace agent.
512
- * ``port``: set the port the trace agent is listening on.
513
- * ``env``: set the environment. Rails users may set it to ``Rails.env`` to use their application settings.
514
- * ``tags``: set global tags that should be applied to all spans. Defaults to an empty hash
515
- * ``log``: defines a custom logger.
516
-
517
- #### Using a custom logger
518
-
519
- By default, all logs are processed by the default Ruby logger.
520
- Typically, when using Rails, you should see the messages in your application log file.
521
- Datadog client log messages are marked with ``[ddtrace]`` so you should be able
522
- to isolate them from other messages.
795
+ - ``debug``: set to true to enable debug logging.
796
+ - ``hostname``: set the hostname of the trace agent.
797
+ - ``port``: set the port the trace agent is listening on.
798
+ - ``env``: set the environment. Rails users may set it to ``Rails.env`` to use their application settings.
799
+ - ``tags``: set global tags that should be applied to all spans. Defaults to an empty hash
800
+ - ``log``: defines a custom logger.
801
+ - ``partial_flush``: set to ``true`` to enable partial trace flushing (for long running traces.) Disabled by default. *Experimental.*
523
802
 
524
- Additionally, it is possible to override the default logger and replace it by a
525
- custom one. This is done using the ``log`` attribute of the tracer.
803
+ #### Custom logging
526
804
 
527
- f = File.new("my-custom.log", "w+") # Log messages should go there
528
- Datadog.configure do |c|
529
- c.tracer log: Logger.new(f) # Overriding the default tracer
530
- end
805
+ By default, all logs are processed by the default Ruby logger. When using Rails, you should see the messages in your application log file.
531
806
 
532
- Datadog::Tracer.log.info { "this is typically called by tracing code" }
807
+ Datadog client log messages are marked with ``[ddtrace]`` so you should be able to isolate them from other messages.
533
808
 
534
- ### Manual Instrumentation
809
+ Additionally, it is possible to override the default logger and replace it by a custom one. This is done using the ``log`` attribute of the tracer.
535
810
 
536
- If you aren't using a supported framework instrumentation, you may want to to manually instrument your code.
537
- Adding tracing to your code is very simple. As an example, let’s imagine we have a web server and we want
538
- to trace requests to the home page:
811
+ ```ruby
812
+ f = File.new("my-custom.log", "w+") # Log messages should go there
813
+ Datadog.configure do |c|
814
+ c.tracer log: Logger.new(f) # Overriding the default tracer
815
+ end
539
816
 
540
- require 'ddtrace'
541
- require 'sinatra'
542
- require 'active_record'
543
-
544
- # a generic tracer that you can use across your application
545
- tracer = Datadog.tracer
546
-
547
- get '/' do
548
- tracer.trace('web.request') do |span|
549
- # set some span metadata
550
- span.service = 'my-web-site'
551
- span.resource = '/'
552
-
553
- # trace the activerecord call
554
- tracer.trace('posts.fetch') do
555
- @posts = Posts.order(created_at: :desc).limit(10)
556
- end
557
-
558
- # add some attributes and metrics
559
- span.set_tag('http.method', request.request_method)
560
- span.set_tag('posts.count', @posts.length)
561
-
562
- # trace the template rendering
563
- tracer.trace('template.render') do
564
- erb :index
565
- end
566
- end
567
- end
817
+ Datadog::Tracer.log.info { "this is typically called by tracing code" }
818
+ ```
568
819
 
569
820
  ### Environment and tags
570
821
 
571
- By default, the trace agent (not this library, but the program running in
572
- the background collecting data from various clients) uses the tags
573
- set in the agent config file, see our
574
- [environments tutorial](https://app.datadoghq.com/apm/docs/tutorials/environments) for details.
822
+ By default, the trace agent (not this library, but the program running in the background collecting data from various clients) uses the tags set in the agent config file, see our [environments tutorial](https://app.datadoghq.com/apm/docs/tutorials/environments) for details.
575
823
 
576
824
  These values can be overridden at the tracer level:
577
825
 
578
- Datadog.configure do |c|
579
- c.tracer tags: { 'env' => 'prod' }
580
- end
826
+ ```ruby
827
+ Datadog.configure do |c|
828
+ c.tracer tags: { 'env' => 'prod' }
829
+ end
830
+ ```
581
831
 
582
- This enables you to set this value on a per tracer basis, so you can have
583
- for example several applications reporting for different environments on the same host.
832
+ This enables you to set this value on a per tracer basis, so you can have for example several applications reporting for different environments on the same host.
584
833
 
585
- Ultimately, tags can be set per span, but `env` should typically be the same
586
- for all spans belonging to a given trace.
834
+ Ultimately, tags can be set per span, but `env` should typically be the same for all spans belonging to a given trace.
587
835
 
588
836
  ### Sampling
589
837
 
590
- `ddtrace` can perform trace sampling. While the trace agent already samples
591
- traces to reduce bandwidth usage, client sampling reduces performance
592
- overhead.
838
+ `ddtrace` can perform trace sampling. While the trace agent already samples traces to reduce bandwidth usage, client sampling reduces performance overhead.
593
839
 
594
840
  `Datadog::RateSampler` samples a ratio of the traces. For example:
595
841
 
596
- # Sample rate is between 0 (nothing sampled) to 1 (everything sampled).
597
- sampler = Datadog::RateSampler.new(0.5) # sample 50% of the traces
598
- Datadog.configure do |c|
599
- c.tracer sampler: sampler
600
- end
842
+ ```ruby
843
+ # Sample rate is between 0 (nothing sampled) to 1 (everything sampled).
844
+ sampler = Datadog::RateSampler.new(0.5) # sample 50% of the traces
845
+ Datadog.configure do |c|
846
+ c.tracer sampler: sampler
847
+ end
848
+ ```
601
849
 
602
850
  #### Priority sampling
603
851
 
@@ -605,12 +853,12 @@ Priority sampling consists in deciding if a trace will be kept by using a priori
605
853
 
606
854
  The sampler can set the priority to the following values:
607
855
 
608
- * `Datadog::Ext::Priority::AUTO_REJECT`: the sampler automatically decided to reject the trace.
609
- * `Datadog::Ext::Priority::AUTO_KEEP`: the sampler automatically decided to keep the trace.
856
+ - `Datadog::Ext::Priority::AUTO_REJECT`: the sampler automatically decided to reject the trace.
857
+ - `Datadog::Ext::Priority::AUTO_KEEP`: the sampler automatically decided to keep the trace.
610
858
 
611
859
  For now, priority sampling is disabled by default. Enabling it ensures that your sampled distributed traces will be complete. To enable the priority sampling:
612
860
 
613
- ```rb
861
+ ```ruby
614
862
  Datadog.configure do |c|
615
863
  c.tracer priority_sampling: true
616
864
  end
@@ -620,19 +868,14 @@ Once enabled, the sampler will automatically assign a priority of 0 or 1 to trac
620
868
 
621
869
  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:
622
870
 
623
- * `Datadog::Ext::Priority::USER_REJECT`: the user asked to reject the trace.
624
- * `Datadog::Ext::Priority::USER_KEEP`: the user asked to keep the trace.
871
+ - `Datadog::Ext::Priority::USER_REJECT`: the user asked to reject the trace.
872
+ - `Datadog::Ext::Priority::USER_KEEP`: the user asked to keep the trace.
625
873
 
626
- When not using [distributed tracing](#Distributed_Tracing), you may change the priority at any time,
627
- as long as the trace is not finished yet.
628
- But it has to be done before any context propagation (fork, RPC calls) to be effective in a distributed context.
629
- Changing the priority after context has been propagated causes different parts of a distributed trace
630
- to use different priorities. Some parts might be kept, some parts might be rejected,
631
- and this can cause the trace to be partially stored and remain incomplete.
874
+ When not using [distributed tracing](#distributed-tracing), you may change the priority at any time, as long as the trace is not finished yet. But it has to be done before any context propagation (fork, RPC calls) to be effective in a distributed context. Changing the priority after context has been propagated causes different parts of a distributed trace to use different priorities. Some parts might be kept, some parts might be rejected, and this can cause the trace to be partially stored and remain incomplete.
632
875
 
633
876
  If you change the priority, we recommend you do it as soon as possible, when the root span has just been created.
634
877
 
635
- ```rb
878
+ ```ruby
636
879
  # Indicate to reject the trace
637
880
  span.context.sampling_priority = Datadog::Ext::Priority::USER_REJECT
638
881
 
@@ -644,14 +887,16 @@ span.context.sampling_priority = Datadog::Ext::Priority::USER_KEEP
644
887
 
645
888
  To trace requests across hosts, the spans on the secondary hosts must be linked together by setting ``trace_id`` and ``parent_id``:
646
889
 
647
- def request_on_secondary_host(parent_trace_id, parent_span_id)
648
- tracer.trace('web.request') do |span|
649
- span.parent_id = parent_span_id
650
- span.trace_id = parent_trace_id
890
+ ```ruby
891
+ def request_on_secondary_host(parent_trace_id, parent_span_id)
892
+ tracer.trace('web.request') do |span|
893
+ span.parent_id = parent_span_id
894
+ span.trace_id = parent_trace_id
651
895
 
652
- # perform user code
653
- end
896
+ # perform user code
654
897
  end
898
+ end
899
+ ```
655
900
 
656
901
  Users can pass along the ``parent_trace_id`` and ``parent_span_id`` via whatever method best matches the RPC framework.
657
902
 
@@ -659,103 +904,109 @@ Below is an example using Net/HTTP and Sinatra, where we bypass the integrations
659
904
 
660
905
  On the client:
661
906
 
662
- require 'net/http'
663
- require 'ddtrace'
907
+ ```ruby
908
+ require 'net/http'
909
+ require 'ddtrace'
664
910
 
665
- uri = URI('http://localhost:4567/')
911
+ uri = URI('http://localhost:4567/')
666
912
 
667
- Datadog.tracer.trace('web.call') do |span|
668
- req = Net::HTTP::Get.new(uri)
669
- req['x-datadog-trace-id'] = span.trace_id.to_s
670
- req['x-datadog-parent-id'] = span.span_id.to_s
913
+ Datadog.tracer.trace('web.call') do |span|
914
+ req = Net::HTTP::Get.new(uri)
915
+ req['x-datadog-trace-id'] = span.trace_id.to_s
916
+ req['x-datadog-parent-id'] = span.span_id.to_s
671
917
 
672
- response = Net::HTTP.start(uri.hostname, uri.port) do |http|
673
- http.request(req)
674
- end
918
+ response = Net::HTTP.start(uri.hostname, uri.port) do |http|
919
+ http.request(req)
920
+ end
675
921
 
676
- puts response.body
677
- end
922
+ puts response.body
923
+ end
924
+ ```
678
925
 
679
926
  On the server:
680
927
 
681
- require 'sinatra'
682
- require 'ddtrace'
928
+ ```ruby
929
+ require 'sinatra'
930
+ require 'ddtrace'
683
931
 
684
- get '/' do
685
- parent_trace_id = request.env['HTTP_X_DATADOG_TRACE_ID']
686
- parent_span_id = request.env['HTTP_X_DATADOG_PARENT_ID']
932
+ get '/' do
933
+ parent_trace_id = request.env['HTTP_X_DATADOG_TRACE_ID']
934
+ parent_span_id = request.env['HTTP_X_DATADOG_PARENT_ID']
687
935
 
688
- Datadog.tracer.trace('web.work') do |span|
689
- if parent_trace_id && parent_span_id
690
- span.trace_id = parent_trace_id.to_i
691
- span.parent_id = parent_span_id.to_i
692
- end
936
+ Datadog.tracer.trace('web.work') do |span|
937
+ if parent_trace_id && parent_span_id
938
+ span.trace_id = parent_trace_id.to_i
939
+ span.parent_id = parent_span_id.to_i
940
+ end
693
941
 
694
- 'Hello world!'
695
- end
696
- end
942
+ 'Hello world!'
943
+ end
944
+ end
945
+ ```
697
946
 
698
- [Rack](#Rack) and [Net/HTTP](#Net_HTTP) have experimental support for this, they
699
- can send and receive these headers automatically and tie spans together automatically,
700
- provided you pass a ``:distributed_tracing`` option set to ``true``.
947
+ [Rack](#rack) and [Net/HTTP](#nethttp) have experimental support for this, they can send and receive these headers automatically and tie spans together automatically, provided you pass a ``:distributed_tracing`` option set to ``true``.
701
948
 
702
- This is disabled by default.
949
+ Distributed tracing is disabled by default.
703
950
 
704
951
  ### Processing Pipeline
705
952
 
706
- Sometimes it might be interesting to intercept `Span` objects before they get
707
- sent upstream. To achieve that, you can hook custom *processors* into the
708
- pipeline using the method `Datadog::Pipeline.before_flush`:
953
+ Some applications might require that traces be altered or filtered out before they are sent upstream. The processing pipeline allows users to create *processors* to define such behavior.
709
954
 
710
- Datadog::Pipeline.before_flush(
711
- # filter the Span if the given block evaluates true
712
- Datadog::Pipeline::SpanFilter.new { |span| span.resource =~ /PingController/ },
713
- Datadog::Pipeline::SpanFilter.new { |span| span.get_tag('host') == 'localhost' }
955
+ Processors can be any object that responds to `#call` accepting `trace` as an argument (which is an `Array` of `Datadog::Span`s.)
714
956
 
715
- # alter the Span updating fields or tags
716
- Datadog::Pipeline::SpanProcessor.new { |span| span.resource.gsub!(/password=.*/, '') }
717
- )
957
+ For example:
718
958
 
719
- For more information, please refer to this [link](https://github.com/DataDog/dd-trace-rb/pull/214).
720
-
721
- ### Supported Versions
722
-
723
- #### Ruby interpreters
724
-
725
- The Datadog Trace Client has been tested with the following Ruby versions:
959
+ ```ruby
960
+ lambda_processor = ->(trace) do
961
+ # Processing logic...
962
+ trace
963
+ end
726
964
 
727
- * Ruby MRI 1.9.1 (experimental)
728
- * Ruby MRI 1.9.3
729
- * Ruby MRI 2.0
730
- * Ruby MRI 2.1
731
- * Ruby MRI 2.2
732
- * Ruby MRI 2.3
733
- * Ruby MRI 2.4
734
- * JRuby 9.1.5 (experimental)
965
+ class MyCustomProcessor
966
+ def call(trace)
967
+ # Processing logic...
968
+ trace
969
+ end
970
+ end
971
+ custom_processor = MyFancyProcessor.new
972
+ ```
735
973
 
736
- Other versions aren't yet officially supported.
974
+ `#call` blocks of processors *must* return the `trace` object; this return value will be passed to the next processor in the pipeline.
737
975
 
738
- #### Ruby on Rails versions
976
+ These processors must then be added to the pipeline via `Datadog::Pipeline.before_flush`:
739
977
 
740
- The supported versions are:
978
+ ```ruby
979
+ Datadog::Pipeline.before_flush(lambda_processor, custom_processor)
980
+ ```
741
981
 
742
- * Rails 3.2 (MRI interpreter, JRuby is experimental)
743
- * Rails 4.2 (MRI interpreter, JRuby is experimental)
744
- * Rails 5.0 (MRI interpreter)
982
+ You can also define processors using the short-hand block syntax for `Datadog::Pipeline.before_flush`:
745
983
 
746
- The currently supported web server are:
747
- * Puma 2.16+ and 3.6+
748
- * Unicorn 4.8+ and 5.1+
749
- * Passenger 5.0+
984
+ ```ruby
985
+ Datadog::Pipeline.before_flush do |trace|
986
+ trace.delete_if { |span| span.name =~ /forbidden/ }
987
+ end
988
+ ```
750
989
 
751
- #### Sinatra versions
990
+ #### Filtering
752
991
 
753
- Currently we are supporting Sinatra >= 1.4.0.
992
+ You can use the `Datadog::Pipeline::SpanFilter` processor to remove spans, when the block evaluates as truthy:
754
993
 
755
- #### Sidekiq versions
994
+ ```ruby
995
+ Datadog::Pipeline.before_flush(
996
+ # Remove spans that match a particular resource
997
+ Datadog::Pipeline::SpanFilter.new { |span| span.resource =~ /PingController/ },
998
+ # Remove spans that are trafficked to localhost
999
+ Datadog::Pipeline::SpanFilter.new { |span| span.get_tag('host') == 'localhost' }
1000
+ )
1001
+ ```
756
1002
 
757
- Currently we are supporting Sidekiq >= 4.0.0.
1003
+ #### Processing
758
1004
 
759
- ### Terminology
1005
+ You can use the `Datadog::Pipeline::SpanProcessor` processor to modify spans:
760
1006
 
761
- If you need more context about the terminology used in the APM, take a look at the [official documentation](https://docs.datadoghq.com/tracing/terminology/).
1007
+ ```ruby
1008
+ Datadog::Pipeline.before_flush(
1009
+ # Strip matching text from the resource field
1010
+ Datadog::Pipeline::SpanProcessor.new { |span| span.resource.gsub!(/password=.*/, '') }
1011
+ )
1012
+ ```