error_log 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/README.txt CHANGED
@@ -3,11 +3,69 @@ error_log
3
3
 
4
4
  == DESCRIPTION:
5
5
 
6
- Easy way to track exceptions and warning in your rails app
6
+ Easy way to track exceptions and warnings in your rails app
7
7
 
8
8
  It's still just a skeleton.
9
9
  More description and documentation will come.. one day.. I guess.
10
10
 
11
+ THIS IS DEVELOPMENT VERSION, DO NOT EVEN TOUCH PRODUCTION SERVER WITH IT.
12
+ Actually, it is so unmature that even playing with it can make you sad.
13
+ And no one likes to be sad.
14
+
15
+ dev screenshot: http://tesuji.pl/error_logs.png
16
+
17
+ == REQUIREMENTS
18
+
19
+ I hope it to work with rails 2.x and 3, currently I'm testing it only on rails 3.
20
+
21
+ == INSTALATION AND USAGE
22
+
23
+ Just put
24
+
25
+ gem 'error_log'
26
+
27
+ in your Gemfile. By default it will use your database to store error logs.
28
+ Automagically table error_logs is going to be created, and all unhandled
29
+ controller exceptions will end up there by default (displaying your 500 page
30
+ as normal).
31
+
32
+ Generate yourself some empty controller (say error_logs) and put this line
33
+ inside:
34
+
35
+ error_logs
36
+
37
+ You can use it now to browse exceptions. It is your responsibility to make this
38
+ controller secure and unaccessible by others.
39
+
40
+ There's also one global method catch_error that you can use to.. catch errors.
41
+
42
+ catch_error do
43
+ # some stuff that may cause problems
44
+ end
45
+
46
+ or
47
+
48
+ catch_error('page parsing', :level => :fatal) do
49
+ raise "tangled cables"
50
+ end
51
+
52
+ To be continued.
53
+
54
+ == TODOS
55
+
56
+ * setting error level threshold while browsing
57
+ * nicer browsing (themes would be good, but I really do not like css so help needed)
58
+ * adding errors to ignore list
59
+ * alternative errors storage (for database failures, maybe just some sqlite?)
60
+ * clickable backtraces? we could show some code
61
+ * rails 2.x compatibility
62
+ * marking single errors as read, browsing archive
63
+ * bugfixes, lots of
64
+
65
+ == STUFF
66
+
67
+ Ideas, opinions and contributions are extrememly welcome.
68
+
11
69
  == LICENSE:
12
70
 
13
71
  (The MIT License)
@@ -1,16 +1,29 @@
1
1
 
2
- #TODO :would be nice to check first if ApplicationController is defined and if not use ActionController::Base
3
2
  module ErrorLog
4
- class Controller < ActionController::Base
3
+ module Controller# < ActionController::Base
5
4
 
6
- prepend_view_path File.join(ErrorLog.path,'views')
5
+ def index
7
6
 
8
- # FIXME: this layout declaration should not be needed here for default layout
9
- # however without it, it does not load default layout for some reason
10
- layout 'application'
7
+ # Rails 2.x compatible finder
8
+ scope = ErrorLog::Model
9
+
10
+ unless params[:errors_category].to_s.empty?
11
+ @errors_category = params[:errors_category]
12
+ scope = scope.where(:category => @errors_category)
13
+ end
14
+
15
+ @error_logs = scope.all(
16
+ :order => 'created_at DESC',
17
+ :conditions => {
18
+ :viewed => false
19
+ }
20
+ ).group_by(&:error_hash)
21
+
22
+ @category_counts = ErrorLog::Model.count(
23
+ :conditions => {:viewed => false},
24
+ :group => :category
25
+ )
11
26
 
12
- def index
13
- @error_logs = ErrorLog::Model.all(:order => 'created_at DESC', :conditions => {:viewed => false}).group_by(&:hash)
14
27
  render :template => '/index'
15
28
  end
16
29
 
@@ -18,6 +31,27 @@ module ErrorLog
18
31
  ErrorLog::Model.update_all(:viewed => true)
19
32
  redirect_to :back
20
33
  end
34
+
21
35
  end
22
36
  end
23
37
 
38
+ class ActionController::Base
39
+
40
+ rescue_from Exception, :with => :error_log_rescue
41
+
42
+ def self.error_logs
43
+ append_view_path File.join(ErrorLog.path,'views')
44
+ self.send(:include,ErrorLog::Controller)
45
+ end
46
+
47
+ def error_log_rescue(e)
48
+ err = ErrorLog::Model.new(
49
+ :error => e.to_str,
50
+ :backtrace => e.backtrace,
51
+ :category => 'rails'
52
+ )
53
+ err.save
54
+ raise e
55
+ end
56
+
57
+ end
@@ -1,4 +1,7 @@
1
1
  class Object
2
+
3
+
4
+ # Handy way to catch exceptions
2
5
  def catch_error(category='catch_error', options={})
3
6
  raise "no block given!" unless block_given?
4
7
  begin
@@ -8,9 +11,10 @@ class Object
8
11
  ErrorLog::Model.create(
9
12
  :error => e.to_str,
10
13
  :backtrace => e.backtrace,
14
+ :level => (options[:level] || :error),
11
15
  :category => category
12
16
  )
13
17
  end
14
-
15
18
  end
19
+
16
20
  end
@@ -9,7 +9,8 @@ module ErrorLog
9
9
  t.text :error
10
10
  t.text :backtrace
11
11
  t.string :category
12
- t.string :hash
12
+ # note to future me: "hash" is a really bad name for the column
13
+ t.string :error_hash
13
14
  t.integer :level_id
14
15
  t.timestamp :created_at
15
16
  t.boolean :viewed, :default => false
@@ -22,14 +23,35 @@ module ErrorLog
22
23
  Migration.up
23
24
  end
24
25
 
26
+ LEVELS = {
27
+ :debug => 0,
28
+ :info => 1,
29
+ :warn => 2,
30
+ :warning => 2,
31
+ :error => 3,
32
+ :fatal => 4,
33
+ :wtf => 5
34
+ }
35
+
36
+ def level
37
+ LEVELS.invert[self.level_id]
38
+ end
39
+
40
+ def level=(name)
41
+ self.level_id = LEVELS[name]
42
+ end
43
+
25
44
  before_save do |obj|
45
+ obj.level ||= :error
46
+
26
47
  if obj.backtrace.kind_of? Array
27
48
  obj.backtrace = obj.backtrace.join("\n")
28
49
  end
29
50
 
30
- obj.hash = Digest::MD5.hexdigest(obj.backtrace.to_s + obj.error.to_s + obj.category.to_s)
51
+ obj.error_hash = Digest::MD5.hexdigest(obj.backtrace.to_s + obj.error.to_s + obj.category.to_s)
31
52
 
32
53
  true
33
54
  end
55
+
34
56
  end
35
57
  end
@@ -1,3 +1,3 @@
1
1
  module ErrorLog
2
- VERSION = "0.0.1" unless defined?(::ErrorLog::VERSION)
2
+ VERSION = "0.0.2" unless defined?(::ErrorLog::VERSION)
3
3
  end
data/lib/error_log.rb CHANGED
@@ -62,7 +62,6 @@ module ErrorLog
62
62
  end # module ErrorLog
63
63
 
64
64
 
65
- # Hook into rails
66
- ActiveSupport.on_load(:after_initialize) do
65
+ ActiveSupport.on_load(:before_initialize) do
67
66
  ErrorLog.require_all_libs_relative_to(__FILE__)
68
67
  end
@@ -0,0 +1,119 @@
1
+
2
+ <%# I'm sorry but view ain't beautiful quite yet. It will probably be totally rewritten %>
3
+
4
+ <style type="text/css">
5
+ #error_logs tr.odd {
6
+ background-color: #fefefe;
7
+ }
8
+
9
+ #error_logs tr.even {
10
+ background-color: #f5f5f5;
11
+ }
12
+
13
+ table#error_logs {
14
+ border: 1px solid #333;
15
+ width: 100%;
16
+ border-collapse: collapse;
17
+ }
18
+
19
+ table#error_logs td {
20
+ border: 1px solid #999;
21
+ padding: 10px;
22
+ font-family: Verdana;
23
+ }
24
+
25
+ table#error_logs .level_error {
26
+ background-color: #ffa;
27
+ }
28
+
29
+ table#error_logs .level_fatal {
30
+ background-color: #f99;
31
+ }
32
+
33
+ table#error_logs .level_warn {
34
+ background-color: #9c9;
35
+ }
36
+
37
+ table#error_logs .level_box {
38
+ border: 1px solid #333;
39
+ padding: 10px;
40
+ font-weight: bold;
41
+ float: right;
42
+ margin: 20px;
43
+ }
44
+
45
+ table#error_logs .backtrace {
46
+ overflow: auto;
47
+ font-family: Monospace;
48
+ font-size: 0.9em;
49
+ color: #999;
50
+ }
51
+
52
+ table#error_logs .time {
53
+ font-size: 0.7em;
54
+ font-style: italic;
55
+ }
56
+
57
+
58
+ </style>
59
+
60
+ <h1>Error logs</h1>
61
+
62
+ <div align="right">
63
+ <%= button_to "Mark all as read", :action => 'set_all_viewed' %>
64
+ </div>
65
+ <br />
66
+
67
+ <!-- Hell I love table layouts -->
68
+ <table style="width: 100%" cellpadding="10">
69
+ <tr><td valign="top">
70
+ <ul>
71
+ <li>
72
+ <%= link_to_if @errors_category, 'all', :action => :index %> (<%= @category_counts.values.sum %>)
73
+ </li>
74
+ <% @category_counts.each_pair do |category,count| %>
75
+ <li>
76
+ <%= link_to_if (@errors_category != category), category, :action => :index, :errors_category => category %>&nbsp;(<%= count %>)
77
+ </li>
78
+ <% end %>
79
+ </ul>
80
+ </td><td>
81
+
82
+ <table id="error_logs">
83
+ <% @error_logs.each_pair do |hash,logs| %>
84
+ <% error_log = logs.first %>
85
+ <tr class="<%= cycle('odd','even') %>">
86
+ <td>
87
+ <div class="level_box level_<%= error_log.level %>">
88
+ <%= error_log.level %>
89
+ </div>
90
+
91
+ <span class="time"><%= error_log.created_at %></span>
92
+ <br />
93
+ [<%= error_log.category %>]
94
+ <b><%= error_log.error %></b>
95
+ <br />
96
+
97
+ <% if logs.count > 1 %>
98
+ <div style="text-align: center">
99
+ Repeated <b><span style="font-size: <%= [12 + logs.count,100].min %>px;"><%= logs.count %></span></b> times.<br />
100
+ </div>
101
+ <% end %>
102
+
103
+ <br />
104
+ <% bt = error_log.backtrace.split("\n") %>
105
+ <div class="backtrace">
106
+ <%= bt[0...3].join("\n") %>
107
+ <% bid = "error_log_bt_#{error_log.id}" %>
108
+ <%= link_to_function '...', "$('#{bid}').show();" %>
109
+ <span style="display: none" id="<%= bid %>">
110
+ <%= bt[4...-1].join("\n") %>
111
+ </span>
112
+ </div>
113
+ </tr>
114
+ </tr>
115
+ <% end %>
116
+ </table>
117
+
118
+ </td></tr>
119
+ </table>
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: error_log
3
3
  version: !ruby/object:Gem::Version
4
- hash: 29
4
+ hash: 27
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 1
10
- version: 0.0.1
9
+ - 2
10
+ version: 0.0.2
11
11
  platform: ruby
12
12
  authors:
13
13
  - Kacper Ciesla
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-08-06 00:00:00 +02:00
18
+ date: 2010-08-07 00:00:00 +02:00
19
19
  default_executable:
20
20
  dependencies: []
21
21
 
@@ -29,12 +29,12 @@ extensions: []
29
29
  extra_rdoc_files: []
30
30
 
31
31
  files:
32
- - bin/error_log
33
32
  - lib/error_log.rb
34
33
  - lib/error_log/version.rb
35
34
  - lib/error_log/model.rb
36
35
  - lib/error_log/controller.rb
37
36
  - lib/error_log/core_ext.rb
37
+ - views/index.html.erb
38
38
  - README.txt
39
39
  has_rdoc: true
40
40
  homepage:
data/bin/error_log DELETED
@@ -1,7 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- require File.expand_path(
4
- File.join(File.dirname(__FILE__), %w[.. lib error_log]))
5
-
6
- # Put your code here
7
-