bugsnag 1.0.2 → 1.0.3
Sign up to get free protection for your applications and to get access to all the features.
- data/VERSION +1 -1
- data/bugsnag.gemspec +1 -1
- data/lib/bugsnag.rb +2 -9
- data/lib/bugsnag/configuration.rb +56 -1
- data/lib/bugsnag/helpers.rb +1 -1
- data/lib/bugsnag/notification.rb +35 -21
- data/lib/bugsnag/rack.rb +2 -2
- data/lib/bugsnag/rails/controller_methods.rb +3 -7
- metadata +3 -3
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.0.
|
1
|
+
1.0.3
|
data/bugsnag.gemspec
CHANGED
data/lib/bugsnag.rb
CHANGED
@@ -18,15 +18,8 @@ module Bugsnag
|
|
18
18
|
end
|
19
19
|
|
20
20
|
def notify(exception, session_data={})
|
21
|
-
|
22
|
-
|
23
|
-
:projectRoot => configuration.project_root.to_s,
|
24
|
-
:appVersion => configuration.app_version
|
25
|
-
}.merge(session_data)
|
26
|
-
|
27
|
-
# Send the notification
|
28
|
-
notification = Notification.new(configuration.api_key, exception, opts)
|
29
|
-
notification.deliver
|
21
|
+
notification = Notification.new(exception, configuration.merge(session_data))
|
22
|
+
notification.deliver unless notification.ignore?
|
30
23
|
end
|
31
24
|
|
32
25
|
def log(message)
|
@@ -1,5 +1,60 @@
|
|
1
1
|
module Bugsnag
|
2
2
|
class Configuration
|
3
|
-
|
3
|
+
OPTIONS = [
|
4
|
+
:api_key, :release_stage, :project_root, :app_version,
|
5
|
+
:framework, :endpoint, :logger, :disable_auto_notification,
|
6
|
+
:params_filters, :stacktrace_filters, :ignore_classes
|
7
|
+
]
|
8
|
+
OPTIONS.each {|o| attr_accessor o }
|
9
|
+
|
10
|
+
|
11
|
+
DEFAULT_ENDPOINT = "http://api.bugsnag.com/notify"
|
12
|
+
DEFAULT_PARAMS_FILTERS = %w(password password_confirmation).freeze
|
13
|
+
|
14
|
+
DEFAULT_STACKTRACE_FILTERS = [
|
15
|
+
lambda { |line|
|
16
|
+
if defined?(Bugsnag.configuration.project_root) && Bugsnag.configuration.project_root.to_s != ''
|
17
|
+
line.sub(/#{Bugsnag.configuration.project_root}\//, "")
|
18
|
+
else
|
19
|
+
line
|
20
|
+
end
|
21
|
+
},
|
22
|
+
lambda { |line| line.gsub(/^\.\//, "") },
|
23
|
+
lambda { |line|
|
24
|
+
if defined?(Gem)
|
25
|
+
Gem.path.inject(line) do |line, path|
|
26
|
+
line.gsub(/#{path}\//, "")
|
27
|
+
end
|
28
|
+
end
|
29
|
+
},
|
30
|
+
lambda { |line| line if line !~ %r{lib/bugsnag} }
|
31
|
+
].freeze
|
32
|
+
|
33
|
+
DEFAULT_IGNORE_CLASSES = [
|
34
|
+
"ActiveRecord::RecordNotFound",
|
35
|
+
"ActionController::RoutingError",
|
36
|
+
"ActionController::InvalidAuthenticityToken",
|
37
|
+
"CGI::Session::CookieStore::TamperedWithCookie",
|
38
|
+
"ActionController::UnknownAction",
|
39
|
+
"AbstractController::ActionNotFound"
|
40
|
+
]
|
41
|
+
|
42
|
+
|
43
|
+
def initialize
|
44
|
+
@endpoint = DEFAULT_ENDPOINT
|
45
|
+
@params_filters = DEFAULT_PARAMS_FILTERS.dup
|
46
|
+
@stacktrace_filters = DEFAULT_STACKTRACE_FILTERS.dup
|
47
|
+
@ignore_classes = DEFAULT_IGNORE_CLASSES.dup
|
48
|
+
end
|
49
|
+
|
50
|
+
def to_hash
|
51
|
+
OPTIONS.inject({}) do |hash, option|
|
52
|
+
hash.merge(option.to_sym => send(option))
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def merge(hash)
|
57
|
+
to_hash.merge(hash)
|
58
|
+
end
|
4
59
|
end
|
5
60
|
end
|
data/lib/bugsnag/helpers.rb
CHANGED
data/lib/bugsnag/notification.rb
CHANGED
@@ -12,31 +12,37 @@ module Bugsnag
|
|
12
12
|
include HTTParty
|
13
13
|
headers "Content-Type" => "application/json"
|
14
14
|
|
15
|
-
|
16
|
-
|
17
|
-
:userId, :context, :metaData
|
15
|
+
# Basic notification attributes
|
16
|
+
attr_accessor :exception
|
18
17
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
18
|
+
# Attributes from session
|
19
|
+
attr_accessor :user_id, :context, :meta_data
|
20
|
+
|
21
|
+
# Attributes from configuration
|
22
|
+
attr_accessor :api_key, :params_filters, :stacktrace_filters,
|
23
|
+
:ignore_classes, :endpoint, :app_version, :release_stage,
|
24
|
+
:project_root
|
23
25
|
|
24
|
-
|
26
|
+
def initialize(exception, opts={})
|
27
|
+
self.exception = exception
|
28
|
+
opts.reject! {|k,v| v.nil?}.each do |k,v|
|
29
|
+
self.send("#{k}=", v) if self.respond_to?("#{k}=")
|
30
|
+
end
|
25
31
|
end
|
26
32
|
|
27
33
|
def deliver
|
28
34
|
Bugsnag.log("Notifying #{self.endpoint} of exception")
|
29
35
|
|
30
36
|
payload = {
|
31
|
-
:apiKey => self.
|
37
|
+
:apiKey => self.api_key,
|
32
38
|
:notifier => notifier_identification,
|
33
39
|
:errors => [{
|
34
|
-
:userId => self.
|
35
|
-
:appVersion => self.
|
36
|
-
:releaseStage => self.
|
40
|
+
:userId => self.user_id,
|
41
|
+
:appVersion => self.app_version,
|
42
|
+
:releaseStage => self.release_stage,
|
37
43
|
:context => self.context,
|
38
44
|
:exceptions => [exception_hash],
|
39
|
-
:metaData => self.
|
45
|
+
:metaData => self.meta_data
|
40
46
|
}.reject {|k,v| v.nil? }]
|
41
47
|
}
|
42
48
|
|
@@ -49,6 +55,10 @@ module Bugsnag
|
|
49
55
|
return response
|
50
56
|
end
|
51
57
|
|
58
|
+
def ignore?
|
59
|
+
self.ignore_classes.include?(self.exception.class.to_s)
|
60
|
+
end
|
61
|
+
|
52
62
|
|
53
63
|
private
|
54
64
|
def notifier_identification
|
@@ -69,21 +79,25 @@ module Bugsnag
|
|
69
79
|
method = nil
|
70
80
|
file, line_str, method_str = trace.split(":")
|
71
81
|
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
}
|
82
|
+
# Generate the stacktrace line hash
|
83
|
+
trace_hash = {}
|
84
|
+
trace_hash[:inProject] = true if self.project_root && file.match(/^#{self.project_root}/)
|
85
|
+
trace_hash[:file] = self.stacktrace_filters.inject(file) {|file, proc| proc.call(file) }
|
86
|
+
trace_hash[:lineNumber] = line_str.to_i
|
76
87
|
|
88
|
+
# Add a method if we have it
|
77
89
|
if method_str
|
78
90
|
method_match = /in `([^']+)'/.match(method_str)
|
79
91
|
method = method_match.captures.first if method_match
|
80
92
|
end
|
81
|
-
|
82
93
|
trace_hash[:method] = method if method
|
83
|
-
trace_hash[:inProject] = true if self.projectRoot && file.match(/^#{self.projectRoot}/)
|
84
94
|
|
85
|
-
trace_hash
|
86
|
-
|
95
|
+
if trace_hash[:file] && !trace_hash[:file].empty?
|
96
|
+
trace_hash
|
97
|
+
else
|
98
|
+
nil
|
99
|
+
end
|
100
|
+
end.compact
|
87
101
|
end
|
88
102
|
|
89
103
|
def exception_hash
|
data/lib/bugsnag/rack.rb
CHANGED
@@ -27,9 +27,9 @@ module Bugsnag
|
|
27
27
|
params = env['action_dispatch.request.parameters'] || request.params || {}
|
28
28
|
|
29
29
|
{
|
30
|
-
:
|
30
|
+
:user_id => session[:session_id] || session["session_id"],
|
31
31
|
:context => Bugsnag::Helpers.param_context(params),
|
32
|
-
:
|
32
|
+
:meta_data => {
|
33
33
|
:request => {
|
34
34
|
:url => request.url,
|
35
35
|
:controller => params[:controller],
|
@@ -5,16 +5,16 @@ module Bugsnag
|
|
5
5
|
def notify_bugsnag(exception, custom_data=nil)
|
6
6
|
unless bugsnag_local_request?
|
7
7
|
request_data = bugsnag_request_data
|
8
|
-
request_data[:
|
8
|
+
request_data[:meta_data][:custom] = custom_data if custom_data
|
9
9
|
Bugsnag.notify(exception, request_data)
|
10
10
|
end
|
11
11
|
end
|
12
12
|
|
13
13
|
def bugsnag_request_data
|
14
14
|
{
|
15
|
-
:
|
15
|
+
:user_id => bugsnag_session_id,
|
16
16
|
:context => Bugsnag::Helpers.param_context(params),
|
17
|
-
:
|
17
|
+
:meta_data => {
|
18
18
|
:request => {
|
19
19
|
:url => bugsnag_request_url,
|
20
20
|
:controller => params[:controller],
|
@@ -40,10 +40,6 @@ module Bugsnag
|
|
40
40
|
session[:session_id] || session["session_id"]
|
41
41
|
end
|
42
42
|
|
43
|
-
def bugsnag_context
|
44
|
-
"#{params[:controller]}##{params[:action]}"
|
45
|
-
end
|
46
|
-
|
47
43
|
def bugsnag_request_url
|
48
44
|
url = "#{request.protocol}#{request.host}"
|
49
45
|
|
metadata
CHANGED