ddtrace 0.11.4 → 0.12.0.beta1

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: 31d6da2597a1d5479adcaf45268088c482e72d30
4
- data.tar.gz: e36b2dcb51d0f780ab15f365c9e5ad3989509e81
3
+ metadata.gz: c35c1da69a010fb6a52f5caf2fe6e4491a9692ed
4
+ data.tar.gz: 863ec1e1fef7a32862e4ed480ec4e2e8cb987ab2
5
5
  SHA512:
6
- metadata.gz: 91cae89a7b193e57861cbb78bc456bae57c1edfe5d3e65869245be105e826fabe604477c34f21c95846f1173b3df80de4889da780b91854c9dd69589766eb1a7
7
- data.tar.gz: 2323a8f95dd92228c607f92550dccf30268369444f2595dcb52673da74cb4a548c363ab46b631a81ddd3d812f2ed0e8f4abafe91d63fb90caca64ea91cde55ef
6
+ metadata.gz: 5bd026479bc9e2e741bc57766a9cccf19d3139ab54fa1a771f31db70dd43f971a57352c25d894f23f1f86a2a32225b37655b5092eb72c2972b812b4388eedd82
7
+ data.tar.gz: 443279a5c424456e89b085d6b7271caa99fb0ba22ffb5d333306d9d3bbeb35d1aea183f6bc3fb26bf4820d2df50965f97d877bbbab1ad28aa0510a0e54ed95f4
data/Appraisals CHANGED
@@ -57,7 +57,7 @@ if RUBY_VERSION < '2.4.0' && RUBY_PLATFORM != 'java'
57
57
  if RUBY_VERSION >= '2.1.10'
58
58
  appraise 'rails4-mysql2' do
59
59
  gem 'rails', '4.2.7.1'
60
- gem 'mysql2', '< 0.5', platform: :ruby
60
+ gem 'mysql2', platform: :ruby
61
61
  gem 'activerecord-jdbcmysql-adapter', platform: :jruby
62
62
  end
63
63
 
@@ -79,7 +79,7 @@ if RUBY_VERSION < '2.4.0' && RUBY_PLATFORM != 'java'
79
79
  if RUBY_VERSION >= '2.2.2'
80
80
  appraise 'rails5-mysql2' do
81
81
  gem 'rails', '5.0.1'
82
- gem 'mysql2', '< 0.5', platform: :ruby
82
+ gem 'mysql2', platform: :ruby
83
83
  end
84
84
 
85
85
  appraise 'rails5-postgres' do
@@ -115,6 +115,7 @@ if RUBY_VERSION >= '2.2.2' && RUBY_PLATFORM != 'java'
115
115
  appraise 'contrib' do
116
116
  gem 'elasticsearch-transport'
117
117
  gem 'mongo', '< 2.5'
118
+ gem 'graphql'
118
119
  gem 'grape'
119
120
  gem 'rack'
120
121
  gem 'rack-test'
@@ -122,14 +123,14 @@ if RUBY_VERSION >= '2.2.2' && RUBY_PLATFORM != 'java'
122
123
  gem 'hiredis'
123
124
  gem 'sinatra'
124
125
  gem 'sqlite3'
125
- gem 'activerecord', '< 5.1.5'
126
+ gem 'activerecord'
126
127
  gem 'sidekiq'
127
128
  gem 'aws-sdk'
128
129
  gem 'sucker_punch'
129
130
  gem 'dalli'
130
131
  gem 'resque', '< 2.0'
131
132
  gem 'racecar', '>= 0.3.5'
132
- gem 'mysql2', '< 0.5', platform: :ruby
133
+ gem 'mysql2', platform: :ruby
133
134
  end
134
135
  else
135
136
  appraise 'contrib-old' do
data/README.md CHANGED
@@ -14,23 +14,21 @@ You can find the latest documentation on [rubydoc.info][docs]
14
14
 
15
15
  Install the Ruby client with the ``gem`` command:
16
16
 
17
- ```
18
- gem install ddtrace
19
- ```
17
+ gem install ddtrace
20
18
 
21
19
  If you're using ``Bundler``, just update your ``Gemfile`` as follows:
22
20
 
23
21
  ```ruby
24
- source 'https://rubygems.org'
22
+ source 'https://rubygems.org'
25
23
 
26
- # tracing gem
27
- gem 'ddtrace'
24
+ # tracing gem
25
+ gem 'ddtrace'
28
26
  ```
29
27
 
30
28
  To use a development/preview version, use:
31
29
 
32
30
  ```ruby
33
- gem 'ddtrace', :github => 'DataDog/dd-trace-rb', :branch => 'me/my-feature-branch'
31
+ gem 'ddtrace', :github => 'DataDog/dd-trace-rb', :branch => 'me/my-feature-branch'
34
32
  ```
35
33
 
36
34
  ### Quickstart (manual instrumentation)
@@ -40,31 +38,31 @@ Adding tracing to your code is very simple. As an example, let’s imagine we ha
40
38
  to trace requests to the home page:
41
39
 
42
40
  ```ruby
43
- require 'ddtrace'
44
- require 'sinatra'
45
- require 'active_record'
46
-
47
- # a generic tracer that you can use across your application
48
- tracer = Datadog.tracer
49
-
50
- get '/' do
51
- tracer.trace('web.request') do |span|
52
- # set some span metadata
53
- span.service = 'my-web-site'
54
- span.resource = '/'
55
- span.set_tag('http.method', request.request_method)
56
-
57
- # trace the activerecord call
58
- tracer.trace('posts.fetch') do
59
- @posts = Posts.order(created_at: :desc).limit(10)
60
- end
61
-
62
- # trace the template rendering
63
- tracer.trace('template.render') do
64
- erb :index
41
+ require 'ddtrace'
42
+ require 'sinatra'
43
+ require 'active_record'
44
+
45
+ # a generic tracer that you can use across your application
46
+ tracer = Datadog.tracer
47
+
48
+ get '/' do
49
+ tracer.trace('web.request') do |span|
50
+ # set some span metadata
51
+ span.service = 'my-web-site'
52
+ span.resource = '/'
53
+ span.set_tag('http.method', request.request_method)
54
+
55
+ # trace the activerecord call
56
+ tracer.trace('posts.fetch') do
57
+ @posts = Posts.order(created_at: :desc).limit(10)
58
+ end
59
+
60
+ # trace the template rendering
61
+ tracer.trace('template.render') do
62
+ erb :index
63
+ end
64
+ end
65
65
  end
66
- end
67
- end
68
66
  ```
69
67
 
70
68
  ### Quickstart (integration)
@@ -73,20 +71,20 @@ Instead of doing the above manually, whenever an integration is available,
73
71
  you can activate it. The example above would become:
74
72
 
75
73
  ```ruby
76
- require 'ddtrace'
77
- require 'sinatra'
78
- require 'active_record'
79
-
80
- Datadog.configure do |c|
81
- c.use :sinatra
82
- c.use :active_record
83
- end
84
-
85
- # now write your code naturally, it's traced automatically
86
- get '/' do
87
- @posts = Posts.order(created_at: :desc).limit(10)
88
- erb :index
89
- end
74
+ require 'ddtrace'
75
+ require 'sinatra'
76
+ require 'active_record'
77
+
78
+ Datadog.configure do |c|
79
+ c.use :sinatra
80
+ c.use :active_record
81
+ end
82
+
83
+ # now write your code naturally, it's traced automatically
84
+ get '/' do
85
+ @posts = Posts.order(created_at: :desc).limit(10)
86
+ erb :index
87
+ end
90
88
  ```
91
89
 
92
90
  This will automatically trace any app inherited from `Sinatra::Application`.
@@ -94,26 +92,14 @@ To trace apps inherited from `Sinatra::Base`, you should manually register
94
92
  the tracer inside your class.
95
93
 
96
94
  ```ruby
97
- require "ddtrace"
98
- require "ddtrace/contrib/sinatra/tracer"
99
-
100
- class App < Sinatra::Base
101
- register Datadog::Contrib::Sinatra::Tracer
102
- end
103
- ```
104
-
105
- To configure the Datadog Tracer, you can define the `configure` block as follows:
95
+ require "ddtrace"
96
+ require "ddtrace/contrib/sinatra/tracer"
106
97
 
107
- ```ruby
108
- Datadog.configure do |c|
109
- c.tracer enabled: false, hostname: 'trace-agent.local'
110
- # [...]
111
- end
98
+ class App < Sinatra::Base
99
+ register Datadog::Contrib::Sinatra::Tracer
100
+ end
112
101
  ```
113
102
 
114
- For a list of available options, check the [Tracer documentation](http://gems.datadoghq.com/trace/docs/#Configure_the_tracer).
115
-
116
-
117
103
  To know if a given framework or lib is supported by our client,
118
104
  please consult our [integrations][contrib] list.
119
105
 
data/Rakefile CHANGED
@@ -48,6 +48,7 @@ namespace :spec do
48
48
  :rack,
49
49
  :faraday,
50
50
  :grape,
51
+ :graphql,
51
52
  :aws,
52
53
  :sucker_punch,
53
54
  :mongodb,
@@ -108,18 +109,19 @@ namespace :test do
108
109
  end
109
110
 
110
111
  [
112
+ :aws,
111
113
  :elasticsearch,
112
- :http,
113
- :redis,
114
- :sinatra,
115
- :sidekiq,
116
- :rack,
117
114
  :faraday,
118
115
  :grape,
119
- :aws,
120
- :sucker_punch,
116
+ :http,
121
117
  :mongodb,
122
- :resque
118
+ :resque,
119
+ :rack,
120
+ :redis,
121
+ :resque,
122
+ :sidekiq,
123
+ :sinatra,
124
+ :sucker_punch
123
125
  ].each do |contrib|
124
126
  Rake::TestTask.new(contrib) do |t|
125
127
  t.libs << %w[test lib]
@@ -230,6 +232,7 @@ task :ci do
230
232
  # RSpec
231
233
  sh 'rvm $MRI_VERSIONS --verbose do appraisal contrib rake spec:active_record'
232
234
  sh 'rvm $MRI_VERSIONS --verbose do appraisal contrib rake spec:dalli'
235
+ sh 'rvm $MRI_VERSIONS --verbose do appraisal contrib rake spec:graphql'
233
236
  sh 'rvm $MRI_VERSIONS --verbose do appraisal contrib rake spec:racecar'
234
237
  sh 'rvm $MRI_OLD_VERSIONS --verbose do appraisal contrib-old rake spec:dalli'
235
238
  sh 'rvm $MRI_OLD_VERSIONS --verbose do appraisal contrib-old rake spec:active_record'
@@ -258,13 +261,6 @@ task :ci do
258
261
  sh 'rvm $RAILS5_VERSIONS --verbose do appraisal rails5-postgres rake test:railsdisableenv'
259
262
  # RSpec
260
263
  sh 'rvm $LAST_STABLE --verbose do rake benchmark'
261
- sh 'rvm $RAILS3_VERSIONS --verbose do appraisal rails30-postgres rake spec:rails'
262
- sh 'rvm $RAILS3_VERSIONS --verbose do appraisal rails32-mysql2 rake spec:rails'
263
- sh 'rvm $RAILS3_VERSIONS --verbose do appraisal rails32-postgres rake spec:rails'
264
- sh 'rvm $RAILS4_VERSIONS --verbose do appraisal rails4-mysql2 rake spec:rails'
265
- sh 'rvm $RAILS4_VERSIONS --verbose do appraisal rails4-postgres rake spec:rails'
266
- sh 'rvm $RAILS5_VERSIONS --verbose do appraisal rails5-mysql2 rake spec:rails'
267
- sh 'rvm $RAILS5_VERSIONS --verbose do appraisal rails5-postgres rake spec:rails'
268
264
  else
269
265
  puts 'Too many workers than parallel tasks'
270
266
  end
@@ -41,6 +41,7 @@ For further details and options, check our integrations list.
41
41
  * [Ruby on Rails](#Ruby_on_Rails)
42
42
  * [Sinatra](#Sinatra)
43
43
  * [Rack](#Rack)
44
+ * [GraphQL](#GraphQL)
44
45
  * [Grape](#Grape)
45
46
  * [Active Record](#Active_Record)
46
47
  * [Elastic Search](#Elastic_Search)
@@ -144,6 +145,57 @@ Where `options` is an optional `Hash` that accepts the following parameters:
144
145
 
145
146
  ## Other libraries
146
147
 
148
+ ### GraphQL
149
+
150
+ *Version 1.7.9+ supported*
151
+
152
+ The GraphQL integration activates instrumentation for GraphQL queries. To activate your integration, use the ``Datadog.configure`` method:
153
+
154
+ # Inside Rails initializer or equivalent
155
+ Datadog.configure do |c|
156
+ c.use :graphql,
157
+ service_name: 'graphql',
158
+ schemas: [YourSchema]
159
+ end
160
+
161
+ # Then run a GraphQL query
162
+ YourSchema.execute(query, variables: {}, context: {}, operation_name: nil)
163
+
164
+ The `use :graphql` method accepts the following parameters:
165
+
166
+ | Key | Description | Default |
167
+ | --- | --- | --- |
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`` |
171
+
172
+ ##### Manually configuring GraphQL schemas
173
+
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):
176
+
177
+ ```
178
+ YourSchema = GraphQL::Schema.define do
179
+ use(
180
+ GraphQL::Tracing::DataDogTracing,
181
+ service: 'graphql'
182
+ )
183
+ end
184
+ ```
185
+
186
+ Or you can modify an already defined schema:
187
+
188
+ ```
189
+ YourSchema.define do
190
+ use(
191
+ GraphQL::Tracing::DataDogTracing,
192
+ service: 'graphql'
193
+ )
194
+ end
195
+ ```
196
+
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.
198
+
147
199
  ### Grape
148
200
 
149
201
  The Grape integration adds the instrumentation to Grape endpoints and filters. This integration can work side by side
@@ -196,7 +248,8 @@ Where `options` is an optional `Hash` that accepts the following parameters:
196
248
 
197
249
  | Key | Description | Default |
198
250
  | --- | --- | --- |
199
- | ``service_name`` | Service name used for `active_record` instrumentation | active_record |
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`` |
200
253
 
201
254
  ### Elastic Search
202
255
 
@@ -657,7 +710,7 @@ pipeline using the method `Datadog::Pipeline.before_flush`:
657
710
  Datadog::Pipeline.before_flush(
658
711
  # filter the Span if the given block evaluates true
659
712
  Datadog::Pipeline::SpanFilter.new { |span| span.resource =~ /PingController/ },
660
- Datadog::Pipeline::SpanFilter.new { |span| span.get_tag('host') == 'localhost' },
713
+ Datadog::Pipeline::SpanFilter.new { |span| span.get_tag('host') == 'localhost' }
661
714
 
662
715
  # alter the Span updating fields or tags
663
716
  Datadog::Pipeline::SpanProcessor.new { |span| span.resource.gsub!(/password=.*/, '') }
@@ -5,6 +5,7 @@ source "https://rubygems.org"
5
5
  gem "pry-nav", git: "https://github.com/nixme/pry-nav.git", branch: "master"
6
6
  gem "elasticsearch-transport"
7
7
  gem "mongo", "< 2.5"
8
+ gem "graphql"
8
9
  gem "grape"
9
10
  gem "rack"
10
11
  gem "rack-test"
@@ -12,13 +13,13 @@ gem "redis", "< 4.0"
12
13
  gem "hiredis"
13
14
  gem "sinatra"
14
15
  gem "sqlite3"
15
- gem "activerecord", "< 5.1.5"
16
+ gem "activerecord"
16
17
  gem "sidekiq"
17
18
  gem "aws-sdk"
18
19
  gem "sucker_punch"
19
20
  gem "dalli"
20
21
  gem "resque", "< 2.0"
21
22
  gem "racecar", ">= 0.3.5"
22
- gem "mysql2", "< 0.5", platform: :ruby
23
+ gem "mysql2", platform: :ruby
23
24
 
24
25
  gemspec path: "../"
@@ -4,7 +4,7 @@ source "https://rubygems.org"
4
4
 
5
5
  gem "pry-nav", git: "https://github.com/nixme/pry-nav.git", branch: "master"
6
6
  gem "rails", "4.2.7.1"
7
- gem "mysql2", "< 0.5", platform: :ruby
7
+ gem "mysql2", platform: :ruby
8
8
  gem "activerecord-jdbcmysql-adapter", platform: :jruby
9
9
 
10
10
  gemspec path: "../"
@@ -4,6 +4,6 @@ source "https://rubygems.org"
4
4
 
5
5
  gem "pry-nav", git: "https://github.com/nixme/pry-nav.git", branch: "master"
6
6
  gem "rails", "5.0.1"
7
- gem "mysql2", "< 0.5", platform: :ruby
7
+ gem "mysql2", platform: :ruby
8
8
 
9
9
  gemspec path: "../"
@@ -59,6 +59,7 @@ require 'ddtrace/contrib/active_record/patcher'
59
59
  require 'ddtrace/contrib/elasticsearch/patcher'
60
60
  require 'ddtrace/contrib/faraday/patcher'
61
61
  require 'ddtrace/contrib/grape/patcher'
62
+ require 'ddtrace/contrib/graphql/patcher'
62
63
  require 'ddtrace/contrib/redis/patcher'
63
64
  require 'ddtrace/contrib/http/patcher'
64
65
  require 'ddtrace/contrib/aws/patcher'
@@ -1,3 +1,6 @@
1
+ require 'ddtrace/ext/sql'
2
+ require 'ddtrace/ext/app_types'
3
+
1
4
  module Datadog
2
5
  module Contrib
3
6
  module ActiveRecord
@@ -5,7 +8,10 @@ module Datadog
5
8
  module Patcher
6
9
  include Base
7
10
  register_as :active_record, auto_patch: false
8
- option :service_name
11
+ option :service_name do |value|
12
+ value.tap { @database_service_name = nil }
13
+ end
14
+ option :orm_service_name
9
15
  option :tracer, default: Datadog.tracer
10
16
 
11
17
  @patched = false
@@ -21,11 +27,8 @@ module Datadog
21
27
  if !@patched && defined?(::ActiveRecord)
22
28
  begin
23
29
  require 'ddtrace/contrib/rails/utils'
24
- require 'ddtrace/ext/sql'
25
- require 'ddtrace/ext/app_types'
26
-
27
- patch_active_record()
28
30
 
31
+ patch_active_record
29
32
  @patched = true
30
33
  rescue StandardError => e
31
34
  Datadog::Tracer.log.error("Unable to apply Active Record integration: #{e}")
@@ -40,25 +43,51 @@ module Datadog
40
43
  ::ActiveSupport::Notifications.subscribe('sql.active_record') do |*args|
41
44
  sql(*args)
42
45
  end
46
+
47
+ if instantiation_tracing_supported?
48
+ # subscribe when the active record instantiates objects
49
+ ::ActiveSupport::Notifications.subscribe('instantiation.active_record') do |*args|
50
+ instantiation(*args)
51
+ end
52
+ end
43
53
  end
44
54
 
45
- def self.database_service
46
- return @database_service if defined?(@database_service)
55
+ def instantiation_tracing_supported?
56
+ Gem.loaded_specs['activerecord'] \
57
+ && Gem.loaded_specs['activerecord'].version >= Gem::Version.new('4.2')
58
+ end
47
59
 
48
- @database_service = get_option(:service_name) || Datadog::Contrib::Rails::Utils.adapter_name
49
- get_option(:tracer).set_service_info(@database_service, 'active_record', Ext::AppTypes::DB)
50
- @database_service
60
+ # NOTE: Resolve this here instead of in the option defaults,
61
+ # because resolving adapter name as a default causes ActiveRecord to connect,
62
+ # which isn't a good idea at initialization time.
63
+ def self.database_service_name
64
+ @database_service_name ||= (get_option(:service_name) || adapter_name).tap do |name|
65
+ get_option(:tracer).set_service_info(name, 'active_record', Ext::AppTypes::DB)
66
+ end
51
67
  end
52
68
 
53
- def self.sql(_name, start, finish, _id, payload)
54
- span_type = Datadog::Ext::SQL::TYPE
55
- connection_config = Datadog::Contrib::Rails::Utils.connection_config(payload[:connection_id])
69
+ def self.adapter_name
70
+ @adapter_name ||= Datadog::Contrib::Rails::Utils.adapter_name
71
+ end
72
+
73
+ def self.database_name
74
+ @database_name ||= Datadog::Contrib::Rails::Utils.database_name
75
+ end
76
+
77
+ def self.adapter_host
78
+ @adapter_host ||= Datadog::Contrib::Rails::Utils.adapter_host
79
+ end
80
+
81
+ def self.adapter_port
82
+ @adapter_port ||= Datadog::Contrib::Rails::Utils.adapter_port
83
+ end
56
84
 
85
+ def self.sql(_name, start, finish, _id, payload)
57
86
  span = get_option(:tracer).trace(
58
- "#{connection_config[:adapter_name]}.query",
87
+ "#{adapter_name}.query",
59
88
  resource: payload.fetch(:sql),
60
- service: database_service,
61
- span_type: span_type
89
+ service: database_service_name,
90
+ span_type: Datadog::Ext::SQL::TYPE
62
91
  )
63
92
 
64
93
  # Find out if the SQL query has been cached in this request. This meta is really
@@ -69,16 +98,39 @@ module Datadog
69
98
  # the span should have the query ONLY in the Resource attribute,
70
99
  # so that the ``sql.query`` tag will be set in the agent with an
71
100
  # obfuscated version
72
- span.span_type = Datadog::Ext::SQL::TYPE
73
- span.set_tag('active_record.db.vendor', connection_config[:adapter_name])
74
- span.set_tag('active_record.db.name', connection_config[:database_name])
101
+ span.set_tag('active_record.db.vendor', adapter_name)
102
+ span.set_tag('active_record.db.name', database_name)
75
103
  span.set_tag('active_record.db.cached', cached) if cached
76
- span.set_tag('out.host', connection_config[:adapter_host])
77
- span.set_tag('out.port', connection_config[:adapter_port])
104
+ span.set_tag('out.host', adapter_host)
105
+ span.set_tag('out.port', adapter_port)
106
+ span.start_time = start
107
+ span.finish(finish)
108
+ rescue StandardError => e
109
+ Datadog::Tracer.log.debug(e.message)
110
+ end
111
+
112
+ def self.instantiation(_name, start, finish, _id, payload)
113
+ span = get_option(:tracer).trace(
114
+ 'active_record.instantiation',
115
+ resource: payload.fetch(:class_name),
116
+ span_type: 'custom'
117
+ )
118
+
119
+ # Inherit service name from parent, if available.
120
+ span.service = if get_option(:orm_service_name)
121
+ get_option(:orm_service_name)
122
+ elsif span.parent
123
+ span.parent.service
124
+ else
125
+ 'active_record'
126
+ end
127
+
128
+ span.set_tag('active_record.instantiation.class_name', payload.fetch(:class_name))
129
+ span.set_tag('active_record.instantiation.record_count', payload.fetch(:record_count))
78
130
  span.start_time = start
79
131
  span.finish(finish)
80
132
  rescue StandardError => e
81
- Datadog::Tracer.log.error(e.message)
133
+ Datadog::Tracer.log.debug(e.message)
82
134
  end
83
135
  end
84
136
  end