appsignal 0.7.0.beta.1 → 0.7.1.beta.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +8 -8
- data/CHANGELOG.md +3 -0
- data/lib/appsignal.rb +2 -0
- data/lib/appsignal/agent.rb +15 -6
- data/lib/appsignal/integrations/unicorn.rb +25 -0
- data/lib/appsignal/version.rb +1 -1
- data/spec/lib/appsignal/agent_spec.rb +49 -1
- data/spec/lib/appsignal/integrations/passenger_spec.rb +4 -1
- data/spec/lib/appsignal/integrations/unicorn_spec.rb +48 -0
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
ODY1ZmU5ZTI5Y2ZlZWM5Mzk0OTUxNGVkYTVhNDEzNTQwM2UwYTE5NQ==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
N2FkZTY5OGIzMWEwZTYzZjM1NDk3ZmRjY2VjYWQ1MGM0MGUwMWM1Mg==
|
7
7
|
!binary "U0hBNTEy":
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
YTJjYmMyMWZhNTE0NDk5Y2ZlOGI0ZTNlMGRmZDNjMzMyM2JmYmEzNjY0Yzkx
|
10
|
+
MzNjZTBmZGJhOWNlMjYyYjA3ODRiNThkNDkwNmJjMDIwZWEyZGZjOWQ4YWY3
|
11
|
+
MDQyMjY4MTE1MzNiYWE2ZWJmY2RhMTFjYTlkNGIxOGY4YTg3ZGQ=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
ZWIwNTUxNDZkMzg4Y2FkMDBlMzk0NTc1Mzg4YTgwNzM3NjlmNjI4NjY0NWQ1
|
14
|
+
NjU0MjA2M2Y5NjY4YmYzMTVjOTIwNWJkMzMyNjdhY2JkODk5NDFmYjVkOWY2
|
15
|
+
MWViZmIzNGM4ZWZlMDE1MzBlMDI2MTQyMTEyZjc3YzlkODUzZmM=
|
data/CHANGELOG.md
CHANGED
data/lib/appsignal.rb
CHANGED
@@ -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'
|
data/lib/appsignal/agent.rb
CHANGED
@@ -2,7 +2,7 @@ module Appsignal
|
|
2
2
|
class Agent
|
3
3
|
ACTION = 'log_entries'.freeze
|
4
4
|
|
5
|
-
|
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
|
-
|
76
|
-
|
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
|
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
|
data/lib/appsignal/version.rb
CHANGED
@@ -25,8 +25,56 @@ describe Appsignal::Agent do
|
|
25
25
|
end
|
26
26
|
|
27
27
|
describe "#start_thread" do
|
28
|
-
|
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)
|
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.
|
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-
|
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
|