error_log 0.0.1 → 0.0.2
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/README.txt +59 -1
- data/lib/error_log/controller.rb +42 -8
- data/lib/error_log/core_ext.rb +5 -1
- data/lib/error_log/model.rb +24 -2
- data/lib/error_log/version.rb +1 -1
- data/lib/error_log.rb +1 -2
- data/views/index.html.erb +119 -0
- metadata +5 -5
- data/bin/error_log +0 -7
data/README.txt
CHANGED
@@ -3,11 +3,69 @@ error_log
|
|
3
3
|
|
4
4
|
== DESCRIPTION:
|
5
5
|
|
6
|
-
Easy way to track exceptions and
|
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)
|
data/lib/error_log/controller.rb
CHANGED
@@ -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
|
-
|
3
|
+
module Controller# < ActionController::Base
|
5
4
|
|
6
|
-
|
5
|
+
def index
|
7
6
|
|
8
|
-
|
9
|
-
|
10
|
-
|
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
|
data/lib/error_log/core_ext.rb
CHANGED
@@ -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
|
data/lib/error_log/model.rb
CHANGED
@@ -9,7 +9,8 @@ module ErrorLog
|
|
9
9
|
t.text :error
|
10
10
|
t.text :backtrace
|
11
11
|
t.string :category
|
12
|
-
|
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.
|
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
|
data/lib/error_log/version.rb
CHANGED
data/lib/error_log.rb
CHANGED
@@ -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 %> (<%= 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:
|
4
|
+
hash: 27
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 0.0.
|
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-
|
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:
|