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 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: []