cheaptoad 0.0.4 → 0.0.6
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +35 -18
- data/TODO +7 -0
- data/app/controllers/notices_controller.rb +3 -2
- data/app/models/notice.rb +16 -6
- data/app/views/notices/list_notices.atom.builder +7 -3
- data/app/views/notices/list_notices.html.erb +8 -2
- data/app/views/notices/show.html.erb +6 -0
- data/generators/cheaptoad_migration/templates/20090914074933_ct_migrate.rb +4 -1
- data/lib/cheaptoad.rb +1 -1
- metadata +2 -2
data/README.rdoc
CHANGED
@@ -7,55 +7,72 @@
|
|
7
7
|
CheapToad is a simple server plugin for the HopToad notifier. Make your
|
8
8
|
app a HopToad server in just a couple of lines!
|
9
9
|
|
10
|
-
== FEATURES
|
10
|
+
== FEATURES:
|
11
11
|
|
12
12
|
* Very simple installation
|
13
13
|
* Very simple configuration
|
14
14
|
* Keeps your exceptions around to browse later
|
15
|
+
* Free for any number of projects! That's cheaper than HopToad
|
16
|
+
* Maintains records of old errors forever, unlike HopToad
|
17
|
+
* RSS feed of errors for each project
|
18
|
+
|
19
|
+
== PROBLEMS:
|
20
|
+
|
21
|
+
* Very simple
|
22
|
+
* Not very configurable
|
23
|
+
* Have to run your own server, or use something like Heroku
|
24
|
+
* 100% Unsecured -- like HopToad, we rely on API key uniqueness for security.
|
25
|
+
Unlike HopToad, we suggest using fairly guessable API keys
|
15
26
|
|
16
27
|
== SYNOPSIS:
|
17
28
|
|
18
|
-
Make a Rails app, or choose an existing one. In
|
19
|
-
add the line 'config.gem "cheaptoad"'.
|
20
|
-
|
21
|
-
|
22
|
-
line "resources :notices".
|
29
|
+
Make a new Rails app, or choose an existing one. In
|
30
|
+
config/environment.rb, add the line 'config.gem "cheaptoad"'. You'll
|
31
|
+
also need to go into config/routes.rb and add the line "resources
|
32
|
+
:notices". Now that app can receive HopToad errors!
|
23
33
|
|
24
34
|
In any and all apps that you want to send errors to your app, create a
|
25
35
|
file called config/initializers/hoptoad.rb, as you always would when
|
26
|
-
using HopToad. Install the HopToad notifier also, of
|
27
|
-
file will look a bit like this:
|
36
|
+
using HopToad. Install the HopToad (or CheapToad) notifier also, of
|
37
|
+
course. The config file will look a bit like this:
|
28
38
|
|
29
39
|
HoptoadNotifier.configure do |config|
|
30
40
|
config.api_key = 'My Project Name'
|
31
|
-
config.host = '
|
32
|
-
config.port =
|
41
|
+
config.host = 'my-cheaptoad-catcher.heroku.com'
|
42
|
+
config.port = 80 # or whatever port number
|
33
43
|
|
44
|
+
# All standard Hoptoad filters are supported
|
34
45
|
config.environment_filters << "MY_SECRET_KEY"
|
35
46
|
|
36
47
|
end
|
37
48
|
|
38
|
-
Note that the host and port are for the app that will *receive*
|
39
|
-
errors
|
49
|
+
Note that the host and port are for the app that will *receive*
|
50
|
+
HopToad errors. That's the app you added the 'config.gem "cheaptoad"'
|
51
|
+
to.
|
40
52
|
|
41
53
|
== REQUIREMENTS:
|
42
54
|
|
43
|
-
You'll need a Rails app, which will be your CheapToad server. It can
|
44
|
-
whatever else you like, but its notices controller
|
45
|
-
|
55
|
+
You'll need a Rails app, which will be your CheapToad server. It can
|
56
|
+
do whatever else you like, but its notices controller will be used for
|
57
|
+
CheapToad stuff.
|
46
58
|
|
47
59
|
You will *not* need a HopToad API key. That's kind of the point of this
|
48
60
|
project. Instead of using a big hexadecimal string as your API key, I
|
49
61
|
recommend you use a simple string like "My Blog" or "Secret Project X".
|
62
|
+
That API key will be used by CheapToad as your project name.
|
50
63
|
|
51
64
|
== RESKINNING:
|
52
65
|
|
53
66
|
By default, CheapToad has a built-in set of HTML and RSS files to give
|
54
67
|
a very simple list of your errors. If you'd rather use your own, it's
|
55
68
|
probably easiest to just build your own notices_controller.rb file and
|
56
|
-
appropriate view files to go with it. You can look at the ones in
|
57
|
-
|
58
|
-
|
69
|
+
appropriate view files to go with it. You can look at the ones in the
|
70
|
+
CheapToad gem to do it -- they're very simple. Then, add your own new
|
71
|
+
HTML, CSS and whatnot to pretty it up.
|
72
|
+
|
73
|
+
We're considering adding the ability to put in your own CSS file
|
74
|
+
without changing the HTML, just to make the output less stark. If you
|
75
|
+
care about this feature and would use it, contact me and let me know!
|
59
76
|
|
60
77
|
== INSTALL:
|
61
78
|
|
data/TODO
CHANGED
@@ -1,2 +1,9 @@
|
|
1
1
|
Add "legal projects list" to make it annoying for attackers to send unlimited
|
2
2
|
false notices
|
3
|
+
|
4
|
+
Add CSS to views for easy stylesheetification, and way to supply a CSS file
|
5
|
+
from app. In general, add some kind of simple configuration block to allow
|
6
|
+
easier customization than "write all your own views."
|
7
|
+
|
8
|
+
Add ability to mark errors handled, so that they go into a different category
|
9
|
+
until/unless they show up again.
|
@@ -1,6 +1,6 @@
|
|
1
1
|
class NoticesController < ApplicationController
|
2
2
|
def create
|
3
|
-
notice = Notice.
|
3
|
+
notice = Notice.notice_from_yaml(request.raw_post)
|
4
4
|
notice.save!
|
5
5
|
|
6
6
|
render :text => "Successfully received error from hoptoad_notifier!"
|
@@ -9,7 +9,8 @@ class NoticesController < ApplicationController
|
|
9
9
|
def index
|
10
10
|
if params[:api_key]
|
11
11
|
@api_key = params[:api_key]
|
12
|
-
@notices = Notice.find_all_by_api_key(@api_key
|
12
|
+
@notices = Notice.find_all_by_api_key(@api_key,
|
13
|
+
:order => "updated_at DESC")
|
13
14
|
render :layout => "with_feed", :action => "list_notices"
|
14
15
|
else
|
15
16
|
# List API keys
|
data/app/models/notice.rb
CHANGED
@@ -1,17 +1,27 @@
|
|
1
1
|
class Notice < ActiveRecord::Base
|
2
2
|
[:session, :request, :environment, :backtrace].each {|a| serialize a}
|
3
3
|
|
4
|
-
def self.
|
4
|
+
def self.notice_from_yaml(str)
|
5
5
|
full_yaml = YAML.load(str) if str.kind_of? String
|
6
6
|
full_yaml = full_yaml['notice'] if full_yaml['notice']
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
backtraces = notice.backtrace
|
8
|
+
if(full_yaml['backtrace'].kind_of? String)
|
9
|
+
backtraces = full_yaml['backtrace']
|
11
10
|
else
|
12
|
-
backtraces =
|
11
|
+
backtraces = full_yaml['backtrace'].join('\n')
|
12
|
+
end
|
13
|
+
digest = Digest::SHA1.hexdigest(backtraces)
|
14
|
+
|
15
|
+
notices = Notice.find_all_by_backtrace_digest(digest)
|
16
|
+
notices = notices.reject! { |i| i.backtrace != full_yaml['backtrace'] }
|
17
|
+
if notices and notices.length > 0
|
18
|
+
notices[0].count += 1
|
19
|
+
return notices[0]
|
13
20
|
end
|
14
|
-
|
21
|
+
|
22
|
+
notice = Notice.create(full_yaml)
|
23
|
+
notice.backtrace_digest = digest
|
24
|
+
notice.count = 1
|
15
25
|
|
16
26
|
notice
|
17
27
|
end
|
@@ -1,6 +1,6 @@
|
|
1
|
-
atom_feed do |feed|
|
2
|
-
feed.title(@feedtitle || "Error Feed from CheapToad")
|
3
|
-
feed.updated(@notices.first.
|
1
|
+
atom_feed(:root_url => request.url) do |feed|
|
2
|
+
feed.title(@feedtitle || "Error Feed for #{@api_key} from CheapToad")
|
3
|
+
feed.updated(@notices.first.updated_at)
|
4
4
|
|
5
5
|
@notices.each do |notice|
|
6
6
|
feed.entry(notice) do |entry|
|
@@ -10,6 +10,10 @@ atom_feed do |feed|
|
|
10
10
|
|
11
11
|
<b>Error location:</b> #{notice.backtrace[0]} <br/>
|
12
12
|
|
13
|
+
<b>Error class:</b> #{notice.error_class}<br/>
|
14
|
+
|
15
|
+
This error has occurred #{notice.count} times<br/>
|
16
|
+
|
13
17
|
<b>Request:</b> #{simple_format notice.request.to_yaml}
|
14
18
|
END
|
15
19
|
:type => 'html')
|
@@ -2,8 +2,14 @@
|
|
2
2
|
|
3
3
|
<h2> Your errors: </h2>
|
4
4
|
|
5
|
-
<
|
5
|
+
<table>
|
6
|
+
<th> <td> Error message </td> <td> Count </td>
|
7
|
+
</th>
|
8
|
+
|
6
9
|
<% (@notices || []).each do |n| %>
|
7
|
-
<
|
10
|
+
<tr>
|
11
|
+
<td><%= link_to(n.error_message, :action => 'show', :id => n.id) %></td>
|
12
|
+
<td><%= n.count %></td>
|
13
|
+
</tr>
|
8
14
|
<% end %>
|
9
15
|
</ul>
|
@@ -1,6 +1,12 @@
|
|
1
1
|
<h1> Notice: <%= @notice.error_message %> </h1>
|
2
2
|
<h3> Project (API_key): <%= @notice.api_key %> </h3>
|
3
3
|
|
4
|
+
<p>
|
5
|
+
first instance of this error: <%= @notice.created_at %> <br />
|
6
|
+
most recent instance of this error: <%= @notice.updated_at %> <br />
|
7
|
+
number of occurrences: <b><%= @notice.count %></b>
|
8
|
+
</p>
|
9
|
+
|
4
10
|
<hr />
|
5
11
|
|
6
12
|
<h2> Request </h2>
|
@@ -5,6 +5,7 @@ class CtMigrate < ActiveRecord::Migration
|
|
5
5
|
t.string :error_message, :limit => 200
|
6
6
|
t.string :error_class, :limit => 100
|
7
7
|
t.string :backtrace_digest, :limit => 256
|
8
|
+
t.integer :count
|
8
9
|
t.text :session
|
9
10
|
t.text :request
|
10
11
|
t.text :environment
|
@@ -14,10 +15,12 @@ class CtMigrate < ActiveRecord::Migration
|
|
14
15
|
end
|
15
16
|
|
16
17
|
add_index("notices", "backtrace_digest")
|
18
|
+
add_index("notices", "updated_at")
|
17
19
|
end
|
18
20
|
|
19
21
|
def self.down
|
20
|
-
drop_table "notices"
|
21
22
|
remove_index("notices", "backtrace_digest")
|
23
|
+
remove_index("notices", "updated_at")
|
24
|
+
drop_table "notices"
|
22
25
|
end
|
23
26
|
end
|
data/lib/cheaptoad.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cheaptoad
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Noah Gibbs
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-
|
12
|
+
date: 2009-11-22 00:00:00 -08:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|