rusen 0.0.1
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/lib/rusen.rb +18 -0
- data/lib/rusen/middleware/rusen_rack.rb +38 -0
- data/lib/rusen/notification.rb +16 -0
- data/lib/rusen/notifier.rb +41 -0
- data/lib/rusen/notifiers/email_notifier.rb +58 -0
- data/lib/rusen/notifiers/io_notifier.rb +67 -0
- data/lib/rusen/settings.rb +38 -0
- data/lib/rusen/templates/email_template.html.erb +77 -0
- metadata +101 -0
data/lib/rusen.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'rusen/settings'
|
2
|
+
require 'rusen/notifier'
|
3
|
+
#require 'rusen/notification'
|
4
|
+
|
5
|
+
module Rusen
|
6
|
+
|
7
|
+
@settings = Settings.new
|
8
|
+
@notifier = Notifier.new(@settings)
|
9
|
+
|
10
|
+
def self.settings
|
11
|
+
@settings
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.notify(exception, request = nil, environment = nil, session = nil)
|
15
|
+
@notifier.notify(exception, request, environment, session)
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'rusen/settings'
|
2
|
+
require 'rusen/notifier'
|
3
|
+
require 'rusen/notification'
|
4
|
+
|
5
|
+
module Rusen
|
6
|
+
module Middleware
|
7
|
+
|
8
|
+
class RusenRack
|
9
|
+
def initialize(app, settings = {})
|
10
|
+
@app = app
|
11
|
+
|
12
|
+
@rusen_settings = Settings.new
|
13
|
+
|
14
|
+
@rusen_settings.outputs = settings[:outputs]
|
15
|
+
@rusen_settings.sections = settings[:sections]
|
16
|
+
@rusen_settings.email_prefix = settings[:email_prefix]
|
17
|
+
@rusen_settings.sender_address = settings[:sender_address]
|
18
|
+
@rusen_settings.exception_recipients = settings[:exception_recipients]
|
19
|
+
@rusen_settings.smtp_settings = settings[:smtp_settings]
|
20
|
+
|
21
|
+
@notifier = Notifier.new(@rusen_settings)
|
22
|
+
end
|
23
|
+
|
24
|
+
def call(env)
|
25
|
+
begin
|
26
|
+
@app.call(env)
|
27
|
+
rescue Exception => error
|
28
|
+
request = Rack::Request.new(env)
|
29
|
+
|
30
|
+
@notifier.notify(error, request.GET.merge(request.POST), env, request.session)
|
31
|
+
|
32
|
+
raise
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Rusen
|
2
|
+
|
3
|
+
class Notification
|
4
|
+
|
5
|
+
attr_reader :exception, :request, :environment, :session
|
6
|
+
|
7
|
+
def initialize(exception, request = nil, environment = nil, session = nil)
|
8
|
+
@exception = exception
|
9
|
+
@request = request || {}
|
10
|
+
@environment = environment || {}
|
11
|
+
@session = session || {}
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'rusen/notification'
|
2
|
+
require 'rusen/notifiers/io_notifier'
|
3
|
+
require 'rusen/notifiers/email_notifier'
|
4
|
+
|
5
|
+
module Rusen
|
6
|
+
|
7
|
+
class Notifier
|
8
|
+
|
9
|
+
def initialize(settings)
|
10
|
+
@settings = settings
|
11
|
+
|
12
|
+
@notifiers = []
|
13
|
+
Notifiers.constants.each do |constant|
|
14
|
+
klass = Notifiers.const_get(constant)
|
15
|
+
if @settings.outputs.include?(klass.identification_symbol)
|
16
|
+
register(klass)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def register(notifier_class)
|
22
|
+
@notifiers << notifier_class.new(@settings)
|
23
|
+
end
|
24
|
+
|
25
|
+
def notify(exception, request = nil, environment = nil, session = nil)
|
26
|
+
begin
|
27
|
+
notification = Notification.new(exception, request, environment, session)
|
28
|
+
|
29
|
+
@notifiers.each do |notifier|
|
30
|
+
notifier.notify(notification)
|
31
|
+
end
|
32
|
+
|
33
|
+
# We need to ignore all the exceptions thrown by the notifiers.
|
34
|
+
rescue Exception
|
35
|
+
ERROR("Rusen: Some or all the notifiers failed to sent the notification.")
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'pony'
|
2
|
+
require 'erb'
|
3
|
+
|
4
|
+
module Rusen
|
5
|
+
module Notifiers
|
6
|
+
|
7
|
+
class EmailNotifier
|
8
|
+
|
9
|
+
def self.identification_symbol
|
10
|
+
:email
|
11
|
+
end
|
12
|
+
|
13
|
+
def initialize(settings)
|
14
|
+
@settings = settings
|
15
|
+
end
|
16
|
+
|
17
|
+
def notify(notification)
|
18
|
+
begin
|
19
|
+
@notification = notification
|
20
|
+
|
21
|
+
Pony.mail(email_options.merge({:body => build_body}))
|
22
|
+
|
23
|
+
# We need to ignore all the exceptions thrown by EmailNotifier.notify.
|
24
|
+
rescue Exception => e
|
25
|
+
ERROR("Rusen: #{e.message} prevented the notification email from being sent.")
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def email_options
|
32
|
+
{
|
33
|
+
:to => @settings.exception_recipients,
|
34
|
+
:via => :smtp,
|
35
|
+
:charset => 'utf-8',
|
36
|
+
:from => @settings.sender_address,
|
37
|
+
:headers => { 'Content-Type' => 'text/html' },
|
38
|
+
:via_options => @settings.smtp_settings,
|
39
|
+
:subject => email_subject.force_encoding('UTF-8')
|
40
|
+
}
|
41
|
+
end
|
42
|
+
|
43
|
+
def email_subject
|
44
|
+
@settings.email_prefix + "#{@notification.exception.class}: #{@notification.exception.message}"
|
45
|
+
end
|
46
|
+
|
47
|
+
def build_body
|
48
|
+
template_path = File.expand_path('../../templates/email_template.html.erb', __FILE__)
|
49
|
+
|
50
|
+
template = File.open(template_path).read
|
51
|
+
rhtml = ERB.new(template)
|
52
|
+
rhtml.result(binding)
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
module Rusen
|
2
|
+
module Notifiers
|
3
|
+
|
4
|
+
class IONotifier
|
5
|
+
|
6
|
+
STDOUT = $stdout
|
7
|
+
|
8
|
+
def self.identification_symbol
|
9
|
+
:io
|
10
|
+
end
|
11
|
+
|
12
|
+
def initialize(settings, output = STDOUT)
|
13
|
+
@settings = settings
|
14
|
+
@output = output
|
15
|
+
end
|
16
|
+
|
17
|
+
def notify(notification)
|
18
|
+
begin
|
19
|
+
if @settings.sections.include?(:backtrace)
|
20
|
+
|
21
|
+
print_title('Backtrace')
|
22
|
+
|
23
|
+
@output.puts notification.exception.message
|
24
|
+
@output.puts notification.exception.backtrace
|
25
|
+
end
|
26
|
+
|
27
|
+
if @settings.sections.include?(:request)
|
28
|
+
print_title('Request')
|
29
|
+
|
30
|
+
print_hash(notification.request)
|
31
|
+
end
|
32
|
+
|
33
|
+
if @settings.sections.include?(:session)
|
34
|
+
print_title('Session')
|
35
|
+
|
36
|
+
print_hash(notification.session)
|
37
|
+
end
|
38
|
+
|
39
|
+
if @settings.sections.include?(:environment)
|
40
|
+
print_title('Environment')
|
41
|
+
|
42
|
+
print_hash(notification.environment)
|
43
|
+
end
|
44
|
+
|
45
|
+
# We need to ignore all the exceptions thrown by IONotifier.notify.
|
46
|
+
rescue Exception => e
|
47
|
+
ERROR("Rusen: #{e.message} prevented the io notifier from login the error.")
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
def print_title(title)
|
54
|
+
@output.puts '-------------------------------'
|
55
|
+
@output.puts "#{title}:"
|
56
|
+
@output.puts '-------------------------------'
|
57
|
+
end
|
58
|
+
|
59
|
+
def print_hash(hash)
|
60
|
+
hash.each.each do |k, v|
|
61
|
+
@output.puts "#{k}\t\t\t#{v}"
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module Rusen
|
2
|
+
|
3
|
+
class Settings
|
4
|
+
|
5
|
+
attr_writer :outputs
|
6
|
+
attr_writer :email_prefix
|
7
|
+
attr_writer :sender_address
|
8
|
+
attr_writer :exception_recipients
|
9
|
+
attr_writer :sections
|
10
|
+
attr_writer :smtp_settings
|
11
|
+
|
12
|
+
def outputs
|
13
|
+
@outputs || [:io, :email]
|
14
|
+
end
|
15
|
+
|
16
|
+
def email_prefix
|
17
|
+
@email_prefix || '[Exception] '
|
18
|
+
end
|
19
|
+
|
20
|
+
def sender_address
|
21
|
+
@sender_address || ''
|
22
|
+
end
|
23
|
+
|
24
|
+
def exception_recipients
|
25
|
+
@exception_recipients || []
|
26
|
+
end
|
27
|
+
|
28
|
+
def sections
|
29
|
+
@sections || [:backtrace, :request, :session, :environment]
|
30
|
+
end
|
31
|
+
|
32
|
+
def smtp_settings
|
33
|
+
@smtp_settings || {}
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
<%= @notification.exception.class %>: <%= @notification.exception.message %>
|
2
|
+
|
3
|
+
<% if @settings.sections.include?(:backtrace) %>
|
4
|
+
<table style="border-collapse: collapse; border-spacing: 0; width: 100%; border: double; margin-bottom: 10px;">
|
5
|
+
<thead style="background-color: #EFEFEF; font-size: 10pt; font-weight: bold;">
|
6
|
+
<tr>
|
7
|
+
<td><h4>Backtrace:</h4></td>
|
8
|
+
<td></td>
|
9
|
+
</tr>
|
10
|
+
</thead>
|
11
|
+
<tbody style="font-size: 11pt;">
|
12
|
+
<% @notification.exception.backtrace.each do |backtrace_step| %>
|
13
|
+
<tr>
|
14
|
+
<td style="border: solid 1px #000000; margin: 0; padding: 4pt 6pt;"><%= backtrace_step %></td>
|
15
|
+
</tr>
|
16
|
+
<% end %>
|
17
|
+
</tbody>
|
18
|
+
</table>
|
19
|
+
<% end %>
|
20
|
+
|
21
|
+
<% if @settings.sections.include?(:request) %>
|
22
|
+
<table style="border-collapse: collapse; border-spacing: 0; width: 100%; border: double; margin-bottom: 10px;">
|
23
|
+
<thead style="background-color: #EFEFEF; font-size: 10pt; font-weight: bold;">
|
24
|
+
<tr>
|
25
|
+
<td><h4>Request:</h4></td>
|
26
|
+
<td></td>
|
27
|
+
</tr>
|
28
|
+
</thead>
|
29
|
+
<tbody style="font-size: 11pt;">
|
30
|
+
<% @notification.request.each do |k, v| %>
|
31
|
+
<tr>
|
32
|
+
<td style="border: solid 1px #000000; margin: 0; padding: 4pt 6pt;"><%= k %></td>
|
33
|
+
<td style="border: solid 1px #000000; margin: 0; padding: 4pt 6pt;"><%= v %></td>
|
34
|
+
</tr>
|
35
|
+
<% end %>
|
36
|
+
</tbody>
|
37
|
+
</table>
|
38
|
+
<% end %>
|
39
|
+
|
40
|
+
<% if @settings.sections.include?(:session) %>
|
41
|
+
<table style="border-collapse: collapse; border-spacing: 0; width: 100%; border: double; margin-bottom: 10px;">
|
42
|
+
<thead style="background-color: #EFEFEF; font-size: 10pt; font-weight: bold;">
|
43
|
+
<tr>
|
44
|
+
<td><h4>Session:</h4></td>
|
45
|
+
<td></td>
|
46
|
+
</tr>
|
47
|
+
</thead>
|
48
|
+
<tbody style="font-size: 11pt;">
|
49
|
+
<% @notification.session.each do |k, v| %>
|
50
|
+
<tr>
|
51
|
+
<td style="border: solid 1px #000000; margin: 0; padding: 4pt 6pt;"><%= k %></td>
|
52
|
+
<td style="border: solid 1px #000000; margin: 0; padding: 4pt 6pt;"><%= v %></td>
|
53
|
+
</tr>
|
54
|
+
<% end %>
|
55
|
+
</tbody>
|
56
|
+
</table>
|
57
|
+
<% end %>
|
58
|
+
|
59
|
+
|
60
|
+
<% if @settings.sections.include?(:environment) %>
|
61
|
+
<table style="border-collapse: collapse; border-spacing: 0; width: 100%; border: double; margin-bottom: 10px;">
|
62
|
+
<thead style="background-color: #EFEFEF; font-size: 10pt; font-weight: bold;">
|
63
|
+
<tr>
|
64
|
+
<td><h4>Environment:</h4></td>
|
65
|
+
<td></td>
|
66
|
+
</tr>
|
67
|
+
</thead>
|
68
|
+
<tbody style="font-size: 11pt;">
|
69
|
+
<% @notification.environment.each do |k, v| %>
|
70
|
+
<tr>
|
71
|
+
<td style="border: solid 1px #000000; margin: 0; padding: 4pt 6pt;"><%= k %></td>
|
72
|
+
<td style="border: solid 1px #000000; margin: 0; padding: 4pt 6pt;"><%= v %></td>
|
73
|
+
</tr>
|
74
|
+
<% end %>
|
75
|
+
</tbody>
|
76
|
+
</table>
|
77
|
+
<% end %>
|
metadata
ADDED
@@ -0,0 +1,101 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rusen
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Adrian Gomez
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-01-25 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: pony
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: rspec
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :development
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: simplecov
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
description: ! "RUby Simple Exception Notification (a.k.a. rusen) as it names indicates
|
63
|
+
is a\n simple exception notification for ruby."
|
64
|
+
email: adri4n.gomez@gmail.com
|
65
|
+
executables: []
|
66
|
+
extensions: []
|
67
|
+
extra_rdoc_files: []
|
68
|
+
files:
|
69
|
+
- lib/rusen.rb
|
70
|
+
- lib/rusen/templates/email_template.html.erb
|
71
|
+
- lib/rusen/notifier.rb
|
72
|
+
- lib/rusen/settings.rb
|
73
|
+
- lib/rusen/notifiers/io_notifier.rb
|
74
|
+
- lib/rusen/notifiers/email_notifier.rb
|
75
|
+
- lib/rusen/notification.rb
|
76
|
+
- lib/rusen/middleware/rusen_rack.rb
|
77
|
+
homepage: https://github.com/Moove-it/rusen
|
78
|
+
licenses: []
|
79
|
+
post_install_message:
|
80
|
+
rdoc_options: []
|
81
|
+
require_paths:
|
82
|
+
- lib
|
83
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
84
|
+
none: false
|
85
|
+
requirements:
|
86
|
+
- - ! '>='
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: '0'
|
89
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
90
|
+
none: false
|
91
|
+
requirements:
|
92
|
+
- - ! '>='
|
93
|
+
- !ruby/object:Gem::Version
|
94
|
+
version: '0'
|
95
|
+
requirements: []
|
96
|
+
rubyforge_project:
|
97
|
+
rubygems_version: 1.8.23
|
98
|
+
signing_key:
|
99
|
+
specification_version: 3
|
100
|
+
summary: RUby Simple Exception Notification
|
101
|
+
test_files: []
|