cheaptoad-silas 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/History.txt ADDED
@@ -0,0 +1,14 @@
1
+ === 0.0.6 2010-07-20
2
+ * HopToad protocol v2 support
3
+ * Removed requirement on hoe and newgem
4
+
5
+ === 0.0.3 2009-09-16
6
+ * Added basic RSS support
7
+
8
+ === 0.0.2 2009-09-16
9
+ * Added support for viewing notices
10
+
11
+ === 0.0.1 2009-09-15
12
+
13
+ * 1 major enhancement:
14
+ * Initial release
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Noah Gibbs
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Manifest.txt ADDED
@@ -0,0 +1,26 @@
1
+ app/controllers/notices_controller.rb
2
+ app/models/notice.rb
3
+ app/views/layouts/with_feed.html.erb
4
+ app/views/notices/index.html.erb
5
+ app/views/notices/list_by_api_key.html.erb
6
+ app/views/notices/list_notices.atom.builder
7
+ app/views/notices/list_notices.html.erb
8
+ app/views/notices/show.html.erb
9
+ generators/cheaptoad_migration/cheaptoad_migration_generator.rb
10
+ generators/cheaptoad_migration/templates/20090914074933_ct_migrate.rb
11
+ generators/cheaptoad_migration/USAGE
12
+ History.txt
13
+ init.rb
14
+ install.rb
15
+ lib/cheaptoad.rb
16
+ lib/tasks/cheaptoad.rake
17
+ MIT-LICENSE
18
+ Manifest.txt
19
+ PostInstall.txt
20
+ rails/init.rb
21
+ Rakefile
22
+ README.rdoc
23
+ test/test_cheaptoad.rb
24
+ test/test_helper.rb
25
+ TODO
26
+ uninstall.rb
data/PostInstall.txt ADDED
@@ -0,0 +1 @@
1
+ For more information on cheaptoad, see http://github.com/noahgibbs/cheaptoad
data/README.rdoc ADDED
@@ -0,0 +1,165 @@
1
+ = CHEAPTOAD
2
+
3
+ * http://noahgibbs.github.com/cheaptoad
4
+
5
+ == INSTALL:
6
+
7
+ sudo gem install cheaptoad
8
+
9
+ == USE:
10
+
11
+ In the app you want to catch hoptoad notices:
12
+
13
+ * Add "config.gem 'cheaptoad'" to environment.rb.
14
+ * Run "./script generate cheaptoad_migration" in your app
15
+ * Run "rake db:migrate" to create the notices table
16
+ * Start your app, and you're catching notices!
17
+
18
+ In the app you want to send hoptoad notices:
19
+
20
+ * Install and configure hoptoad like usual (see hoptoad_notifier)
21
+ * In initializers/hoptoad.rb, add:
22
+ config.host = 'my-app-hostname.mydomain.com'
23
+ config.port = 4321 # Whatever your app port is
24
+ * Start your app, and errors will now go to your cheaptoad-ified app
25
+
26
+ == DESCRIPTION:
27
+
28
+ CheapToad is a simple server plugin for the Hoptoad notifier. Make an
29
+ app receive and store errors from any app in just a couple of lines!
30
+
31
+ Hoptoad (hoptoadapp.com) is a commercial application and hosting
32
+ service, run by thoughtbot. For larger or more important apps, you'll
33
+ want your error logging handled by a reliable, professional service,
34
+ such as thoughtbot and Hoptoad. For small, simple and experimental
35
+ apps, why pay money?
36
+
37
+ == WHY CHEAPTOAD?
38
+
39
+ With CheapToad and Heroku, you can get mostly-reliable remote error
40
+ logging for nothing. When and if your app grows larger, you can
41
+ change two lines in config/initializers/hoptoad.rb and switch to
42
+ Hoptoad for extra reliability.
43
+
44
+ Hoptoad has a far better interface, and is free for the first project
45
+ and first two users (up to a given rate of errors received). But CheapToad
46
+ could still be the right choice if you:
47
+
48
+ * have a lot of projects and don't want to spend money
49
+ * don't want to let anybody else store your error data
50
+ * have a lot of people to collaborate with, but not that many errors yet
51
+ * feel bad about making a new Hoptoad account for each of your projects
52
+ just to scam service for free (this is me)
53
+ * need a lot of control over your old error notices -- if cleaning them up
54
+ after a while is Not Okay for some reason, for instance
55
+ * don't mind hosting for yourself and/or have a hosting solution you like
56
+ * just like running your own stuff, and like to get your hands dirty (also me)
57
+
58
+ By the way, I'm not affiliated with thoughtbot. This is all reverse
59
+ engineered from the Hoptoad notifier and somebody's RedMine plugin for
60
+ Hoptoad. Thoughtbot is aware of CheapToad's existence, but I'm not an
61
+ employee or anything.
62
+
63
+ Also, if you like CheapToad for your experimental projects, consider
64
+ upgrading a project or two to Hoptoad, or getting your employer to do
65
+ the same. I don't get a cut, but if I/we are costing them money
66
+ overall then they have less incentive to keep giving us code to use.
67
+ If we act like the farm team for their stuff and occasionally upgrade,
68
+ they have more incentive to keep writing things like the
69
+ hoptoad_notifier for us to bend to our own purposes.
70
+
71
+ == FEATURES:
72
+
73
+ * Very simple installation
74
+ * Very simple configuration
75
+ * Keeps your error notices around to browse later
76
+ * 100% free for any number of projects
77
+ * Maintains records of old error notices forever
78
+ * RSS feed of error notices for each project
79
+
80
+ == PROBLEMS:
81
+
82
+ * Very simple
83
+ * Not very configurable
84
+ * You have to run your own server, or use something like Heroku
85
+ * 100% Unsecured -- like Hoptoad, we rely on API key uniqueness for security.
86
+ Unlike Hoptoad, we suggest using fairly guessable API keys.
87
+ * All of these problems can be summed up as "not industrial strength"
88
+
89
+ == SYNOPSIS:
90
+
91
+ Make a new Rails app, or choose an existing one. Install the cheaptoad
92
+ plugin, and configure as mentioned above. Now that app can receive
93
+ Hoptoad errors!
94
+
95
+ In any and all apps that you want to send errors to your app, you'll
96
+ need to create a file called config/initializers/hoptoad.rb, just as
97
+ you always would when using Hoptoad. Here's an example config file:
98
+
99
+ HoptoadNotifier.configure do |config|
100
+ config.api_key = 'My Project Name'
101
+ config.host = 'my-cheaptoad-catcher.heroku.com'
102
+ config.port = 80 # or whatever port number
103
+
104
+ # All standard Hoptoad filters are supported
105
+ config.filter_parameters << "MY_SECRET_KEY"
106
+
107
+ end
108
+
109
+ Note that the host and port are for the app that will *receive*
110
+ Hoptoad errors. That's the app you added 'config.gem "cheaptoad"'
111
+ to.
112
+
113
+ == REQUIREMENTS:
114
+
115
+ You'll need a Rails app, which will be your CheapToad server. It can
116
+ do whatever else you like, but its notices controller will be used for
117
+ CheapToad stuff.
118
+
119
+ You will *not* need a Hoptoad API key. That's kind of the point of this
120
+ project. Instead of using a big hexadecimal string as your API key, I
121
+ recommend you use a simple string like "My Blog" or "Secret Project X".
122
+ That API key will be used by CheapToad as your project name.
123
+
124
+ == RESKINNING:
125
+
126
+ By default, CheapToad has a built-in set of HTML and RSS files to give
127
+ a very simple list of your errors. If you'd rather use your own, it's
128
+ probably easiest to just build your own notices_controller.rb file and
129
+ appropriate view files to go with it. You can look at the ones in the
130
+ CheapToad gem to do it -- they're very simple. Then, add your own new
131
+ HTML, CSS and whatnot to pretty it up.
132
+
133
+ We're considering adding the ability to put in your own CSS file
134
+ without changing the HTML, just to make the output less stark. If you
135
+ care about this feature and would use it, contact me and let me know!
136
+
137
+ == COMPATIBILITY:
138
+
139
+ CheapToad is compatible with the HopToad protocol v1. v2 compatibility
140
+ is in the works, and may work as you read this.
141
+
142
+ == LICENSE:
143
+
144
+ (The MIT License)
145
+
146
+ Copyright (c) 2009 Noah Gibbs
147
+
148
+ Permission is hereby granted, free of charge, to any person obtaining
149
+ a copy of this software and associated documentation files (the
150
+ 'Software'), to deal in the Software without restriction, including
151
+ without limitation the rights to use, copy, modify, merge, publish,
152
+ distribute, sublicense, and/or sell copies of the Software, and to
153
+ permit persons to whom the Software is furnished to do so, subject to
154
+ the following conditions:
155
+
156
+ The above copyright notice and this permission notice shall be
157
+ included in all copies or substantial portions of the Software.
158
+
159
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
160
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
161
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
162
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
163
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
164
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
165
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,23 @@
1
+ require 'rake'
2
+ require 'rake/testtask'
3
+ require 'rake/rdoctask'
4
+
5
+ desc 'Default: run unit tests.'
6
+ task :default => :test
7
+
8
+ desc 'Test the cheaptoad plugin.'
9
+ Rake::TestTask.new(:test) do |t|
10
+ t.libs << 'lib'
11
+ t.libs << 'test'
12
+ t.pattern = 'test/**/*_test.rb'
13
+ t.verbose = true
14
+ end
15
+
16
+ desc 'Generate documentation for the cheaptoad plugin.'
17
+ Rake::RDocTask.new(:rdoc) do |rdoc|
18
+ rdoc.rdoc_dir = 'rdoc'
19
+ rdoc.title = 'Cheaptoad'
20
+ rdoc.options << '--line-numbers' << '--inline-source'
21
+ rdoc.rdoc_files.include('README')
22
+ rdoc.rdoc_files.include('lib/**/*.rb')
23
+ end
data/TODO ADDED
@@ -0,0 +1,9 @@
1
+ Add "legal projects list" to make it annoying for attackers to send unlimited
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.
@@ -0,0 +1,27 @@
1
+ class NoticesController < ApplicationController
2
+ def create
3
+ notice = Notice.from_v1_yaml(request.raw_post)
4
+ notice.save!
5
+
6
+ render :text => "Successfully received error from hoptoad_notifier!"
7
+ end
8
+
9
+ def index
10
+ if params[:api_key]
11
+ @api_key = params[:api_key]
12
+ @notices = Notice.find_all_by_api_key(@api_key,
13
+ :order => "updated_at DESC")
14
+ render :layout => "with_feed", :action => "list_notices"
15
+ else
16
+ # List API keys
17
+ res = Notice.connection.execute("SELECT DISTINCT api_key FROM notices")
18
+ @keys = res.map {|i| i["api_key"]}
19
+ render :action => "list_by_api_key"
20
+ end
21
+ end
22
+
23
+ def show
24
+ @notice = Notice.find(params[:id])
25
+ end
26
+
27
+ end
@@ -0,0 +1,40 @@
1
+ class Notice < ActiveRecord::Base
2
+ [:session, :request, :environment, :backtrace].each {|a| serialize a}
3
+
4
+ # Accepts a string or parsed XML
5
+ def self.from_v2_xml(str)
6
+ full_xml = Hash.from_xml(str) if str.kind_of? String
7
+ self.from_hash(full_xml)
8
+ end
9
+
10
+ def self.from_v1_yaml(str)
11
+ full_yaml = YAML.load(str) if str.kind_of? String
12
+ self.from_hash(full_yaml)
13
+ end
14
+
15
+ # Accepts a string or parsed YAML
16
+ def self.from_hash(full_hash)
17
+ full_hash = full_hash['notice'] if full_hash['notice']
18
+
19
+ if(full_hash['backtrace'].kind_of? String)
20
+ backtraces = full_hash['backtrace']
21
+ else
22
+ backtraces = full_hash['backtrace'].join('\n')
23
+ end
24
+ digest = Digest::SHA1.hexdigest(backtraces)
25
+
26
+ notices = Notice.find_all_by_backtrace_digest(digest)
27
+ notices = notices.reject! { |i| i.backtrace != full_hash['backtrace'] }
28
+ if notices and notices.length > 0
29
+ notices[0].count += 1
30
+ return notices[0]
31
+ end
32
+
33
+ notice = Notice.create(full_hash)
34
+ notice.backtrace_digest = digest
35
+ notice.count = 1
36
+
37
+ notice
38
+ end
39
+
40
+ end
@@ -0,0 +1,5 @@
1
+ <head>
2
+ <%= auto_discovery_link_tag :atom, notices_url(:format => :atom, :api_key => @api_key) %>
3
+ <body>
4
+ <%= yield %>
5
+ </body>
@@ -0,0 +1,4 @@
1
+ <p>
2
+ You shouldn't see this page unless you manually go to index.html here.
3
+ Maybe you want <a href="list_notices.html">this page</a>?
4
+ </p>
@@ -0,0 +1,7 @@
1
+ <h1> CheapToad Projects (API Keys) </h1>
2
+
3
+ <ul>
4
+ <% @keys.each do |k| %>
5
+ <li> <%= link_to(k, :action => 'index', :api_key => k) -%> </li>
6
+ <% end %>
7
+ </ul>
@@ -0,0 +1,22 @@
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
+
5
+ @notices.each do |notice|
6
+ feed.entry(notice) do |entry|
7
+ entry.title(notice.error_message)
8
+ entry.content(<<END ,
9
+ <b>Project/APIkey:</b> #{notice.api_key} <br/>
10
+
11
+ <b>Error location:</b> #{notice.backtrace[0]} <br/>
12
+
13
+ <b>Error class:</b> #{notice.error_class}<br/>
14
+
15
+ This error has occurred #{notice.count} times<br/>
16
+
17
+ <b>Request:</b> #{simple_format notice.request.to_yaml}
18
+ END
19
+ :type => 'html')
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,15 @@
1
+ <h1> CheapToad Notices (errors) for Project <%= @api_key %> </h1>
2
+
3
+ <h2> Your errors: </h2>
4
+
5
+ <table>
6
+ <th> <td> Error message </td> <td> Count </td>
7
+ </th>
8
+
9
+ <% (@notices || []).each do |n| %>
10
+ <tr>
11
+ <td><%= link_to(n.error_message, :action => 'show', :id => n.id) %></td>
12
+ <td><%= n.count %></td>
13
+ </tr>
14
+ <% end %>
15
+ </ul>
@@ -0,0 +1,26 @@
1
+ <h1> Notice: <%= @notice.error_message %> </h1>
2
+ <h3> Project (API_key): <%= @notice.api_key %> </h3>
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
+
10
+ <hr />
11
+
12
+ <h2> Request </h2>
13
+
14
+ <%= simple_format @notice.request.to_yaml %>
15
+
16
+ <h2> Backtrace </h2>
17
+
18
+ <%= simple_format @notice.backtrace.to_yaml %>
19
+
20
+ <h2> Session Info </h2>
21
+
22
+ <%= simple_format @notice.session.to_yaml %>
23
+
24
+ <h2> Environment Variables </h2>
25
+
26
+ <%= simple_format @notice.environment.to_yaml %>
@@ -0,0 +1,5 @@
1
+ Description:
2
+ This generator creates a migration for entries in the CheapToad database.
3
+
4
+ Example:
5
+ ./script/generate cheaptoad_generator
@@ -0,0 +1,11 @@
1
+ class CheaptoadMigrationGenerator < Rails::Generator::Base
2
+
3
+ def manifest
4
+ record do |m|
5
+ m.directory "db/migrate"
6
+ m.template '20090914074933_ct_migrate.rb',
7
+ "db/migrate/20090914074933_ct_migrate.rb"
8
+ end
9
+ end
10
+
11
+ end
@@ -0,0 +1,26 @@
1
+ class CtMigrate < ActiveRecord::Migration
2
+ def self.up
3
+ create_table "notices", :force => true do |t|
4
+ t.string :api_key, :limit => 100
5
+ t.string :error_message, :limit => 200
6
+ t.string :error_class, :limit => 100
7
+ t.string :backtrace_digest, :limit => 256
8
+ t.integer :count
9
+ t.text :session
10
+ t.text :request
11
+ t.text :environment
12
+ t.text :backtrace
13
+
14
+ t.timestamps
15
+ end
16
+
17
+ add_index("notices", "backtrace_digest")
18
+ add_index("notices", "updated_at")
19
+ end
20
+
21
+ def self.down
22
+ remove_index("notices", "backtrace_digest")
23
+ remove_index("notices", "updated_at")
24
+ drop_table "notices"
25
+ end
26
+ end
data/init.rb ADDED
@@ -0,0 +1,2 @@
1
+ # Include hook code here
2
+ require File.join(File.dirname(__FILE__), "rails", "init.rb")
data/install.rb ADDED
@@ -0,0 +1 @@
1
+ # Install hook code here
data/lib/cheaptoad.rb ADDED
@@ -0,0 +1,6 @@
1
+ $:.unshift(File.dirname(__FILE__)) unless
2
+ $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
3
+
4
+ module Cheaptoad
5
+ VERSION = '0.0.5'
6
+ end
@@ -0,0 +1,4 @@
1
+ # desc "Explaining what the task does"
2
+ # task :cheaptoad do
3
+ # # Task goes here
4
+ # end
data/rails/init.rb ADDED
@@ -0,0 +1 @@
1
+ # Include hook code here
@@ -0,0 +1,11 @@
1
+ require File.dirname(__FILE__) + '/test_helper.rb'
2
+
3
+ class TestCheaptoad < Test::Unit::TestCase
4
+
5
+ def setup
6
+ end
7
+
8
+ def test_truth
9
+ assert true
10
+ end
11
+ end
@@ -0,0 +1,3 @@
1
+ require 'stringio'
2
+ require 'test/unit'
3
+ require File.dirname(__FILE__) + '/../lib/cheaptoad'
data/uninstall.rb ADDED
@@ -0,0 +1 @@
1
+ # Uninstall hook code here
metadata ADDED
@@ -0,0 +1,109 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: cheaptoad-silas
3
+ version: !ruby/object:Gem::Version
4
+ hash: 19
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 6
10
+ version: 0.0.6
11
+ platform: ruby
12
+ authors:
13
+ - Noah Gibbs
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2010-08-30 00:00:00 -04:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: rails
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ hash: 7
30
+ segments:
31
+ - 2
32
+ - 3
33
+ - 2
34
+ version: 2.3.2
35
+ type: :runtime
36
+ version_requirements: *id001
37
+ description: Add just a couple of lines to your app, and have it receive exceptions from your other apps via the hoptoad_notifier.
38
+ email: noah_nospam_gibbs@remove_nospam.yahoo.com
39
+ executables: []
40
+
41
+ extensions: []
42
+
43
+ extra_rdoc_files: []
44
+
45
+ files:
46
+ - app/controllers/notices_controller.rb
47
+ - app/models/notice.rb
48
+ - app/views/layouts/with_feed.html.erb
49
+ - app/views/notices/index.html.erb
50
+ - app/views/notices/list_by_api_key.html.erb
51
+ - app/views/notices/list_notices.atom.builder
52
+ - app/views/notices/list_notices.html.erb
53
+ - app/views/notices/show.html.erb
54
+ - generators/cheaptoad_migration/cheaptoad_migration_generator.rb
55
+ - generators/cheaptoad_migration/templates/20090914074933_ct_migrate.rb
56
+ - generators/cheaptoad_migration/USAGE
57
+ - History.txt
58
+ - init.rb
59
+ - install.rb
60
+ - lib/cheaptoad.rb
61
+ - lib/tasks/cheaptoad.rake
62
+ - MIT-LICENSE
63
+ - Manifest.txt
64
+ - PostInstall.txt
65
+ - rails/init.rb
66
+ - Rakefile
67
+ - README.rdoc
68
+ - test/test_cheaptoad.rb
69
+ - test/test_helper.rb
70
+ - TODO
71
+ - uninstall.rb
72
+ has_rdoc: true
73
+ homepage: http://github.com/noahgibbs
74
+ licenses: []
75
+
76
+ post_install_message:
77
+ rdoc_options: []
78
+
79
+ require_paths:
80
+ - lib
81
+ required_ruby_version: !ruby/object:Gem::Requirement
82
+ none: false
83
+ requirements:
84
+ - - ">="
85
+ - !ruby/object:Gem::Version
86
+ hash: 57
87
+ segments:
88
+ - 1
89
+ - 8
90
+ - 7
91
+ version: 1.8.7
92
+ required_rubygems_version: !ruby/object:Gem::Requirement
93
+ none: false
94
+ requirements:
95
+ - - ">="
96
+ - !ruby/object:Gem::Version
97
+ hash: 3
98
+ segments:
99
+ - 0
100
+ version: "0"
101
+ requirements: []
102
+
103
+ rubyforge_project: cheaptoad
104
+ rubygems_version: 1.3.7
105
+ signing_key:
106
+ specification_version: 3
107
+ summary: Catch hoptoad notices from your app.
108
+ test_files: []
109
+