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