rnotifier 0.0.2

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