appsignal 0.7.0.beta.1 → 0.7.1.beta.1

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,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- MGRlODlhNDE2MjZhZjY0NTJiMDA0OGJlNTk1NGZjMjZjMmM1ZjdlNA==
4
+ ODY1ZmU5ZTI5Y2ZlZWM5Mzk0OTUxNGVkYTVhNDEzNTQwM2UwYTE5NQ==
5
5
  data.tar.gz: !binary |-
6
- ODNjODNiODliMTM1ZWFjNWNlOTIxNDNiNzIwNTIwMWJkNGQ4MDc1Yg==
6
+ N2FkZTY5OGIzMWEwZTYzZjM1NDk3ZmRjY2VjYWQ1MGM0MGUwMWM1Mg==
7
7
  !binary "U0hBNTEy":
8
8
  metadata.gz: !binary |-
9
- NWUwN2M0N2U1ZWFjYTUxZWJlNGE2ZTU4YWVhZTFmMDEyOWI5MmFiYjY1NWJk
10
- ZDFjNjQ5MDk2NTNlOWQzMjM5OWNhMmEyMTRiZDE0NzlkYWU4YWQ3ZjNkYzYy
11
- NTk0MTY2ZmJkMTRhYTg5YjcwODhjN2VkNGNiMzhkOGE2ZDAwZTY=
9
+ YTJjYmMyMWZhNTE0NDk5Y2ZlOGI0ZTNlMGRmZDNjMzMyM2JmYmEzNjY0Yzkx
10
+ MzNjZTBmZGJhOWNlMjYyYjA3ODRiNThkNDkwNmJjMDIwZWEyZGZjOWQ4YWY3
11
+ MDQyMjY4MTE1MzNiYWE2ZWJmY2RhMTFjYTlkNGIxOGY4YTg3ZGQ=
12
12
  data.tar.gz: !binary |-
13
- MWU1M2M4ZDI1NWM2NjgzZTdmNjRkMDRkOTJlYTM0YzA2MjM5Nzc1MDNlNmMx
14
- NDBlYzkyY2Q5M2Q0YTA4OWYwMGI5YzVhNDcwM2RmZjAwYzQ1MjgwNmJiMWU4
15
- YmVmMDVkNTA1ZDAxMGM2ZDQ4YmM4OTY3ZWVjOWU3ODM4NGYyNjU=
13
+ ZWIwNTUxNDZkMzg4Y2FkMDBlMzk0NTc1Mzg4YTgwNzM3NjlmNjI4NjY0NWQ1
14
+ NjU0MjA2M2Y5NjY4YmYzMTVjOTIwNWJkMzMyNjdhY2JkODk5NDFmYjVkOWY2
15
+ MWViZmIzNGM4ZWZlMDE1MzBlMDI2MTQyMTEyZjc3YzlkODUzZmM=
@@ -1,3 +1,6 @@
1
+ # 0.7.1
2
+ * Better support for forking webservers
3
+
1
4
  # 0.7.0
2
5
  * Mayor refactor and cleanup
3
6
  * New easier onboarding process
@@ -16,6 +16,7 @@ module Appsignal
16
16
  end
17
17
  logger.info("Starting appsignal-#{Appsignal::VERSION}")
18
18
  @agent = Appsignal::Agent.new
19
+ at_exit { @agent.shutdown(true) }
19
20
  else
20
21
  logger.error("Can't start, no config loaded")
21
22
  end
@@ -118,4 +119,5 @@ require 'appsignal/transmitter'
118
119
  require 'appsignal/version'
119
120
 
120
121
  require 'appsignal/integrations/passenger'
122
+ require 'appsignal/integrations/unicorn'
121
123
  require 'appsignal/integrations/rails'
@@ -2,7 +2,7 @@ module Appsignal
2
2
  class Agent
3
3
  ACTION = 'log_entries'.freeze
4
4
 
5
- attr_reader :aggregator, :thread, :active, :sleep_time, :transmitter, :subscriber
5
+ attr_accessor :aggregator, :thread, :active, :sleep_time, :transmitter, :subscriber
6
6
 
7
7
  def initialize
8
8
  return unless Appsignal.active?
@@ -15,8 +15,6 @@ module Appsignal
15
15
  @transmitter = Transmitter.new(ACTION)
16
16
  subscribe
17
17
  start_thread
18
- # Shutdown at exit. This does not work in passenger, see integrations/passenger
19
- #at_exit { Appsignal.agent.shutdown(true) }
20
18
  Appsignal.logger.info('Started Appsignal agent')
21
19
  end
22
20
 
@@ -31,6 +29,14 @@ module Appsignal
31
29
  end
32
30
  end
33
31
 
32
+ def restart_thread
33
+ if @thread && @thread.alive?
34
+ Appsignal.logger.debug 'Killing agent thread'
35
+ Thread.kill(@thread)
36
+ end
37
+ start_thread
38
+ end
39
+
34
40
  def subscribe
35
41
  Appsignal.logger.debug('Subscribing to notifications')
36
42
  # Subscribe to notifications that don't start with a !
@@ -71,9 +77,12 @@ module Appsignal
71
77
  end
72
78
 
73
79
  def forked!
80
+ Appsignal.logger.debug('Forked worker process')
74
81
  @forked = true
75
- @aggregator = Aggregator.new
76
- Appsignal.logger.info('Forked the Appsignal agent')
82
+ Thread.exclusive do
83
+ @aggregator = Aggregator.new
84
+ end
85
+ restart_thread
77
86
  end
78
87
 
79
88
  def forked?
@@ -81,7 +90,7 @@ module Appsignal
81
90
  end
82
91
 
83
92
  def shutdown(send_current_queue=false)
84
- Appsignal.logger.info('Shutting down the agent')
93
+ Appsignal.logger.info('Shutting down agent')
85
94
  ActiveSupport::Notifications.unsubscribe(subscriber)
86
95
  Thread.kill(thread) if thread
87
96
  send_queue if send_current_queue && @aggregator.has_transactions?
@@ -0,0 +1,25 @@
1
+ if defined?(::Unicorn) && defined?(::Unicorn::HttpServer)
2
+ Appsignal.logger.info('Using Unicorn')
3
+
4
+ # We'd love to be able to hook this into Unicorn in a less
5
+ # intrusive way, but this is the best we can do given the
6
+ # options we have.
7
+
8
+ class Unicorn::HttpServer
9
+ alias_method :original_worker_loop, :worker_loop
10
+
11
+ def worker_loop(worker)
12
+ Appsignal.agent.forked!
13
+ original_worker_loop(worker)
14
+ end
15
+ end
16
+
17
+ class Unicorn::Worker
18
+ alias_method :original_close, :close
19
+
20
+ def close
21
+ Appsignal.agent.shutdown(true)
22
+ original_close
23
+ end
24
+ end
25
+ end
@@ -1,3 +1,3 @@
1
1
  module Appsignal
2
- VERSION = '0.7.0.beta.1'
2
+ VERSION = '0.7.1.beta.1'
3
3
  end
@@ -25,8 +25,56 @@ describe Appsignal::Agent do
25
25
  end
26
26
 
27
27
  describe "#start_thread" do
28
- it "should have started a background thread" do
28
+ before { subject.thread = nil }
29
+
30
+ it "should start a background thread" do
31
+ subject.start_thread
32
+
29
33
  subject.thread.should be_a(Thread)
34
+ subject.thread.should be_alive
35
+ end
36
+ end
37
+
38
+ describe "#restart_thread" do
39
+ context "if there is no thread" do
40
+ before { subject.thread = nil }
41
+
42
+ it "should start a thread" do
43
+ subject.restart_thread
44
+
45
+ subject.thread.should be_a(Thread)
46
+ subject.thread.should be_alive
47
+ end
48
+ end
49
+
50
+ context "if there is an inactive thread" do
51
+ before do
52
+ Thread.kill(subject.thread)
53
+ sleep 0.1 # We need to wait for the thread to exit
54
+ end
55
+
56
+ it "should start a thread" do
57
+ subject.restart_thread
58
+
59
+ subject.thread.should be_a(Thread)
60
+ subject.thread.should be_alive
61
+ end
62
+ end
63
+
64
+ context "if there is an active thread" do
65
+ it "should kill the current thread and start a new one" do
66
+ previous_thread = subject.thread
67
+ previous_thread.should be_alive
68
+
69
+ subject.restart_thread
70
+
71
+ subject.thread.should be_a(Thread)
72
+ subject.thread.should be_alive
73
+ subject.thread.should_not == previous_thread
74
+
75
+ sleep 0.1 # We need to wait for the thread to exit
76
+ previous_thread.should_not be_alive
77
+ end
30
78
  end
31
79
  end
32
80
 
@@ -2,7 +2,10 @@ require 'spec_helper'
2
2
 
3
3
  describe "Passenger integration" do
4
4
  let(:file) { File.expand_path('lib/appsignal/integrations/passenger.rb') }
5
- before(:all) { module PhusionPassenger ; end }
5
+ before(:all) do
6
+ module PhusionPassenger
7
+ end
8
+ end
6
9
 
7
10
  it "adds behavior to stopping_worker_process and starting_worker_process" do
8
11
  PhusionPassenger.should_receive(:on_event).with(:starting_worker_process)
@@ -0,0 +1,48 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Unicorn integration" do
4
+ let(:file) { File.expand_path('lib/appsignal/integrations/unicorn.rb') }
5
+ before(:all) do
6
+ module Unicorn
7
+ class HttpServer
8
+ def worker_loop(worker)
9
+ end
10
+ end
11
+
12
+ class Worker
13
+ def close
14
+ end
15
+ end
16
+ end
17
+ end
18
+ before do
19
+ load file
20
+ start_agent
21
+ end
22
+
23
+ it "adds behavior to Unicorn::HttpServer#worker_loop" do
24
+ server = Unicorn::HttpServer.new
25
+ worker = double
26
+
27
+ Appsignal.agent.should_receive(:forked!)
28
+ server.should_receive(:original_worker_loop).with(worker)
29
+
30
+ server.worker_loop(worker)
31
+ end
32
+
33
+ it "should add behavior to Unicorn::Worker#close" do
34
+ worker = Unicorn::Worker.new
35
+
36
+ Appsignal.agent.should_receive(:shutdown).with(true)
37
+ worker.should_receive(:original_close)
38
+
39
+ worker.close
40
+ end
41
+
42
+ context "without unicorn" do
43
+ before(:all) { Object.send(:remove_const, :Unicorn) }
44
+
45
+ specify { expect { Unicorn }.to raise_error(NameError) }
46
+ specify { expect { load file }.to_not raise_error }
47
+ end
48
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: appsignal
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.0.beta.1
4
+ version: 0.7.1.beta.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Robert Beekman
@@ -12,7 +12,7 @@ authors:
12
12
  autorequire:
13
13
  bindir: bin
14
14
  cert_chain: []
15
- date: 2013-12-13 00:00:00.000000000 Z
15
+ date: 2013-12-20 00:00:00.000000000 Z
16
16
  dependencies:
17
17
  - !ruby/object:Gem::Dependency
18
18
  name: activesupport
@@ -154,6 +154,7 @@ files:
154
154
  - lib/appsignal/integrations/passenger.rb
155
155
  - lib/appsignal/integrations/rails.rb
156
156
  - lib/appsignal/integrations/sinatra.rb
157
+ - lib/appsignal/integrations/unicorn.rb
157
158
  - lib/appsignal/marker.rb
158
159
  - lib/appsignal/rack/instrumentation.rb
159
160
  - lib/appsignal/rack/listener.rb
@@ -180,6 +181,7 @@ files:
180
181
  - spec/lib/appsignal/integrations/passenger_spec.rb
181
182
  - spec/lib/appsignal/integrations/rails_spec.rb
182
183
  - spec/lib/appsignal/integrations/sinatra_spec.rb
184
+ - spec/lib/appsignal/integrations/unicorn_spec.rb
183
185
  - spec/lib/appsignal/marker_spec.rb
184
186
  - spec/lib/appsignal/rack/instrumentation_spec.rb
185
187
  - spec/lib/appsignal/rack/listener_spec.rb
@@ -239,6 +241,7 @@ test_files:
239
241
  - spec/lib/appsignal/integrations/passenger_spec.rb
240
242
  - spec/lib/appsignal/integrations/rails_spec.rb
241
243
  - spec/lib/appsignal/integrations/sinatra_spec.rb
244
+ - spec/lib/appsignal/integrations/unicorn_spec.rb
242
245
  - spec/lib/appsignal/marker_spec.rb
243
246
  - spec/lib/appsignal/rack/instrumentation_spec.rb
244
247
  - spec/lib/appsignal/rack/listener_spec.rb