crashlog 1.0.3 → 1.0.4
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.
- data/.gitignore +4 -1
- data/Gemfile +4 -2
- data/Gemfile.lock +15 -78
- data/README.md +3 -1
- data/Rakefile +2 -4
- data/crashlog.gemspec +1 -1
- data/lib/core_ext/hash/keys.rb +51 -0
- data/lib/core_ext/kernel/require_relative.rb +7 -0
- data/lib/crash_log.rb +31 -28
- data/lib/crash_log/backtrace.rb +4 -4
- data/lib/crash_log/configuration.rb +59 -2
- data/lib/crash_log/helpers.rb +47 -0
- data/lib/crash_log/logging.rb +28 -7
- data/lib/crash_log/rack.rb +2 -2
- data/lib/crash_log/rails/controller_methods.rb +1 -1
- data/lib/crash_log/railtie.rb +18 -15
- data/lib/crash_log/reporter.rb +20 -6
- data/lib/crash_log/system_information.rb +14 -2
- data/lib/crash_log/version.rb +1 -1
- data/rails/init.rb +1 -1
- data/resources/README.md +34 -0
- data/resources/ca-bundle.crt +3376 -0
- data/script/integration_test +6 -5
- data/spec/crash_log/backtrace_spec.rb +21 -0
- data/spec/crash_log/configuration_spec.rb +7 -0
- data/spec/crash_log/initializer_spec.rb +20 -21
- data/spec/crash_log/rack_spec.rb +82 -0
- data/spec/crash_log/reporter_spec.rb +1 -0
- data/spec/crash_log_spec.rb +2 -0
- data/spec/requests/rails_controller_rescue_spec.rb +89 -86
- data/spec/spec_helper.rb +9 -4
- data/spec/support/define_constants.rb +11 -0
- metadata +32 -25
data/script/integration_test
CHANGED
@@ -14,10 +14,8 @@ require File.expand_path('../../rails/init', __FILE__)
|
|
14
14
|
|
15
15
|
fail "Please supply an API Key as the first argument" if ARGV.empty?
|
16
16
|
|
17
|
-
host = ARGV[
|
18
|
-
host
|
19
|
-
|
20
|
-
secure = (ARGV[2] == "secure")
|
17
|
+
host = ARGV[2]
|
18
|
+
host = "https://stdin.crashlog.io" if host.blank?
|
21
19
|
|
22
20
|
class SimulatedExceptionRaiser
|
23
21
|
attr_reader :secure
|
@@ -37,12 +35,15 @@ end
|
|
37
35
|
CrashLog.configure(true) do |config|
|
38
36
|
config.api_key = ARGV[0]
|
39
37
|
config.secret = ARGV[1]
|
40
|
-
config.scheme =
|
38
|
+
config.scheme = URI.parse(host).scheme
|
41
39
|
config.host = URI.parse(host).host
|
42
40
|
config.port = URI.parse(host).port
|
41
|
+
config.development_mode = true
|
43
42
|
# config.service_name = 'Staging'
|
44
43
|
end
|
45
44
|
|
45
|
+
secure = CrashLog.configuration.secure?
|
46
|
+
|
46
47
|
puts "Configuration:"
|
47
48
|
CrashLog.configuration.each do |key, value|
|
48
49
|
puts sprintf("%25s: %s", key.to_s, value.inspect.slice(0, 55))
|
@@ -20,6 +20,27 @@ describe CrashLog::Backtrace do
|
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
23
|
+
describe '.split_multiline_backtrace' do
|
24
|
+
it 'splits multiple lines into an array' do
|
25
|
+
CrashLog::Backtrace.send(:split_multiline_backtrace, "line.rb:1\nline.rb:2").size.should == 2
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
describe 'comparisson' do
|
30
|
+
it 'matches backtraces on lines' do
|
31
|
+
backtrace_1 = CrashLog::Backtrace.parse(caller)
|
32
|
+
backtrace_2 = CrashLog::Backtrace.parse(caller)
|
33
|
+
|
34
|
+
backtrace_1.should == backtrace_2
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'fails to match different backtraces' do
|
38
|
+
backtrace_1 = CrashLog::Backtrace.parse(caller)
|
39
|
+
backtrace_2 = CrashLog::Backtrace.parse(raised_error.backtrace)
|
40
|
+
backtrace_1.should_not == backtrace_2
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
23
44
|
describe 'lines' do
|
24
45
|
it 'are converted into a parsed Line object' do
|
25
46
|
CrashLog::Backtrace.parse(raised_error.backtrace).lines.first.should be_a(CrashLog::Backtrace::Line)
|
@@ -34,4 +34,11 @@ describe CrashLog::Configuration do
|
|
34
34
|
subject.should be_valid
|
35
35
|
end
|
36
36
|
end
|
37
|
+
|
38
|
+
describe 'ca bundle config' do
|
39
|
+
it 'locates packaged ca bundle' do
|
40
|
+
subject.ca_bundle_path.should end_with("resources/ca-bundle.crt")
|
41
|
+
File.should exist(subject.ca_bundle_path)
|
42
|
+
end
|
43
|
+
end
|
37
44
|
end
|
@@ -1,22 +1,30 @@
|
|
1
1
|
require 'spec_helper'
|
2
|
-
|
2
|
+
require 'crash_log/rails'
|
3
3
|
|
4
4
|
describe "Initializer" do
|
5
5
|
|
6
6
|
let(:logger) { stub("Logger") }
|
7
7
|
let(:other_logger) { stub("OtherLogger") }
|
8
8
|
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
let(:rails) { double('Rails') }
|
10
|
+
|
11
|
+
before(:each) do
|
12
|
+
define_constant('Rails', rails)
|
13
|
+
end
|
14
|
+
|
15
|
+
it "triggers use of Rails' logger if logger isn't set and Rails' logger exists" do
|
16
|
+
rails = Module.new do
|
17
|
+
def self.logger
|
18
|
+
"RAILS LOGGER"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
define_constant("Rails", rails)
|
22
|
+
CrashLog::Rails.initialize
|
23
|
+
expect("RAILS LOGGER").to eq(CrashLog.logger)
|
24
|
+
end
|
12
25
|
|
13
26
|
describe 'auto configure logger' do
|
14
27
|
before do
|
15
|
-
load_dummy_app
|
16
|
-
# unless defined?(Rails)
|
17
|
-
# module Rails
|
18
|
-
# end
|
19
|
-
# end
|
20
28
|
Rails.stub(:logger).and_return(logger)
|
21
29
|
logger.stub(:error)
|
22
30
|
other_logger.stub(:error)
|
@@ -24,22 +32,13 @@ describe "Initializer" do
|
|
24
32
|
|
25
33
|
|
26
34
|
it 'detects presence of Rails logger' do
|
27
|
-
|
28
|
-
|
29
|
-
CrashLog.logger.should be(logger)
|
35
|
+
CrashLog::Rails.__send__(:initialize)
|
36
|
+
CrashLog.logger.should eq(logger)
|
30
37
|
end
|
31
38
|
|
32
39
|
it "allows overriding of the logger if already assigned" do
|
33
|
-
pending
|
34
|
-
unless defined?(::Rails)
|
35
|
-
module Rails
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
Rails.stub(:logger).and_return(logger)
|
40
|
-
|
41
40
|
CrashLog.logger.should_not == logger
|
42
|
-
|
41
|
+
CrashLog::Rails.initialize
|
43
42
|
CrashLog.logger.should == logger
|
44
43
|
|
45
44
|
CrashLog.configure do |config|
|
@@ -0,0 +1,82 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe CrashLog::Rack do
|
4
|
+
before do
|
5
|
+
CrashLog.configure do |config|
|
6
|
+
config.api_key = 'KEY'
|
7
|
+
config.secret = 'secret'
|
8
|
+
config.developer_mode = true
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
class BacktracedException < Exception
|
13
|
+
attr_accessor :backtrace
|
14
|
+
|
15
|
+
def initialize(opts)
|
16
|
+
@backtrace = opts[:backtrace]
|
17
|
+
end
|
18
|
+
|
19
|
+
def set_backtrace(bt)
|
20
|
+
@backtrace = bt
|
21
|
+
end
|
22
|
+
|
23
|
+
def message
|
24
|
+
"Something went wrong. Did you press the red button?"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def build_exception(opts = {})
|
29
|
+
backtrace = caller
|
30
|
+
opts = {:backtrace => backtrace}.merge(opts)
|
31
|
+
BacktracedException.new(opts)
|
32
|
+
end
|
33
|
+
|
34
|
+
it "calls the upstream app with the environment" do
|
35
|
+
environment = { 'key' => 'value' }
|
36
|
+
app = lambda { |env| ['response', {}, env] }
|
37
|
+
stack = CrashLog::Rack.new(app)
|
38
|
+
|
39
|
+
response = stack.call(environment)
|
40
|
+
|
41
|
+
expect(['response', {}, environment]).to eq(response)
|
42
|
+
end
|
43
|
+
|
44
|
+
it "delivers an exception raised while calling an upstream app" do
|
45
|
+
exception = build_exception
|
46
|
+
environment = { 'key' => 'value' }
|
47
|
+
|
48
|
+
CrashLog.should_receive(:notify_or_ignore).with(exception, :rack_env => environment)
|
49
|
+
|
50
|
+
app = lambda do |env|
|
51
|
+
raise exception
|
52
|
+
end
|
53
|
+
|
54
|
+
begin
|
55
|
+
stack = CrashLog::Rack.new(app)
|
56
|
+
stack.call(environment)
|
57
|
+
rescue Exception => raised
|
58
|
+
expect(exception).to eq(raised)
|
59
|
+
else
|
60
|
+
fail "Didn't raise an exception"
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
it "delivers an exception in rack.exception" do
|
65
|
+
CrashLog.stub(:notify)
|
66
|
+
exception = build_exception
|
67
|
+
environment = { 'key' => 'value' }
|
68
|
+
|
69
|
+
CrashLog.should_receive(:notify_or_ignore).with(exception, :rack_env => environment)
|
70
|
+
|
71
|
+
response = [200, {}, ['okay']]
|
72
|
+
app = lambda do |env|
|
73
|
+
env['rack.exception'] = exception
|
74
|
+
response
|
75
|
+
end
|
76
|
+
stack = CrashLog::Rack.new(app)
|
77
|
+
actual_response = stack.call(environment)
|
78
|
+
|
79
|
+
expect(response).to eq(actual_response)
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
data/spec/crash_log_spec.rb
CHANGED
@@ -93,6 +93,8 @@ describe CrashLog do
|
|
93
93
|
|
94
94
|
describe '.ready' do
|
95
95
|
it 'logs an ready message' do
|
96
|
+
CrashLog.configuration.colorize = false
|
97
|
+
|
96
98
|
CrashLog::Reporter.any_instance.stub(:announce).and_return("Test Application")
|
97
99
|
logger = stub('Logger')
|
98
100
|
logger.should_receive(:info).
|
@@ -1,115 +1,118 @@
|
|
1
|
-
|
2
|
-
require 'rack/test'
|
3
|
-
require 'uuid'
|
1
|
+
if defined?(Rails)
|
4
2
|
|
5
|
-
|
6
|
-
|
7
|
-
|
3
|
+
require 'spec_helper'
|
4
|
+
require 'rack/test'
|
5
|
+
require 'uuid'
|
8
6
|
|
9
|
-
|
10
|
-
|
7
|
+
describe 'Rescue from within a Rails 3.x controller' do
|
8
|
+
# include RSpec::Rails::RequestExampleGroup
|
9
|
+
include Rack::Test::Methods
|
11
10
|
|
12
|
-
|
13
|
-
|
14
|
-
end
|
11
|
+
class CollectingReporter
|
12
|
+
attr_reader :collected
|
15
13
|
|
16
|
-
|
17
|
-
|
18
|
-
|
14
|
+
def initialize
|
15
|
+
@collected = []
|
16
|
+
end
|
17
|
+
|
18
|
+
def result
|
19
|
+
{:location_id => UUID.generate }
|
20
|
+
end
|
19
21
|
|
20
|
-
|
21
|
-
|
22
|
-
|
22
|
+
def notify(payload)
|
23
|
+
@collected << payload
|
24
|
+
true
|
25
|
+
end
|
23
26
|
end
|
24
|
-
end
|
25
27
|
|
26
|
-
|
27
|
-
|
28
|
-
|
28
|
+
def assert_caught_and_sent
|
29
|
+
CrashLog.reporter.collected.should_not be_empty
|
30
|
+
end
|
29
31
|
|
30
|
-
|
31
|
-
|
32
|
-
|
32
|
+
def assert_caught_and_not_sent
|
33
|
+
expect { CrashLog.reporter.collected.empty? }.to be_true
|
34
|
+
end
|
33
35
|
|
34
|
-
|
35
|
-
|
36
|
-
|
36
|
+
def last_notice
|
37
|
+
CrashLog.reporter.collected.last
|
38
|
+
end
|
37
39
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
40
|
+
before do
|
41
|
+
CrashLog.reporter = CollectingReporter.new
|
42
|
+
CrashLog.configuration.root = File.expand_path("../..", __FILE__)
|
43
|
+
end
|
42
44
|
|
43
|
-
|
44
|
-
|
45
|
-
|
45
|
+
it 'is testing tails 3.x' do
|
46
|
+
Rails.version.should =~ /^3\.2\./
|
47
|
+
end
|
46
48
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
49
|
+
describe 'dummy app' do
|
50
|
+
it 'should response nicely to index' do
|
51
|
+
get '/'
|
52
|
+
last_response.should be_ok
|
53
|
+
last_response.body.should == 'Works fine here'
|
54
|
+
end
|
52
55
|
end
|
53
|
-
end
|
54
56
|
|
55
|
-
|
57
|
+
let(:action) { get '/broken' }
|
56
58
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
59
|
+
it 'collects payloads' do
|
60
|
+
CrashLog.notify(RuntimeError.new("TEST"))
|
61
|
+
assert_caught_and_sent
|
62
|
+
end
|
61
63
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
64
|
+
# it 'should intercept error and notify crashlog' do
|
65
|
+
# begin
|
66
|
+
# get '/broken'
|
67
|
+
# rescue StandardError; end
|
66
68
|
|
67
|
-
|
68
|
-
|
69
|
+
# last_response.status.should == 500
|
70
|
+
# last_response.body.should match /We're sorry, but something went wrong/
|
69
71
|
|
70
|
-
|
71
|
-
|
72
|
+
# assert_caught_and_sent
|
73
|
+
# end
|
72
74
|
|
73
|
-
|
74
|
-
|
75
|
+
# it 'captures standard backtrace attributes' do
|
76
|
+
# action
|
75
77
|
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
78
|
+
# last_notice.to_json.should have_json_path('notifier/name')
|
79
|
+
# last_notice.to_json.should have_json_path('backtrace/0/number')
|
80
|
+
# last_notice.to_json.should have_json_path('backtrace/0/method')
|
81
|
+
# last_notice.to_json.should have_json_path('backtrace/0/file')
|
82
|
+
# last_notice.to_json.should have_json_path('backtrace/0/context_line')
|
83
|
+
# last_notice.to_json.should have_json_path('backtrace/0/pre_context/1')
|
84
|
+
# last_notice.to_json.should have_json_path('backtrace/0/pre_context/2')
|
85
|
+
# last_notice.to_json.should have_json_path('backtrace/0/pre_context/3')
|
86
|
+
# last_notice.to_json.should have_json_path('backtrace/0/pre_context/4')
|
87
|
+
# last_notice.to_json.should have_json_path('environment/system/hostname')
|
88
|
+
# last_notice.to_json.should have_json_path('environment/system/application_root')
|
89
|
+
# end
|
88
90
|
|
89
|
-
|
90
|
-
|
91
|
+
# it 'captures current user' do
|
92
|
+
# # ActionController::Base.any_instance.stub(:crash_log_context).and_return({current_user: {id: 1}})
|
91
93
|
|
92
|
-
|
94
|
+
# action
|
93
95
|
|
94
|
-
|
95
|
-
|
96
|
-
|
96
|
+
# # last_notice.should == ''
|
97
|
+
# last_notice.to_json.should have_json_path('context/current_user')
|
98
|
+
# end
|
97
99
|
|
98
|
-
|
100
|
+
# it 'should capture crash log custom data'
|
99
101
|
|
100
|
-
|
101
|
-
|
102
|
+
# it 'should raise error again after notifying' do
|
103
|
+
# ENV['RAILS_ENV']='production'
|
102
104
|
|
103
|
-
|
104
|
-
|
105
|
-
|
105
|
+
# logger = stub("Logger")
|
106
|
+
# ActionDispatch::DebugExceptions.any_instance.stub(:logger).and_return(logger)
|
107
|
+
# logger.should_receive(:fatal).once
|
106
108
|
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
109
|
+
# begin
|
110
|
+
# get '/broken'
|
111
|
+
# last_response.status.should == 500
|
112
|
+
# rescue
|
113
|
+
# end
|
114
|
+
# end
|
113
115
|
|
114
|
-
|
116
|
+
it 'should be able to defer reporting to another thread'
|
117
|
+
end
|
115
118
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,11 +1,15 @@
|
|
1
|
-
|
1
|
+
begin
|
2
2
|
require 'simplecov'
|
3
|
-
SimpleCov.start
|
3
|
+
SimpleCov.start do
|
4
|
+
add_filter "spec/"
|
5
|
+
end
|
6
|
+
rescue LoadError
|
7
|
+
puts "Skipping SimpleCov"
|
4
8
|
end
|
5
9
|
|
6
|
-
require File.expand_path("../dummy/config/environment.rb", __FILE__)
|
10
|
+
# require File.expand_path("../dummy/config/environment.rb", __FILE__)
|
7
11
|
|
8
|
-
require 'rspec/rails'
|
12
|
+
# require 'rspec/rails'
|
9
13
|
require 'delorean'
|
10
14
|
require 'json_spec'
|
11
15
|
require 'uuid'
|
@@ -26,5 +30,6 @@ RSpec.configure do |config|
|
|
26
30
|
|
27
31
|
config.after(:each) do
|
28
32
|
teardown_constants
|
33
|
+
CrashLog.reset_configuration!
|
29
34
|
end
|
30
35
|
end
|