signalfx-tracing 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: a420459939e98542547b4e5e7e6c767b004cb711
4
+ data.tar.gz: f688a0ec1e90979c4abdd6b3384d75f6d4146bb5
5
+ SHA512:
6
+ metadata.gz: 191c96d35b8e2ff7eb6b77f734be4a1ebf30a7f6f3daf0e95f7e4e87f3499f56498d63e13e27093c2cb88b4a7e769e9df62709e1f63012329ae53add06ae9dcb
7
+ data.tar.gz: bcff8a6b2a0b9742b104299dfe22e331c32a3f5b38bf68912e6df0239f4277e6264d164cf4331fee241d12284c8c01a3755257b84d4093a5ae853472fd82c393
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source "https://rubygems.org"
2
+
3
+ git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
4
+
5
+ # Specify your gem's dependencies in signalfx-tracing.gemspec
6
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,177 @@
1
+
2
+ Apache License
3
+ Version 2.0, January 2004
4
+ http://www.apache.org/licenses/
5
+
6
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
7
+
8
+ 1. Definitions.
9
+
10
+ "License" shall mean the terms and conditions for use, reproduction,
11
+ and distribution as defined by Sections 1 through 9 of this document.
12
+
13
+ "Licensor" shall mean the copyright owner or entity authorized by
14
+ the copyright owner that is granting the License.
15
+
16
+ "Legal Entity" shall mean the union of the acting entity and all
17
+ other entities that control, are controlled by, or are under common
18
+ control with that entity. For the purposes of this definition,
19
+ "control" means (i) the power, direct or indirect, to cause the
20
+ direction or management of such entity, whether by contract or
21
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
22
+ outstanding shares, or (iii) beneficial ownership of such entity.
23
+
24
+ "You" (or "Your") shall mean an individual or Legal Entity
25
+ exercising permissions granted by this License.
26
+
27
+ "Source" form shall mean the preferred form for making modifications,
28
+ including but not limited to software source code, documentation
29
+ source, and configuration files.
30
+
31
+ "Object" form shall mean any form resulting from mechanical
32
+ transformation or translation of a Source form, including but
33
+ not limited to compiled object code, generated documentation,
34
+ and conversions to other media types.
35
+
36
+ "Work" shall mean the work of authorship, whether in Source or
37
+ Object form, made available under the License, as indicated by a
38
+ copyright notice that is included in or attached to the work
39
+ (an example is provided in the Appendix below).
40
+
41
+ "Derivative Works" shall mean any work, whether in Source or Object
42
+ form, that is based on (or derived from) the Work and for which the
43
+ editorial revisions, annotations, elaborations, or other modifications
44
+ represent, as a whole, an original work of authorship. For the purposes
45
+ of this License, Derivative Works shall not include works that remain
46
+ separable from, or merely link (or bind by name) to the interfaces of,
47
+ the Work and Derivative Works thereof.
48
+
49
+ "Contribution" shall mean any work of authorship, including
50
+ the original version of the Work and any modifications or additions
51
+ to that Work or Derivative Works thereof, that is intentionally
52
+ submitted to Licensor for inclusion in the Work by the copyright owner
53
+ or by an individual or Legal Entity authorized to submit on behalf of
54
+ the copyright owner. For the purposes of this definition, "submitted"
55
+ means any form of electronic, verbal, or written communication sent
56
+ to the Licensor or its representatives, including but not limited to
57
+ communication on electronic mailing lists, source code control systems,
58
+ and issue tracking systems that are managed by, or on behalf of, the
59
+ Licensor for the purpose of discussing and improving the Work, but
60
+ excluding communication that is conspicuously marked or otherwise
61
+ designated in writing by the copyright owner as "Not a Contribution."
62
+
63
+ "Contributor" shall mean Licensor and any individual or Legal Entity
64
+ on behalf of whom a Contribution has been received by Licensor and
65
+ subsequently incorporated within the Work.
66
+
67
+ 2. Grant of Copyright License. Subject to the terms and conditions of
68
+ this License, each Contributor hereby grants to You a perpetual,
69
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
70
+ copyright license to reproduce, prepare Derivative Works of,
71
+ publicly display, publicly perform, sublicense, and distribute the
72
+ Work and such Derivative Works in Source or Object form.
73
+
74
+ 3. Grant of Patent License. Subject to the terms and conditions of
75
+ this License, each Contributor hereby grants to You a perpetual,
76
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
77
+ (except as stated in this section) patent license to make, have made,
78
+ use, offer to sell, sell, import, and otherwise transfer the Work,
79
+ where such license applies only to those patent claims licensable
80
+ by such Contributor that are necessarily infringed by their
81
+ Contribution(s) alone or by combination of their Contribution(s)
82
+ with the Work to which such Contribution(s) was submitted. If You
83
+ institute patent litigation against any entity (including a
84
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
85
+ or a Contribution incorporated within the Work constitutes direct
86
+ or contributory patent infringement, then any patent licenses
87
+ granted to You under this License for that Work shall terminate
88
+ as of the date such litigation is filed.
89
+
90
+ 4. Redistribution. You may reproduce and distribute copies of the
91
+ Work or Derivative Works thereof in any medium, with or without
92
+ modifications, and in Source or Object form, provided that You
93
+ meet the following conditions:
94
+
95
+ (a) You must give any other recipients of the Work or
96
+ Derivative Works a copy of this License; and
97
+
98
+ (b) You must cause any modified files to carry prominent notices
99
+ stating that You changed the files; and
100
+
101
+ (c) You must retain, in the Source form of any Derivative Works
102
+ that You distribute, all copyright, patent, trademark, and
103
+ attribution notices from the Source form of the Work,
104
+ excluding those notices that do not pertain to any part of
105
+ the Derivative Works; and
106
+
107
+ (d) If the Work includes a "NOTICE" text file as part of its
108
+ distribution, then any Derivative Works that You distribute must
109
+ include a readable copy of the attribution notices contained
110
+ within such NOTICE file, excluding those notices that do not
111
+ pertain to any part of the Derivative Works, in at least one
112
+ of the following places: within a NOTICE text file distributed
113
+ as part of the Derivative Works; within the Source form or
114
+ documentation, if provided along with the Derivative Works; or,
115
+ within a display generated by the Derivative Works, if and
116
+ wherever such third-party notices normally appear. The contents
117
+ of the NOTICE file are for informational purposes only and
118
+ do not modify the License. You may add Your own attribution
119
+ notices within Derivative Works that You distribute, alongside
120
+ or as an addendum to the NOTICE text from the Work, provided
121
+ that such additional attribution notices cannot be construed
122
+ as modifying the License.
123
+
124
+ You may add Your own copyright statement to Your modifications and
125
+ may provide additional or different license terms and conditions
126
+ for use, reproduction, or distribution of Your modifications, or
127
+ for any such Derivative Works as a whole, provided Your use,
128
+ reproduction, and distribution of the Work otherwise complies with
129
+ the conditions stated in this License.
130
+
131
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
132
+ any Contribution intentionally submitted for inclusion in the Work
133
+ by You to the Licensor shall be under the terms and conditions of
134
+ this License, without any additional terms or conditions.
135
+ Notwithstanding the above, nothing herein shall supersede or modify
136
+ the terms of any separate license agreement you may have executed
137
+ with Licensor regarding such Contributions.
138
+
139
+ 6. Trademarks. This License does not grant permission to use the trade
140
+ names, trademarks, service marks, or product names of the Licensor,
141
+ except as required for reasonable and customary use in describing the
142
+ origin of the Work and reproducing the content of the NOTICE file.
143
+
144
+ 7. Disclaimer of Warranty. Unless required by applicable law or
145
+ agreed to in writing, Licensor provides the Work (and each
146
+ Contributor provides its Contributions) on an "AS IS" BASIS,
147
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
148
+ implied, including, without limitation, any warranties or conditions
149
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
150
+ PARTICULAR PURPOSE. You are solely responsible for determining the
151
+ appropriateness of using or redistributing the Work and assume any
152
+ risks associated with Your exercise of permissions under this License.
153
+
154
+ 8. Limitation of Liability. In no event and under no legal theory,
155
+ whether in tort (including negligence), contract, or otherwise,
156
+ unless required by applicable law (such as deliberate and grossly
157
+ negligent acts) or agreed to in writing, shall any Contributor be
158
+ liable to You for damages, including any direct, indirect, special,
159
+ incidental, or consequential damages of any character arising as a
160
+ result of this License or out of the use or inability to use the
161
+ Work (including but not limited to damages for loss of goodwill,
162
+ work stoppage, computer failure or malfunction, or any and all
163
+ other commercial damages or losses), even if such Contributor
164
+ has been advised of the possibility of such damages.
165
+
166
+ 9. Accepting Warranty or Additional Liability. While redistributing
167
+ the Work or Derivative Works thereof, You may choose to offer,
168
+ and charge a fee for, acceptance of support, warranty, indemnity,
169
+ or other liability obligations and/or rights consistent with this
170
+ License. However, in accepting such obligations, You may act only
171
+ on Your own behalf and on Your sole responsibility, not on behalf
172
+ of any other Contributor, and only if You agree to indemnify,
173
+ defend, and hold each Contributor harmless for any liability
174
+ incurred by, or claims asserted against, such Contributor by reason
175
+ of your accepting any such warranty or additional liability.
176
+
177
+ END OF TERMS AND CONDITIONS
data/README.md ADDED
@@ -0,0 +1,254 @@
1
+ # Ruby auto-instrumenter
2
+
3
+ ## Usage
4
+
5
+ Configure the instrumentation anywhere in the setup portion of your code or before doing anything
6
+ that needs to be traced.
7
+
8
+ For Rails, this would go in `config/initializer/tracing.rb`.
9
+
10
+ The instrumentation can be done automatically, where the auto-instrumenter will
11
+ check for modules defined in the code and instrument them if available:
12
+
13
+ ```ruby
14
+ SignalFx::Tracing::Instrumenter.configure(auto_instrument:true)
15
+ ```
16
+
17
+ Manual configuration may be desirable when only some libraries should be traced.
18
+ These instrumentations to can be selected in a block:
19
+
20
+ ```ruby
21
+ SignalFx::Tracing::Instrumenter.configure do |patcher|
22
+ patcher.instrument(:LibName)
23
+ ...
24
+ end
25
+ ```
26
+
27
+ Valid lib names are listed below with the instrumentation documentation.
28
+
29
+ `configure` accepts several optional parameters:
30
+ - `tracer`: a preconfigured OpenTracing tracer to use. If one is not provided,
31
+ a new tracer will be initialized.
32
+ - Default: `nil`
33
+ - `ingest_url`: this is the endpoint to which spans are sent by the tracer.
34
+ - Default: `https://ingest.signalfx.com/v1/trace`
35
+ - `service_name`: service name to send spans under.
36
+ - Default: `signalfx-ruby-tracing`
37
+ - `access_token`: SignalFx access token for authentication.
38
+ - Default: `''`
39
+
40
+ Environment variables can be used to configure `service_name` and `access_token`
41
+ if not given to the `configure` method.
42
+
43
+ ```bash
44
+ export SIGNALFX_ACCESS_TOKEN="<token>"
45
+ export SIGNALFX_SERVICE_NAME="<service_name>"
46
+ export SIGNALFX_INGEST_URL="<url>"
47
+ ```
48
+
49
+ If these environment variables are not set, the values will default to the ones
50
+ listed above.
51
+
52
+ The `access_token` or `SIGNALFX_ACCESS_TOKEN` only needs to be set when sending
53
+ spans to a SignalFx ingest directly. It is not required when using the Smart
54
+ Agent or Smart Gateway.
55
+
56
+ # Instrumentation
57
+
58
+ This section contains details and configuration for specific frameworks.
59
+
60
+ ### Runtimes
61
+
62
+ - MRI Ruby (CRuby) 2.0+
63
+
64
+ ### Web servers
65
+
66
+ - Puma >= 5.0.0
67
+
68
+ ### Libraries/Frameworks
69
+
70
+ | Library | Versions Supported |
71
+ | ------------- | ------------------ |
72
+ | ActiveRecord | > 3.2 |
73
+ | Elasticsearch | >= 5.x |
74
+ | Faraday | > 0.9.2 |
75
+ | Mongo | >= 2.1 |
76
+ | Mysql2 | >= 0.5.0 |
77
+ | Net::HTTP | Ruby > 2.0 |
78
+ | Rack | |
79
+ | Rails | |
80
+ | REST Client | >= 2.0.0 |
81
+ | Sinatra | >= 1.1.4 |
82
+
83
+ ## Active Record
84
+
85
+ This instrumentation creates spans for each Active Record query using the Active
86
+ Support notifications framework.
87
+
88
+ The source for this instrumentation is located [here](https://github.com/salemove/ruby-activerecord-opentracing).
89
+
90
+ ### Usage
91
+
92
+ ```ruby
93
+ SignalFx::Tracing::Instrumenter.configure do |p|
94
+ p.instrument(:ActiveRecord)
95
+ end
96
+ ```
97
+
98
+ ## Elasticsearch
99
+
100
+ Elasticsearch queries through the Ruby client are traced using a wrapper around
101
+ the transport.
102
+
103
+ The forked source for the instrumentation is located [here](https://github.com/signalfx/ruby-elasticsearch-tracer).
104
+
105
+ ### Usage
106
+
107
+ ```ruby
108
+ SignalFx::Tracing::Instrumenter.configure do |p|
109
+ p.instrument(:Elasticsearch, auto_instrument: true)
110
+ end
111
+ ```
112
+
113
+ When the `auto_instrument` option is `true`, it will allow all new Elasticsearch
114
+ clients to automatically wrap the default or configured transport and get
115
+ traces for queries. No additional configuration is necessary.
116
+
117
+ Alternatively, the instrumentation can be used selectively by setting a custom
118
+ transport on the clients to be traced manually:
119
+
120
+ ```ruby
121
+ require 'elasticsearch'
122
+ require 'elasticsearch-tracer'
123
+
124
+ client = Elasticsearch::TracingClient.new
125
+ client.transport = Elasticsearch::Tracer::Transport.new(tracer: OpenTracing.global_tracer,
126
+ active_span: -> { OpenTracing.global_tracer.active_span },
127
+ transport: client.transport)
128
+ ```
129
+
130
+ ## Faraday
131
+
132
+ Faraday HTTP client instrumentation automatically creates spans for outgoing
133
+ requests. If the remote service has instrumentation that is aware of Rack,
134
+ those spans will be automatically nested with Faraday's spans.
135
+
136
+ The source for this instrumentation is located [here](https://github.com/opentracing-contrib/ruby-faraday-tracer).
137
+
138
+ ### Usage
139
+
140
+ ```ruby
141
+ SignalFx::Tracing::Instrumenter.configure do |p|
142
+ p.instrument(:Faraday)
143
+ end
144
+ ```
145
+
146
+ To use the instrumentation directly without patching, the Faraday middleware
147
+ must be inserted for each new connection:
148
+ ```ruby
149
+ conn = Faraday.new(url: 'http://localhost:3000/') do |faraday|
150
+ faraday.use Faraday::Tracer
151
+ end
152
+ ```
153
+
154
+ For more detailed usage, please check the instrumenation's page.
155
+
156
+ ## Mysql2
157
+
158
+ Mysql2 instrumentation traces all queries performed with the Mysql2 client.
159
+
160
+ The source for this instrumentation is located [here](https://github.com/signalfx/ruby-mysql2-instrumentation)
161
+
162
+ ### Usage
163
+
164
+ ```ruby
165
+ SignalFx::Tracing::Instrumenter.configure do |p|
166
+ p.instrument(:Mysql2)
167
+ end
168
+ ```
169
+
170
+ ## Net::HTTP
171
+
172
+ This automatically traces all requests using Net::HTTP.
173
+
174
+ The source for this instrumentation is located [here](https://github.com/signalfx/ruby-net-http-instrumentation).
175
+
176
+ ### Usage
177
+
178
+ ```ruby
179
+ SignalFx::Tracing::Instrumenter.configure do |p|
180
+ p.instrument(:NetHttp)
181
+ end
182
+ ```
183
+
184
+ ## Rack
185
+
186
+ Rack spans are created using the `rack-tracer` gem. This is enabled
187
+ automatically for other frameworks that are built on top of Rack, but it can
188
+ also be separately enabled.
189
+
190
+ The source for this instrumentation is located [here](https://github.com/opentracing-contrib/ruby-rack-tracer).
191
+
192
+ ### Usage
193
+
194
+ ```ruby
195
+ SignalFx::Tracing::Instrumenter.configure do |p|
196
+ p.instrument(:Rack)
197
+ end
198
+ ```
199
+
200
+ ## Rails
201
+
202
+ Rails applications can be traced using the notifications provided by ActiveSupport.
203
+ It can use `rack-tracer` to trace by requests, or it'll try to group spans by
204
+ request ID.
205
+
206
+ The forked source for this instrumentation is located [here](https://github.com/signalfx/ruby-rails-tracer).
207
+
208
+ ### Usage
209
+
210
+ ```ruby
211
+ SignalFx::Tracing::Instrumenter.configure do |p|
212
+ p.instrument(:Rails)
213
+ end
214
+ ```
215
+
216
+ Optionally, to disable Rack instrumentation, set the `rack_tracer` field to false.
217
+
218
+ ```ruby
219
+ SignalFx::Tracing::Instrumenter.configure do |p|
220
+ p.instrument(:Rails, rack_tracer: false)
221
+ end
222
+ ```
223
+
224
+ ## RestClient
225
+
226
+ RestClient requests can be patched to automatically be wrapped in a span. It
227
+ will also inject the span context so remote services can extract it.
228
+
229
+ The source for this instrumentation is located [here](https://github.com/signalfx/ruby-restclient-instrumentation).
230
+
231
+ ### Usage
232
+
233
+ ```ruby
234
+ SignalFx::Tracing::Instrumenter.configure do |p|
235
+ p.instrument(:RestClient)
236
+ end
237
+ ```
238
+
239
+ ## Sinatra
240
+
241
+ Sinatra instrumentation traces requests and template rendering. The instrumenter
242
+ registers a Sinatra extension that uses `rack-tracer` to trace requests and
243
+ monkey-patches to trace view rendering. Rack instrumentation is automatically
244
+ enabled when using Sinatra instrumentation.
245
+
246
+ The source for this instrumentation is located [here](https://github.com/signalfx/ruby-sinatra-instrumentation).
247
+
248
+ ### Usage
249
+
250
+ ```ruby
251
+ SignalFx::Tracing::Instrumenter.configure do |p|
252
+ p.instrument(:Sinatra)
253
+ end
254
+ ```
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+ task :default => :spec
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "signalfx/tracing"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start(__FILE__)
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,60 @@
1
+ require 'jaeger/client'
2
+ require 'signalfx/tracing/http_sender'
3
+ require 'signalfx/tracing/register'
4
+ require 'thread'
5
+
6
+ module SignalFx
7
+ module Tracing
8
+ module Instrumenter
9
+
10
+ class << self
11
+
12
+ attr_reader :ingest_url
13
+ attr_accessor :tracer
14
+
15
+ def configure(tracer: nil,
16
+ ingest_url: ENV['SIGNALFX_INGEST_URL'] || 'https://ingest.signalfx.com/v1/trace',
17
+ service_name: ENV['SIGNALFX_SERVICE_NAME'] || "signalfx-ruby-tracing",
18
+ access_token: ENV['SIGNALFX_ACCESS_TOKEN'],
19
+ auto_instrument: false)
20
+ @ingest_url = ingest_url
21
+ set_tracer(tracer: tracer, service_name: service_name, access_token: access_token)
22
+ if auto_instrument
23
+ Register.available_libs.each_pair do |key, value|
24
+ value.instrument
25
+ end
26
+ else
27
+ yield self
28
+ end
29
+ end
30
+
31
+ def instrument(to_patch, **args)
32
+ if Register.available_libs[to_patch].nil?
33
+ puts "instrumentation not found"
34
+ else
35
+ Register.available_libs[to_patch].instrument(**args)
36
+ end
37
+ end
38
+
39
+ def set_tracer(tracer: nil, service_name: nil, access_token: nil)
40
+ # build a new tracer if one wasn't provided
41
+ if tracer.nil?
42
+ headers = {}
43
+
44
+ # don't set the header if no token was provided
45
+ headers["X-SF-Token"] = access_token if access_token && !access_token.empty?
46
+
47
+ encoder = Jaeger::Client::Encoders::ThriftEncoder.new(service_name: service_name)
48
+
49
+ http_sender = SignalFx::Tracing::HttpSenderWithFlag.new(url: @ingest_url, headers: headers, encoder: encoder)
50
+
51
+ @tracer = Jaeger::Client.build(service_name: service_name, sender: http_sender, flush_interval: 1)
52
+ OpenTracing.global_tracer = @tracer
53
+ else
54
+ @tracer = tracer
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,23 @@
1
+ require 'jaeger/client/http_sender'
2
+
3
+ # This child class of HttpSender exists to allow Net::HTTP instrumentation to
4
+ # ignore requests made by the tracer. The tracer uses the Thrift HTTP Transport,
5
+ # which uses Net::HTTP internally, to send spans to the collector.
6
+ #
7
+ # The sender spins in a separate thread to send spans. The overridden
8
+ # HttpSender#send_spans sets a thread variable, :http_sender_thread, which is
9
+ # checked with a block passed to the Net::HTTP instrumentation.
10
+
11
+ module SignalFx
12
+ module Tracing
13
+ class HttpSenderWithFlag < Jaeger::Client::HttpSender
14
+ def send_spans(spans)
15
+ Thread.current.thread_variable_set(:http_sender_thread, true)
16
+
17
+ super
18
+ ensure
19
+ Thread.current.thread_variable_set(:http_sender_thread, nil)
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,26 @@
1
+ module SignalFx
2
+ module Tracing
3
+ module Instrumenter
4
+ module ActiveRecord
5
+
6
+ Register.add_lib :ActiveRecord, self
7
+
8
+ class << self
9
+
10
+ def instrument(opts = {})
11
+ # load ActiveRecord and ActiveSupport if present
12
+ begin
13
+ require 'active_support'
14
+ require 'active_record'
15
+ rescue LoadError
16
+ return
17
+ end
18
+
19
+ require 'active_record/opentracing'
20
+ ::ActiveRecord::OpenTracing.instrument
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,52 @@
1
+ module SignalFx
2
+ module Tracing
3
+ module Instrumenter
4
+ module Elasticsearch
5
+
6
+ Register.add_lib :Elasticsearch, self
7
+
8
+ class << self
9
+
10
+ attr_reader :instrumented
11
+
12
+ def instrument(opts = {})
13
+ return if @instrumented
14
+
15
+ begin
16
+ require 'elasticsearch'
17
+ rescue LoadError
18
+ return
19
+ end
20
+
21
+ require 'elasticsearch-tracer'
22
+
23
+ patch_new if opts.fetch(:auto_instrument, false)
24
+
25
+ # prevent re-instrumenting
26
+ @instrumented = true
27
+ end
28
+
29
+ def patch_new
30
+ ::Elasticsearch::Client.module_eval do
31
+ alias_method :new_original, :new
32
+
33
+ def new(arguments = {}, &block)
34
+ # create a new TracingClient, which is almost identical to the
35
+ # default client, and add the tracing transport afterwards. This
36
+ # allows us to maintain the original transport if the user has
37
+ # specified a non-default transport
38
+ client = ::Elasticsearch::Tracer::TracingClient.new(arguments, &block)
39
+ client.transport = ::Elasticsearch::Tracer::Transport.new(tracer: OpenTracing.global_tracer,
40
+ active_span: -> { OpenTracing.global_tracer.active_span },
41
+ transport: client.transport)
42
+
43
+ return client
44
+ end
45
+ end
46
+ end
47
+
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,42 @@
1
+ module SignalFx
2
+ module Tracing
3
+ module Instrumenter
4
+ module Faraday
5
+
6
+ Register.add_lib :Faraday, self
7
+
8
+ class << self
9
+
10
+ def instrument(opts = {})
11
+ begin
12
+ require 'faraday'
13
+ rescue LoadError
14
+ return
15
+ end
16
+
17
+ require 'faraday/tracer'
18
+
19
+ patch_initialize
20
+ end
21
+
22
+ # somewhat messy, but this lets connections be traced without manual
23
+ # configuration to use the middleware
24
+ def patch_initialize
25
+ ::Faraday::Connection.module_eval do
26
+ alias_method :initialize_original, :initialize
27
+
28
+ def initialize(url = nil, options = nil)
29
+ # initialize the connection as usual
30
+ initialize_original(url, options)
31
+
32
+ # before we let go, add the Faraday tracer to the beginning of the stack
33
+ @builder.insert(0, ::Faraday::Tracer)
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
42
+
@@ -0,0 +1,25 @@
1
+ module SignalFx
2
+ module Tracing
3
+ module Instrumenter
4
+ module MongoDB
5
+
6
+ Register.add_lib :MongoDB, self
7
+
8
+ class << self
9
+
10
+ def instrument(opts = {})
11
+ begin
12
+ require 'mongo'
13
+ rescue LoadError
14
+ return
15
+ end
16
+
17
+ require 'mongodb/instrumentation'
18
+
19
+ ::MongoDB::Instrumentation.instrument
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,25 @@
1
+ module SignalFx
2
+ module Tracing
3
+ module Instrumenter
4
+ module Mysql2
5
+
6
+ Register.add_lib :Mysql2, self
7
+
8
+ class << self
9
+
10
+ def instrument(opts = {})
11
+ begin
12
+ require 'mysql2'
13
+ rescue LoadError
14
+ return
15
+ end
16
+
17
+ require 'mysql2/instrumentation'
18
+
19
+ ::Mysql2::Instrumentation.instrument(tracer: SignalFx::Tracing::Instrumenter.tracer)
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,20 @@
1
+ module SignalFx
2
+ module Tracing
3
+ module Instrumenter
4
+ module NetHttp
5
+
6
+ Register.add_lib :NetHttp, self
7
+
8
+ class << self
9
+
10
+ def instrument(opts = {})
11
+ require 'net/http/tracer'
12
+
13
+ ignore_request = lambda { Thread.current.thread_variable_get(:http_sender_thread) }
14
+ ::Net::Http::Tracer.instrument(ignore_request: ignore_request)
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,23 @@
1
+ module SignalFx
2
+ module Tracing
3
+ module Instrumenter
4
+ module PatchingTest
5
+
6
+ Register.add_lib :PatchingTest, self
7
+
8
+ class << self
9
+
10
+ def instrument
11
+ ::PatchingTest::ToPatch.class_eval do
12
+ alias_method :test_old, :test
13
+
14
+ def test
15
+ puts "patched test"
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,23 @@
1
+ module SignalFx
2
+ module Tracing
3
+ module Instrumenter
4
+ module Rack
5
+
6
+ Register.add_lib :Rack, self
7
+
8
+ class << self
9
+
10
+ def instrument(opts = {})
11
+ begin
12
+ require 'rack'
13
+ rescue LoadError
14
+ return
15
+ end
16
+
17
+ require 'rack/tracer'
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,29 @@
1
+ module SignalFx
2
+ module Tracing
3
+ module Instrumenter
4
+ module Rails
5
+
6
+ Register.add_lib :Rails, self
7
+
8
+ class << self
9
+
10
+ def instrument(opts = {})
11
+ # instrument supported versions
12
+ return if !defined?(::Rails) or Gem::Version.new(::Rails::VERSION::STRING) < Gem::Version.new('3.2')
13
+
14
+ require 'rails/tracer'
15
+ require 'rack/tracer'
16
+
17
+ if opts.fetch(:rack_tracer, false)
18
+ # add rack middlewares
19
+ ::Rails.configuration.middleware.use(::Rack::Tracer)
20
+ ::Rails.configuration.middleware.insert_after(::Rack::Tracer, ::Rails::Rack::Tracer)
21
+ end
22
+
23
+ ::Rails::Tracer.instrument(full_trace: true)
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,25 @@
1
+ module SignalFx
2
+ module Tracing
3
+ module Instrumenter
4
+ module RestClient
5
+
6
+ Register.add_lib :RestClient, self
7
+
8
+ class << self
9
+
10
+ def instrument(opts = {})
11
+ begin
12
+ require 'restclient'
13
+ rescue LoadError
14
+ return
15
+ end
16
+
17
+ require 'restclient/instrumentation'
18
+
19
+ ::RestClient::Instrumentation.instrument
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,23 @@
1
+ module SignalFx
2
+ module Tracing
3
+ module Instrumenter
4
+ module Sinatra
5
+
6
+ Register.add_lib :Sinatra, self
7
+
8
+ class << self
9
+
10
+ def instrument(opt = {})
11
+ begin
12
+ require 'sinatra'
13
+ rescue LoadError
14
+ return
15
+ end
16
+
17
+ require 'sinatra/tracer'
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,41 @@
1
+ module SignalFx
2
+ module Tracing
3
+ module Instrumenter
4
+ class Register
5
+
6
+ @available_libs = {}
7
+ @initialized = false
8
+
9
+ def self.available_libs
10
+ return @available_libs
11
+ end
12
+
13
+ def self.initialized?
14
+ return @initialized
15
+ end
16
+
17
+ def self.include_patches
18
+ # all of the available patches must be added to the table here
19
+ @available_libs[:PatchingTest] = Patches::PatchingTest::ToPatch.new
20
+
21
+ @initialized = true
22
+ end
23
+
24
+ def self.add_lib(patch_key, patch_module)
25
+ @available_libs[patch_key] = patch_module
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
31
+
32
+ require 'signalfx/tracing/instrumentation/active_record'
33
+ require 'signalfx/tracing/instrumentation/sinatra'
34
+ require 'signalfx/tracing/instrumentation/faraday'
35
+ require 'signalfx/tracing/instrumentation/rack'
36
+ require 'signalfx/tracing/instrumentation/net_http'
37
+ require 'signalfx/tracing/instrumentation/rails'
38
+ require 'signalfx/tracing/instrumentation/restclient'
39
+ require 'signalfx/tracing/instrumentation/mongodb'
40
+ require 'signalfx/tracing/instrumentation/elasticsearch'
41
+ require 'signalfx/tracing/instrumentation/mysql2'
@@ -0,0 +1,5 @@
1
+ module Signalfx
2
+ module Tracing
3
+ VERSION = "0.1.0"
4
+ end
5
+ end
@@ -0,0 +1,55 @@
1
+ lib = File.expand_path("../lib", __FILE__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+ require "signalfx/tracing/version"
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "signalfx-tracing"
7
+ spec.version = Signalfx::Tracing::VERSION
8
+ spec.authors = ["Ashwin Chandrasekar"]
9
+ spec.email = ["achandrasekar@signalfx.com"]
10
+
11
+ spec.summary = %q{Auto-instrumentation framework for Ruby}
12
+ # spec.description = %q{TODO: Write a longer description or delete this line.}
13
+ spec.homepage = "https://github.com/signalfx/signalfx-ruby-tracing"
14
+ spec.license = "Apache 2.0"
15
+
16
+ # Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
17
+ # to allow pushing to a single host or delete this section to allow pushing to any host.
18
+ # if spec.respond_to?(:metadata)
19
+ # spec.metadata["allowed_push_host"] = "TODO: Set to 'http://mygemserver.com'"
20
+ # else
21
+ # raise "RubyGems 2.0 or newer is required to protect against " \
22
+ # "public gem pushes."
23
+ # end
24
+
25
+ # Specify which files should be added to the gem when it is released.
26
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
27
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
28
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
29
+ end
30
+ spec.bindir = "exe"
31
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
32
+ spec.require_paths = ["lib"]
33
+
34
+ spec.add_development_dependency "bundler", "~> 1.16"
35
+ spec.add_development_dependency "rake", "~> 10.0"
36
+
37
+ # TODO pin versions once consistent across all dependencies
38
+ spec.add_dependency "opentracing", "> 0.3.0"
39
+ spec.add_dependency "jaeger-client", "~> 0.6.1"
40
+
41
+ spec.add_dependency "sinatra-instrumentation", "~> 0.1"
42
+ spec.add_dependency "nethttp-instrumentation", "~> 0.1"
43
+ spec.add_dependency "restclient-instrumentation", "~> 0.1"
44
+ spec.add_dependency "mongodb-instrumentation", "~> 0.1"
45
+ spec.add_dependency "mysql2-instrumentation", "~> 0.1"
46
+
47
+ # forks
48
+ spec.add_dependency "signalfx-rails-instrumentation", "~> 0.1.0"
49
+ spec.add_dependency "signalfx-elasticsearch-instrumentation", "~> 0.1.0"
50
+
51
+ # external
52
+ spec.add_dependency "faraday-tracer", "~> 0.7.0"
53
+ spec.add_dependency "rack-tracer", "~> 0.8"
54
+ spec.add_dependency "activerecord-opentracing", "~> 0.2.1"
55
+ end
metadata ADDED
@@ -0,0 +1,262 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: signalfx-tracing
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Ashwin Chandrasekar
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2018-12-14 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.16'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.16'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: opentracing
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">"
46
+ - !ruby/object:Gem::Version
47
+ version: 0.3.0
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">"
53
+ - !ruby/object:Gem::Version
54
+ version: 0.3.0
55
+ - !ruby/object:Gem::Dependency
56
+ name: jaeger-client
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 0.6.1
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 0.6.1
69
+ - !ruby/object:Gem::Dependency
70
+ name: sinatra-instrumentation
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '0.1'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '0.1'
83
+ - !ruby/object:Gem::Dependency
84
+ name: nethttp-instrumentation
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '0.1'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '0.1'
97
+ - !ruby/object:Gem::Dependency
98
+ name: restclient-instrumentation
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '0.1'
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '0.1'
111
+ - !ruby/object:Gem::Dependency
112
+ name: mongodb-instrumentation
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: '0.1'
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: '0.1'
125
+ - !ruby/object:Gem::Dependency
126
+ name: mysql2-instrumentation
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - "~>"
130
+ - !ruby/object:Gem::Version
131
+ version: '0.1'
132
+ type: :runtime
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - "~>"
137
+ - !ruby/object:Gem::Version
138
+ version: '0.1'
139
+ - !ruby/object:Gem::Dependency
140
+ name: signalfx-rails-instrumentation
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - "~>"
144
+ - !ruby/object:Gem::Version
145
+ version: 0.1.0
146
+ type: :runtime
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - "~>"
151
+ - !ruby/object:Gem::Version
152
+ version: 0.1.0
153
+ - !ruby/object:Gem::Dependency
154
+ name: signalfx-elasticsearch-instrumentation
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - "~>"
158
+ - !ruby/object:Gem::Version
159
+ version: 0.1.0
160
+ type: :runtime
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - "~>"
165
+ - !ruby/object:Gem::Version
166
+ version: 0.1.0
167
+ - !ruby/object:Gem::Dependency
168
+ name: faraday-tracer
169
+ requirement: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - "~>"
172
+ - !ruby/object:Gem::Version
173
+ version: 0.7.0
174
+ type: :runtime
175
+ prerelease: false
176
+ version_requirements: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - "~>"
179
+ - !ruby/object:Gem::Version
180
+ version: 0.7.0
181
+ - !ruby/object:Gem::Dependency
182
+ name: rack-tracer
183
+ requirement: !ruby/object:Gem::Requirement
184
+ requirements:
185
+ - - "~>"
186
+ - !ruby/object:Gem::Version
187
+ version: '0.8'
188
+ type: :runtime
189
+ prerelease: false
190
+ version_requirements: !ruby/object:Gem::Requirement
191
+ requirements:
192
+ - - "~>"
193
+ - !ruby/object:Gem::Version
194
+ version: '0.8'
195
+ - !ruby/object:Gem::Dependency
196
+ name: activerecord-opentracing
197
+ requirement: !ruby/object:Gem::Requirement
198
+ requirements:
199
+ - - "~>"
200
+ - !ruby/object:Gem::Version
201
+ version: 0.2.1
202
+ type: :runtime
203
+ prerelease: false
204
+ version_requirements: !ruby/object:Gem::Requirement
205
+ requirements:
206
+ - - "~>"
207
+ - !ruby/object:Gem::Version
208
+ version: 0.2.1
209
+ description:
210
+ email:
211
+ - achandrasekar@signalfx.com
212
+ executables: []
213
+ extensions: []
214
+ extra_rdoc_files: []
215
+ files:
216
+ - Gemfile
217
+ - LICENSE
218
+ - README.md
219
+ - Rakefile
220
+ - bin/console
221
+ - bin/setup
222
+ - lib/signalfx/tracing.rb
223
+ - lib/signalfx/tracing/http_sender.rb
224
+ - lib/signalfx/tracing/instrumentation/active_record.rb
225
+ - lib/signalfx/tracing/instrumentation/elasticsearch.rb
226
+ - lib/signalfx/tracing/instrumentation/faraday.rb
227
+ - lib/signalfx/tracing/instrumentation/mongodb.rb
228
+ - lib/signalfx/tracing/instrumentation/mysql2.rb
229
+ - lib/signalfx/tracing/instrumentation/net_http.rb
230
+ - lib/signalfx/tracing/instrumentation/patching-test.rb
231
+ - lib/signalfx/tracing/instrumentation/rack.rb
232
+ - lib/signalfx/tracing/instrumentation/rails.rb
233
+ - lib/signalfx/tracing/instrumentation/restclient.rb
234
+ - lib/signalfx/tracing/instrumentation/sinatra.rb
235
+ - lib/signalfx/tracing/register.rb
236
+ - lib/signalfx/tracing/version.rb
237
+ - signalfx-tracing.gemspec
238
+ homepage: https://github.com/signalfx/signalfx-ruby-tracing
239
+ licenses:
240
+ - Apache 2.0
241
+ metadata: {}
242
+ post_install_message:
243
+ rdoc_options: []
244
+ require_paths:
245
+ - lib
246
+ required_ruby_version: !ruby/object:Gem::Requirement
247
+ requirements:
248
+ - - ">="
249
+ - !ruby/object:Gem::Version
250
+ version: '0'
251
+ required_rubygems_version: !ruby/object:Gem::Requirement
252
+ requirements:
253
+ - - ">="
254
+ - !ruby/object:Gem::Version
255
+ version: '0'
256
+ requirements: []
257
+ rubyforge_project:
258
+ rubygems_version: 2.6.13
259
+ signing_key:
260
+ specification_version: 4
261
+ summary: Auto-instrumentation framework for Ruby
262
+ test_files: []