rack_hoptoad 0.0.5 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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'