signalfx-tracing 0.1.2 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: fbe697abb23f55c936cd5937309410b186258073
4
- data.tar.gz: 7d32357ae60676f74828bf95fa7294b67880a039
3
+ metadata.gz: 3ccd213e2f5bb365118397b466f3ac34e660ab5e
4
+ data.tar.gz: 8b64213ad7583469a8e7c4aea8de6b7b3a6c12ea
5
5
  SHA512:
6
- metadata.gz: 3e40fc35b33a468d4fcc501a1d3e00b76645bff8389960cf7b61b26a7d51a53fefc1dacb1f32a5facbbe6992ba1de08e64b32765d97b57e7ec7ae963eb5c61a8
7
- data.tar.gz: 7682f03f50444badb12acd4039405ef9ccd6c6675f7fd3de3885ddc850793a513d9caea75c846d755f01f01881ea69c9bdc37e58d4eb53e4fc4f716804096f9f
6
+ metadata.gz: d6c606ea3b6832d534d50c5ea50e9012e6a6d665300c2a7b40a657e241cc675f2548a7387c602dd60f6a39c3586061f412fe25880376dd21ee00be2b70ce7f8c
7
+ data.tar.gz: 5695eef0830c459b516d8d143a1e0e4e0a032a7120229141cb40a1dc9e1f012632c7a7795468f00120e2ae33fd34f223ac4f00339eb6ec7f5beed29fdd8c05e2
data/README.md CHANGED
@@ -50,6 +50,9 @@ Valid lib names are listed below with the instrumentation documentation.
50
50
  - Default: `signalfx-ruby-tracing`
51
51
  - `access_token`: SignalFx access token for authentication.
52
52
  - Default: `''`
53
+ - `fork_safe`: If `true`, makes the tracer safe to fork if events cannot
54
+ be controlled
55
+ - Default: `false`
53
56
 
54
57
  Environment variables can be used to configure `service_name` and `access_token`
55
58
  if not given to the `configure` method.
@@ -78,6 +81,15 @@ This section contains details and configuration for specific frameworks.
78
81
  ### Web servers
79
82
 
80
83
  - Puma >= 3.0.0
84
+ - Passenger >= 5.0.25
85
+
86
+ Instrumentation for routes using these web servers is provided through Rack.
87
+ If using a framework that builds on top of Rack, such as Rails or Sinatra, our
88
+ instrumentation includes Rack instrumentation. In these cases, the routes
89
+ through the web server will be automatically traced.
90
+
91
+ When interfacing with these web servers as a Rack application, please configure
92
+ [Rack instrumentation](#rack) and insert it as middleware.
81
93
 
82
94
  ### Libraries/Frameworks
83
95
 
@@ -225,6 +237,8 @@ The source for this instrumentation is located [here](https://github.com/opentra
225
237
  SignalFx::Tracing::Instrumenter.configure do |p|
226
238
  p.instrument(:Rack)
227
239
  end
240
+
241
+ use Rack::Tracer
228
242
  ```
229
243
 
230
244
  ## Rails
@@ -292,3 +306,18 @@ SignalFx::Tracing::Instrumenter.configure do |p|
292
306
  p.instrument(:Sinatra)
293
307
  end
294
308
  ```
309
+
310
+ ## Troubleshooting
311
+
312
+ ### Forking
313
+
314
+ If spans are no longer sent after forking a process, the span reporter thread
315
+ has been lost while copying to the process.
316
+
317
+ The reporter can be revived by calling `SignalFx::Tracing::Instrumenter.revive`
318
+ in the newly created process.
319
+
320
+ When the new process can't be handled directly, setting `fork_safe: true`
321
+ when configuring the instrumentation will use a reporter that checks and revives
322
+ itself every time a span is reported.
323
+
@@ -1,8 +1,11 @@
1
1
  require 'jaeger/client'
2
2
  require 'jaeger/client/injectors'
3
3
  require 'jaeger/client/extractors'
4
+ require 'signalfx/tracing/reporter/auto_reviving_async_reporter'
4
5
  require 'signalfx/tracing/http_sender'
6
+ require 'signalfx/tracing/tracer'
5
7
  require 'signalfx/tracing/register'
8
+ require 'signalfx/tracing/compat'
6
9
  require 'thread'
7
10
 
8
11
  module SignalFx
@@ -11,16 +14,21 @@ module SignalFx
11
14
 
12
15
  class << self
13
16
 
14
- attr_reader :ingest_url
17
+ attr_reader :ingest_url, :service_name, :access_token
15
18
  attr_accessor :tracer
16
19
 
17
20
  def configure(tracer: nil,
18
21
  ingest_url: ENV['SIGNALFX_INGEST_URL'] || 'https://ingest.signalfx.com/v1/trace',
19
22
  service_name: ENV['SIGNALFX_SERVICE_NAME'] || "signalfx-ruby-tracing",
20
23
  access_token: ENV['SIGNALFX_ACCESS_TOKEN'],
21
- auto_instrument: false)
24
+ auto_instrument: false,
25
+ fork_safe: false)
22
26
  @ingest_url = ingest_url
27
+ @service_name = service_name
28
+ @access_token = access_token
29
+ @fork_safe = fork_safe
23
30
  set_tracer(tracer: tracer, service_name: service_name, access_token: access_token)
31
+
24
32
  if auto_instrument
25
33
  Register.available_libs.each_pair do |key, value|
26
34
  value.instrument
@@ -28,6 +36,8 @@ module SignalFx
28
36
  else
29
37
  yield self
30
38
  end
39
+
40
+ Compat.apply
31
41
  end
32
42
 
33
43
  def instrument(to_patch, **args)
@@ -47,8 +57,10 @@ module SignalFx
47
57
  headers["X-SF-Token"] = access_token if access_token && !access_token.empty?
48
58
 
49
59
  encoder = Jaeger::Client::Encoders::ThriftEncoder.new(service_name: service_name)
60
+ @http_sender = SignalFx::Tracing::HttpSenderWithFlag.new(url: @ingest_url, headers: headers, encoder: encoder)
61
+ reporter = create_reporter(@http_sender)
50
62
 
51
- http_sender = SignalFx::Tracing::HttpSenderWithFlag.new(url: @ingest_url, headers: headers, encoder: encoder)
63
+ sampler = Jaeger::Client::Samplers::Const.new(true)
52
64
 
53
65
  injectors = {
54
66
  OpenTracing::FORMAT_RACK => [Jaeger::Client::Injectors::B3RackCodec]
@@ -57,16 +69,30 @@ module SignalFx
57
69
  OpenTracing::FORMAT_RACK => [Jaeger::Client::Extractors::B3RackCodec]
58
70
  }
59
71
 
60
- @tracer = Jaeger::Client.build(service_name: service_name,
61
- sender: http_sender,
62
- injectors: injectors,
63
- extractors: extractors,
64
- flush_interval: 1)
72
+ @tracer = SignalFx::Tracing::Tracer.new(reporter: reporter, sampler: sampler, injectors: injectors, extractors: extractors)
65
73
  OpenTracing.global_tracer = @tracer
66
74
  else
67
75
  @tracer = tracer
68
76
  end
69
77
  end
78
+
79
+ # This method will either use the default reporter, which will not check
80
+ # for the sender thread, or if fork_safe is true then it will create the
81
+ # self-reviving reporter. The main use for this is
82
+ # when the process with the tracer gets forked or goes through some
83
+ # other process that kills child threads.
84
+ def create_reporter(sender)
85
+ if @fork_safe
86
+ SignalFx::Tracing::AutoRevivingAsyncReporter.new(sender, 1)
87
+ else
88
+ Jaeger::Client::AsyncReporter.create(sender: sender, flush_interval: 1)
89
+ end
90
+ end
91
+
92
+ # at the moment this just sets a new reporter in the tracer
93
+ def revive
94
+ @tracer.set_reporter(create_reporter(@http_sender)) if @tracer.respond_to? :set_reporter
95
+ end
70
96
  end
71
97
  end
72
98
 
@@ -0,0 +1,16 @@
1
+ module SignalFx
2
+ module Tracing
3
+ module Compat
4
+ def self.apply
5
+ @compat.each { |mod| mod.apply } if @compat
6
+ end
7
+
8
+ def self.add_compat(mod)
9
+ @compat = [] unless @compat
10
+ @compat.push(mod)
11
+ end
12
+ end
13
+ end
14
+ end
15
+
16
+ require 'signalfx/tracing/compat/phusion_passenger'
@@ -0,0 +1,20 @@
1
+ module SignalFx
2
+ module Tracing
3
+ module Compat
4
+ module PhusionPassenger
5
+ def self.apply
6
+ # register a hook for newly spawned processes
7
+ if defined? ::PhusionPassenger
8
+ ::PhusionPassenger.on_event(:starting_worker_process) do |forked|
9
+ if forked
10
+ SignalFx::Tracing::Instrumenter.revive
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
16
+
17
+ add_compat PhusionPassenger
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,35 @@
1
+ require 'jaeger/client/async_reporter'
2
+
3
+ # The Jaeger client's AsyncReporter creates a thread to handle sending spans on
4
+ # a flush interval. However, when a forking web server like Passenger forks a
5
+ # process that includes the tracer, the sender thread is lost.
6
+ #
7
+ # This checks for the thread's before pushing in a span to the buffer.
8
+ # If it doesn't exist, it tells the instrumenter module to crate a new reporter.
9
+ #
10
+ # If you have control over hooking into fork events, signalfx/tracing/async_reporter
11
+ # and reviving it should be preferred to avoid an unnecessary check with every
12
+ # reported span.
13
+
14
+ module SignalFx
15
+ module Tracing
16
+ class AutoRevivingAsyncReporter < ::Jaeger::Client::AsyncReporter
17
+ def initialize(sender, flush_interval)
18
+ @flush_interval = flush_interval
19
+ @poll_thread = Thread.new do
20
+ loop do
21
+ flush
22
+ sleep(@flush_interval)
23
+ end
24
+ end
25
+
26
+ super(sender)
27
+ end
28
+
29
+ def report(span)
30
+ ::SignalFx::Tracing::Instrumenter.revive if !@poll_thread
31
+ super
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,15 @@
1
+ require 'jaeger/client/tracer'
2
+
3
+ # The default jaeger tracer doesn't expose @reporter, and attr_accessor can't
4
+ # be added after the fact in a child class. So this just adds an old-fashioned
5
+ # setter for @reporter.
6
+
7
+ module SignalFx
8
+ module Tracing
9
+ class Tracer < ::Jaeger::Client::Tracer
10
+ def set_reporter(reporter)
11
+ @reporter = reporter
12
+ end
13
+ end
14
+ end
15
+ end
@@ -1,5 +1,5 @@
1
1
  module Signalfx
2
2
  module Tracing
3
- VERSION = "0.1.2"
3
+ VERSION = "0.1.3"
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: signalfx-tracing
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ashwin Chandrasekar
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-12-17 00:00:00.000000000 Z
11
+ date: 2018-12-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -220,6 +220,8 @@ files:
220
220
  - bin/console
221
221
  - bin/setup
222
222
  - lib/signalfx/tracing.rb
223
+ - lib/signalfx/tracing/compat.rb
224
+ - lib/signalfx/tracing/compat/phusion_passenger.rb
223
225
  - lib/signalfx/tracing/http_sender.rb
224
226
  - lib/signalfx/tracing/instrumentation/active_record.rb
225
227
  - lib/signalfx/tracing/instrumentation/elasticsearch.rb
@@ -233,6 +235,8 @@ files:
233
235
  - lib/signalfx/tracing/instrumentation/restclient.rb
234
236
  - lib/signalfx/tracing/instrumentation/sinatra.rb
235
237
  - lib/signalfx/tracing/register.rb
238
+ - lib/signalfx/tracing/reporter/auto_reviving_async_reporter.rb
239
+ - lib/signalfx/tracing/tracer.rb
236
240
  - lib/signalfx/tracing/version.rb
237
241
  - signalfx-tracing.gemspec
238
242
  homepage: https://github.com/signalfx/signalfx-ruby-tracing