cheaptoad 0.0.4 → 0.0.6
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.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
|