appsignal 0.12.beta.49 → 0.12.beta.50
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/ext/agent.yml +5 -5
- data/lib/appsignal/rack/streaming_listener.rb +70 -0
- data/lib/appsignal/version.rb +1 -1
- data/spec/lib/appsignal/rack/streaming_listener_spec.rb +153 -0
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6f4983934fcdf39da6dede5551dda1a8caa25db3
|
4
|
+
data.tar.gz: 2ffafd503a9951363ffe07e3a968700b39bd740e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 84e1091639bd740344c69121064d3a5fc91e7023cf2bb9e21f5ef4c970840830e3c92f3406dd6b46c8c1608423ae0b919415907ab39844fca6d9c8e8a6adef37
|
7
|
+
data.tar.gz: 8cecfffc66f3c8d2815a85b39ff3d5d36a87e640db8f454d49e2b73abd592225ffacca0693229e642536e4bdd5733146b57c1ed9e94a37ff1965375dc01c66c0
|
data/ext/agent.yml
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
---
|
2
|
-
:version:
|
2
|
+
:version: ac7fefc
|
3
3
|
:triples:
|
4
4
|
x86_64-linux:
|
5
|
-
:checksum:
|
6
|
-
:download_url: https://appsignal-agent-releases.global.ssl.fastly.net/
|
5
|
+
:checksum: 04dbd6009135c3f023cf879bb31947a0991cef3d8e39bd592564df40915f0ee9
|
6
|
+
:download_url: https://appsignal-agent-releases.global.ssl.fastly.net/ac7fefc/appsignal-agent-x86_64-linux-static.tar.gz
|
7
7
|
:lib_filename: libappsignal.a
|
8
8
|
x86_64-darwin:
|
9
|
-
:checksum:
|
10
|
-
:download_url: https://appsignal-agent-releases.global.ssl.fastly.net/
|
9
|
+
:checksum: 3028676f73537b03b6afccc0d027519559053450369d16a798bdb9904ea43d2a
|
10
|
+
:download_url: https://appsignal-agent-releases.global.ssl.fastly.net/ac7fefc/appsignal-agent-x86_64-darwin-static.tar.gz
|
11
11
|
:lib_filename: libappsignal.a
|
@@ -0,0 +1,70 @@
|
|
1
|
+
# Appsignal module that tracks exceptions in Streaming rack responses.
|
2
|
+
module Appsignal
|
3
|
+
module Rack
|
4
|
+
class StreamingListener
|
5
|
+
def initialize(app, options = {})
|
6
|
+
Appsignal.logger.debug 'Initializing Appsignal::Rack::StreamingListener'
|
7
|
+
@app, @options = app, options
|
8
|
+
end
|
9
|
+
|
10
|
+
def call(env)
|
11
|
+
if Appsignal.active?
|
12
|
+
call_with_appsignal_monitoring(env)
|
13
|
+
else
|
14
|
+
@app.call(env)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def call_with_appsignal_monitoring(env)
|
19
|
+
transaction = Appsignal::Transaction.create(SecureRandom.uuid, env)
|
20
|
+
streaming = false
|
21
|
+
|
22
|
+
# Instrument a `process_action`, to set params/action name
|
23
|
+
status, headers, body = ActiveSupport::Notifications
|
24
|
+
.instrument('process_action.rack', raw_payload(env)) do |payload|
|
25
|
+
begin
|
26
|
+
@app.call(env)
|
27
|
+
rescue Exception => e
|
28
|
+
transaction.add_exception(e); raise e;
|
29
|
+
ensure
|
30
|
+
payload[:action] = env['appsignal.action']
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# Wrap the result body with our StreamWrapper
|
35
|
+
[status, headers, StreamWrapper.new(body, transaction)]
|
36
|
+
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
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
class StreamWrapper
|
51
|
+
def initialize(stream, transaction)
|
52
|
+
@stream = stream
|
53
|
+
@transaction = transaction
|
54
|
+
end
|
55
|
+
|
56
|
+
def each
|
57
|
+
@stream.each { |c| yield(c) }
|
58
|
+
rescue Exception => e
|
59
|
+
@transaction.add_exception(e); raise e
|
60
|
+
end
|
61
|
+
|
62
|
+
def close
|
63
|
+
@stream.close if @stream.respond_to?(:close)
|
64
|
+
rescue Exception => e
|
65
|
+
@transaction.add_exception(e); raise e
|
66
|
+
ensure
|
67
|
+
@transaction.complete!
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
data/lib/appsignal/version.rb
CHANGED
@@ -0,0 +1,153 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'appsignal/rack/streaming_listener'
|
3
|
+
|
4
|
+
describe Appsignal::Rack::StreamingListener do
|
5
|
+
let(:headers) { {} }
|
6
|
+
let(:env) { {} }
|
7
|
+
let(:app) { double(:call => [200, headers, 'body']) }
|
8
|
+
let(:listener) { Appsignal::Rack::StreamingListener.new(app, {}) }
|
9
|
+
|
10
|
+
describe "#call" do
|
11
|
+
context "when Appsignal is active" do
|
12
|
+
before { Appsignal.stub(:active? => true) }
|
13
|
+
|
14
|
+
it "should call `call_with_appsignal_monitoring`" do
|
15
|
+
expect( listener ).to receive(:call_with_appsignal_monitoring)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
context "when Appsignal is not active" do
|
20
|
+
before { Appsignal.stub(:active? => false) }
|
21
|
+
|
22
|
+
it "should not call `call_with_appsignal_monitoring`" do
|
23
|
+
expect( listener ).to_not receive(:call_with_appsignal_monitoring)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
after { listener.call(env) }
|
28
|
+
end
|
29
|
+
|
30
|
+
describe "#call_with_appsignal_monitoring" do
|
31
|
+
let!(:transaction) { Appsignal::Transaction.create(SecureRandom.uuid, env) }
|
32
|
+
let(:wrapper) { Appsignal::StreamWrapper.new('body', transaction) }
|
33
|
+
let(:raw_payload) { {:foo => :bar} }
|
34
|
+
|
35
|
+
before do
|
36
|
+
SecureRandom.stub(:uuid => '123')
|
37
|
+
listener.stub(:raw_payload => raw_payload)
|
38
|
+
Appsignal::Transaction.stub(:create => transaction)
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should create a transaction" do
|
42
|
+
expect( Appsignal::Transaction ).to receive(:create)
|
43
|
+
.with('123', env)
|
44
|
+
.and_return(transaction)
|
45
|
+
|
46
|
+
listener.call_with_appsignal_monitoring(env)
|
47
|
+
end
|
48
|
+
|
49
|
+
it "should instrument the call" do
|
50
|
+
expect( ActiveSupport::Notifications ).to receive(:instrument)
|
51
|
+
.with('process_action.rack', raw_payload)
|
52
|
+
.and_yield(raw_payload)
|
53
|
+
|
54
|
+
listener.call_with_appsignal_monitoring(env)
|
55
|
+
end
|
56
|
+
|
57
|
+
it "should add `appsignal.action` to the payload" do
|
58
|
+
allow( ActiveSupport::Notifications ).to receive(:instrument)
|
59
|
+
.and_yield(raw_payload)
|
60
|
+
|
61
|
+
env['appsignal.action'] = 'Action'
|
62
|
+
listener.call_with_appsignal_monitoring(env)
|
63
|
+
|
64
|
+
expect( raw_payload ).to eql({:foo => :bar, :action => 'Action'})
|
65
|
+
end
|
66
|
+
|
67
|
+
context "with an exception in the instrumentation call" do
|
68
|
+
it "should add the exception to the transaction" do
|
69
|
+
allow( app ).to receive(:call).and_raise(VerySpecificError.new('broken'))
|
70
|
+
|
71
|
+
expect( transaction ).to receive(:add_exception)
|
72
|
+
|
73
|
+
listener.call_with_appsignal_monitoring(env) rescue VerySpecificError
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
it "should wrap the body in a wrapper" do
|
78
|
+
expect( Appsignal::StreamWrapper ).to receive(:new)
|
79
|
+
.with('body', transaction)
|
80
|
+
.and_return(wrapper)
|
81
|
+
|
82
|
+
status, headers, body = listener.call_with_appsignal_monitoring(env)
|
83
|
+
|
84
|
+
expect( body ).to be_a(Appsignal::StreamWrapper)
|
85
|
+
end
|
86
|
+
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
|
+
end
|
108
|
+
|
109
|
+
describe Appsignal::StreamWrapper do
|
110
|
+
let(:stream) { double }
|
111
|
+
let(:transaction) { Appsignal::Transaction.create(SecureRandom.uuid, {}) }
|
112
|
+
let(:wrapper) { Appsignal::StreamWrapper.new(stream, transaction) }
|
113
|
+
|
114
|
+
describe "#each" do
|
115
|
+
it "should call the original stream" do
|
116
|
+
expect( stream ).to receive(:each)
|
117
|
+
|
118
|
+
wrapper.each
|
119
|
+
end
|
120
|
+
|
121
|
+
context "when each raises an error" do
|
122
|
+
it "should add the exception to the transaction" do
|
123
|
+
allow( stream ).to receive(:each)
|
124
|
+
.and_raise(VerySpecificError.new('broken'))
|
125
|
+
|
126
|
+
expect( transaction ).to receive(:add_exception)
|
127
|
+
|
128
|
+
wrapper.send(:each) rescue VerySpecificError
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
describe "#close" do
|
134
|
+
it "should call the original stream and close the transaction" do
|
135
|
+
expect( stream ).to receive(:close)
|
136
|
+
expect( transaction ).to receive(:complete!)
|
137
|
+
|
138
|
+
wrapper.close
|
139
|
+
end
|
140
|
+
|
141
|
+
context "when each raises an error" do
|
142
|
+
it "should add the exception to the transaction and close it" do
|
143
|
+
allow( stream ).to receive(:close)
|
144
|
+
.and_raise(VerySpecificError.new('broken'))
|
145
|
+
|
146
|
+
expect( transaction ).to receive(:add_exception)
|
147
|
+
expect( transaction ).to receive(:complete!)
|
148
|
+
|
149
|
+
wrapper.send(:close) rescue VerySpecificError
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
153
|
+
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.12.beta.
|
4
|
+
version: 0.12.beta.50
|
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-20 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rack
|
@@ -177,6 +177,7 @@ files:
|
|
177
177
|
- lib/appsignal/rack/js_exception_catcher.rb
|
178
178
|
- lib/appsignal/rack/rails_instrumentation.rb
|
179
179
|
- lib/appsignal/rack/sinatra_instrumentation.rb
|
180
|
+
- lib/appsignal/rack/streaming_listener.rb
|
180
181
|
- lib/appsignal/subscriber.rb
|
181
182
|
- lib/appsignal/transaction.rb
|
182
183
|
- lib/appsignal/transmitter.rb
|
@@ -220,6 +221,7 @@ files:
|
|
220
221
|
- spec/lib/appsignal/rack/js_exception_catcher_spec.rb
|
221
222
|
- spec/lib/appsignal/rack/rails_instrumentation_spec.rb
|
222
223
|
- spec/lib/appsignal/rack/sinatra_instrumentation_spec.rb
|
224
|
+
- spec/lib/appsignal/rack/streaming_listener_spec.rb
|
223
225
|
- spec/lib/appsignal/subscriber_spec.rb
|
224
226
|
- spec/lib/appsignal/transaction_spec.rb
|
225
227
|
- spec/lib/appsignal/transmitter_spec.rb
|
@@ -295,6 +297,7 @@ test_files:
|
|
295
297
|
- spec/lib/appsignal/rack/js_exception_catcher_spec.rb
|
296
298
|
- spec/lib/appsignal/rack/rails_instrumentation_spec.rb
|
297
299
|
- spec/lib/appsignal/rack/sinatra_instrumentation_spec.rb
|
300
|
+
- spec/lib/appsignal/rack/streaming_listener_spec.rb
|
298
301
|
- spec/lib/appsignal/subscriber_spec.rb
|
299
302
|
- spec/lib/appsignal/transaction_spec.rb
|
300
303
|
- spec/lib/appsignal/transmitter_spec.rb
|