r3_exception_logger 0.1.10
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/exception_loggable_controller_mixin.rb +82 -0
- data/lib/exception_logger/engine.rb +18 -0
- data/lib/exception_logger/exception_loggable.rb +91 -0
- data/lib/exception_logger.rb +4 -0
- data/lib/generators/exception_logger/migration/migration_generator.rb +37 -0
- data/lib/generators/exception_logger/migration/templates/migration.rb +18 -0
- data/lib/generators/exception_logger/stylescripts/stylescripts_generator.rb +24 -0
- data/lib/logged_exception_rake.rb +52 -0
- data/lib/railties/tasks.rake +6 -0
- metadata +54 -0
@@ -0,0 +1,82 @@
|
|
1
|
+
module ExceptionLoggableControllerMixin
|
2
|
+
|
3
|
+
class << self
|
4
|
+
attr_accessor :custom_view_paths;
|
5
|
+
|
6
|
+
def included(app)
|
7
|
+
app.module_eval do
|
8
|
+
cattr_accessor :application_name
|
9
|
+
layout nil
|
10
|
+
self.view_paths = ExceptionLoggableControllerMixin.custom_view_paths
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def index
|
16
|
+
@exception_names = LoggedException.find_exception_class_names
|
17
|
+
@controller_actions = LoggedException.find_exception_controllers_and_actions
|
18
|
+
query
|
19
|
+
end
|
20
|
+
|
21
|
+
def query
|
22
|
+
conditions = []
|
23
|
+
parameters = []
|
24
|
+
unless params[:id].blank?
|
25
|
+
conditions << 'id = ?'
|
26
|
+
parameters << params[:id]
|
27
|
+
end
|
28
|
+
unless params[:query].blank?
|
29
|
+
conditions << 'message LIKE ?'
|
30
|
+
parameters << "%#{params[:query]}%"
|
31
|
+
end
|
32
|
+
unless params[:date_ranges_filter].blank?
|
33
|
+
conditions << 'created_at >= ?'
|
34
|
+
parameters << params[:date_ranges_filter].to_f.days.ago.utc
|
35
|
+
end
|
36
|
+
unless params[:exception_names_filter].blank?
|
37
|
+
conditions << 'exception_class = ?'
|
38
|
+
parameters << params[:exception_names_filter]
|
39
|
+
end
|
40
|
+
unless params[:controller_actions_filter].blank?
|
41
|
+
conditions << 'controller_name = ? AND action_name = ?'
|
42
|
+
parameters += params[:controller_actions_filter].split('/').collect(&:downcase)
|
43
|
+
end
|
44
|
+
@exceptions = LoggedException.paginate :order => 'created_at desc', :per_page => 30,
|
45
|
+
:conditions => conditions.empty? ? nil : parameters.unshift(conditions * ' and '), :page => params[:page]
|
46
|
+
|
47
|
+
respond_to do |format|
|
48
|
+
format.html { redirect_to :action => 'index' unless action_name == 'index' }
|
49
|
+
format.js { render :action => 'query.rjs' }
|
50
|
+
format.rss { render :action => 'query.rxml' }
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def show
|
55
|
+
@exception = LoggedException.find params[:id]
|
56
|
+
end
|
57
|
+
|
58
|
+
def destroy
|
59
|
+
@exception = LoggedException.find params[:id]
|
60
|
+
@exception.destroy
|
61
|
+
end
|
62
|
+
|
63
|
+
def destroy_all
|
64
|
+
LoggedException.delete_all ['id in (?)', params[:ids]] unless params[:ids].blank?
|
65
|
+
query
|
66
|
+
end
|
67
|
+
|
68
|
+
private
|
69
|
+
def access_denied_with_basic_auth
|
70
|
+
headers["Status"] = "Unauthorized"
|
71
|
+
headers["WWW-Authenticate"] = %(Basic realm="Web Password")
|
72
|
+
render :text => "Could't authenticate you", :status => '401 Unauthorized'
|
73
|
+
end
|
74
|
+
|
75
|
+
@@http_auth_headers = %w(X-HTTP_AUTHORIZATION HTTP_AUTHORIZATION Authorization)
|
76
|
+
# gets BASIC auth info
|
77
|
+
def get_auth_data
|
78
|
+
auth_key = @@http_auth_headers.detect { |h| request.env.has_key?(h) }
|
79
|
+
auth_data = request.env[auth_key].to_s.split unless auth_key.blank?
|
80
|
+
return auth_data && auth_data[0] == 'Basic' ? Base64.decode64(auth_data[1]).split(':')[0..1] : [nil, nil]
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require "exception_logger"
|
2
|
+
require "rails"
|
3
|
+
require "kaminari"
|
4
|
+
require "i18n"
|
5
|
+
require "squeel"
|
6
|
+
|
7
|
+
module ExceptionLogger
|
8
|
+
class Engine < Rails::Engine
|
9
|
+
## Better: TODO create rake task to copy files to application/public
|
10
|
+
initializer "static assets" do |app|
|
11
|
+
app.middleware.use ::ActionDispatch::Static, "#{root}/public"
|
12
|
+
end
|
13
|
+
rake_tasks do
|
14
|
+
load File.expand_path(File.dirname(__FILE__) + '/../railties/tasks.rake')
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
require 'ipaddr'
|
2
|
+
require 'active_support/core_ext/class/attribute'
|
3
|
+
|
4
|
+
module ExceptionLogger
|
5
|
+
# Copyright (c) 2005 Jamis Buck
|
6
|
+
#
|
7
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
8
|
+
# a copy of this software and associated documentation files (the
|
9
|
+
# "Software"), to deal in the Software without restriction, including
|
10
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
11
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
12
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
13
|
+
# the following conditions:
|
14
|
+
#
|
15
|
+
# The above copyright notice and this permission notice shall be
|
16
|
+
# included in all copies or substantial portions of the Software.
|
17
|
+
#
|
18
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
19
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
20
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
21
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
22
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
23
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
24
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
25
|
+
module ExceptionLoggable
|
26
|
+
def self.included(target)
|
27
|
+
target.class_attribute :local_addresses
|
28
|
+
target.class_attribute :exception_data
|
29
|
+
|
30
|
+
target.extend(ClassMethods)
|
31
|
+
|
32
|
+
#ActiveSupport::CoreExtensions::Time::Conversions::DATE_FORMATS.merge!({
|
33
|
+
# :exc_full => "%A, %b %d, %Y at %l:%M %p",
|
34
|
+
# :exc_date => "%b %d, %Y",
|
35
|
+
# :exc_time => "%l:%M %p"
|
36
|
+
# })
|
37
|
+
end
|
38
|
+
|
39
|
+
module ClassMethods
|
40
|
+
def consider_local(*args)
|
41
|
+
local_addresses.concat(args.flatten.map { |a| IPAddr.new(a) })
|
42
|
+
end
|
43
|
+
|
44
|
+
def local_addresses
|
45
|
+
addresses = self.local_addresses
|
46
|
+
unless addresses
|
47
|
+
addresses = [IPAddr.new("127.0.0.1")]
|
48
|
+
self.local_addresses = addresses
|
49
|
+
end
|
50
|
+
addresses
|
51
|
+
end
|
52
|
+
|
53
|
+
def exception_data(deliverer = self, &block)
|
54
|
+
deliverer = block if block
|
55
|
+
if deliverer == self
|
56
|
+
self.exception_data
|
57
|
+
else
|
58
|
+
self.exception_data = deliverer
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def local_request?
|
64
|
+
remote = IPAddr.new(request.remote_ip)
|
65
|
+
!self.class.local_addresses.detect { |addr| addr.include?(remote) }.nil?
|
66
|
+
end
|
67
|
+
|
68
|
+
# we log the exception and raise it again, for the normal handling.
|
69
|
+
def log_exception_handler(exception)
|
70
|
+
log_exception(exception)
|
71
|
+
raise exception
|
72
|
+
end
|
73
|
+
|
74
|
+
def rescue_action(exception)
|
75
|
+
status = response_code_for_rescue(exception)
|
76
|
+
log_exception(exception) if status != :not_found
|
77
|
+
super
|
78
|
+
end
|
79
|
+
|
80
|
+
def log_exception(exception)
|
81
|
+
deliverer = self.class.exception_data
|
82
|
+
data = case deliverer
|
83
|
+
when nil then {}
|
84
|
+
when Symbol then send(deliverer)
|
85
|
+
when Proc then deliverer.call(self)
|
86
|
+
end
|
87
|
+
|
88
|
+
LoggedException.create_from_exception(self, exception, data)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'rails/generators'
|
2
|
+
require 'rails/generators/migration'
|
3
|
+
|
4
|
+
module ExceptionLogger
|
5
|
+
class MigrationGenerator < Rails::Generators::Base
|
6
|
+
desc "The exception migration generator creates a database migration for the logged exceptions model."
|
7
|
+
include Rails::Generators::Migration
|
8
|
+
source_root File.join(File.dirname(__FILE__), 'templates')
|
9
|
+
|
10
|
+
class_option :exception_table_name,
|
11
|
+
:type => :string,
|
12
|
+
:desc => "Name for the Exception Table",
|
13
|
+
:required => false,
|
14
|
+
:default => "logged_exceptions"
|
15
|
+
|
16
|
+
def initialize(args = [], options = {}, config = {})
|
17
|
+
super
|
18
|
+
end
|
19
|
+
|
20
|
+
#attr_reader :exception_table_name
|
21
|
+
|
22
|
+
# Implement the required interface for Rails::Generators::Migration.
|
23
|
+
# taken from http://github.com/rails/rails/blob/master/activerecord/lib/generators/active_record.rb
|
24
|
+
def self.next_migration_number(dirname)
|
25
|
+
if ActiveRecord::Base.timestamped_migrations
|
26
|
+
Time.now.utc.strftime("%Y%m%d%H%M%S")
|
27
|
+
else
|
28
|
+
"%.3d" % (current_migration_number(dirname) + 1)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def create_migration_file
|
33
|
+
migration_template 'migration.rb', 'db/migrate/add_logged_exception_table.rb'
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
class AddLoggedExceptionTable < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
create_table "<%= options[:exception_table_name] %>", :force => true do |t|
|
4
|
+
t.string :exception_class
|
5
|
+
t.string :controller_name
|
6
|
+
t.string :action_name
|
7
|
+
t.text :message
|
8
|
+
t.text :backtrace
|
9
|
+
t.text :environment
|
10
|
+
t.text :request
|
11
|
+
t.datetime :created_at
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.down
|
16
|
+
drop_table "<%= options[:exception_table_name] %>"
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'rails/generators'
|
2
|
+
|
3
|
+
module ExceptionLogger
|
4
|
+
class StylescriptsGenerator < Rails::Generators::Base
|
5
|
+
desc "Copies exception_logger.css to app/assets/stylesheets/ and copies exception_logger.js to app/assets/javascripts/"
|
6
|
+
|
7
|
+
def self.source_root
|
8
|
+
# Set source directory for the templates to the rails2 generator template directory
|
9
|
+
@source_root ||= File.expand_path(File.join('..', '..', '..', '..', 'public'), File.dirname(__FILE__))
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.banner
|
13
|
+
"rails generate exception_logger:stylescripts [options]"
|
14
|
+
end
|
15
|
+
|
16
|
+
def copy_files
|
17
|
+
empty_directory 'public/stylesheets'
|
18
|
+
template 'stylesheets/exception_logger.css', 'app/assets/stylesheets/exception_logger.css'
|
19
|
+
|
20
|
+
empty_directory 'public/javascripts'
|
21
|
+
template 'javascripts/exception_logger.js', 'app/assets/javascripts/exception_logger.js'
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# Copyright (c) 2008-2009 Zhurbiy Oleg aka Ol.keene
|
2
|
+
#
|
3
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
# a copy of this software and associated documentation files (the
|
5
|
+
# "Software"), to deal in the Software without restriction, including
|
6
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
# the following conditions:
|
10
|
+
#
|
11
|
+
# The above copyright notice and this permission notice shall be
|
12
|
+
# included in all copies or substantial portions of the Software.
|
13
|
+
#
|
14
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
21
|
+
|
22
|
+
class LoggedExceptionRake
|
23
|
+
module RakeExt
|
24
|
+
def create_from_rake_exception(exception, rake_task, environment)
|
25
|
+
message = exception.message.inspect
|
26
|
+
max = environment.keys.max { |a,b| a.length <=> b.length }
|
27
|
+
|
28
|
+
env = environment.keys.sort.inject [] do |env, key|
|
29
|
+
env << '* ' + ("%-*s: %s" % [max.length, key, environment[key].to_s.strip])
|
30
|
+
end
|
31
|
+
|
32
|
+
e = create! :exception_class => exception.class.name,
|
33
|
+
:controller_name => 'RakeTask',
|
34
|
+
:action_name => rake_task.name,
|
35
|
+
:message => message,
|
36
|
+
:backtrace => exception.backtrace,
|
37
|
+
:environment => (env << "* Process: #{$$}") * "\n",
|
38
|
+
:request => ''
|
39
|
+
|
40
|
+
deliver_exception(e)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
class << self
|
45
|
+
def save_exception(e, rake_task, env)
|
46
|
+
# TODO envoronment not saving fully..wtf?
|
47
|
+
LoggedException.create_from_rake_exception(e, rake_task, env)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
LoggedException.extend LoggedExceptionRake::RakeExt
|
metadata
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: r3_exception_logger
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.10
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Chris Wise
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-05-26 00:00:00.000000000 Z
|
13
|
+
dependencies: []
|
14
|
+
description: Fork of exception_logger gem
|
15
|
+
email:
|
16
|
+
- cwise@murmurinformatics.com
|
17
|
+
executables: []
|
18
|
+
extensions: []
|
19
|
+
extra_rdoc_files: []
|
20
|
+
files:
|
21
|
+
- lib/exception_loggable_controller_mixin.rb
|
22
|
+
- lib/exception_logger/engine.rb
|
23
|
+
- lib/exception_logger/exception_loggable.rb
|
24
|
+
- lib/exception_logger.rb
|
25
|
+
- lib/generators/exception_logger/migration/migration_generator.rb
|
26
|
+
- lib/generators/exception_logger/migration/templates/migration.rb
|
27
|
+
- lib/generators/exception_logger/stylescripts/stylescripts_generator.rb
|
28
|
+
- lib/logged_exception_rake.rb
|
29
|
+
- lib/railties/tasks.rake
|
30
|
+
homepage: http://github.com/cwise/exception_logger
|
31
|
+
licenses: []
|
32
|
+
post_install_message:
|
33
|
+
rdoc_options: []
|
34
|
+
require_paths:
|
35
|
+
- lib
|
36
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
37
|
+
none: false
|
38
|
+
requirements:
|
39
|
+
- - ! '>='
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '0'
|
42
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
43
|
+
none: false
|
44
|
+
requirements:
|
45
|
+
- - ! '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 1.3.6
|
48
|
+
requirements: []
|
49
|
+
rubyforge_project:
|
50
|
+
rubygems_version: 1.8.16
|
51
|
+
signing_key:
|
52
|
+
specification_version: 3
|
53
|
+
summary: Fork of exception_logger gem
|
54
|
+
test_files: []
|