appsignal 0.11.7 → 0.11.8.beta.0
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/CHANGELOG.md +3 -0
- data/lib/appsignal.rb +2 -0
- data/lib/appsignal/config.rb +12 -10
- data/lib/appsignal/integrations/rails.rb +4 -0
- data/lib/appsignal/js_exception_transaction.rb +46 -0
- data/lib/appsignal/rack/js_exception_catcher.rb +25 -0
- data/lib/appsignal/version.rb +1 -1
- data/spec/lib/appsignal/config_spec.rb +23 -19
- data/spec/lib/appsignal/integrations/rails_spec.rb +4 -0
- data/spec/lib/appsignal/js_exception_transaction_spec.rb +91 -0
- data/spec/lib/appsignal/rack/js_exception_catcher_spec.rb +89 -0
- metadata +10 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 69c0fe4aba981d664f4b5a320c2cf47816ae4598
|
4
|
+
data.tar.gz: 546e20aa73e171ca1183c4cba04beed672ced563
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: dba3ef8508c2b43ef0456f926397ae29cd34a0b454de79cf3cf10e853386a2bfb90fb2d1e60ef21f9ffcf8e56c9425f6ede6669436430b35e2fb95936851be8c
|
7
|
+
data.tar.gz: 26d06743732e417cd38ddf55372f25f80be96f38d55ed5719c3740b746a32cc0579e5f399e75b1b9d31a62564a31d643778ca8a0ff8ddc02ba7142c582762cb8
|
data/CHANGELOG.md
CHANGED
data/lib/appsignal.rb
CHANGED
@@ -195,6 +195,7 @@ require 'appsignal/marker'
|
|
195
195
|
require 'appsignal/rack/listener'
|
196
196
|
require 'appsignal/rack/instrumentation'
|
197
197
|
require 'appsignal/rack/sinatra_instrumentation'
|
198
|
+
require 'appsignal/rack/js_exception_catcher'
|
198
199
|
require 'appsignal/params_sanitizer'
|
199
200
|
require 'appsignal/transaction'
|
200
201
|
require 'appsignal/transaction/formatter'
|
@@ -203,3 +204,4 @@ require 'appsignal/transmitter'
|
|
203
204
|
require 'appsignal/ipc'
|
204
205
|
require 'appsignal/version'
|
205
206
|
require 'appsignal/integrations/rails'
|
207
|
+
require 'appsignal/js_exception_transaction'
|
data/lib/appsignal/config.rb
CHANGED
@@ -7,22 +7,24 @@ module Appsignal
|
|
7
7
|
include Appsignal::CarefulLogger
|
8
8
|
|
9
9
|
DEFAULT_CONFIG = {
|
10
|
-
:ignore_exceptions
|
11
|
-
:ignore_actions
|
12
|
-
:send_params
|
13
|
-
:endpoint
|
14
|
-
:slow_request_threshold
|
15
|
-
:instrument_net_http
|
16
|
-
:skip_session_data
|
10
|
+
:ignore_exceptions => [],
|
11
|
+
:ignore_actions => [],
|
12
|
+
:send_params => true,
|
13
|
+
:endpoint => 'https://push.appsignal.com/1',
|
14
|
+
:slow_request_threshold => 200,
|
15
|
+
:instrument_net_http => true,
|
16
|
+
:skip_session_data => false,
|
17
|
+
:enable_frontend_error_catching => false,
|
18
|
+
:frontend_error_catching_path => '/appsignal_error_catcher'
|
17
19
|
}.freeze
|
18
20
|
|
19
21
|
attr_reader :root_path, :env, :initial_config, :config_hash
|
20
22
|
|
21
23
|
def initialize(root_path, env, initial_config={}, logger=Appsignal.logger)
|
22
|
-
@root_path
|
23
|
-
@env
|
24
|
+
@root_path = root_path
|
25
|
+
@env = env.to_s
|
24
26
|
@initial_config = initial_config
|
25
|
-
@logger
|
27
|
+
@logger = logger
|
26
28
|
|
27
29
|
if File.exists?(config_file)
|
28
30
|
load_config_from_disk
|
@@ -7,6 +7,10 @@ if defined?(::Rails)
|
|
7
7
|
initializer 'appsignal.configure_rails_initialization' do |app|
|
8
8
|
app.middleware.insert_before(
|
9
9
|
ActionDispatch::RemoteIp,
|
10
|
+
Appsignal::Rack::JSExceptionCatcher
|
11
|
+
)
|
12
|
+
app.middleware.insert_after(
|
13
|
+
Appsignal::Rack::JSExceptionCatcher,
|
10
14
|
Appsignal::Rack::Listener
|
11
15
|
)
|
12
16
|
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module Appsignal
|
2
|
+
class JSExceptionTransaction
|
3
|
+
|
4
|
+
def initialize(data)
|
5
|
+
@data = data
|
6
|
+
@time = Time.now.to_i
|
7
|
+
end
|
8
|
+
|
9
|
+
def type
|
10
|
+
:exception
|
11
|
+
end
|
12
|
+
|
13
|
+
def action
|
14
|
+
@data['action']
|
15
|
+
end
|
16
|
+
|
17
|
+
def clear_events!; end
|
18
|
+
def convert_values_to_primitives!; end
|
19
|
+
def events; []; end
|
20
|
+
|
21
|
+
def to_hash
|
22
|
+
{
|
23
|
+
:request_id => SecureRandom.uuid,
|
24
|
+
:log_entry => {
|
25
|
+
:action => action,
|
26
|
+
:path => @data['path'],
|
27
|
+
:kind => 'frontend',
|
28
|
+
:time => @time,
|
29
|
+
:environment => @data['environment'],
|
30
|
+
:revision => Appsignal.agent.revision
|
31
|
+
},
|
32
|
+
:exception => {
|
33
|
+
:exception => @data['name'],
|
34
|
+
:message => @data['message'],
|
35
|
+
:backtrace => @data['backtrace']
|
36
|
+
},
|
37
|
+
:failed => true
|
38
|
+
}
|
39
|
+
end
|
40
|
+
|
41
|
+
def complete!
|
42
|
+
Appsignal.enqueue(self)
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Appsignal
|
2
|
+
module Rack
|
3
|
+
class JSExceptionCatcher
|
4
|
+
def initialize(app, options = {})
|
5
|
+
Appsignal.logger.debug 'Initializing Appsignal::Rack::JSExceptionCatcher'
|
6
|
+
@app, @options = app, options
|
7
|
+
end
|
8
|
+
|
9
|
+
def call(env)
|
10
|
+
if env['PATH_INFO'] == Appsignal.config[:frontend_error_catching_path]
|
11
|
+
if Appsignal.config.active? &&
|
12
|
+
Appsignal.config[:enable_frontend_error_catching] == true
|
13
|
+
|
14
|
+
body = JSON.parse(env['rack.input'].read)
|
15
|
+
transaction = JSExceptionTransaction.new(body)
|
16
|
+
transaction.complete!
|
17
|
+
end
|
18
|
+
return [ 200, {}, []]
|
19
|
+
else
|
20
|
+
@app.call(env)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
data/lib/appsignal/version.rb
CHANGED
@@ -16,16 +16,18 @@ describe Appsignal::Config do
|
|
16
16
|
|
17
17
|
it "should merge with the default config and fill the config hash" do
|
18
18
|
subject.config_hash.should == {
|
19
|
-
:ignore_exceptions
|
20
|
-
:ignore_actions
|
21
|
-
:instrument_net_http
|
22
|
-
:skip_session_data
|
23
|
-
:send_params
|
24
|
-
:endpoint
|
25
|
-
:slow_request_threshold
|
26
|
-
:push_api_key
|
27
|
-
:name
|
28
|
-
:active
|
19
|
+
:ignore_exceptions => [],
|
20
|
+
:ignore_actions => [],
|
21
|
+
:instrument_net_http => true,
|
22
|
+
:skip_session_data => false,
|
23
|
+
:send_params => true,
|
24
|
+
:endpoint => 'https://push.appsignal.com/1',
|
25
|
+
:slow_request_threshold => 200,
|
26
|
+
:push_api_key => 'abc',
|
27
|
+
:name => 'TestApp',
|
28
|
+
:active => true,
|
29
|
+
:enable_frontend_error_catching => false,
|
30
|
+
:frontend_error_catching_path => '/appsignal_error_catcher'
|
29
31
|
}
|
30
32
|
end
|
31
33
|
|
@@ -127,15 +129,17 @@ describe Appsignal::Config do
|
|
127
129
|
)
|
128
130
|
|
129
131
|
subject.config_hash.should == {
|
130
|
-
:push_api_key
|
131
|
-
:ignore_exceptions
|
132
|
-
:ignore_actions
|
133
|
-
:send_params
|
134
|
-
:instrument_net_http
|
135
|
-
:skip_session_data
|
136
|
-
:endpoint
|
137
|
-
:slow_request_threshold
|
138
|
-
:active
|
132
|
+
:push_api_key => 'push_api_key',
|
133
|
+
:ignore_exceptions => [],
|
134
|
+
:ignore_actions => [],
|
135
|
+
:send_params => true,
|
136
|
+
:instrument_net_http => true,
|
137
|
+
:skip_session_data => false,
|
138
|
+
:endpoint => 'https://push.appsignal.com/1',
|
139
|
+
:slow_request_threshold => 200,
|
140
|
+
:active => true,
|
141
|
+
:enable_frontend_error_catching => false,
|
142
|
+
:frontend_error_catching_path => '/appsignal_error_catcher'
|
139
143
|
}
|
140
144
|
end
|
141
145
|
|
@@ -40,6 +40,10 @@ if rails_present?
|
|
40
40
|
MyApp::Application.middleware.to_a.should include Appsignal::Rack::Listener
|
41
41
|
end
|
42
42
|
|
43
|
+
it "should have added the js exception catcher middleware" do
|
44
|
+
MyApp::Application.middleware.to_a.should include Appsignal::Rack::JSExceptionCatcher
|
45
|
+
end
|
46
|
+
|
43
47
|
it "should not have added the instrumentation middleware" do
|
44
48
|
MyApp::Application.middleware.to_a.should_not include Appsignal::Rack::Instrumentation
|
45
49
|
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Appsignal::JSExceptionTransaction do
|
4
|
+
let(:transaction) { Appsignal::JSExceptionTransaction.new(data) }
|
5
|
+
let(:data) do
|
6
|
+
{
|
7
|
+
'name' => 'TypeError',
|
8
|
+
'message' => 'foo is not a valid method',
|
9
|
+
'action' => 'ExceptionIncidentComponent',
|
10
|
+
'path' => 'foo.bar/moo',
|
11
|
+
'environment' => 'development',
|
12
|
+
'backtrace' => [
|
13
|
+
'foo.bar/js:11:1',
|
14
|
+
'foo.bar/js:22:2',
|
15
|
+
]
|
16
|
+
}
|
17
|
+
end
|
18
|
+
|
19
|
+
describe "#type" do
|
20
|
+
it "should return `:exception`" do
|
21
|
+
expect( transaction.type ).to eql :exception
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe "#action" do
|
26
|
+
it "should return the action" do
|
27
|
+
expect( transaction.action ).to eql 'ExceptionIncidentComponent'
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
describe "#clear_events" do
|
32
|
+
it "should respond to `clear_events!`" do
|
33
|
+
expect( transaction ).to respond_to :clear_events!
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
describe "#convert_values_to_primitives!" do
|
38
|
+
it "should respond to `convert_values_to_primitives!`" do
|
39
|
+
expect( transaction ).to respond_to :convert_values_to_primitives!
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
describe "#events" do
|
44
|
+
it "should respond to `events` with an empty array" do
|
45
|
+
expect( transaction.events ).to eql []
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
describe "#to_hash" do
|
50
|
+
around do |sample|
|
51
|
+
Timecop.freeze(Time.at(123)) { sample.run }
|
52
|
+
end
|
53
|
+
|
54
|
+
before do
|
55
|
+
SecureRandom.stub(:uuid => 'uuid')
|
56
|
+
Appsignal.stub(:agent => double(:revision => 'abcdef'))
|
57
|
+
end
|
58
|
+
|
59
|
+
it "should generate a hash based on the given data" do
|
60
|
+
expect( transaction.to_hash).to eql({
|
61
|
+
:request_id => 'uuid',
|
62
|
+
:log_entry => {
|
63
|
+
:action => 'ExceptionIncidentComponent',
|
64
|
+
:path => 'foo.bar/moo',
|
65
|
+
:kind => 'frontend',
|
66
|
+
:time => 123,
|
67
|
+
:environment => 'development',
|
68
|
+
:revision => 'abcdef'
|
69
|
+
},
|
70
|
+
:exception => {
|
71
|
+
:exception => 'TypeError',
|
72
|
+
:message => 'foo is not a valid method',
|
73
|
+
:backtrace => [
|
74
|
+
'foo.bar/js:11:1',
|
75
|
+
'foo.bar/js:22:2',
|
76
|
+
]
|
77
|
+
},
|
78
|
+
:failed => true
|
79
|
+
})
|
80
|
+
end
|
81
|
+
|
82
|
+
describe "#complete!" do
|
83
|
+
it "should enqueue itself" do
|
84
|
+
expect( Appsignal ).to receive(:enqueue).with(transaction)
|
85
|
+
|
86
|
+
transaction.complete!
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
end
|
91
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Appsignal::Rack::JSExceptionCatcher do
|
4
|
+
let(:app) { double(:call => true) }
|
5
|
+
let(:options) { double }
|
6
|
+
let(:active) { true }
|
7
|
+
let(:config_options) { {:enable_frontend_error_catching => true} }
|
8
|
+
let(:config) { project_fixture_config('production', config_options) }
|
9
|
+
|
10
|
+
before do
|
11
|
+
Appsignal.stub(:config => config)
|
12
|
+
config.stub(:active? => active)
|
13
|
+
end
|
14
|
+
|
15
|
+
describe "#initialize" do
|
16
|
+
it "should log to the logger" do
|
17
|
+
expect( Appsignal.logger ).to receive(:debug)
|
18
|
+
.with('Initializing Appsignal::Rack::JSExceptionCatcher')
|
19
|
+
|
20
|
+
Appsignal::Rack::JSExceptionCatcher.new(app, options)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
describe "#call" do
|
25
|
+
let(:catcher) { Appsignal::Rack::JSExceptionCatcher.new(app, options) }
|
26
|
+
|
27
|
+
context "when path is not `/appsignal_error_catcher`" do
|
28
|
+
let(:env) { {'PATH_INFO' => '/foo'} }
|
29
|
+
|
30
|
+
it "should call the next middleware" do
|
31
|
+
expect( app ).to receive(:call).with(env)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
context "when path is `/appsignal_error_catcher`" do
|
36
|
+
let(:transaction) { double(:complete! => true) }
|
37
|
+
let(:env) do
|
38
|
+
{
|
39
|
+
'PATH_INFO' => '/appsignal_error_catcher',
|
40
|
+
'rack.input' => double(:read => '{"foo": "bar"}')
|
41
|
+
}
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should create a JSExceptionTransaction" do
|
45
|
+
expect( Appsignal::JSExceptionTransaction ).to receive(:new)
|
46
|
+
.with({'foo' => 'bar'})
|
47
|
+
.and_return(transaction)
|
48
|
+
|
49
|
+
expect( transaction ).to receive(:complete!)
|
50
|
+
end
|
51
|
+
|
52
|
+
context "when appsignal is not active" do
|
53
|
+
let(:active) { false }
|
54
|
+
|
55
|
+
it "should not create a transaction" do
|
56
|
+
expect( Appsignal::JSExceptionTransaction ).to_not receive(:new)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
context "when `enable_frontend_error_catching` is disabled" do
|
61
|
+
let(:config_options) { {:enable_frontend_error_catching => false} }
|
62
|
+
|
63
|
+
it "should not create a transaction" do
|
64
|
+
expect( Appsignal::JSExceptionTransaction ).to_not receive(:new)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
context "when `frontend_error_catching_path` is different" do
|
69
|
+
let(:config_options) do
|
70
|
+
{
|
71
|
+
:enable_frontend_error_catching => true,
|
72
|
+
:frontend_error_catching_path => '/foo'
|
73
|
+
}
|
74
|
+
end
|
75
|
+
|
76
|
+
it "should not create a transaction" do
|
77
|
+
expect( Appsignal::JSExceptionTransaction ).to_not receive(:new)
|
78
|
+
end
|
79
|
+
|
80
|
+
it "should call the next middleware" do
|
81
|
+
expect( app ).to receive(:call).with(env)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
after { catcher.call(env) }
|
87
|
+
end
|
88
|
+
|
89
|
+
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.11.
|
4
|
+
version: 0.11.8.beta.0
|
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: 2015-
|
15
|
+
date: 2015-03-03 00:00:00.000000000 Z
|
16
16
|
dependencies:
|
17
17
|
- !ruby/object:Gem::Dependency
|
18
18
|
name: rack
|
@@ -170,9 +170,11 @@ files:
|
|
170
170
|
- lib/appsignal/integrations/sinatra.rb
|
171
171
|
- lib/appsignal/integrations/unicorn.rb
|
172
172
|
- lib/appsignal/ipc.rb
|
173
|
+
- lib/appsignal/js_exception_transaction.rb
|
173
174
|
- lib/appsignal/marker.rb
|
174
175
|
- lib/appsignal/params_sanitizer.rb
|
175
176
|
- lib/appsignal/rack/instrumentation.rb
|
177
|
+
- lib/appsignal/rack/js_exception_catcher.rb
|
176
178
|
- lib/appsignal/rack/listener.rb
|
177
179
|
- lib/appsignal/rack/sinatra_instrumentation.rb
|
178
180
|
- lib/appsignal/transaction.rb
|
@@ -213,9 +215,11 @@ files:
|
|
213
215
|
- spec/lib/appsignal/integrations/sinatra_spec.rb
|
214
216
|
- spec/lib/appsignal/integrations/unicorn_spec.rb
|
215
217
|
- spec/lib/appsignal/ipc_spec.rb
|
218
|
+
- spec/lib/appsignal/js_exception_transaction_spec.rb
|
216
219
|
- spec/lib/appsignal/marker_spec.rb
|
217
220
|
- spec/lib/appsignal/params_sanitizer_spec.rb
|
218
221
|
- spec/lib/appsignal/rack/instrumentation_spec.rb
|
222
|
+
- spec/lib/appsignal/rack/js_exception_catcher_spec.rb
|
219
223
|
- spec/lib/appsignal/rack/listener_spec.rb
|
220
224
|
- spec/lib/appsignal/rack/sinatra_instrumentation_spec.rb
|
221
225
|
- spec/lib/appsignal/transaction/formatter_spec.rb
|
@@ -250,9 +254,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
250
254
|
version: '1.9'
|
251
255
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
252
256
|
requirements:
|
253
|
-
- - "
|
257
|
+
- - ">"
|
254
258
|
- !ruby/object:Gem::Version
|
255
|
-
version:
|
259
|
+
version: 1.3.1
|
256
260
|
requirements: []
|
257
261
|
rubyforge_project:
|
258
262
|
rubygems_version: 2.2.2
|
@@ -284,9 +288,11 @@ test_files:
|
|
284
288
|
- spec/lib/appsignal/integrations/sinatra_spec.rb
|
285
289
|
- spec/lib/appsignal/integrations/unicorn_spec.rb
|
286
290
|
- spec/lib/appsignal/ipc_spec.rb
|
291
|
+
- spec/lib/appsignal/js_exception_transaction_spec.rb
|
287
292
|
- spec/lib/appsignal/marker_spec.rb
|
288
293
|
- spec/lib/appsignal/params_sanitizer_spec.rb
|
289
294
|
- spec/lib/appsignal/rack/instrumentation_spec.rb
|
295
|
+
- spec/lib/appsignal/rack/js_exception_catcher_spec.rb
|
290
296
|
- spec/lib/appsignal/rack/listener_spec.rb
|
291
297
|
- spec/lib/appsignal/rack/sinatra_instrumentation_spec.rb
|
292
298
|
- spec/lib/appsignal/transaction/formatter_spec.rb
|