rnotifier 0.0.2

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/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source 'http://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in rnotifier.gemspec
4
+ gem 'rake'
5
+ gem 'json'
6
+ gemspec
data/README.md ADDED
@@ -0,0 +1,11 @@
1
+ Rnotifier
2
+ =============
3
+
4
+ Rails 3 Exception catcher gem
5
+
6
+ Usage
7
+ -----
8
+
9
+ In your rails app
10
+
11
+ rails g rnotifier -k "API-KEY"
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
@@ -0,0 +1,23 @@
1
+ class RnotifierGenerator < Rails::Generators::Base
2
+
3
+ source_root File.expand_path('../templates', __FILE__)
4
+ class_option :api_key, :aliases => '-k', :type => :string, :desc => 'Rnotifier API key.'
5
+
6
+ def add_config
7
+ if options[:api_key]
8
+ template 'initializer.rb', 'config/initializers/rnotifier.rb'
9
+ p "******* INFO *************"
10
+ p "Set exception recipients email address in 'config/initializers/rnotifier.rb'"
11
+ p "i.e. c.exception_recipients => %w{user1@example.com, user2@example.com} "
12
+ else
13
+ p 'Set option --api-key or -k.'
14
+ end
15
+ end
16
+
17
+ private
18
+ def api_key
19
+ "'#{options[:api_key]}'"
20
+ end
21
+
22
+ end
23
+
@@ -0,0 +1,5 @@
1
+ Rnotifier::Notifier.config do |c|
2
+ c.api_key = <%= api_key %>
3
+ c.exception_recipients = %w{user1@example.com user2@example.com}
4
+ end
5
+
@@ -0,0 +1,49 @@
1
+ module Rnotifier
2
+ class Configuration
3
+ DEFAULT_CONFIG = {
4
+ :api_host => 'http://rnotifier.com/notify/api/v1',
5
+ :validate_path => 'validate',
6
+ :notify_path => 'exception'
7
+ }
8
+
9
+ FILTER_PARAMS = ['password', 'password_confirmation']
10
+
11
+ class << self
12
+ attr_accessor :api_key
13
+ attr_accessor :client_ip
14
+ attr_accessor :client_host_name
15
+ attr_accessor :is_valid
16
+ attr_accessor :filter_params
17
+ attr_accessor :notification_server
18
+ attr_accessor :exception_recipients
19
+
20
+ def [](key)
21
+ DEFAULT_CONFIG[key] || send(key)
22
+ end
23
+
24
+ def validate_config
25
+
26
+ unless self.notification_server
27
+ self.notification_server = DEFAULT_CONFIG[:api_host]
28
+ else
29
+ self.notification_server += '/notify/api/v1'
30
+ end
31
+
32
+ if self.api_key
33
+ response = Util.get(self[:validate_path])
34
+ self.is_valid = true if response['valid_api_key']
35
+ else
36
+ Rlogger.error('[CONFIG] Check your config API key is not define.')
37
+ end
38
+
39
+ unless self.is_valid
40
+ Rlogger.error('[CONFIG] Invalid API KEY. Please check it.')
41
+ else
42
+ Rlogger.info('[CONFIG] API key is valid.')
43
+ end
44
+
45
+ end
46
+ end
47
+ end
48
+ end
49
+
@@ -0,0 +1,19 @@
1
+ module Rnotifier
2
+ class EmailNotifier < ActionMailer::Base
3
+ default :from => 'Rnotifier Exception<exception@rnotifier.in>'
4
+ self.mailer_name = 'email_notifier'
5
+ self.append_view_path "#{File.dirname(__FILE__)}/views"
6
+
7
+ def exception_notify(exception)
8
+ @exception = exception
9
+ @project_name = Rails.application.class.to_s.sub('::Application', '')
10
+
11
+ emails = Configuration.exception_recipients
12
+ subject = "[RNOTIFIER][#{@project_name}##{@exception[:environment]}] #{@exception[:message]}"
13
+
14
+ mail(:to => emails, :subject => subject) do |format|
15
+ format.html { render "#{mailer_name}/exception_notify" }
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,58 @@
1
+ module Rnotifier
2
+ class Notifier
3
+
4
+ class << self
5
+ def config(&block)
6
+ yield(Rnotifier::Configuration)
7
+ Configuration.validate_config rescue Rlogger.error('[CONFIG] Error from notification server.')
8
+
9
+ #Initialize Rails Exception handler
10
+ Rnotifier::RailsException.initialize if Configuration.is_valid
11
+
12
+ Configuration.filter_params ||= []
13
+
14
+ if Configuration.filter_params.empty?
15
+ Configuration.filter_params.concat(Configuration::FILTER_PARAMS)
16
+ end
17
+
18
+ Configuration.freeze
19
+ end
20
+
21
+ def send_exception(exception_data)
22
+ exception_data[:params] = filter_params(exception_data[:params])
23
+ exception_data[:occurred_at] = Time.now
24
+
25
+ t = Thread.new do
26
+ begin
27
+ response = Util.post(Configuration[:notify_path], {:exception_data => exception_data})
28
+
29
+ Rlogger.error("[SEND] #{response['message']}") unless response['notify']
30
+ rescue Exception => e
31
+ Rlogger.error("[SERVER] #{e.message}")
32
+ Rlogger.error("[SERVER] #{e.backtrace}")
33
+ end
34
+ send_email_notification(exception_data)
35
+ end
36
+ end
37
+
38
+ def send_email_notification(exception_data)
39
+ begin
40
+ EmailNotifier.exception_notify(exception_data).deliver
41
+ rescue Exception => e
42
+ Rlogger.error("[MAILER] #{e.message}")
43
+ Rlogger.error("[MAILER] #{e.backtrace}")
44
+ end
45
+ end
46
+
47
+ def filter_params(params = {})
48
+ return if params.empty?
49
+
50
+ Configuration.filter_params.each do |key|
51
+ params[key] = '[FILTERED]' if params.has_key?(key)
52
+ end
53
+ params
54
+ end
55
+
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,49 @@
1
+ module Rnotifier
2
+ module RailsException
3
+ module Catcher
4
+
5
+ def self.included(base)
6
+ base.send(:alias_method, :render_exception_without_rnotifier, :render_exception)
7
+ base.send(:alias_method, :render_exception, :render_exception_with_rnotifier)
8
+ end
9
+
10
+ private
11
+ def render_exception_with_rnotifier(env,exception)
12
+ request = ActionDispatch::Request.new(env)
13
+ unless (@consider_all_requests_local || request.local?)
14
+ exception_data = {
15
+ :url => request.url,
16
+ :params => request.params,
17
+ :session => request.session,
18
+ :ip => request.ip,
19
+ :http_method => request.method,
20
+ :status_code => status_code(exception),
21
+ :class_name => exception.class.to_s,
22
+ :message => exception.message,
23
+ :exception_line => Rails.backtrace_cleaner.clean(exception.backtrace, :silent).first,
24
+ :backtrace => Rails.backtrace_cleaner.clean(exception.backtrace, nil),
25
+ :environment => Rails.env.capitalize,
26
+ :user_agent => request.user_agent
27
+ }
28
+
29
+ exception_data[:session].delete('session_id')
30
+ exception_data[:exception_hash] = Digest::MD5.hexdigest(exception_data[:message].gsub(/#<\w*:\w*>/, '') +
31
+ exception_data[:exception_line])
32
+ exception_data[:env_variables] = Util.request_env(request.filtered_env)
33
+
34
+ Notifier.send_exception(exception_data)
35
+ end
36
+
37
+ render_exception_without_rnotifier(env, exception)
38
+ end
39
+
40
+ end
41
+
42
+ def self.initialize
43
+ if defined?(ActionDispatch::ShowExceptions)
44
+ Configuration.filter_params = Rails.application.config.filter_parameters.uniq
45
+ ActionDispatch::ShowExceptions.send(:include, Rnotifier::RailsException::Catcher)
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,27 @@
1
+ module Rnotifier
2
+ class Rlogger
3
+
4
+ LOG_TITLE = '[RNOTIFIER]'
5
+
6
+ class << self
7
+
8
+ def info(msg)
9
+ logger.info("#{LOG_TITLE}#{msg}")
10
+ end
11
+
12
+ def error(msg)
13
+ logger.error("#{LOG_TITLE}#{msg}")
14
+ end
15
+
16
+ def warn(msg)
17
+ logger.warn("#{LOG_TITLE}#{msg}")
18
+ end
19
+
20
+ private
21
+ def logger
22
+ @rlogger ||= (defined?(Rails.logger) ? Rails.logger : Logger.new(STDERR))
23
+ end
24
+
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,29 @@
1
+ module Rnotifier
2
+ class Util
3
+ class << self
4
+ def post(path, data = {})
5
+ url = URI.parse(Configuration.notification_server)
6
+ post = Net::HTTP::Post.new("#{url.path}/#{path}/#{Configuration[:api_key]}",{'Content-Type' =>'application/json'})
7
+
8
+ http = Net::HTTP.new(url.host, url.port)
9
+ http.use_ssl = true if url.port == 443
10
+ JSON.parse(http.request(post, data.to_json).body)
11
+ end
12
+
13
+ def get(path, params = {})
14
+ url = "#{Configuration.notification_server}/#{path}/#{Configuration[:api_key]}"
15
+ JSON.parse(Net::HTTP.get(URI.parse(url)))
16
+ end
17
+
18
+ def request_env(env)
19
+ env_hash = env.reject{|k,v| k.include?('action') || k.include?('rack')}
20
+ env_hash.delete('HTTP_COOKIE')
21
+ env_hash['HOSTNAME'] = Socket.gethostname
22
+
23
+ env_hash.to_json
24
+ end
25
+
26
+
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,3 @@
1
+ module Rnotifier
2
+ VERSION = "0.0.2"
3
+ end
@@ -0,0 +1,29 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta content='text/html; charset=UTF-8' http-equiv='Content-Type'>
5
+ </head>
6
+ <body style='color:#333;font-size:14px;margin-top:30px;'>
7
+ <span style='font-size:15px;'>
8
+ <strong style='margin-right:45px;'>Project</strong> : <%= @project_name %>
9
+ <br/>
10
+ <strong style='margin-right:5px;'>Environment</strong> : <%= @exception[:environment] %>
11
+ </span>
12
+ <div style='border:2px solid #FBC7C6;padding:10px 15px;margin-top:20px;'>
13
+ <p style='font-weight:bold'>
14
+ Exception: <%= @exception[:message] %>
15
+ </p>
16
+ <p>
17
+ <strong>Action : </strong><%= "#{@exception[:params][:controller]}##{@exception[:params][:action]}" %>
18
+ </p>
19
+ <p>
20
+ <strong>Exception Line : </strong><%= @exception[:exception_line] %>
21
+ </p>
22
+ <p>
23
+ <strong>Occurred at : </strong><%= @exception[:occurred_at] %> </p>
24
+ <p>
25
+ <strong>Request Url : </strong><%= "#{@exception[:http_method]} #{@exception[:url]}" %>
26
+ </p>
27
+ </div>
28
+ </body>
29
+ </html>
data/lib/rnotifier.rb ADDED
@@ -0,0 +1,15 @@
1
+ require 'rnotifier/version'
2
+ require 'net/http'
3
+ require 'json'
4
+ require 'logger'
5
+ require 'action_mailer'
6
+
7
+ module Rnotifier
8
+ autoload :Notifier, 'rnotifier/notifier'
9
+ autoload :Configuration, 'rnotifier/configuration'
10
+ autoload :RailsException, 'rnotifier/rails_exception'
11
+ autoload :EmailNotifier, 'rnotifier/email_notifier'
12
+ autoload :Util, 'rnotifier/util'
13
+ autoload :Rlogger, 'rnotifier/rlogger'
14
+ end
15
+
data/rnotifier.gemspec ADDED
@@ -0,0 +1,19 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/rnotifier/version', __FILE__)
3
+ #require "rnotifier/version"
4
+
5
+ Gem::Specification.new do |gem|
6
+ gem.authors = ["Jiren Patel"]
7
+ gem.email = ["jiren@joshsoftware.com"]
8
+ gem.description = %q{Rails 3 Exception catcher}
9
+ gem.summary = %q{Rails 3 Exception catcher}
10
+ gem.homepage = "https://github.com/jiren/rnotifier"
11
+
12
+ gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
13
+ gem.files = `git ls-files`.split("\n")
14
+ gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
15
+ gem.name = "rnotifier"
16
+ gem.require_paths = ["lib"]
17
+ gem.version = Rnotifier::VERSION
18
+ gem.add_dependency('json', '>= 1.5.3')
19
+ end
metadata ADDED
@@ -0,0 +1,96 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rnotifier
3
+ version: !ruby/object:Gem::Version
4
+ hash: 27
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 2
10
+ version: 0.0.2
11
+ platform: ruby
12
+ authors:
13
+ - Jiren Patel
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2011-11-18 00:00:00 Z
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ version_requirements: &id001 !ruby/object:Gem::Requirement
22
+ none: false
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ hash: 5
27
+ segments:
28
+ - 1
29
+ - 5
30
+ - 3
31
+ version: 1.5.3
32
+ prerelease: false
33
+ requirement: *id001
34
+ type: :runtime
35
+ name: json
36
+ description: Rails 3 Exception catcher
37
+ email:
38
+ - jiren@joshsoftware.com
39
+ executables: []
40
+
41
+ extensions: []
42
+
43
+ extra_rdoc_files: []
44
+
45
+ files:
46
+ - .gitignore
47
+ - Gemfile
48
+ - README.md
49
+ - Rakefile
50
+ - lib/generators/rnotifier/rnotifier_generator.rb
51
+ - lib/generators/rnotifier/templates/initializer.rb
52
+ - lib/rnotifier.rb
53
+ - lib/rnotifier/configuration.rb
54
+ - lib/rnotifier/email_notifier.rb
55
+ - lib/rnotifier/notifier.rb
56
+ - lib/rnotifier/rails_exception.rb
57
+ - lib/rnotifier/rlogger.rb
58
+ - lib/rnotifier/util.rb
59
+ - lib/rnotifier/version.rb
60
+ - lib/rnotifier/views/email_notifier/exception_notify.html.erb
61
+ - rnotifier.gemspec
62
+ homepage: https://github.com/jiren/rnotifier
63
+ licenses: []
64
+
65
+ post_install_message:
66
+ rdoc_options: []
67
+
68
+ require_paths:
69
+ - lib
70
+ required_ruby_version: !ruby/object:Gem::Requirement
71
+ none: false
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ hash: 3
76
+ segments:
77
+ - 0
78
+ version: "0"
79
+ required_rubygems_version: !ruby/object:Gem::Requirement
80
+ none: false
81
+ requirements:
82
+ - - ">="
83
+ - !ruby/object:Gem::Version
84
+ hash: 3
85
+ segments:
86
+ - 0
87
+ version: "0"
88
+ requirements: []
89
+
90
+ rubyforge_project:
91
+ rubygems_version: 1.8.11
92
+ signing_key:
93
+ specification_version: 3
94
+ summary: Rails 3 Exception catcher
95
+ test_files: []
96
+