rnotifier 0.0.6 → 0.0.8
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.
- checksums.yaml +7 -0
- data/Gemfile +1 -3
- data/LICENSE.txt +22 -0
- data/README.md +24 -33
- data/Rakefile +0 -1
- data/bin/rnotifier +38 -0
- data/lib/generators/rnotifier/rnotifier_generator.rb +0 -3
- data/lib/generators/rnotifier/templates/initializer.rb +0 -2
- data/lib/rnotifier/config.rb +85 -0
- data/lib/rnotifier/exception_code.rb +31 -0
- data/lib/rnotifier/exception_data.rb +98 -0
- data/lib/rnotifier/notifier.rb +16 -50
- data/lib/rnotifier/parameter_filter.rb +78 -0
- data/lib/rnotifier/rack_middleware.rb +26 -0
- data/lib/rnotifier/railtie.rb +21 -0
- data/lib/rnotifier/rlogger.rb +20 -18
- data/lib/rnotifier/version.rb +1 -1
- data/lib/rnotifier.rb +49 -11
- data/rnotifier.gemspec +25 -16
- data/spec/code.text +18 -0
- data/spec/config_spec.rb +60 -0
- data/spec/exception_code_spec.rb +48 -0
- data/spec/exception_data_spec.rb +60 -0
- data/spec/fixtures/fake_app.rb +21 -0
- data/spec/fixtures/rnotifier.yaml +2 -0
- data/spec/fixtures/rnotifier_test.yaml +2 -0
- data/spec/rack_middleware_spec.rb +22 -0
- data/spec/spec_helper.rb +59 -0
- metadata +152 -69
- data/LICENSE +0 -21
- data/lib/rnotifier/configuration.rb +0 -51
- data/lib/rnotifier/email_notifier.rb +0 -19
- data/lib/rnotifier/rails_exception.rb +0 -48
- data/lib/rnotifier/util.rb +0 -29
- data/lib/rnotifier/views/email_notifier/exception_notify.html.erb +0 -29
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 50c10d0bf67e250e5ca27a71467daca164c6bdb3
|
4
|
+
data.tar.gz: 7326f599dc1a0d6bdf85a51253bcf3c0931f3e96
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 94f5b55b64acfff14967da646858a232457cbd0008dbf29092b95b2c0d9b273e7420a1c087a25eacc85ef186c871bd8c88cda0cc8b8eb3263eeb053695823302
|
7
|
+
data.tar.gz: 8fcfb420fd001c7a3769bcf2148b586f41ed97ed6f47553a926e1e2fb4304d63936d25274e224b4c8d96cd41049588193a75a8d822a79b5aec5d26d2ddef6cf1
|
data/Gemfile
CHANGED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Jiren Patel
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
CHANGED
@@ -1,48 +1,39 @@
|
|
1
|
-
Rnotifier
|
2
|
-
=========
|
1
|
+
# Rnotifier
|
3
2
|
|
4
|
-
|
3
|
+
Exception catcher for rack base applications.
|
5
4
|
|
6
|
-
|
5
|
+
## Installation
|
7
6
|
|
8
|
-
|
9
|
-
-----
|
7
|
+
Add this line to your application's Gemfile:
|
10
8
|
|
11
|
-
|
9
|
+
gem 'rnotifier'
|
12
10
|
|
13
|
-
|
11
|
+
And then execute:
|
14
12
|
|
15
|
-
|
13
|
+
$ bundle
|
16
14
|
|
17
|
-
|
15
|
+
Or install it yourself as:
|
18
16
|
|
19
|
-
|
20
|
-
------------------------------------------------
|
17
|
+
$ gem install rnotifier
|
21
18
|
|
22
|
-
|
19
|
+
## Usage
|
23
20
|
|
24
|
-
|
25
|
-
c.exception_recipients = %w{jiren@joshsoftware.com example@example.com}
|
26
|
-
```
|
21
|
+
rnotifier install 'API-KEY' # This will create 'config/rnotifier.yaml' file.
|
27
22
|
|
28
|
-
|
23
|
+
### Config file options
|
29
24
|
|
30
|
-
|
31
|
-
|
32
|
-
|
25
|
+
- environments: development #Default is production
|
26
|
+
- capture_code: true #Default false
|
27
|
+
- api_host: 'http://yourapp.com' #Default http://rnotifier.com
|
33
28
|
|
34
|
-
|
35
|
-
--------------------
|
29
|
+
## Contributing
|
36
30
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
end
|
43
|
-
```
|
44
|
-
|
45
|
-
Contributing
|
46
|
-
------------
|
47
|
-
Please send me a pull request so that this can be improved.
|
31
|
+
1. Fork it
|
32
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
33
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
34
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
35
|
+
5. Create new Pull Request
|
48
36
|
|
37
|
+
License
|
38
|
+
-------
|
39
|
+
This is released under the MIT license.
|
data/Rakefile
CHANGED
data/bin/rnotifier
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
ARGV[0] = 'help' if ARGV.empty?
|
4
|
+
|
5
|
+
case ARGV[0]
|
6
|
+
when 'help'
|
7
|
+
puts %Q{
|
8
|
+
---- HELP ----
|
9
|
+
test #Test rnotifier configuration is correct and send test exception.
|
10
|
+
|
11
|
+
install api-key [environments] #Create config/rnotifier.yaml with api_key and enabled for supplied environments.environments are optionbal, default is production.
|
12
|
+
}
|
13
|
+
when 'test'
|
14
|
+
require 'rnotifier'
|
15
|
+
|
16
|
+
Rnotofier::Config.load_config('config/rnotifier.yml')
|
17
|
+
if Rnotofier::Config.valid?
|
18
|
+
#NOTE: Add test code
|
19
|
+
else
|
20
|
+
puts 'Configuration is invalid. Check api key'
|
21
|
+
end
|
22
|
+
when 'install'
|
23
|
+
if (api_key = ARGV[1]).nil?
|
24
|
+
puts "'api-key' is required. Use like i.e rnotifier install api-key [environments]"
|
25
|
+
else
|
26
|
+
environments = ARGV[2..-1]
|
27
|
+
Dir.mkdir('config') unless Dir.exists?('config')
|
28
|
+
|
29
|
+
File.open('config/rnotifier.yaml', 'w') do |f|
|
30
|
+
f.puts("apikey: #{api_key}\n")
|
31
|
+
f.puts("environments: #{environments.join(', ')}") unless environments.empty?
|
32
|
+
f.puts("capture_code: false")
|
33
|
+
f.close
|
34
|
+
end
|
35
|
+
|
36
|
+
puts "Rnotofier configuration written in config/rnotifier.yaml"
|
37
|
+
end
|
38
|
+
end
|
@@ -6,9 +6,6 @@ class RnotifierGenerator < Rails::Generators::Base
|
|
6
6
|
def add_config
|
7
7
|
if options[:api_key]
|
8
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
9
|
else
|
13
10
|
p 'Set option --api-key or -k.'
|
14
11
|
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
module Rnotifier
|
2
|
+
class Config
|
3
|
+
DEFAULT = {
|
4
|
+
:api_host => 'http://api.rnotifier.com',
|
5
|
+
:api_version => 'v1',
|
6
|
+
:notify_path => 'exception',
|
7
|
+
:ignore_env => ['development', 'test'],
|
8
|
+
:http_open_timeout => 2,
|
9
|
+
:http_read_timeout => 4
|
10
|
+
}
|
11
|
+
|
12
|
+
CLIENT = "RN-RUBY-GEM:#{Rnotifier::VERSION}"
|
13
|
+
|
14
|
+
class << self
|
15
|
+
attr_accessor :api_key, :notification_path, :environments, :current_env,
|
16
|
+
:valid, :app_env, :api_host, :ignore_exceptions, :capture_code
|
17
|
+
|
18
|
+
def [](val)
|
19
|
+
DEFAULT[val]
|
20
|
+
end
|
21
|
+
|
22
|
+
def init
|
23
|
+
Rlogger.init
|
24
|
+
|
25
|
+
self.valid = false
|
26
|
+
self.current_env = ENV['RACK_ENV'] || ENV['RAILS_ENV'] || 'development'
|
27
|
+
self.environments ||= []
|
28
|
+
|
29
|
+
if self.environments.is_a?(String) || self.environments.is_a?(Symbol)
|
30
|
+
self.environments = self.environments.to_s.split(',')
|
31
|
+
end
|
32
|
+
|
33
|
+
#Return if config environments not include current env
|
34
|
+
return if !self.environments.empty? && !self.environments.include?(self.current_env)
|
35
|
+
|
36
|
+
#Check for ignore env
|
37
|
+
if DEFAULT[:ignore_env].include?(self.current_env) && !self.environments.include?(self.current_env)
|
38
|
+
return
|
39
|
+
end
|
40
|
+
|
41
|
+
if self.api_key.nil? and !ENV['RNOTIFIER_API_KEY'].nil?
|
42
|
+
self.api_key = ENV['RNOTIFIER_API_KEY']
|
43
|
+
end
|
44
|
+
|
45
|
+
return if self.api_key.to_s.length == 0
|
46
|
+
|
47
|
+
self.api_host ||= DEFAULT[:api_host]
|
48
|
+
self.notification_path = '/' + [DEFAULT[:api_version], DEFAULT[:notify_path], self.api_key].join('/')
|
49
|
+
self.app_env = get_app_env
|
50
|
+
self.ignore_exceptions = self.ignore_exceptions.split(',') if self.ignore_exceptions.is_a?(String)
|
51
|
+
|
52
|
+
self.valid = true
|
53
|
+
end
|
54
|
+
|
55
|
+
def valid?
|
56
|
+
self.valid
|
57
|
+
end
|
58
|
+
|
59
|
+
def get_app_env
|
60
|
+
{
|
61
|
+
:env => self.current_env,
|
62
|
+
:pid => $$,
|
63
|
+
:host => (Socket.gethostname rescue ''),
|
64
|
+
:user_name => ENV['USER'] || ENV['USERNAME'],
|
65
|
+
:program_name => $PROGRAM_NAME,
|
66
|
+
:app_root => self.app_root,
|
67
|
+
:language => {
|
68
|
+
:name => 'ruby',
|
69
|
+
:version => (RUBY_VERSION rescue ''),
|
70
|
+
:patch_level => (RUBY_PATCHLEVEL rescue ''),
|
71
|
+
:platform => (RUBY_PLATFORM rescue ''),
|
72
|
+
:release_date => (RUBY_RELEASE_DATE rescue ''),
|
73
|
+
:ruby_path => Gem.ruby,
|
74
|
+
:gem_path => Gem.path
|
75
|
+
}
|
76
|
+
}
|
77
|
+
end
|
78
|
+
|
79
|
+
def app_root
|
80
|
+
(defined?(Rails) && Rails.respond_to?(:root)) ? Rails.root.to_s : Dir.pwd
|
81
|
+
end
|
82
|
+
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Rnotifier
|
2
|
+
class ExceptionCode
|
3
|
+
class << self
|
4
|
+
|
5
|
+
def get(backtrace)
|
6
|
+
return unless backtrace
|
7
|
+
filename, line, method = (backtrace.find{|l| l =~ /^#{Config.app_env[:app_root]}/} || backtrace[0]).split(':')
|
8
|
+
self.find(filename, line.to_i, 3)
|
9
|
+
end
|
10
|
+
|
11
|
+
def find(filename, line_no, wrap_size = 1)
|
12
|
+
s_range = [line_no - wrap_size, 1].max - 1
|
13
|
+
e_range = line_no + wrap_size - 1
|
14
|
+
#s_range, e_range = [ (line_no - wrap_size) > 0 ? line_no - wrap_size : 0, line_no + wrap_size]
|
15
|
+
code = [s_range]
|
16
|
+
|
17
|
+
begin
|
18
|
+
File.open(filename) do |f|
|
19
|
+
f.each_with_index do |line, i|
|
20
|
+
code << line if i >= s_range && i <= e_range
|
21
|
+
break if i > e_range
|
22
|
+
end
|
23
|
+
end
|
24
|
+
rescue Exception => e
|
25
|
+
end
|
26
|
+
code
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,98 @@
|
|
1
|
+
module Rnotifier
|
2
|
+
class ExceptionData
|
3
|
+
attr_reader :env, :request, :exception, :options
|
4
|
+
|
5
|
+
def initialize(exception, env, options = {})
|
6
|
+
@exception = exception
|
7
|
+
@options = options
|
8
|
+
if options[:type] == :rack
|
9
|
+
@request = Rack::Request.new(env)
|
10
|
+
else
|
11
|
+
@env = env
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def notify
|
16
|
+
return unless Config.valid?
|
17
|
+
return if Config.ignore_exceptions && Config.ignore_exceptions.include?(exception.class.to_s)
|
18
|
+
|
19
|
+
|
20
|
+
begin
|
21
|
+
data = if options[:type] == :rack
|
22
|
+
self.rack_exception_data
|
23
|
+
else
|
24
|
+
{:exception => self.exception_data, :extra => self.env }
|
25
|
+
end
|
26
|
+
|
27
|
+
data[:exception][:code] = ExceptionCode.get(data[:exception][:backtrace]) if Config.capture_code
|
28
|
+
data[:context_data] = Thread.current[:rnotifier_context] if Thread.current[:rnotifier_context]
|
29
|
+
data[:data_from] = options[:type]
|
30
|
+
data[:rnotifier_client] = Config::CLIENT
|
31
|
+
|
32
|
+
Notifier.send(data)
|
33
|
+
rescue Exception => e
|
34
|
+
Rlogger.error("[NOTIFY] #{e.message}")
|
35
|
+
Rlogger.error("[NOTIFY] #{e.backtrace}")
|
36
|
+
ensure
|
37
|
+
Rnotifier.clear_context
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def rack_exception_data
|
42
|
+
data = {
|
43
|
+
:occurred_at => Time.now.to_s,
|
44
|
+
:app_env => Rnotifier::Config.app_env,
|
45
|
+
:exception => self.exception_data
|
46
|
+
}
|
47
|
+
data[:request] = {
|
48
|
+
:url => request.url,
|
49
|
+
:referer_url => request.referer,
|
50
|
+
:ip => request.ip,
|
51
|
+
:http_method => "#{request.request_method}#{' # XHR' if request.xhr?}",
|
52
|
+
:params => filtered_params,
|
53
|
+
:headers => self.headers,
|
54
|
+
:session => request.session
|
55
|
+
}
|
56
|
+
|
57
|
+
data
|
58
|
+
end
|
59
|
+
|
60
|
+
def exception_data
|
61
|
+
{
|
62
|
+
:class_name => exception.class.to_s,
|
63
|
+
:message => exception.message,
|
64
|
+
:backtrace => exception.backtrace,
|
65
|
+
:fingerprint => (self.fingerprint rescue nil)
|
66
|
+
}
|
67
|
+
end
|
68
|
+
|
69
|
+
def fingerprint
|
70
|
+
#data[:fingerprint] = Digest::MD5.hexdigest("#{exception.message.gsub(/#<\w*:\w*>/, '')}#{data[:fingerprint]}")
|
71
|
+
|
72
|
+
if exception.backtrace && !exception.backtrace.empty?
|
73
|
+
Digest::MD5.hexdigest(exception.backtrace.join)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def filtered_params
|
78
|
+
if rp = request.env['action_dispatch.parameter_filter']
|
79
|
+
ParameterFilter.filter(request.env['action_dispatch.request.parameters'] || request.params, rp)
|
80
|
+
else
|
81
|
+
ParameterFilter.default_filter(request.params)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
HEADER_REGX = /^HTTP_/
|
86
|
+
|
87
|
+
def headers
|
88
|
+
headers = {}
|
89
|
+
request.env.each do |k, v|
|
90
|
+
headers[k.sub(HEADER_REGX, '').downcase] = v if k =~ HEADER_REGX
|
91
|
+
end
|
92
|
+
headers['cookie'] = headers['cookie'].sub(/_session=\S+/, '_session=[FILTERED]') if headers['cookie']
|
93
|
+
headers
|
94
|
+
end
|
95
|
+
|
96
|
+
|
97
|
+
end
|
98
|
+
end
|
data/lib/rnotifier/notifier.rb
CHANGED
@@ -1,58 +1,24 @@
|
|
1
1
|
module Rnotifier
|
2
|
-
|
2
|
+
class Notifier
|
3
|
+
class << self
|
3
4
|
|
4
|
-
|
5
|
-
|
6
|
-
|
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}")
|
5
|
+
def connection
|
6
|
+
@connection ||= Faraday.new(:url => Rnotifier::Config.api_host) do |faraday|
|
7
|
+
faraday.adapter Faraday.default_adapter
|
44
8
|
end
|
45
9
|
end
|
46
10
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
11
|
+
def send(data)
|
12
|
+
response = self.connection.post do |req|
|
13
|
+
req.url Rnotifier::Config.notification_path
|
14
|
+
req.headers['Content-Type'] = 'application/json'
|
15
|
+
req.options[:timeout] = Rnotifier::Config[:http_open_timeout]
|
16
|
+
req.options[:open_timeout] = Rnotifier::Config[:http_read_timeout]
|
17
|
+
req.body = MultiJson.dump(data)
|
18
|
+
end
|
55
19
|
|
20
|
+
Rlogger.error("[RNOTIFIER SERVER] Response Status:#{response.status}") unless response.status == 200
|
21
|
+
end
|
56
22
|
end
|
57
|
-
|
23
|
+
end
|
58
24
|
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
module Rnotifier
|
2
|
+
class ParameterFilter
|
3
|
+
|
4
|
+
DEFAULT_FIELDS = [:password, :password_confirmation, :authorization, :secret, :passwd]
|
5
|
+
FILTERED = '[FILTERED]'
|
6
|
+
|
7
|
+
def self.filter(params, filters)
|
8
|
+
@filter ||= ParameterFilter.new(filters)
|
9
|
+
@filter.filter(params)
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.default_filter(params)
|
13
|
+
@default_filter ||= ParameterFilter.new(DEFAULT_FIELDS)
|
14
|
+
@default_filter.filter(params)
|
15
|
+
end
|
16
|
+
|
17
|
+
def initialize(filters)
|
18
|
+
@filters = filters
|
19
|
+
end
|
20
|
+
|
21
|
+
def filter(params)
|
22
|
+
if @filters && !@filters.empty?
|
23
|
+
compiled_filter.call(params)
|
24
|
+
else
|
25
|
+
params
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def compiled_filter
|
32
|
+
@compiled_filter ||= begin
|
33
|
+
regexps, blocks = compile_filter
|
34
|
+
|
35
|
+
lambda do |original_params|
|
36
|
+
filtered_params = {}
|
37
|
+
|
38
|
+
original_params.each do |key, value|
|
39
|
+
if regexps.find { |r| key =~ r }
|
40
|
+
value = FILTERED
|
41
|
+
elsif value.is_a?(Hash)
|
42
|
+
value = filter(value)
|
43
|
+
elsif value.is_a?(Array)
|
44
|
+
value = value.map { |v| v.is_a?(Hash) ? filter(v) : v }
|
45
|
+
elsif blocks
|
46
|
+
key = key.dup
|
47
|
+
value = value.dup rescue value
|
48
|
+
blocks.each { |b| b.call(key, value) }
|
49
|
+
end
|
50
|
+
|
51
|
+
filtered_params[key] = value
|
52
|
+
end
|
53
|
+
|
54
|
+
filtered_params
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def compile_filter
|
60
|
+
strings, regexps, blocks = [], [], []
|
61
|
+
|
62
|
+
@filters.each do |item|
|
63
|
+
case item
|
64
|
+
when NilClass
|
65
|
+
when Proc
|
66
|
+
blocks << item
|
67
|
+
when Regexp
|
68
|
+
regexps << item
|
69
|
+
else
|
70
|
+
strings << item.to_s
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
regexps << Regexp.new(strings.join('|'), true) unless strings.empty?
|
75
|
+
[regexps, blocks]
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Rnotifier
|
2
|
+
class RackMiddleware
|
3
|
+
|
4
|
+
def initialize(app, config_file = nil)
|
5
|
+
@app = app
|
6
|
+
Rnotifier.load_config(config_file) if config_file
|
7
|
+
end
|
8
|
+
|
9
|
+
def call(env)
|
10
|
+
begin
|
11
|
+
response = @app.call(env)
|
12
|
+
rescue Exception => e
|
13
|
+
Rnotifier::ExceptionData.new(e, env, {:type => :rack}).notify
|
14
|
+
env['rnotifier.notify'] = true
|
15
|
+
raise e
|
16
|
+
end
|
17
|
+
|
18
|
+
if e = (env['rack.exception'] || env['sinatra.error'])
|
19
|
+
Rnotifier::ExceptionData.new(e, env, {:type => :rack}).notify
|
20
|
+
env['rnotifier.notify'] = true
|
21
|
+
end
|
22
|
+
|
23
|
+
response
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Rnotifier
|
2
|
+
class Railtie < Rails::Railtie
|
3
|
+
|
4
|
+
initializer 'rnotifier.initialize' do |app|
|
5
|
+
|
6
|
+
file = File.join(Rails.root, 'config', 'rnotifier.yaml')
|
7
|
+
File.exist?(file) ? Rnotifier.load_config(file) : Rnotifier::Config.init
|
8
|
+
|
9
|
+
if Rnotifier::Config.valid?
|
10
|
+
if defined?(ActionDispatch::DebugExceptions)
|
11
|
+
app.middleware.insert_after ActionDispatch::DebugExceptions, Rnotifier::RackMiddleware
|
12
|
+
elsif defined?(ActionDispatch::ShowExceptions)
|
13
|
+
app.middleware.insert_after ActionDispatch::ShowExceptions, Rnotifier::RackMiddleware
|
14
|
+
else
|
15
|
+
app.middleware.use Rnotifier::RackMiddleware
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
data/lib/rnotifier/rlogger.rb
CHANGED
@@ -1,26 +1,28 @@
|
|
1
1
|
module Rnotifier
|
2
2
|
class Rlogger
|
3
|
-
|
4
|
-
LOG_TITLE = '[RNOTIFIER]'
|
5
|
-
|
3
|
+
TAG = '[RNOTIFIER]'
|
6
4
|
class << self
|
7
5
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
6
|
+
['info', 'error', 'warn'].each do |level|
|
7
|
+
class_eval <<-METHOD, __FILE__, __LINE__ + 1
|
8
|
+
def #{level}(msg)
|
9
|
+
logger.#{level}("#{TAG} \#{msg}")
|
10
|
+
end
|
11
|
+
METHOD
|
12
|
+
end
|
13
|
+
|
14
|
+
def init
|
15
|
+
@logger = if defined?(Rails) && Rails.respond_to?(:logger)
|
16
|
+
Rails.logger
|
17
|
+
else
|
18
|
+
require 'logger' unless defined?(Logger)
|
19
|
+
Logger.new($stdout)
|
20
|
+
end
|
21
|
+
end
|
19
22
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
end
|
23
|
+
def logger
|
24
|
+
@logger
|
25
|
+
end
|
24
26
|
|
25
27
|
end
|
26
28
|
end
|
data/lib/rnotifier/version.rb
CHANGED