lichtamberg-Lighthouse_Exception_Logger 0.0.1

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.
Files changed (3) hide show
  1. data/README.txt +50 -0
  2. data/lib/LighthouseExceptionLogger.rb +252 -0
  3. metadata +64 -0
data/README.txt ADDED
@@ -0,0 +1,50 @@
1
+ THIS GEM IS IN PROGRESS - ITS NOT WORKING AT THE MOMENT!
2
+
3
+ = LighthouseExe
4
+
5
+ * FIX (url)
6
+
7
+ == DESCRIPTION:
8
+
9
+ FIX (describe your package)
10
+
11
+ == FEATURES/PROBLEMS:
12
+
13
+ * FIX (list of features or problems)
14
+
15
+ == SYNOPSIS:
16
+
17
+ FIX (code sample of usage)
18
+
19
+ == REQUIREMENTS:
20
+
21
+ * FIX (list of requirements)
22
+
23
+ == INSTALL:
24
+
25
+ * FIX (sudo gem install, anything else)
26
+
27
+ == LICENSE:
28
+
29
+ (The MIT License)
30
+
31
+ Copyright (c) 2008 FIX
32
+
33
+ Permission is hereby granted, free of charge, to any person obtaining
34
+ a copy of this software and associated documentation files (the
35
+ 'Software'), to deal in the Software without restriction, including
36
+ without limitation the rights to use, copy, modify, merge, publish,
37
+ distribute, sublicense, and/or sell copies of the Software, and to
38
+ permit persons to whom the Software is furnished to do so, subject to
39
+ the following conditions:
40
+
41
+ The above copyright notice and this permission notice shall be
42
+ included in all copies or substantial portions of the Software.
43
+
44
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
45
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
46
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
47
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
48
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
49
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
50
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,252 @@
1
+ require 'net/http'
2
+ require 'net/https'
3
+ require 'rubygems'
4
+ require 'active_support'
5
+ require 'lighthouse'
6
+
7
+ # Plugin for applications to automatically post errors to the Hoptoad of their choice.
8
+ module LighthouseExceptionLogger
9
+
10
+ VERSION = '0.0.1'
11
+ IGNORE_DEFAULT = ['ActiveRecord::RecordNotFound',
12
+ 'ActionController::RoutingError',
13
+ 'ActionController::InvalidAuthenticityToken',
14
+ 'CGI::Session::CookieStore::TamperedWithCookie']
15
+
16
+ # Some of these don't exist for Rails 1.2.*, so we have to consider that.
17
+ IGNORE_DEFAULT.map!{|e| eval(e) rescue nil }.compact!
18
+ IGNORE_DEFAULT.freeze
19
+
20
+ class << self
21
+ attr_accessor :host, :port, :secure, :api_key
22
+ attr_reader :backtrace_filters
23
+
24
+ # Takes a block and adds it to the list of backtrace filters. When the filters
25
+ # run, the block will be handed each line of the backtrace and can modify
26
+ # it as necessary. For example, by default a path matching the RAILS_ROOT
27
+ # constant will be transformed into "[RAILS_ROOT]"
28
+ def filter_backtrace &block
29
+ (@backtrace_filters ||= []) << block
30
+ end
31
+
32
+ # Returns the list of errors that are being ignored. The array can be appended to.
33
+ def ignore
34
+ @ignore ||= (LighthouseExceptionLogger::IGNORE_DEFAULT.dup)
35
+ @ignore.flatten!
36
+ @ignore
37
+ end
38
+
39
+ # Sets the list of ignored errors to only what is passed in here. This method
40
+ # can be passed a single error or a list of errors.
41
+ def ignore_only=(names)
42
+ @ignore = [names].flatten
43
+ end
44
+
45
+ # Returns a list of parameters that should be filtered out of what is sent to Lighthouse.
46
+ # By default, all "password" attributes will have their contents replaced.
47
+ def params_filters
48
+ @params_filters ||= %w(password)
49
+ end
50
+
51
+ def environment_filters
52
+ @environment_filters ||= %w()
53
+ end
54
+
55
+ # You can send an exception manually using this method, even when you are not in a
56
+ # controller. You can pass an exception or a hash that contains the attributes that
57
+ # would be sent to Hoptoad:
58
+ # * api_key: The API key for this project. The API key is a unique identifier that Hoptoad
59
+ # uses for identification.
60
+ # * error_message: The error returned by the exception (or the message you want to log).
61
+ # * backtrace: A backtrace, usually obtained with +caller+.
62
+ # * request: The controller's request object.
63
+ # * session: The contents of the user's session.
64
+ # * environment: ENV merged with the contents of the request's environment.
65
+ def notify notice = {}
66
+ Sender.new.notify_lighthouse( notice )
67
+ end
68
+ end
69
+
70
+ filter_backtrace do |line|
71
+ line.gsub(/#{RAILS_ROOT}/, "[RAILS_ROOT]")
72
+ end
73
+
74
+ filter_backtrace do |line|
75
+ line.gsub(/^\.\//, "")
76
+ end
77
+
78
+ filter_backtrace do |line|
79
+ if defined?(Gem)
80
+ Gem.path.inject(line) do |line, path|
81
+ line.gsub(/#{path}/, "[GEM_ROOT]")
82
+ end
83
+ end
84
+ end
85
+
86
+ # Include this module in Controllers in which you want to be notified of errors.
87
+ module Catcher
88
+
89
+ def self.included(base) #:nodoc:
90
+ if base.instance_methods.include? 'rescue_action_in_public' and !base.instance_methods.include? 'rescue_action_in_public_without_LighthouseExceptionLogger'
91
+ base.send(:alias_method, :rescue_action_in_public_without_LighthouseExceptionLogger, :rescue_action_in_public)
92
+ base.send(:alias_method, :rescue_action_in_public, :rescue_action_in_public_with_LighthouseExceptionLogger)
93
+ end
94
+ end
95
+
96
+ # Overrides the rescue_action method in ActionController::Base, but does not inhibit
97
+ # any custom processing that is defined with Rails 2's exception helpers.
98
+ def rescue_action_in_public_with_LighthouseExceptionLogger exception
99
+ notify_lighthouse(exception) unless ignore?(exception)
100
+ rescue_action_in_public_without_LighthouseExceptionLogger(exception)
101
+ end
102
+
103
+ # This method should be used for sending manual notifications while you are still
104
+ # inside the controller. Otherwise it works like LighthouseExceptionLogger.notify.
105
+ def notify_lighthouse hash_or_exception
106
+ if public_environment?
107
+ notice = normalize_notice(hash_or_exception)
108
+ notice = clean_notice(notice)
109
+ send_to_LighthouseExceptionLogger(:notice => notice)
110
+ end
111
+ end
112
+
113
+ alias_method :inform_lighthouse, :notify_lighthouse
114
+
115
+ # Returns the default logger or a logger that prints to STDOUT. Necessary for manual
116
+ # notifications outside of controllers.
117
+ def logger
118
+ ActiveRecord::Base.logger
119
+ rescue
120
+ @logger ||= Logger.new(STDERR)
121
+ end
122
+
123
+ private
124
+
125
+ def public_environment? #nodoc:
126
+ defined?(RAILS_ENV) and !['development', 'test'].include?(RAILS_ENV)
127
+ end
128
+
129
+ def ignore?(exception) #:nodoc:
130
+ ignore_these = LighthouseExceptionLogger.ignore.flatten
131
+ ignore_these.include?(exception.class) || ignore_these.include?(exception.class.name)
132
+ end
133
+
134
+ def exception_to_data exception #:nodoc:
135
+ data = {
136
+ :error_class => exception.class.name,
137
+ :error_message => "#{exception.class.name}: #{exception.message}",
138
+ :backtrace => exception.backtrace,
139
+ :environment => ENV.to_hash
140
+ }
141
+
142
+ if self.respond_to? :request
143
+ data[:request] = {
144
+ :params => request.parameters.to_hash,
145
+ :rails_root => File.expand_path(RAILS_ROOT),
146
+ :url => "#{request.protocol}#{request.host}#{request.request_uri}"
147
+ }
148
+ data[:environment].merge!(request.env.to_hash)
149
+ end
150
+
151
+ if self.respond_to? :session
152
+ data[:session] = {
153
+ :key => session.instance_variable_get("@session_id"),
154
+ :data => session.instance_variable_get("@data")
155
+ }
156
+ end
157
+
158
+ data
159
+ end
160
+
161
+ def normalize_notice(notice) #:nodoc:
162
+ case notice
163
+ when Hash
164
+ LighthouseExceptionLogger.default_notice_options.merge(notice)
165
+ when Exception
166
+ LighthouseExceptionLogger.default_notice_options.merge(exception_to_data(notice))
167
+ end
168
+ end
169
+
170
+ def clean_notice(notice) #:nodoc:
171
+ notice[:backtrace] = clean_LighthouseExceptionLogger_backtrace(notice[:backtrace])
172
+ if notice[:request].is_a?(Hash) && notice[:request][:params].is_a?(Hash)
173
+ notice[:request][:params] = filter_parameters(notice[:request][:params]) if respond_to?(:filter_parameters)
174
+ notice[:request][:params] = clean_LighthouseExceptionLogger_params(notice[:request][:params])
175
+ end
176
+ if notice[:environment].is_a?(Hash)
177
+ notice[:environment] = filter_parameters(notice[:environment]) if respond_to?(:filter_parameters)
178
+ notice[:environment] = clean_LighthouseExceptionLogger_environment(notice[:environment])
179
+ end
180
+ clean_non_serializable_data(notice)
181
+ end
182
+
183
+ def send_to_LighthouseExceptionLogger data #:nodoc:
184
+ Lighthouse.account = LIGHTHOUSE_ACCOUNT
185
+ if defined?(LIGHTHOUSE_TOKEN)
186
+ Lighthouse.token = LIGHTHOUSE_TOKEN
187
+ else
188
+ Lighthouse.authenticate(LIGHTHOUSE_USERNAME, LIGHTHOUSE_PASSWORD)
189
+ end
190
+
191
+ act_project = Project.find(LIGHTHOUSE_PROJETCT_ID)
192
+ if act_project.tickets.count(:conditions => {["subject like ?", data.hashcode]})
193
+ act_project.tickets.new(data).save
194
+ end
195
+ end
196
+
197
+ def clean_LighthouseExceptionLogger_backtrace backtrace #:nodoc:
198
+ if backtrace.to_a.size == 1
199
+ backtrace = backtrace.to_a.first.split(/\n\s*/)
200
+ end
201
+
202
+ backtrace.to_a.map do |line|
203
+ LighthouseExceptionLogger.backtrace_filters.inject(line) do |line, proc|
204
+ proc.call(line)
205
+ end
206
+ end
207
+ end
208
+
209
+ def clean_LighthouseExceptionLogger_params params #:nodoc:
210
+ params.each do |k, v|
211
+ params[k] = "[FILTERED]" if LighthouseExceptionLogger.params_filters.any? do |filter|
212
+ k.to_s.match(/#{filter}/)
213
+ end
214
+ end
215
+ end
216
+
217
+ def clean_LighthouseExceptionLogger_environment env #:nodoc:
218
+ env.each do |k, v|
219
+ env[k] = "[FILTERED]" if LighthouseExceptionLogger.environment_filters.any? do |filter|
220
+ k.to_s.match(/#{filter}/)
221
+ end
222
+ end
223
+ end
224
+
225
+ def clean_non_serializable_data(notice) #:nodoc:
226
+ notice.select{|k,v| serialzable?(v) }.inject({}) do |h, pair|
227
+ h[pair.first] = pair.last.is_a?(Hash) ? clean_non_serializable_data(pair.last) : pair.last
228
+ h
229
+ end
230
+ end
231
+
232
+ def serialzable?(value) #:nodoc:
233
+ !(value.is_a?(Module) || value.kind_of?(IO))
234
+ end
235
+
236
+ def stringify_keys(hash) #:nodoc:
237
+ hash.inject({}) do |h, pair|
238
+ h[pair.first.to_s] = pair.last.is_a?(Hash) ? stringify_keys(pair.last) : pair.last
239
+ h
240
+ end
241
+ end
242
+
243
+ end
244
+
245
+ # A dummy class for sending notifications manually outside of a controller.
246
+ class Sender
247
+ def rescue_action_in_public(exception)
248
+ end
249
+
250
+ include LighthouseExceptionLogger::Catcher
251
+ end
252
+ end
metadata ADDED
@@ -0,0 +1,64 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: lichtamberg-Lighthouse_Exception_Logger
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Peter Lampesberger
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2008-11-25 00:00:00 -08:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: Caged-lighthouse-api
17
+ version_requirement:
18
+ version_requirements: !ruby/object:Gem::Requirement
19
+ requirements:
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 1.0.0
23
+ version:
24
+ description: Creates exception-tickets in Lighthouse, similar to HopToads-functionality
25
+ email:
26
+ - lampesberger.peter@gmail.com
27
+ executables: []
28
+
29
+ extensions: []
30
+
31
+ extra_rdoc_files: []
32
+
33
+ files:
34
+ - README.txt
35
+ - lib/LighthouseExceptionLogger.rb
36
+ has_rdoc: true
37
+ homepage: http://github.com/lichtamberg/lighthouse_exception_logger/tree/master
38
+ post_install_message:
39
+ rdoc_options:
40
+ - --main
41
+ - README.markdown
42
+ require_paths:
43
+ - lib
44
+ required_ruby_version: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ version: "0"
49
+ version:
50
+ required_rubygems_version: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: "0"
55
+ version:
56
+ requirements: []
57
+
58
+ rubyforge_project: Lighthouse_Exception_Logger
59
+ rubygems_version: 1.2.0
60
+ signing_key:
61
+ specification_version: 2
62
+ summary: Creates exception-tickets in Lighthouse, similar to HopToads-functionality
63
+ test_files: []
64
+