rusen 0.0.2 → 0.0.3

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