rack_hoptoad 0.0.5 → 0.1.0

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.md CHANGED
@@ -7,15 +7,15 @@ Usage
7
7
  =====
8
8
  Throw something like this in your config.ru to enable notifications.
9
9
 
10
- require 'rack_hoptoad'
10
+ require 'rack/hoptoad'
11
11
 
12
- use Rack::HoptoadNotifier, 'fd48c7d26f724503a0280f808f44b339fc65fab8'
12
+ use Rack::Hoptoad, 'fd48c7d26f724503a0280f808f44b339fc65fab8'
13
13
 
14
14
  You can also exclude certain sensitive environmental variables using the block syntax
15
15
 
16
- require 'rack_hoptoad'
16
+ require 'rack/hoptoad'
17
17
 
18
- use Rack::HoptoadNotifier, 'fd48c7d26f724503a0280f808f44b339fc65fab8' do |notifier|
18
+ use Rack::Hoptoad, 'fd48c7d26f724503a0280f808f44b339fc65fab8' do |notifier|
19
19
  notifier.environment_filters << %w(MY_SECRET_KEY MY_SECRET_TOKEN)
20
20
  end
21
21
 
@@ -37,4 +37,4 @@ In order for exceptions to propagate up to Rack in Sinatra you need to enable ra
37
37
  enable :raise_errors
38
38
  end
39
39
 
40
- Note that the errors block does not execute so you'll need to handle the 500 elsewhere.
40
+ Note that the errors block does not execute so you'll need to handle the 500 elsewhere. Normally this is done with a 500.html in the document root.
data/Rakefile CHANGED
@@ -3,9 +3,10 @@ require 'rake/gempackagetask'
3
3
  require 'rubygems/specification'
4
4
  require 'spec/rake/spectask'
5
5
  require 'date'
6
+ require 'bundler'
6
7
 
7
8
  GEM = "rack_hoptoad"
8
- GEM_VERSION = "0.0.5"
9
+ GEM_VERSION = "0.1.0"
9
10
  AUTHOR = "Corey Donohoe"
10
11
  EMAIL = "atmos@atmos.org"
11
12
  HOMEPAGE = "http://github.com/atmos/rack_hoptoad"
@@ -23,11 +24,13 @@ spec = Gem::Specification.new do |s|
23
24
  s.email = EMAIL
24
25
  s.homepage = HOMEPAGE
25
26
 
26
- # Uncomment this to add a dependency
27
- s.add_dependency "rack"
27
+ manifest = Bundler::Environment.load(File.dirname(__FILE__) + '/Gemfile')
28
+ manifest.dependencies.each do |d|
29
+ next unless d.only && d.only.include?('release')
30
+ s.add_dependency(d.name, d.version)
31
+ end
28
32
 
29
33
  s.require_path = 'lib'
30
- s.autorequire = GEM
31
34
  s.files = %w(LICENSE README.md Rakefile TODO) + Dir.glob("{lib,specs}/**/*")
32
35
  end
33
36
 
@@ -35,11 +38,6 @@ Rake::GemPackageTask.new(spec) do |pkg|
35
38
  pkg.gem_spec = spec
36
39
  end
37
40
 
38
- desc "install the gem locally"
39
- task :install => [:package] do
40
- sh %{sudo gem install pkg/#{GEM}-#{GEM_VERSION}}
41
- end
42
-
43
41
  desc "create a gemspec file"
44
42
  task :make_spec do
45
43
  File.open("#{GEM}.gemspec", "w") do |file|
@@ -60,6 +58,5 @@ namespace :rack_hoptoad do
60
58
  t.rcov = ENV.has_key?('NO_RCOV') ? ENV['NO_RCOV'] != 'true' : true
61
59
  t.rcov_opts << '--text-summary'
62
60
  t.rcov_opts << '--sort' << 'coverage' << '--sort-reverse'
63
- # t.rcov_opts << '--only-uncovered'
64
61
  end
65
62
  end
@@ -0,0 +1,63 @@
1
+ require 'rack'
2
+ require 'erb'
3
+ require 'toadhopper'
4
+
5
+ module Rack
6
+ # Catches all exceptions raised from the app it wraps and
7
+ # posts the results to hoptoad.
8
+ class Hoptoad
9
+ attr_accessor :api_key, :environment_filters
10
+
11
+ def initialize(app, api_key = nil)
12
+ @app = app
13
+ @api_key = api_key
14
+ @environment_filters = %w(AWS_ACCESS_KEY AWS_SECRET_ACCESS_KEY AWS_ACCOUNT SSH_AUTH_SOCK)
15
+ yield self if block_given?
16
+ end
17
+
18
+ def call(env)
19
+ status, headers, body =
20
+ begin
21
+ @app.call(env)
22
+ rescue StandardError, LoadError, SyntaxError => boom
23
+ # TODO don't allow exceptions from send_notification to
24
+ # propogate
25
+ send_notification boom, env
26
+ raise
27
+ end
28
+ send_notification env['rack.exception'], env if env['rack.exception']
29
+ [status, headers, body]
30
+ end
31
+
32
+ def environment_filter_keys
33
+ @environment_filters.flatten
34
+ end
35
+ private
36
+
37
+ def send_notification(exception, env)
38
+ request = Rack::Request.new(env)
39
+
40
+ options = {
41
+ :api_key => api_key,
42
+ :url => "#{request.scheme}://#{request.host}#{request.path}",
43
+ :request => request,
44
+ :framework_env => ENV['RACK_ENV'] || 'development',
45
+ :notifier_name => 'Rack::Hoptoad',
46
+ :notifier_version => '0.0.6',
47
+ :session => env['rack.session']
48
+ }
49
+
50
+ if %w(staging production).include?(ENV['RACK_ENV'])
51
+ ToadHopper.new(api_key).post!(exception, options, {'X-Hoptoad-Client-Name' => 'Rack::Hoptoad'})
52
+ end
53
+ env['hoptoad.notified'] = true
54
+ end
55
+
56
+ def extract_body(env)
57
+ if io = env['rack.input']
58
+ io.rewind if io.respond_to?(:rewind)
59
+ io.read
60
+ end
61
+ end
62
+ end
63
+ end
metadata CHANGED
@@ -1,15 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rack_hoptoad
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.5
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Corey Donohoe
8
- autorequire: rack_hoptoad
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-12-01 00:00:00 -08:00
12
+ date: 2009-12-15 00:00:00 -08:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -22,6 +22,16 @@ dependencies:
22
22
  - !ruby/object:Gem::Version
23
23
  version: "0"
24
24
  version:
25
+ - !ruby/object:Gem::Dependency
26
+ name: toadhopper
27
+ type: :runtime
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: 0.9.1
34
+ version:
25
35
  description: A gem that provides hoptoad notifications from rack
26
36
  email: atmos@atmos.org
27
37
  executables: []
@@ -36,9 +46,7 @@ files:
36
46
  - README.md
37
47
  - Rakefile
38
48
  - TODO
39
- - lib/rack/hoptoad_notifier.rb
40
- - lib/rack/notice.xml.erb
41
- - lib/rack_hoptoad.rb
49
+ - lib/rack/hoptoad.rb
42
50
  has_rdoc: true
43
51
  homepage: http://github.com/atmos/rack_hoptoad
44
52
  licenses: []
@@ -1,130 +0,0 @@
1
- require 'net/http'
2
-
3
- module Rack
4
- # Catches all exceptions raised from the app it wraps and
5
- # posts the results to hoptoad.
6
- class HoptoadNotifier
7
- attr_accessor :api_key, :environment_filters
8
-
9
- def initialize(app, api_key = nil)
10
- @app = app
11
- @api_key = api_key
12
- @environment_filters = %w(AWS_ACCESS_KEY AWS_SECRET_ACCESS_KEY AWS_ACCOUNT SSH_AUTH_SOCK)
13
- yield self if block_given?
14
- end
15
-
16
- def call(env)
17
- status, headers, body =
18
- begin
19
- @app.call(env)
20
- rescue StandardError, LoadError, SyntaxError => boom
21
- # TODO don't allow exceptions from send_notification to
22
- # propogate
23
- send_notification boom, env
24
- raise
25
- end
26
- send_notification env['rack.exception'], env if env['rack.exception']
27
- [status, headers, body]
28
- end
29
-
30
- def environment_filter_keys
31
- @environment_filters.flatten
32
- end
33
- private
34
-
35
- def notice_template
36
- ::File.read(::File.join(::File.dirname(__FILE__), 'notice.xml.erb'))
37
- end
38
-
39
- INPUT_FORMAT = %r{^([^:]+):(\d+)(?::in `([^']+)')?$}.freeze
40
-
41
- class Backtrace < Struct.new(:file, :number, :method); end
42
- def build_backtrace(exception)
43
- exception.backtrace.map do |line|
44
- _, file, number, method = line.match(INPUT_FORMAT).to_a
45
- Backtrace.new(file, number, method)
46
- end
47
- end
48
-
49
- def send_notification(exception, env)
50
- @error = exception
51
- @api_key = api_key
52
- @request = Rack::Request.new(env)
53
- @request_path = @request.script_name + @request.path_info
54
- @environment = clean_hoptoad_environment(ENV.to_hash.merge(env))
55
- @backtrace = build_backtrace(exception)
56
-
57
- document = ERB.new(notice_template).result(binding)
58
-
59
- if %w(staging production).include?(ENV['RACK_ENV'])
60
- send_to_hoptoad document
61
- end
62
- env['hoptoad.notified'] = true
63
- end
64
-
65
- def extract_body(env)
66
- if io = env['rack.input']
67
- io.rewind if io.respond_to?(:rewind)
68
- io.read
69
- end
70
- end
71
-
72
- def send_to_hoptoad(data) #:nodoc:
73
- url = URI.parse("http://hoptoadapp.com:80/notifier_api/v2/notices")
74
-
75
- Net::HTTP.start(url.host, url.port) do |http|
76
- headers = {
77
- 'Content-type' => 'text/xml',
78
- 'Accept' => 'text/xml, application/xml'
79
- }
80
-
81
- http.read_timeout = 5 # seconds
82
- http.open_timeout = 2 # seconds
83
- # http.use_ssl = HoptoadNotifier.secure
84
- response = begin
85
- http.post(url.path, data, headers)
86
- rescue TimeoutError => e
87
- logger "Timeout while contacting the Hoptoad server."
88
- nil
89
- end
90
- case response
91
- when Net::HTTPSuccess then
92
- logger "Hoptoad Success: #{response.class}"
93
- else
94
- logger "Hoptoad Failure: #{response.class}\n#{response.body if response.respond_to? :body}"
95
- end
96
- end
97
- end
98
-
99
- def logger(str)
100
- puts str if ENV['RACK_DEBUG']
101
- end
102
-
103
- def clean_non_serializable_data(notice) #:nodoc:
104
- notice.select{|k,v| serializable?(v) }.inject({}) do |h, pair|
105
- h[pair.first] = pair.last.is_a?(Hash) ? clean_non_serializable_data(pair.last) : pair.last
106
- h
107
- end
108
- end
109
-
110
- def clean_hoptoad_environment(environment) #:nodoc:
111
- clean_non_serializable_data(environment).each do |key, value|
112
- environment[key] = "[FILTERED]" if filter?(key)
113
- end
114
- end
115
-
116
- def filter?(key)
117
- environment_filter_keys.any? do |filter|
118
- key.to_s.match(/#{filter}/)
119
- end
120
- end
121
-
122
- def serializable?(value) #:nodoc:
123
- value.is_a?(Fixnum) ||
124
- value.is_a?(Array) ||
125
- value.is_a?(String) ||
126
- value.is_a?(Hash) ||
127
- value.is_a?(Bignum)
128
- end
129
- end
130
- end
@@ -1,40 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <notice version="2.0.0">
3
- <api-key><%= @api_key %></api-key>
4
- <notifier>
5
- <name>Rack Hoptoad Notifier</name>
6
- <version>0.0.5</version>
7
- <url>http://github.com//atmos/rack_hoptoad</url>
8
- </notifier>
9
- <error>
10
- <class><%= @error.class.name %></class>
11
- <message><%= @error.message %></message>
12
- <backtrace>
13
- <% @backtrace.each do |line| %>
14
- <line method="<%= line.method %>" file="<%= line.file %>" number="<%= line.number %>"/>
15
- <% end %>
16
- </backtrace>
17
- </error>
18
- <request>
19
- <url><%= @request_path %></url>
20
- <component><%= @request_path %></component>
21
- <% if @request.params.any? %>
22
- <params>
23
- <% @request.params.each do |key,value| %>
24
- <var key="<%= key %>"><%= value %></var>
25
- <% end %>
26
- </params>
27
- <% end %>
28
- <% if @environment.any? %>
29
- <cgi-data>
30
- <% @environment.each do |key,value| %>
31
- <var key="<%= key %>"><%= value %></var>
32
- <% end %>
33
- </cgi-data>
34
- <% end %>
35
- </request>
36
- <server-environment>
37
- <project-root><%= Dir.pwd %></project-root>
38
- <environment-name><%= ENV['RACK_ENV'] || 'development' %></environment-name>
39
- </server-environment>
40
- </notice>
@@ -1,5 +0,0 @@
1
- require 'rack'
2
- require 'erb'
3
-
4
- root = File.expand_path(File.dirname(__FILE__))
5
- require root + '/rack/hoptoad_notifier.rb'