rusen 0.0.2 → 0.0.3

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.
@@ -5,13 +5,21 @@ module Rusen
5
5
 
6
6
  attr_reader :exception, :request, :environment, :session
7
7
 
8
- def initialize(exception, request = nil, environment = nil, session = nil)
9
- @exception = exception
10
- @request = request || {}
11
- @environment = environment || {}
12
- @session = session || {}
8
+ def initialize(exception, request = {} , environment = {}, session = {})
9
+ @exception = exception
10
+ @request = request
11
+ @environment = environment
12
+ @session = session
13
+ end
14
+
15
+ def session
16
+ if @session.respond_to?(:each)
17
+ @session
18
+ else
19
+ @session.to_hash
20
+ end
13
21
  end
14
22
 
15
23
  end
16
24
 
17
- end
25
+ end
@@ -1,6 +1,5 @@
1
+ require 'rusen/notifiers'
1
2
  require 'rusen/notification'
2
- require 'rusen/notifiers/io_notifier'
3
- require 'rusen/notifiers/email_notifier'
4
3
 
5
4
  module Rusen
6
5
 
@@ -10,11 +9,20 @@ module Rusen
10
9
  @settings = settings
11
10
 
12
11
  @notifiers = []
13
- Notifiers.constants.each do |constant|
14
- klass = Notifiers.const_get(constant)
15
- if @settings.outputs.include?(klass.identification_symbol)
16
- register(klass)
12
+ @settings.outputs.each do |ident|
13
+ ident = Notifiers.check_deprecation(ident)
14
+ # For notifiers bundled in this gem
15
+ klass = Notifiers.load_klass(ident)
16
+ if klass.nil?
17
+ Notifiers.constants.each do |constant|
18
+ klass = Notifiers.const_get(constant)
19
+ next unless klass.is_a?(Class)
20
+ break if ident == klass.identification_symbol
21
+ klass = nil
22
+ end
17
23
  end
24
+ raise "Unable to load Output Notifier identified by: #{ident}" if klass.nil? || !klass.is_a?(Class)
25
+ register(klass)
18
26
  end
19
27
  end
20
28
 
@@ -28,7 +36,7 @@ module Rusen
28
36
  # @param [Hash<Object, Object>] request The request params
29
37
  # @param [Hash<Object, Object>] environment The environment status.
30
38
  # @param [Hash<Object, Object>] session The session status.
31
- def notify(exception, request = nil, environment = nil, session = nil)
39
+ def notify(exception, request = {}, environment = {}, session = {})
32
40
  begin
33
41
  notification = Notification.new(exception, request, environment, session)
34
42
 
@@ -0,0 +1,29 @@
1
+ module Rusen
2
+ module Notifiers
3
+
4
+ NOTIFIERS = {
5
+ :pony => :PonyNotifier,
6
+ :mail => :MailNotifier,
7
+ :io => :IONotifier,
8
+ :log4r => :Log4rNotifier,
9
+ }
10
+
11
+ def self.load_klass(ident, klass_sym = nil)
12
+ klass_sym ||= NOTIFIERS[ident]
13
+ if klass_sym
14
+ require "rusen/notifiers/#{ident}_notifier" unless Notifiers.constants.include?(klass_sym)
15
+ Notifiers.const_get(klass_sym)
16
+ else
17
+ return nil
18
+ end
19
+ end
20
+
21
+ def self.check_deprecation(ident)
22
+ if ident == :email
23
+ warn ':email is a deprecated output type. :pony replaces :email. A new alternative is :mail (mail gem).'
24
+ return :pony
25
+ end
26
+ return ident
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,53 @@
1
+ require 'erb'
2
+ require_relative '../utils/parameter_filter'
3
+
4
+ module Rusen
5
+ module Notifiers
6
+
7
+ class BaseNotifier
8
+
9
+ def self.identification_symbol
10
+ :base_notifier
11
+ end
12
+
13
+ def initialize(settings)
14
+ @settings = settings.dup
15
+ end
16
+
17
+ def get_sessions(notification)
18
+ result = {}
19
+
20
+ include_session(result, notification.exception.backtrace, :backtrace)
21
+ include_session(result, notification.request, :request)
22
+ include_session(result, notification.session, :session)
23
+ include_session(result, notification.environment, :environment)
24
+
25
+ result
26
+ end
27
+
28
+ def handle_notification_exception(exception)
29
+ name = self.class.identification_symbol.to_s
30
+
31
+ warn("Rusen: #{exception.message} prevented the #{name} notifier from login the error.")
32
+ end
33
+
34
+ private
35
+
36
+ def include_session(sessions, session, session_key)
37
+ @settings.sections
38
+
39
+ if @settings.sections.include?(session_key) && session
40
+ session = parameter_filter.filter(session) if session_key != :backtrace
41
+
42
+ sessions[session_key.to_s.capitalize] = session
43
+ end
44
+ end
45
+
46
+ def parameter_filter
47
+ @parameter_filter ||= ParameterFilter.new(@settings.filter_parameters)
48
+ end
49
+
50
+ end
51
+
52
+ end
53
+ end
@@ -1,7 +1,9 @@
1
+ require_relative 'base_notifier'
2
+
1
3
  module Rusen
2
4
  module Notifiers
3
5
 
4
- class IONotifier
6
+ class IONotifier < BaseNotifier
5
7
 
6
8
  STDOUT = $stdout
7
9
 
@@ -10,58 +12,31 @@ module Rusen
10
12
  end
11
13
 
12
14
  def initialize(settings, output = STDOUT)
13
- @settings = settings
14
- @output = output
15
+ super(settings)
16
+ @output = output
15
17
  end
16
18
 
17
19
  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
20
+ @notification = notification
21
+ @sessions = get_sessions(@notification)
44
22
 
45
23
  # We need to ignore all the exceptions thrown by IONotifier#notify.
46
- rescue Exception => e
47
- warn("Rusen: #{e.message} prevented the io notifier from login the error.")
48
- end
24
+ @output.puts build_content
25
+ rescue Exception => exception
26
+ handle_notification_exception(exception)
49
27
  end
50
28
 
51
29
  private
52
30
 
53
- def print_title(title)
54
- @output.puts '-------------------------------'
55
- @output.puts "#{title}:"
56
- @output.puts '-------------------------------'
57
- end
31
+ def build_content
32
+ template_path = File.expand_path('../../templates/io_template.txt.erb', __FILE__)
58
33
 
59
- def print_hash(hash)
60
- hash.each.each do |k, v|
61
- @output.puts "#{k}\t\t\t#{v}"
62
- end
34
+ template = File.open(template_path).read
35
+ rhtml = ERB.new(template, nil, '-')
36
+ rhtml.result(binding)
63
37
  end
38
+
64
39
  end
65
40
 
66
41
  end
67
- end
42
+ end
@@ -0,0 +1,70 @@
1
+ require_relative 'base_notifier'
2
+
3
+ begin
4
+ require 'log4r'
5
+ require 'log4r/yamlconfigurator'
6
+ rescue LoadError
7
+ puts <<-MESSAGE
8
+ [Rusen Error] To use log4r notifier add this to your Gemfile:
9
+ gem 'log4r'
10
+ MESSAGE
11
+ raise
12
+ end
13
+
14
+ module Rusen
15
+ module Notifiers
16
+
17
+ class Log4rNotifier < BaseNotifier
18
+
19
+ def self.identification_symbol
20
+ :log4r
21
+ end
22
+
23
+ def initialize(settings)
24
+ super(settings)
25
+
26
+ load_config(@settings.log4r_config_file)
27
+
28
+ @logger = logger_instance(@settings.logger_name)
29
+ end
30
+
31
+ def notify(notification)
32
+ @notification = notification
33
+ @sessions = get_sessions(@notification)
34
+
35
+ # We need to ignore all the exceptions thrown by Log4rNotifier#notify.
36
+ @logger.error { build_content }
37
+ rescue Exception => exception
38
+ handle_notification_exception(exception)
39
+ end
40
+
41
+ private
42
+
43
+ def build_content
44
+ template_path = File.expand_path('../../templates/log4r_template.txt.erb', __FILE__)
45
+
46
+ template = File.open(template_path).read
47
+ rhtml = ERB.new(template, nil, '-')
48
+ rhtml.result(binding)
49
+ end
50
+
51
+ def logger_instance(name = nil)
52
+ if name
53
+ Log4r::Logger[name]
54
+ else
55
+ Log4r::Logger.root
56
+ end
57
+ end
58
+
59
+ # Loads the given config file.
60
+ #
61
+ # @param [String] config_yml Configuration file path.
62
+ def load_config(config_yml)
63
+ if config_yml
64
+ Log4r::YamlConfigurator.load_yaml_file(config_yml)
65
+ end
66
+ end
67
+ end
68
+
69
+ end
70
+ end
@@ -0,0 +1,86 @@
1
+ require_relative 'base_notifier'
2
+
3
+ begin
4
+ require 'mail'
5
+ rescue LoadError
6
+ puts <<-MESSAGE
7
+ [Rusen Error] To use Mail notifier add this to your Gemfile:
8
+ gem 'mail'
9
+ MESSAGE
10
+ raise
11
+ end
12
+
13
+ module Rusen
14
+ module Notifiers
15
+
16
+ class MailNotifier < BaseNotifier
17
+
18
+ def self.identification_symbol
19
+ :mail
20
+ end
21
+
22
+ def initialize(settings)
23
+ super(settings)
24
+
25
+ if @settings && @settings.smtp_settings.any?
26
+ smtp_settings = @settings.smtp_settings
27
+
28
+ Mail.defaults do
29
+ delivery_method :smtp, smtp_settings
30
+ end
31
+ end
32
+ end
33
+
34
+ def notify(notification)
35
+ @notification = notification
36
+ @sessions = get_sessions(@notification)
37
+
38
+ options = email_options.dup
39
+ options.merge!({:body => build_body})
40
+ mail = Mail.new do
41
+ from options[:from]
42
+ to options[:to]
43
+ reply_to options[:reply_to]
44
+ cc options[:cc]
45
+ bcc options[:bcc]
46
+ subject options[:subject]
47
+ html_part do
48
+ content_type "text/html; charset=#{options[:charset]}"
49
+ body options[:body]
50
+ end
51
+ end
52
+
53
+ # We need to ignore all the exceptions thrown by MailNotifier#notify.
54
+ mail.deliver!
55
+ rescue Exception => exception
56
+ handle_notification_exception(exception)
57
+ end
58
+
59
+ private
60
+
61
+ def email_options
62
+ {
63
+ :to => @settings.exception_recipients,
64
+ :charset => 'UTF-8',
65
+ :from => @settings.sender_address,
66
+ :subject => email_subject
67
+ }
68
+ end
69
+
70
+ def email_subject
71
+ @settings.email_prefix + "#{@notification.exception.class}: #{@notification.exception.message}"
72
+ end
73
+
74
+ def build_body
75
+ template_path = File.expand_path('../../templates/email_template.html.erb', __FILE__)
76
+
77
+ template = File.open(template_path).read
78
+ rhtml = ERB.new(template, nil, '-')
79
+ rhtml.result(binding)
80
+ end
81
+
82
+ end
83
+
84
+ end
85
+
86
+ end
@@ -1,30 +1,32 @@
1
- require 'pony'
2
- require 'erb'
1
+ require_relative 'base_notifier'
2
+
3
+ begin
4
+ require 'pony'
5
+ rescue LoadError
6
+ puts <<-MESSAGE
7
+ [Rusen Error] To use Pony notifier add this to your Gemfile:
8
+ gem 'pony'
9
+ MESSAGE
10
+ raise
11
+ end
3
12
 
4
13
  module Rusen
5
14
  module Notifiers
6
15
 
7
- class EmailNotifier
16
+ class PonyNotifier < BaseNotifier
8
17
 
9
18
  def self.identification_symbol
10
- :email
11
- end
12
-
13
- def initialize(settings)
14
- @settings = settings
19
+ :pony
15
20
  end
16
21
 
17
22
  def notify(notification)
18
- begin
19
- @notification = notification
23
+ @notification = notification
24
+ @sessions = get_sessions(@notification)
20
25
 
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
- warn("Rusen: #{e.class}: #{e.message} prevented the notification email from being sent.")
26
- puts e.backtrace
27
- end
26
+ # We need to ignore all the exceptions thrown by PonyNotifier#notify.
27
+ Pony.mail(email_options.merge({:body => build_body}))
28
+ rescue Exception => exception
29
+ handle_notification_exception(exception)
28
30
  end
29
31
 
30
32
  private
@@ -32,7 +34,7 @@ module Rusen
32
34
  def email_options
33
35
  {
34
36
  :to => @settings.exception_recipients,
35
- :via => :smtp,
37
+ :via => @settings.email_via,
36
38
  :charset => 'utf-8',
37
39
  :from => @settings.sender_address,
38
40
  :headers => { 'Content-Type' => 'text/html' },
@@ -49,11 +51,12 @@ module Rusen
49
51
  template_path = File.expand_path('../../templates/email_template.html.erb', __FILE__)
50
52
 
51
53
  template = File.open(template_path).read
52
- rhtml = ERB.new(template)
54
+ rhtml = ERB.new(template, nil, '-')
53
55
  rhtml.result(binding)
54
56
  end
55
57
 
56
58
  end
57
59
 
58
60
  end
61
+
59
62
  end