error_stalker 0.0.12

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.
Files changed (51) hide show
  1. data/.gitignore +4 -0
  2. data/Gemfile +30 -0
  3. data/Gemfile.lock +76 -0
  4. data/README.rdoc +3 -0
  5. data/Rakefile +19 -0
  6. data/bin/create_indexes +14 -0
  7. data/bin/error_stalker_server +16 -0
  8. data/error_stalker.gemspec +21 -0
  9. data/lib/error_stalker.rb +4 -0
  10. data/lib/error_stalker/backend.rb +14 -0
  11. data/lib/error_stalker/backend/base.rb +14 -0
  12. data/lib/error_stalker/backend/in_memory.rb +25 -0
  13. data/lib/error_stalker/backend/log_file.rb +33 -0
  14. data/lib/error_stalker/backend/server.rb +41 -0
  15. data/lib/error_stalker/client.rb +62 -0
  16. data/lib/error_stalker/exception_group.rb +29 -0
  17. data/lib/error_stalker/exception_report.rb +116 -0
  18. data/lib/error_stalker/plugin.rb +42 -0
  19. data/lib/error_stalker/plugin/base.rb +24 -0
  20. data/lib/error_stalker/plugin/email_sender.rb +60 -0
  21. data/lib/error_stalker/plugin/lighthouse_reporter.rb +95 -0
  22. data/lib/error_stalker/plugin/views/exception_email.erb +18 -0
  23. data/lib/error_stalker/plugin/views/report.erb +18 -0
  24. data/lib/error_stalker/server.rb +152 -0
  25. data/lib/error_stalker/server/public/exception_logger.css +173 -0
  26. data/lib/error_stalker/server/public/grid.css +338 -0
  27. data/lib/error_stalker/server/public/images/background.png +0 -0
  28. data/lib/error_stalker/server/public/jquery-1.4.4.min.js +167 -0
  29. data/lib/error_stalker/server/views/_exception_message.erb +1 -0
  30. data/lib/error_stalker/server/views/_exception_table.erb +34 -0
  31. data/lib/error_stalker/server/views/index.erb +31 -0
  32. data/lib/error_stalker/server/views/layout.erb +18 -0
  33. data/lib/error_stalker/server/views/search.erb +41 -0
  34. data/lib/error_stalker/server/views/show.erb +32 -0
  35. data/lib/error_stalker/server/views/similar.erb +6 -0
  36. data/lib/error_stalker/sinatra_link_renderer.rb +25 -0
  37. data/lib/error_stalker/store.rb +11 -0
  38. data/lib/error_stalker/store/base.rb +75 -0
  39. data/lib/error_stalker/store/in_memory.rb +109 -0
  40. data/lib/error_stalker/store/mongoid.rb +318 -0
  41. data/lib/error_stalker/version.rb +4 -0
  42. data/test/test_helper.rb +8 -0
  43. data/test/unit/backend/base_test.rb +9 -0
  44. data/test/unit/backend/in_memory_test.rb +22 -0
  45. data/test/unit/backend/log_file_test.rb +25 -0
  46. data/test/unit/client_test.rb +67 -0
  47. data/test/unit/exception_report_test.rb +24 -0
  48. data/test/unit/plugins/email_sender_test.rb +12 -0
  49. data/test/unit/server_test.rb +141 -0
  50. data/test/unit/stores/in_memory_test.rb +58 -0
  51. metadata +109 -0
@@ -0,0 +1,4 @@
1
+ module ErrorStalker
2
+ # ErrorStalker's current version.
3
+ VERSION = "0.0.12"
4
+ end
@@ -0,0 +1,8 @@
1
+ require 'test/unit'
2
+ require 'error_stalker'
3
+ require 'mail'
4
+ require 'error_stalker/server'
5
+
6
+ Mail.defaults do
7
+ delivery_method :test
8
+ end
@@ -0,0 +1,9 @@
1
+ require 'test_helper'
2
+
3
+ class BackendBaseTest < Test::Unit::TestCase
4
+ def test_report_is_not_implemented
5
+ assert_raises NotImplementedError do
6
+ ErrorStalker::Backend::Base.new.report("foo")
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,22 @@
1
+ require 'test_helper'
2
+ require 'error_stalker/backend/in_memory'
3
+
4
+ class BackendInMemoryTest < Test::Unit::TestCase
5
+
6
+ def setup
7
+ super
8
+ @backend = ErrorStalker::Backend::InMemory.new
9
+ @exception_report = ErrorStalker::ExceptionReport.new(:application => :unit_test, :exception => 'Test Exception')
10
+ end
11
+
12
+ def test_report_is_implemented
13
+ @backend.report(@exception_report)
14
+ assert_equal 1, @backend.exceptions.length
15
+ end
16
+
17
+ def test_clear_is_implemented
18
+ @backend.report(@exception_report)
19
+ @backend.clear
20
+ assert_equal 0, @backend.exceptions.length
21
+ end
22
+ end
@@ -0,0 +1,25 @@
1
+ require 'test_helper'
2
+ require 'error_stalker/backend/log_file'
3
+ require 'tempfile'
4
+
5
+ class BackendLogFileTest < Test::Unit::TestCase
6
+
7
+ def setup
8
+ super
9
+ filename = File.join(Dir.tmpdir, 'exceptions.log')
10
+ @backend = ErrorStalker::Backend::LogFile.new(filename)
11
+ @exception_report = ErrorStalker::ExceptionReport.new(:application => :unit_test, :exception => 'Test Exception', :data => {:name => 'Bob'})
12
+ end
13
+
14
+ def teardown
15
+ File.delete(@backend.filename) if File.exists?(@backend.filename)
16
+ super
17
+ end
18
+
19
+ def test_report_is_implemented
20
+ @backend.report(@exception_report)
21
+ exception_string = File.read(@backend.filename)
22
+ assert_match /Application: unit_test/, exception_string
23
+ assert_match /Exception: Test Exception/, exception_string
24
+ end
25
+ end
@@ -0,0 +1,67 @@
1
+ require 'test_helper'
2
+ require 'error_stalker/backend/in_memory'
3
+
4
+ class ClientTest < Test::Unit::TestCase
5
+
6
+ def setup
7
+ super
8
+ @backend = ErrorStalker::Backend::InMemory.new
9
+ ErrorStalker::Client.backend = @backend
10
+ end
11
+
12
+ def test_report
13
+ ErrorStalker::Client.report(:unit_test, new_exception, {:name => "Bob"})
14
+
15
+ assert_equal 1, @backend.exceptions.length
16
+ exception_report = @backend.exceptions.first
17
+ assert_equal :unit_test, exception_report.application
18
+ assert_equal exception_report.send(:machine_name), exception_report.machine
19
+ assert_match "test/unit/client_test.rb:", exception_report.backtrace.first
20
+ assert_equal 'Bob', exception_report.data[:name]
21
+ assert_equal 'NoMethodError', exception_report.type
22
+ end
23
+
24
+ def test_report_exceptions_in_block
25
+ assert_raises NoMethodError do
26
+ ErrorStalker::Client.report_exceptions(:unit_test) do
27
+ raise new_exception
28
+ end
29
+
30
+ assert_equal 1, @backend.exceptions.length
31
+ end
32
+ end
33
+
34
+ def test_report_exceptions_in_block_without_reraise
35
+ assert_nothing_raised do
36
+ ErrorStalker::Client.report_exceptions(:unit_test, :reraise => false) do
37
+ raise new_exception
38
+ end
39
+
40
+ assert_equal 1, @backend.exceptions.length
41
+
42
+ ErrorStalker::Client.report_exceptions(:unit_test, :reraise => nil) do
43
+ raise new_exception
44
+ end
45
+
46
+ assert_equal 2, @backend.exceptions.length
47
+ end
48
+ end
49
+
50
+ def test_dont_raise_exceptions_during_report
51
+ ErrorStalker::Client.backend = nil
52
+
53
+ assert_nothing_raised do
54
+ ErrorStalker::Client.report(:unit_test, new_exception, {:name => "Bob"})
55
+ end
56
+ end
57
+
58
+ def new_exception
59
+ exception = nil
60
+ begin
61
+ nil.foo
62
+ rescue => e
63
+ exception = e
64
+ end
65
+ exception
66
+ end
67
+ end
@@ -0,0 +1,24 @@
1
+ require 'test_helper'
2
+
3
+ class ExceptionReportTest < Test::Unit::TestCase
4
+
5
+ def test_serialization
6
+ original_report = ErrorStalker::ExceptionReport.new(:application => :unit_test, :exception => NoMethodError.new, :data => {:name => "Bob"})
7
+
8
+ exception_report = ErrorStalker::ExceptionReport.new(JSON.parse(original_report.to_json))
9
+
10
+ assert_equal 'unit_test', exception_report.application
11
+ assert_equal exception_report.send(:machine_name), exception_report.machine
12
+ assert_equal 'Bob', exception_report.data['name']
13
+ assert_equal 'NoMethodError', exception_report.type
14
+ end
15
+
16
+ def test_digest
17
+ report = ErrorStalker::ExceptionReport.new(:application => :unit_test, :exception => "Bob", :data => {:name => "Bob"})
18
+ report2 = ErrorStalker::ExceptionReport.new(:application => :unit_test, :exception => "Bob", :data => {:name => "Bob"})
19
+ report3 = ErrorStalker::ExceptionReport.new(:application => :unit_test, :exception => "Fred", :data => {:name => "Bob"})
20
+
21
+ assert_equal report.digest, report2.digest
22
+ assert_not_equal report.digest, report3.digest
23
+ end
24
+ end
@@ -0,0 +1,12 @@
1
+ require 'test_helper'
2
+
3
+ class EmailSenderTest < Test::Unit::TestCase
4
+
5
+ def test_email_configuration_with_strings
6
+ p = ErrorStalker::Plugin::EmailSender.new(nil, {'to' => nil, 'from' => nil, 'delivery_method' => 'sendmail'})
7
+ e = ErrorStalker::ExceptionReport.new(:exception => 'test', :application => 'test', :data => {})
8
+ mail = p.build_email(e, nil)
9
+ assert_equal Mail::Sendmail, mail.delivery_method.class
10
+ end
11
+ end
12
+
@@ -0,0 +1,141 @@
1
+ require 'test_helper'
2
+ require 'rack/test'
3
+ require 'error_stalker/server'
4
+ require 'mocha'
5
+
6
+ ENV['RACK_ENV'] = 'test'
7
+
8
+ class ServerTest < Test::Unit::TestCase
9
+ include Rack::Test::Methods
10
+
11
+ def app
12
+ ErrorStalker::Server
13
+ end
14
+
15
+ def setup
16
+ @store = ErrorStalker::Store::InMemory.new
17
+ ErrorStalker::Server.any_instance.stubs(:store).returns(@store)
18
+ end
19
+
20
+ def test_report_exception
21
+ report_exception
22
+ assert last_response.ok?
23
+ assert_equal 1, @store.exceptions.length
24
+ end
25
+
26
+ def test_can_see_homepage
27
+ get '/'
28
+ assert last_response.ok?
29
+ assert_no_match /table/, last_response.body
30
+ end
31
+
32
+ def test_can_see_homepage_table_after_exception_logged
33
+ report_exception
34
+ get '/'
35
+ assert last_response.ok?
36
+ assert_match /table/, last_response.body
37
+ assert_match /failed/, last_response.body
38
+ end
39
+
40
+ def test_groups_aggregated_on_homepage
41
+ report_exception
42
+ report_exception('test2', 2)
43
+ get '/'
44
+ assert last_response.ok?
45
+ assert_match /<td class="count">2/, last_response.body
46
+ end
47
+
48
+ def test_find_exception
49
+ report_exception
50
+ get '/exceptions/0.html'
51
+ assert last_response.ok?
52
+ assert_match /failed/, last_response.body
53
+ assert_match /server_test.rb/, last_response.body
54
+ end
55
+
56
+ def test_find_related
57
+ e = report_exception('test', 4)
58
+ report_exception('test2', 1)
59
+ get "/similar/#{e.digest}.html"
60
+ assert last_response.ok?
61
+ assert_match /exceptions\/0.html/, last_response.body
62
+ assert_no_match /exceptions\/4.html/, last_response.body
63
+ end
64
+
65
+ def test_emails_sent_only_on_first_report_in_group
66
+ app.any_instance.stubs(:plugins).returns([ErrorStalker::Plugin::EmailSender.new(nil, {'to' => nil, 'from' => nil})])
67
+ report_exception('test', 2)
68
+ assert_equal 1, Mail::TestMailer.deliveries.length
69
+ report_exception('test', 1)
70
+ assert_equal 2, Mail::TestMailer.deliveries.length
71
+ end
72
+
73
+ def test_stats_renders_total
74
+ report_exception('test', 4)
75
+ get "/stats.json"
76
+ assert last_response.ok?
77
+ stats = JSON.parse(last_response.body)
78
+ assert_equal 4, stats['total']
79
+ end
80
+
81
+ def test_stats_renders_timestamp
82
+ report_exception('test', 1)
83
+ timestamp = Time.now.to_i - 60 # one minute ago
84
+ get "/stats.json", :timestamp => timestamp
85
+ assert last_response.ok?
86
+ stats = JSON.parse(last_response.body)
87
+ assert_equal timestamp, stats['timestamp']
88
+ end
89
+
90
+ def test_stats_renders_total_since
91
+ report_exception('test', 1)
92
+ timestamp = Time.now.to_i - 60 # one minute ago
93
+ get "/stats.json", :timestamp => timestamp
94
+ assert last_response.ok?
95
+ stats = JSON.parse(last_response.body)
96
+ assert_equal 1, stats['total_since']
97
+ end
98
+
99
+ def test_advanced_search_shows_up
100
+ get "/search"
101
+ assert last_response.ok?
102
+ assert_no_match /<label for="data">/, last_response.body
103
+
104
+ @store.stubs(:supports_extended_searches?).returns(true)
105
+ get "/search"
106
+ assert last_response.ok?
107
+ assert_match /<label for="data">/, last_response.body
108
+ end
109
+
110
+ def test_perform_search
111
+ report_exception('test', 4)
112
+ report_exception('te-t')
113
+ get "/search?application=&machine=&exception=test&Search=Search"
114
+ assert_match /exceptions\/0.html/, last_response.body
115
+ assert_no_match /exceptions\/4.html/, last_response.body
116
+
117
+ get "/search?application=&machine=&exception=te&Search=Search"
118
+ assert_match /exceptions\/0.html/, last_response.body
119
+ assert_match /exceptions\/4.html/, last_response.body
120
+
121
+ get "/search?application=foo&machine=&exception=te&Search=Search"
122
+ assert_no_match /exceptions\/0.html/, last_response.body
123
+ assert_no_match /exceptions\/4.html/, last_response.body
124
+ end
125
+
126
+ protected
127
+ def report_exception(message = "failed", count = 1, data = {})
128
+ e = nil
129
+ count.times do
130
+ begin
131
+ raise NoMethodError, message
132
+ rescue => ex
133
+ e = ErrorStalker::ExceptionReport.new(:exception => ex, :application => 'test', :data => data)
134
+ end
135
+
136
+ post '/report.json', e.to_json
137
+ end
138
+ e
139
+ end
140
+ end
141
+
@@ -0,0 +1,58 @@
1
+ require 'test_helper'
2
+
3
+ class InMemoryTest < Test::Unit::TestCase
4
+ def setup
5
+ @store = ErrorStalker::Store::InMemory.new
6
+ end
7
+
8
+ def test_store_exception
9
+ assert @store.empty?
10
+ store_exception(@store)
11
+ assert !@store.empty?
12
+ assert_equal 1, @store.recent.length
13
+ assert @store.find(0)
14
+ end
15
+
16
+ def test_group
17
+ store_exception(@store, "test", 2)
18
+ store_exception(@store, "test2")
19
+
20
+ assert_equal 2, @store.recent.length
21
+ assert_equal 1, @store.reports_in_group(@store.find(2).digest).length
22
+ assert_equal 1, @store.group(@store.find(2).digest).count
23
+ assert_equal 2, @store.reports_in_group(@store.find(0).digest).length
24
+ assert_equal 2, @store.group(@store.find(0).digest).count
25
+ end
26
+
27
+ def test_search
28
+ store_exception(@store, "test", 2)
29
+ store_exception(@store, "text")
30
+ assert_equal 3, @store.search(:application => 'test').length
31
+ assert_equal 0, @store.search(:application => 'foo').length
32
+ assert_equal 3, @store.search(:machine => `hostname`.chomp, :application => 'test').length
33
+ assert_equal 0, @store.search(:machine => 'example.com', :application => 'test').length
34
+ assert_equal 1, @store.search(:application => 'test', :exception => 'tex').length
35
+ assert_equal 3, @store.search(:application => 'test', :exception => 'te').length
36
+ end
37
+
38
+ def test_machines_and_applications
39
+ store_exception(@store, "test", 2)
40
+ assert_equal 1, @store.machines.length
41
+ assert_equal 1, @store.applications.length
42
+ assert_equal 'test', @store.applications.first
43
+ end
44
+
45
+ protected
46
+ def store_exception(store, message = "failed", count = 1, data = {})
47
+ e = nil
48
+ count.times do
49
+ begin
50
+ raise NoMethodError, message
51
+ rescue => ex
52
+ e = ErrorStalker::ExceptionReport.new(:exception => ex, :application => 'test', :data => data)
53
+ end
54
+ @store.store(e)
55
+ end
56
+ e
57
+ end
58
+ end
metadata ADDED
@@ -0,0 +1,109 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: error_stalker
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.12
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Justin Weiss
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2011-08-10 00:00:00.000000000 -07:00
13
+ default_executable:
14
+ dependencies: []
15
+ description: Logs exceptions to a pluggable backend. Also provides a server for centralized
16
+ exception logging using a pluggable data store.
17
+ email:
18
+ - jweiss@avvo.com
19
+ executables:
20
+ - create_indexes
21
+ - error_stalker_server
22
+ extensions: []
23
+ extra_rdoc_files: []
24
+ files:
25
+ - .gitignore
26
+ - Gemfile
27
+ - Gemfile.lock
28
+ - README.rdoc
29
+ - Rakefile
30
+ - bin/create_indexes
31
+ - bin/error_stalker_server
32
+ - error_stalker.gemspec
33
+ - lib/error_stalker.rb
34
+ - lib/error_stalker/backend.rb
35
+ - lib/error_stalker/backend/base.rb
36
+ - lib/error_stalker/backend/in_memory.rb
37
+ - lib/error_stalker/backend/log_file.rb
38
+ - lib/error_stalker/backend/server.rb
39
+ - lib/error_stalker/client.rb
40
+ - lib/error_stalker/exception_group.rb
41
+ - lib/error_stalker/exception_report.rb
42
+ - lib/error_stalker/plugin.rb
43
+ - lib/error_stalker/plugin/base.rb
44
+ - lib/error_stalker/plugin/email_sender.rb
45
+ - lib/error_stalker/plugin/lighthouse_reporter.rb
46
+ - lib/error_stalker/plugin/views/exception_email.erb
47
+ - lib/error_stalker/plugin/views/report.erb
48
+ - lib/error_stalker/server.rb
49
+ - lib/error_stalker/server/public/exception_logger.css
50
+ - lib/error_stalker/server/public/grid.css
51
+ - lib/error_stalker/server/public/images/background.png
52
+ - lib/error_stalker/server/public/jquery-1.4.4.min.js
53
+ - lib/error_stalker/server/views/_exception_message.erb
54
+ - lib/error_stalker/server/views/_exception_table.erb
55
+ - lib/error_stalker/server/views/index.erb
56
+ - lib/error_stalker/server/views/layout.erb
57
+ - lib/error_stalker/server/views/search.erb
58
+ - lib/error_stalker/server/views/show.erb
59
+ - lib/error_stalker/server/views/similar.erb
60
+ - lib/error_stalker/sinatra_link_renderer.rb
61
+ - lib/error_stalker/store.rb
62
+ - lib/error_stalker/store/base.rb
63
+ - lib/error_stalker/store/in_memory.rb
64
+ - lib/error_stalker/store/mongoid.rb
65
+ - lib/error_stalker/version.rb
66
+ - test/test_helper.rb
67
+ - test/unit/backend/base_test.rb
68
+ - test/unit/backend/in_memory_test.rb
69
+ - test/unit/backend/log_file_test.rb
70
+ - test/unit/client_test.rb
71
+ - test/unit/exception_report_test.rb
72
+ - test/unit/plugins/email_sender_test.rb
73
+ - test/unit/server_test.rb
74
+ - test/unit/stores/in_memory_test.rb
75
+ has_rdoc: true
76
+ homepage: ''
77
+ licenses: []
78
+ post_install_message:
79
+ rdoc_options: []
80
+ require_paths:
81
+ - lib
82
+ required_ruby_version: !ruby/object:Gem::Requirement
83
+ none: false
84
+ requirements:
85
+ - - ! '>='
86
+ - !ruby/object:Gem::Version
87
+ version: '0'
88
+ required_rubygems_version: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ requirements: []
95
+ rubyforge_project: error_stalker
96
+ rubygems_version: 1.6.2
97
+ signing_key:
98
+ specification_version: 3
99
+ summary: Logs exceptions to a pluggable backend and/or a pluggable store
100
+ test_files:
101
+ - test/test_helper.rb
102
+ - test/unit/backend/base_test.rb
103
+ - test/unit/backend/in_memory_test.rb
104
+ - test/unit/backend/log_file_test.rb
105
+ - test/unit/client_test.rb
106
+ - test/unit/exception_report_test.rb
107
+ - test/unit/plugins/email_sender_test.rb
108
+ - test/unit/server_test.rb
109
+ - test/unit/stores/in_memory_test.rb