appsignal 0.12.beta.50 → 0.12.beta.51
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 +4 -4
- data/lib/appsignal.rb +6 -0
- data/lib/appsignal/integrations/passenger.rb +4 -0
- data/lib/appsignal/integrations/unicorn.rb +11 -1
- data/lib/appsignal/rack/streaming_listener.rb +22 -24
- data/lib/appsignal/version.rb +1 -1
- data/spec/lib/appsignal/integrations/passenger_spec.rb +2 -1
- data/spec/lib/appsignal/integrations/unicorn_spec.rb +15 -0
- data/spec/lib/appsignal/rack/streaming_listener_spec.rb +43 -40
- data/spec/lib/appsignal_spec.rb +9 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f05c4b10cdcc8be1365e375c99b4a5ca0e33136c
|
4
|
+
data.tar.gz: a91ad31e98f8e55d82bca201a9b2ffb5435a588c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a23198201451e493cbda260759a7e5acd844867d590b0170258de0fb1899caa91597d6b770415e0ecaf34801016585c6920e0b4a4ba08ba7fc94913ea70c3fbf
|
7
|
+
data.tar.gz: 043df589063492ff8bac2f4ac914807ed9f5eedb34ce21be9b0a4161cf1e1ff2504acd6192c88700194f513fd6d9727cc8fc5651c36c518968edc209d962b996
|
data/lib/appsignal.rb
CHANGED
@@ -78,6 +78,12 @@ module Appsignal
|
|
78
78
|
Appsignal::Extension.stop
|
79
79
|
end
|
80
80
|
|
81
|
+
def forked
|
82
|
+
logger.debug('Forked process, resubscribing and restarting extension')
|
83
|
+
Appsignal::Extension.start
|
84
|
+
@subscriber = Appsignal::Subscriber.new
|
85
|
+
end
|
86
|
+
|
81
87
|
# Wrap a transaction with appsignal monitoring.
|
82
88
|
def monitor_transaction(name, env={})
|
83
89
|
unless active?
|
@@ -1,6 +1,10 @@
|
|
1
1
|
if defined?(::PhusionPassenger)
|
2
2
|
Appsignal.logger.info('Loading Passenger integration')
|
3
3
|
|
4
|
+
::PhusionPassenger.on_event(:starting_worker_process) do |forked|
|
5
|
+
Appsignal.forked
|
6
|
+
end
|
7
|
+
|
4
8
|
::PhusionPassenger.on_event(:stopping_worker_process) do
|
5
9
|
Appsignal.stop
|
6
10
|
end
|
@@ -1,12 +1,22 @@
|
|
1
1
|
if defined?(::Unicorn)
|
2
2
|
Appsignal.logger.info('Loading Unicorn integration')
|
3
3
|
|
4
|
-
# Make sure the
|
4
|
+
# Make sure the appsignal is started and the last transaction
|
5
|
+
# in a worker gets flushed.
|
5
6
|
#
|
6
7
|
# We'd love to be able to hook this into Unicorn in a less
|
7
8
|
# intrusive way, but this is the best we can do given the
|
8
9
|
# options we have.
|
9
10
|
|
11
|
+
class Unicorn::HttpServer
|
12
|
+
alias_method :original_worker_loop, :worker_loop
|
13
|
+
|
14
|
+
def worker_loop(worker)
|
15
|
+
Appsignal.forked
|
16
|
+
original_worker_loop(worker)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
10
20
|
class Unicorn::Worker
|
11
21
|
alias_method :original_close, :close
|
12
22
|
|
@@ -16,34 +16,32 @@ module Appsignal
|
|
16
16
|
end
|
17
17
|
|
18
18
|
def call_with_appsignal_monitoring(env)
|
19
|
-
|
20
|
-
|
19
|
+
request = ::Rack::Request.new(env)
|
20
|
+
transaction = Appsignal::Transaction.create(
|
21
|
+
SecureRandom.uuid,
|
22
|
+
Appsignal::Transaction::HTTP_REQUEST,
|
23
|
+
request
|
24
|
+
)
|
21
25
|
|
22
26
|
# Instrument a `process_action`, to set params/action name
|
23
|
-
status, headers, body =
|
24
|
-
.instrument('process_action.rack'
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
27
|
+
status, headers, body =
|
28
|
+
ActiveSupport::Notifications.instrument('process_action.rack') do
|
29
|
+
begin
|
30
|
+
@app.call(env)
|
31
|
+
rescue Exception => e
|
32
|
+
transaction.set_error(e)
|
33
|
+
raise e
|
34
|
+
ensure
|
35
|
+
transaction.set_action(env['appsignal.action'])
|
36
|
+
transaction.set_metadata('path', request.path)
|
37
|
+
transaction.set_metadata('method', request.request_method)
|
38
|
+
transaction.set_http_or_background_queue_start
|
39
|
+
end
|
31
40
|
end
|
32
|
-
end
|
33
41
|
|
34
42
|
# Wrap the result body with our StreamWrapper
|
35
43
|
[status, headers, StreamWrapper.new(body, transaction)]
|
36
44
|
end
|
37
|
-
|
38
|
-
def raw_payload(env)
|
39
|
-
request = ::Rack::Request.new(env)
|
40
|
-
{
|
41
|
-
:params => request.params,
|
42
|
-
:session => request.session,
|
43
|
-
:method => request.request_method,
|
44
|
-
:path => request.path
|
45
|
-
}
|
46
|
-
end
|
47
45
|
end
|
48
46
|
end
|
49
47
|
|
@@ -56,15 +54,15 @@ module Appsignal
|
|
56
54
|
def each
|
57
55
|
@stream.each { |c| yield(c) }
|
58
56
|
rescue Exception => e
|
59
|
-
@transaction.
|
57
|
+
@transaction.set_error(e); raise e
|
60
58
|
end
|
61
59
|
|
62
60
|
def close
|
63
61
|
@stream.close if @stream.respond_to?(:close)
|
64
62
|
rescue Exception => e
|
65
|
-
@transaction.
|
63
|
+
@transaction.set_error(e); raise e
|
66
64
|
ensure
|
67
|
-
|
65
|
+
Appsignal::Transaction.complete_current!
|
68
66
|
end
|
69
67
|
end
|
70
68
|
end
|
data/lib/appsignal/version.rb
CHANGED
@@ -7,7 +7,8 @@ describe "Passenger integration" do
|
|
7
7
|
end
|
8
8
|
end
|
9
9
|
|
10
|
-
it "adds behavior to stopping_worker_process" do
|
10
|
+
it "adds behavior to stopping_worker_process and starting_worker_process" do
|
11
|
+
PhusionPassenger.should_receive(:on_event).with(:starting_worker_process)
|
11
12
|
PhusionPassenger.should_receive(:on_event).with(:stopping_worker_process)
|
12
13
|
load file
|
13
14
|
end
|
@@ -4,6 +4,11 @@ describe "Unicorn integration" do
|
|
4
4
|
let(:file) { File.expand_path('lib/appsignal/integrations/unicorn.rb') }
|
5
5
|
before(:all) do
|
6
6
|
module Unicorn
|
7
|
+
class HttpServer
|
8
|
+
def worker_loop(worker)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
7
12
|
class Worker
|
8
13
|
def close
|
9
14
|
end
|
@@ -15,6 +20,16 @@ describe "Unicorn integration" do
|
|
15
20
|
start_agent
|
16
21
|
end
|
17
22
|
|
23
|
+
it "adds behavior to Unicorn::HttpServer#worker_loop" do
|
24
|
+
server = Unicorn::HttpServer.new
|
25
|
+
worker = double
|
26
|
+
|
27
|
+
Appsignal.should_receive(:forked)
|
28
|
+
server.should_receive(:original_worker_loop).with(worker)
|
29
|
+
|
30
|
+
server.worker_loop(worker)
|
31
|
+
end
|
32
|
+
|
18
33
|
it "should add behavior to Unicorn::Worker#close" do
|
19
34
|
worker = Unicorn::Worker.new
|
20
35
|
|
@@ -3,7 +3,14 @@ require 'appsignal/rack/streaming_listener'
|
|
3
3
|
|
4
4
|
describe Appsignal::Rack::StreamingListener do
|
5
5
|
let(:headers) { {} }
|
6
|
-
let(:env)
|
6
|
+
let(:env) do
|
7
|
+
{
|
8
|
+
'rack.input' => StringIO.new,
|
9
|
+
'REQUEST_METHOD' => 'GET',
|
10
|
+
'PATH_INFO' => '/homepage',
|
11
|
+
'QUERY_STRING' => 'param=something'
|
12
|
+
}
|
13
|
+
end
|
7
14
|
let(:app) { double(:call => [200, headers, 'body']) }
|
8
15
|
let(:listener) { Appsignal::Rack::StreamingListener.new(app, {}) }
|
9
16
|
|
@@ -28,9 +35,15 @@ describe Appsignal::Rack::StreamingListener do
|
|
28
35
|
end
|
29
36
|
|
30
37
|
describe "#call_with_appsignal_monitoring" do
|
31
|
-
let!(:transaction)
|
32
|
-
|
33
|
-
|
38
|
+
let!(:transaction) do
|
39
|
+
Appsignal::Transaction.create(
|
40
|
+
SecureRandom.uuid,
|
41
|
+
Appsignal::Transaction::HTTP_REQUEST,
|
42
|
+
::Rack::Request.new(env)
|
43
|
+
)
|
44
|
+
end
|
45
|
+
let(:wrapper) { Appsignal::StreamWrapper.new('body', transaction) }
|
46
|
+
let(:raw_payload) { {:foo => :bar} }
|
34
47
|
|
35
48
|
before do
|
36
49
|
SecureRandom.stub(:uuid => '123')
|
@@ -40,7 +53,7 @@ describe Appsignal::Rack::StreamingListener do
|
|
40
53
|
|
41
54
|
it "should create a transaction" do
|
42
55
|
expect( Appsignal::Transaction ).to receive(:create)
|
43
|
-
.with('123',
|
56
|
+
.with('123', Appsignal::Transaction::HTTP_REQUEST, instance_of(Rack::Request))
|
44
57
|
.and_return(transaction)
|
45
58
|
|
46
59
|
listener.call_with_appsignal_monitoring(env)
|
@@ -48,27 +61,37 @@ describe Appsignal::Rack::StreamingListener do
|
|
48
61
|
|
49
62
|
it "should instrument the call" do
|
50
63
|
expect( ActiveSupport::Notifications ).to receive(:instrument)
|
51
|
-
.with('process_action.rack'
|
52
|
-
.and_yield
|
64
|
+
.with('process_action.rack')
|
65
|
+
.and_yield
|
53
66
|
|
54
67
|
listener.call_with_appsignal_monitoring(env)
|
55
68
|
end
|
56
69
|
|
57
|
-
it "should add `appsignal.action` to the
|
58
|
-
allow( ActiveSupport::Notifications ).to receive(:instrument)
|
59
|
-
.and_yield(raw_payload)
|
70
|
+
it "should add `appsignal.action` to the transaction" do
|
71
|
+
allow( ActiveSupport::Notifications ).to receive(:instrument).and_yield
|
60
72
|
|
61
73
|
env['appsignal.action'] = 'Action'
|
74
|
+
|
75
|
+
expect( transaction ).to receive(:set_action).with('Action')
|
76
|
+
|
62
77
|
listener.call_with_appsignal_monitoring(env)
|
78
|
+
end
|
79
|
+
|
80
|
+
it "should add the path, method and queue start to the transaction" do
|
81
|
+
allow( ActiveSupport::Notifications ).to receive(:instrument).and_yield
|
82
|
+
|
83
|
+
expect( transaction ).to receive(:set_metadata).with('path', '/homepage')
|
84
|
+
expect( transaction ).to receive(:set_metadata).with('method', 'GET')
|
85
|
+
expect( transaction ).to receive(:set_http_or_background_queue_start)
|
63
86
|
|
64
|
-
|
87
|
+
listener.call_with_appsignal_monitoring(env)
|
65
88
|
end
|
66
89
|
|
67
90
|
context "with an exception in the instrumentation call" do
|
68
91
|
it "should add the exception to the transaction" do
|
69
92
|
allow( app ).to receive(:call).and_raise(VerySpecificError.new('broken'))
|
70
93
|
|
71
|
-
expect( transaction ).to receive(:
|
94
|
+
expect( transaction ).to receive(:set_error)
|
72
95
|
|
73
96
|
listener.call_with_appsignal_monitoring(env) rescue VerySpecificError
|
74
97
|
end
|
@@ -79,37 +102,17 @@ describe Appsignal::Rack::StreamingListener do
|
|
79
102
|
.with('body', transaction)
|
80
103
|
.and_return(wrapper)
|
81
104
|
|
82
|
-
|
105
|
+
body = listener.call_with_appsignal_monitoring(env)[2]
|
83
106
|
|
84
107
|
expect( body ).to be_a(Appsignal::StreamWrapper)
|
85
108
|
end
|
86
109
|
end
|
87
|
-
|
88
|
-
describe "#raw_payload" do
|
89
|
-
let(:env) do
|
90
|
-
{
|
91
|
-
'rack.input' => StringIO.new,
|
92
|
-
'REQUEST_METHOD' => 'GET',
|
93
|
-
'PATH_INFO' => '/homepage',
|
94
|
-
'QUERY_STRING' => 'param=something'
|
95
|
-
}
|
96
|
-
end
|
97
|
-
|
98
|
-
it "should return an Appsignal compatible playload" do
|
99
|
-
expect( listener.raw_payload(env) ).to eql({
|
100
|
-
:params => {'param' => 'something'},
|
101
|
-
:session => {},
|
102
|
-
:method => 'GET',
|
103
|
-
:path => '/homepage'
|
104
|
-
})
|
105
|
-
end
|
106
|
-
end
|
107
110
|
end
|
108
111
|
|
109
112
|
describe Appsignal::StreamWrapper do
|
110
|
-
let(:stream)
|
111
|
-
let(:transaction)
|
112
|
-
let(:wrapper)
|
113
|
+
let(:stream) { double }
|
114
|
+
let(:transaction) { Appsignal::Transaction.create(SecureRandom.uuid, Appsignal::Transaction::HTTP_REQUEST, {}) }
|
115
|
+
let(:wrapper) { Appsignal::StreamWrapper.new(stream, transaction) }
|
113
116
|
|
114
117
|
describe "#each" do
|
115
118
|
it "should call the original stream" do
|
@@ -123,7 +126,7 @@ describe Appsignal::StreamWrapper do
|
|
123
126
|
allow( stream ).to receive(:each)
|
124
127
|
.and_raise(VerySpecificError.new('broken'))
|
125
128
|
|
126
|
-
expect( transaction ).to receive(:
|
129
|
+
expect( transaction ).to receive(:set_error)
|
127
130
|
|
128
131
|
wrapper.send(:each) rescue VerySpecificError
|
129
132
|
end
|
@@ -133,7 +136,7 @@ describe Appsignal::StreamWrapper do
|
|
133
136
|
describe "#close" do
|
134
137
|
it "should call the original stream and close the transaction" do
|
135
138
|
expect( stream ).to receive(:close)
|
136
|
-
expect(
|
139
|
+
expect( Appsignal::Transaction ).to receive(:complete_current!)
|
137
140
|
|
138
141
|
wrapper.close
|
139
142
|
end
|
@@ -143,8 +146,8 @@ describe Appsignal::StreamWrapper do
|
|
143
146
|
allow( stream ).to receive(:close)
|
144
147
|
.and_raise(VerySpecificError.new('broken'))
|
145
148
|
|
146
|
-
expect( transaction ).to receive(:
|
147
|
-
expect(
|
149
|
+
expect( transaction ).to receive(:set_error)
|
150
|
+
expect( Appsignal::Transaction ).to receive(:complete_current!)
|
148
151
|
|
149
152
|
wrapper.send(:close) rescue VerySpecificError
|
150
153
|
end
|
data/spec/lib/appsignal_spec.rb
CHANGED
@@ -162,6 +162,15 @@ describe Appsignal do
|
|
162
162
|
end
|
163
163
|
end
|
164
164
|
|
165
|
+
describe ".forked" do
|
166
|
+
it "should resubscribe and start the extension" do
|
167
|
+
Appsignal::Extension.should_receive(:start)
|
168
|
+
Appsignal::Subscriber.should_receive(:new)
|
169
|
+
|
170
|
+
Appsignal.forked
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
165
174
|
describe ".stop" do
|
166
175
|
it "should call stop on the extension" do
|
167
176
|
Appsignal::Extension.should_receive(:stop)
|
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.12.beta.
|
4
|
+
version: 0.12.beta.51
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Robert Beekman
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2015-10-
|
12
|
+
date: 2015-10-21 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rack
|