bugsnag 4.2.1 → 6.27.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.
- checksums.yaml +5 -5
- data/.yardopts +12 -0
- data/CHANGELOG.md +814 -0
- data/README.md +21 -25
- data/VERSION +1 -1
- data/bugsnag.gemspec +19 -8
- data/lib/bugsnag/breadcrumb_type.rb +14 -0
- data/lib/bugsnag/breadcrumbs/breadcrumb.rb +109 -0
- data/lib/bugsnag/breadcrumbs/breadcrumbs.rb +13 -0
- data/lib/bugsnag/breadcrumbs/on_breadcrumb_callback_list.rb +48 -0
- data/lib/bugsnag/breadcrumbs/validator.rb +29 -0
- data/lib/bugsnag/cleaner.rb +170 -59
- data/lib/bugsnag/code_extractor.rb +137 -0
- data/lib/bugsnag/configuration.rb +670 -45
- data/lib/bugsnag/delivery/synchronous.rb +31 -14
- data/lib/bugsnag/delivery/thread_queue.rb +23 -6
- data/lib/bugsnag/delivery.rb +13 -0
- data/lib/bugsnag/endpoint_configuration.rb +11 -0
- data/lib/bugsnag/endpoint_validator.rb +80 -0
- data/lib/bugsnag/error.rb +25 -0
- data/lib/bugsnag/event.rb +5 -0
- data/lib/bugsnag/feature_flag.rb +74 -0
- data/lib/bugsnag/helpers.rb +121 -25
- data/lib/bugsnag/integrations/delayed_job.rb +51 -0
- data/lib/bugsnag/integrations/mailman.rb +43 -0
- data/lib/bugsnag/integrations/mongo.rb +133 -0
- data/lib/bugsnag/integrations/que.rb +53 -0
- data/lib/bugsnag/integrations/rack.rb +83 -0
- data/lib/bugsnag/integrations/rails/active_job.rb +100 -0
- data/lib/bugsnag/{rails → integrations/rails}/active_record_rescue.rb +10 -1
- data/lib/bugsnag/{rails → integrations/rails}/controller_methods.rb +1 -9
- data/lib/bugsnag/integrations/rails/rails_breadcrumbs.rb +115 -0
- data/lib/bugsnag/integrations/railtie.rb +153 -0
- data/lib/bugsnag/integrations/rake.rb +74 -0
- data/lib/bugsnag/integrations/resque.rb +94 -0
- data/lib/bugsnag/integrations/shoryuken.rb +50 -0
- data/lib/bugsnag/integrations/sidekiq.rb +68 -0
- data/lib/bugsnag/meta_data.rb +1 -0
- data/lib/bugsnag/middleware/active_job.rb +18 -0
- data/lib/bugsnag/middleware/breadcrumbs.rb +21 -0
- data/lib/bugsnag/middleware/callbacks.rb +6 -8
- data/lib/bugsnag/middleware/classify_error.rb +50 -0
- data/lib/bugsnag/middleware/clearance_user.rb +33 -0
- data/lib/bugsnag/middleware/delayed_job.rb +93 -0
- data/lib/bugsnag/middleware/discard_error_class.rb +30 -0
- data/lib/bugsnag/middleware/exception_meta_data.rb +42 -0
- data/lib/bugsnag/middleware/ignore_error_class.rb +26 -0
- data/lib/bugsnag/middleware/mailman.rb +6 -4
- data/lib/bugsnag/middleware/rack_request.rb +126 -30
- data/lib/bugsnag/middleware/rails3_request.rb +15 -17
- data/lib/bugsnag/middleware/rake.rb +7 -5
- data/lib/bugsnag/middleware/session_data.rb +25 -0
- data/lib/bugsnag/middleware/sidekiq.rb +9 -4
- data/lib/bugsnag/middleware/suggestion_data.rb +34 -0
- data/lib/bugsnag/middleware/warden_user.rb +11 -6
- data/lib/bugsnag/middleware_stack.rb +62 -9
- data/lib/bugsnag/on_error_callbacks.rb +33 -0
- data/lib/bugsnag/report.rb +516 -0
- data/lib/bugsnag/session_tracker.rb +182 -0
- data/lib/bugsnag/stacktrace.rb +82 -0
- data/lib/bugsnag/tasks/bugsnag.rake +2 -70
- data/lib/bugsnag/utility/circular_buffer.rb +62 -0
- data/lib/bugsnag/utility/duplicator.rb +124 -0
- data/lib/bugsnag/utility/feature_data_store.rb +41 -0
- data/lib/bugsnag/utility/feature_flag_delegate.rb +89 -0
- data/lib/bugsnag/utility/metadata_delegate.rb +102 -0
- data/lib/bugsnag.rb +528 -80
- metadata +61 -123
- data/.document +0 -5
- data/.gitignore +0 -52
- data/.rspec +0 -3
- data/.travis.yml +0 -14
- data/CONTRIBUTING.md +0 -47
- data/Gemfile +0 -2
- data/Rakefile +0 -29
- data/lib/bugsnag/capistrano.rb +0 -7
- data/lib/bugsnag/capistrano2.rb +0 -32
- data/lib/bugsnag/delay/resque.rb +0 -21
- data/lib/bugsnag/delayed_job.rb +0 -57
- data/lib/bugsnag/deploy.rb +0 -34
- data/lib/bugsnag/mailman.rb +0 -28
- data/lib/bugsnag/middleware/rails2_request.rb +0 -52
- data/lib/bugsnag/notification.rb +0 -459
- data/lib/bugsnag/rack.rb +0 -53
- data/lib/bugsnag/rails/action_controller_rescue.rb +0 -62
- data/lib/bugsnag/rails.rb +0 -66
- data/lib/bugsnag/railtie.rb +0 -80
- data/lib/bugsnag/rake.rb +0 -25
- data/lib/bugsnag/resque.rb +0 -40
- data/lib/bugsnag/sidekiq.rb +0 -42
- data/lib/bugsnag/tasks/bugsnag.cap +0 -48
- data/rails/init.rb +0 -7
- data/spec/cleaner_spec.rb +0 -138
- data/spec/code_spec.rb +0 -86
- data/spec/fixtures/crashes/end_of_file.rb +0 -9
- data/spec/fixtures/crashes/short_file.rb +0 -1
- data/spec/fixtures/crashes/start_of_file.rb +0 -9
- data/spec/fixtures/middleware/internal_info_setter.rb +0 -11
- data/spec/fixtures/middleware/public_info_setter.rb +0 -11
- data/spec/fixtures/tasks/Rakefile +0 -15
- data/spec/helper_spec.rb +0 -163
- data/spec/integration_spec.rb +0 -132
- data/spec/middleware_spec.rb +0 -181
- data/spec/notification_spec.rb +0 -877
- data/spec/rack_spec.rb +0 -56
- data/spec/spec_helper.rb +0 -53
@@ -1,132 +1,757 @@
|
|
1
|
-
require "
|
2
|
-
|
3
|
-
require "
|
1
|
+
require "bugsnag/breadcrumbs/on_breadcrumb_callback_list"
|
2
|
+
|
3
|
+
require "bugsnag/endpoint_configuration"
|
4
|
+
require "bugsnag/endpoint_validator"
|
5
|
+
|
6
|
+
require "bugsnag/middleware/breadcrumbs"
|
7
|
+
require "bugsnag/middleware/callbacks"
|
8
|
+
require "bugsnag/middleware/classify_error"
|
9
|
+
require "bugsnag/middleware/clearance_user"
|
10
|
+
require "bugsnag/middleware/delayed_job"
|
11
|
+
require "bugsnag/middleware/discard_error_class"
|
12
|
+
require "bugsnag/middleware/exception_meta_data"
|
13
|
+
require "bugsnag/middleware/ignore_error_class"
|
14
|
+
require "bugsnag/middleware/mailman"
|
15
|
+
require "bugsnag/middleware/rack_request"
|
16
|
+
require "bugsnag/middleware/rails3_request"
|
17
|
+
require "bugsnag/middleware/rake"
|
18
|
+
require "bugsnag/middleware/session_data"
|
19
|
+
require "bugsnag/middleware/sidekiq"
|
20
|
+
require "bugsnag/middleware/suggestion_data"
|
21
|
+
require "bugsnag/middleware/warden_user"
|
22
|
+
|
4
23
|
require "bugsnag/middleware_stack"
|
5
24
|
|
25
|
+
require "bugsnag/utility/circular_buffer"
|
26
|
+
|
6
27
|
module Bugsnag
|
7
28
|
class Configuration
|
29
|
+
# Your Integration API Key
|
30
|
+
# @return [String, nil]
|
8
31
|
attr_accessor :api_key
|
32
|
+
|
33
|
+
# The current stage of the release process, e.g. 'development', production'
|
34
|
+
# @return [String, nil]
|
9
35
|
attr_accessor :release_stage
|
36
|
+
|
37
|
+
# A list of which release stages should cause notifications to be sent
|
38
|
+
# @deprecated Use {#enabled_release_stages} instead
|
39
|
+
# @return [Array<String>, nil]
|
10
40
|
attr_accessor :notify_release_stages
|
41
|
+
|
42
|
+
# Whether notifications should automatically be sent
|
43
|
+
# @return [Boolean]
|
11
44
|
attr_accessor :auto_notify
|
12
|
-
|
45
|
+
|
46
|
+
# @return [String, nil]
|
13
47
|
attr_accessor :ca_file
|
48
|
+
|
49
|
+
# Whether to automatically attach the Rack environment to notifications
|
50
|
+
# @return [Boolean]
|
14
51
|
attr_accessor :send_environment
|
52
|
+
|
53
|
+
# Whether code snippets from the exception stacktrace should be sent with notifications
|
54
|
+
# @return [Boolean]
|
15
55
|
attr_accessor :send_code
|
56
|
+
|
57
|
+
# Any stacktrace lines that match this path will be marked as 'in project'
|
58
|
+
# @return [String, nil]
|
16
59
|
attr_accessor :project_root
|
17
|
-
|
60
|
+
|
61
|
+
# The current version of your application
|
62
|
+
# @return [String, nil]
|
18
63
|
attr_accessor :app_version
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
64
|
+
|
65
|
+
# A list of keys that should be filtered out from the report and breadcrumb
|
66
|
+
# metadata before sending them to Bugsnag
|
67
|
+
# @deprecated Use {#redacted_keys} instead
|
68
|
+
# @return [Set<String, Regexp>]
|
69
|
+
attr_accessor :meta_data_filters
|
70
|
+
|
71
|
+
# A set of keys that should be redacted from the report and breadcrumb
|
72
|
+
# metadata before sending them to Bugsnag
|
73
|
+
#
|
74
|
+
# When adding strings, keys that are equal to the string (ignoring case)
|
75
|
+
# will be redacted. When adding regular expressions, any keys which match
|
76
|
+
# the regular expression will be redacted
|
77
|
+
#
|
78
|
+
# @return [Set<String, Regexp>]
|
79
|
+
attr_accessor :redacted_keys
|
80
|
+
|
81
|
+
# The logger to use for Bugsnag log messages
|
82
|
+
# @return [Logger]
|
23
83
|
attr_accessor :logger
|
84
|
+
|
85
|
+
# The middleware stack that will run on every notification
|
86
|
+
# @return [MiddlewareStack]
|
24
87
|
attr_accessor :middleware
|
88
|
+
|
89
|
+
# @api private
|
90
|
+
# @return [MiddlewareStack]
|
25
91
|
attr_accessor :internal_middleware
|
26
|
-
|
27
|
-
|
92
|
+
|
93
|
+
# The host address of the HTTP proxy that should be used when making requests
|
94
|
+
# @see parse_proxy
|
95
|
+
# @return [String, nil]
|
28
96
|
attr_accessor :proxy_host
|
97
|
+
|
98
|
+
# The port number of the HTTP proxy that should be used when making requests
|
99
|
+
# @see parse_proxy
|
100
|
+
# @return [Integer, nil]
|
29
101
|
attr_accessor :proxy_port
|
102
|
+
|
103
|
+
# The user that should be used when making requests via a HTTP proxy
|
104
|
+
# @see parse_proxy
|
105
|
+
# @return [String, nil]
|
30
106
|
attr_accessor :proxy_user
|
107
|
+
|
108
|
+
# The password for the user that should be used when making requests via a HTTP proxy
|
109
|
+
# @see parse_proxy
|
110
|
+
# @return [String, nil]
|
31
111
|
attr_accessor :proxy_password
|
112
|
+
|
113
|
+
# The HTTP request timeout, defaults to 15 seconds
|
114
|
+
# @return [Integer]
|
32
115
|
attr_accessor :timeout
|
116
|
+
|
117
|
+
# The name or descriptor of the Ruby server host
|
118
|
+
# @return [String]
|
33
119
|
attr_accessor :hostname
|
34
|
-
attr_accessor :delivery_method
|
35
|
-
attr_writer :ignore_classes
|
36
120
|
|
121
|
+
# @api private
|
122
|
+
# @return [Hash{String => String}]
|
123
|
+
attr_accessor :runtime_versions
|
124
|
+
|
125
|
+
# Exception classes that will be discarded and not sent to Bugsnag
|
126
|
+
# @return [Set<String, Regexp>]
|
127
|
+
attr_accessor :discard_classes
|
128
|
+
|
129
|
+
# Whether Bugsnag should automatically record sessions
|
130
|
+
# @deprecated Use {#auto_track_sessions} instead
|
131
|
+
# @return [Boolean]
|
132
|
+
attr_accessor :auto_capture_sessions
|
133
|
+
|
134
|
+
# @deprecated Use {#discard_classes} instead
|
135
|
+
# @return [Set<Class, Proc>]
|
136
|
+
attr_accessor :ignore_classes
|
137
|
+
|
138
|
+
# The URLs to send events and sessions to
|
139
|
+
# @return [EndpointConfiguration]
|
140
|
+
attr_reader :endpoints
|
141
|
+
|
142
|
+
# Whether events will be delivered
|
143
|
+
# @api private
|
144
|
+
# @return [Boolean]
|
145
|
+
attr_reader :enable_events
|
146
|
+
|
147
|
+
# Whether sessions will be delivered
|
148
|
+
# @api private
|
149
|
+
# @return [Boolean]
|
150
|
+
attr_reader :enable_sessions
|
151
|
+
|
152
|
+
# A list of strings indicating allowable automatic breadcrumb types
|
153
|
+
# @deprecated Use {#enabled_breadcrumb_types} instead
|
154
|
+
# @see Bugsnag::BreadcrumbType
|
155
|
+
# @return [Array<String>]
|
156
|
+
attr_accessor :enabled_automatic_breadcrumb_types
|
157
|
+
|
158
|
+
# Callables to be run before a breadcrumb is logged
|
159
|
+
# @return [Array<#call>]
|
160
|
+
attr_accessor :before_breadcrumb_callbacks
|
161
|
+
|
162
|
+
# The maximum allowable amount of breadcrumbs per thread
|
163
|
+
# @return [Integer]
|
164
|
+
attr_reader :max_breadcrumbs
|
165
|
+
|
166
|
+
# @deprecated Use {vendor_paths} instead
|
167
|
+
# @return [Regexp]
|
168
|
+
attr_accessor :vendor_path
|
169
|
+
|
170
|
+
# An array of paths within the {project_root} that should not be considered
|
171
|
+
# as "in project"
|
172
|
+
#
|
173
|
+
# These paths should be relative to the {project_root} and will only match
|
174
|
+
# whole directory names
|
175
|
+
#
|
176
|
+
# @return [Array<String>]
|
177
|
+
attr_accessor :vendor_paths
|
178
|
+
|
179
|
+
# The default context for all future events
|
180
|
+
# Setting this will disable automatic context setting
|
181
|
+
# @return [String, nil]
|
182
|
+
attr_accessor :context
|
183
|
+
|
184
|
+
# Global metadata added to every event
|
185
|
+
# @return [Hash]
|
186
|
+
attr_reader :metadata
|
187
|
+
|
188
|
+
# @api private
|
189
|
+
# @return [Array<String>]
|
190
|
+
attr_reader :scopes_to_filter
|
191
|
+
|
192
|
+
# Expose on_breadcrumb_callbacks internally for Bugsnag.leave_breadcrumb
|
193
|
+
# @api private
|
194
|
+
# @return [Breadcrumbs::OnBreadcrumbCallbackList]
|
195
|
+
attr_reader :on_breadcrumb_callbacks
|
196
|
+
|
197
|
+
API_KEY_REGEX = /[0-9a-f]{32}/i
|
37
198
|
THREAD_LOCAL_NAME = "bugsnag_req_data"
|
38
199
|
|
39
|
-
|
200
|
+
DEFAULT_NOTIFY_ENDPOINT = "https://notify.bugsnag.com"
|
201
|
+
DEFAULT_SESSION_ENDPOINT = "https://sessions.bugsnag.com"
|
202
|
+
DEFAULT_ENDPOINT = DEFAULT_NOTIFY_ENDPOINT
|
40
203
|
|
41
|
-
|
204
|
+
DEFAULT_META_DATA_FILTERS = [
|
42
205
|
/authorization/i,
|
43
206
|
/cookie/i,
|
44
207
|
/password/i,
|
45
208
|
/secret/i,
|
209
|
+
/warden\.user\.([^.]+)\.key/,
|
46
210
|
"rack.request.form_vars"
|
47
211
|
].freeze
|
48
212
|
|
49
|
-
|
50
|
-
"AbstractController::ActionNotFound",
|
51
|
-
"ActionController::InvalidAuthenticityToken",
|
52
|
-
"ActionController::ParameterMissing",
|
53
|
-
"ActionController::RoutingError",
|
54
|
-
"ActionController::UnknownAction",
|
55
|
-
"ActionController::UnknownFormat",
|
56
|
-
"ActionController::UnknownHttpMethod",
|
57
|
-
"ActiveRecord::RecordNotFound",
|
58
|
-
"CGI::Session::CookieStore::TamperedWithCookie",
|
59
|
-
"Mongoid::Errors::DocumentNotFound",
|
60
|
-
"SignalException",
|
61
|
-
"SystemExit",
|
62
|
-
].freeze
|
213
|
+
DEFAULT_MAX_BREADCRUMBS = 25
|
63
214
|
|
64
|
-
|
215
|
+
# Path to vendored code. Used to mark file paths as out of project.
|
216
|
+
DEFAULT_VENDOR_PATH = %r{^(vendor/|\.bundle/)}
|
65
217
|
|
66
|
-
|
218
|
+
# @api private
|
219
|
+
DEFAULT_SCOPES_TO_FILTER = ['events.metaData', 'events.breadcrumbs.metaData'].freeze
|
220
|
+
|
221
|
+
alias :track_sessions :auto_capture_sessions
|
222
|
+
alias :track_sessions= :auto_capture_sessions=
|
67
223
|
|
68
224
|
def initialize
|
69
225
|
@mutex = Mutex.new
|
70
226
|
|
71
227
|
# Set up the defaults
|
72
228
|
self.auto_notify = true
|
73
|
-
self.use_ssl = true
|
74
229
|
self.send_environment = false
|
75
230
|
self.send_code = true
|
76
|
-
self.
|
77
|
-
|
78
|
-
self.
|
79
|
-
self.endpoint = DEFAULT_ENDPOINT
|
231
|
+
self.meta_data_filters = Set.new(DEFAULT_META_DATA_FILTERS)
|
232
|
+
@redacted_keys = Set.new
|
233
|
+
self.scopes_to_filter = DEFAULT_SCOPES_TO_FILTER
|
80
234
|
self.hostname = default_hostname
|
81
|
-
self.
|
235
|
+
self.runtime_versions = {}
|
236
|
+
self.runtime_versions["ruby"] = RUBY_VERSION
|
237
|
+
self.runtime_versions["jruby"] = JRUBY_VERSION if defined?(JRUBY_VERSION)
|
82
238
|
self.timeout = 15
|
83
|
-
self.
|
239
|
+
self.release_stage = ENV['BUGSNAG_RELEASE_STAGE']
|
84
240
|
self.notify_release_stages = nil
|
241
|
+
self.auto_capture_sessions = true
|
242
|
+
|
243
|
+
# All valid breadcrumb types should be allowable initially
|
244
|
+
self.enabled_automatic_breadcrumb_types = Bugsnag::Breadcrumbs::VALID_BREADCRUMB_TYPES.dup
|
245
|
+
self.before_breadcrumb_callbacks = []
|
246
|
+
@on_breadcrumb_callbacks = Breadcrumbs::OnBreadcrumbCallbackList.new(self)
|
247
|
+
|
248
|
+
# Store max_breadcrumbs here instead of outputting breadcrumbs.max_items
|
249
|
+
# to avoid infinite recursion when creating breadcrumb buffer
|
250
|
+
@max_breadcrumbs = DEFAULT_MAX_BREADCRUMBS
|
251
|
+
|
252
|
+
@endpoints = EndpointConfiguration.new(DEFAULT_NOTIFY_ENDPOINT, DEFAULT_SESSION_ENDPOINT)
|
253
|
+
|
254
|
+
@enable_events = true
|
255
|
+
@enable_sessions = true
|
256
|
+
|
257
|
+
@metadata = {}
|
258
|
+
@metadata_delegate = Utility::MetadataDelegate.new
|
259
|
+
|
260
|
+
# SystemExit and SignalException are common Exception types seen with
|
261
|
+
# successful exits and are not automatically reported to Bugsnag
|
262
|
+
# TODO move these defaults into `discard_classes` when `ignore_classes`
|
263
|
+
# is removed
|
264
|
+
self.ignore_classes = Set.new([SystemExit, SignalException])
|
265
|
+
self.discard_classes = Set.new([])
|
85
266
|
|
86
267
|
# Read the API key from the environment
|
87
268
|
self.api_key = ENV["BUGSNAG_API_KEY"]
|
88
269
|
|
270
|
+
# Read NET::HTTP proxy environment variables
|
271
|
+
if (proxy_uri = ENV["https_proxy"] || ENV['http_proxy'])
|
272
|
+
parse_proxy(proxy_uri)
|
273
|
+
end
|
274
|
+
|
275
|
+
# Set up vendor_path regex to mark stacktrace file paths as out of project.
|
276
|
+
# Stacktrace lines that matches regex will be marked as "out of project"
|
277
|
+
# will only appear in the full trace.
|
278
|
+
self.vendor_path = DEFAULT_VENDOR_PATH
|
279
|
+
@vendor_paths = []
|
280
|
+
|
89
281
|
# Set up logging
|
90
282
|
self.logger = Logger.new(STDOUT)
|
91
|
-
self.logger.level = Logger::
|
283
|
+
self.logger.level = Logger::INFO
|
284
|
+
self.logger.formatter = proc do |severity, datetime, progname, msg|
|
285
|
+
"** #{progname} #{datetime}: #{msg}\n"
|
286
|
+
end
|
92
287
|
|
93
288
|
# Configure the bugsnag middleware stack
|
94
289
|
self.internal_middleware = Bugsnag::MiddlewareStack.new
|
290
|
+
self.internal_middleware.use Bugsnag::Middleware::ExceptionMetaData
|
291
|
+
self.internal_middleware.use Bugsnag::Middleware::DiscardErrorClass
|
292
|
+
self.internal_middleware.use Bugsnag::Middleware::IgnoreErrorClass
|
293
|
+
self.internal_middleware.use Bugsnag::Middleware::SuggestionData
|
294
|
+
self.internal_middleware.use Bugsnag::Middleware::ClassifyError
|
295
|
+
self.internal_middleware.use Bugsnag::Middleware::SessionData
|
296
|
+
self.internal_middleware.use Bugsnag::Middleware::Breadcrumbs
|
95
297
|
|
96
298
|
self.middleware = Bugsnag::MiddlewareStack.new
|
97
299
|
self.middleware.use Bugsnag::Middleware::Callbacks
|
98
300
|
end
|
99
301
|
|
100
|
-
|
101
|
-
|
102
|
-
|
302
|
+
##
|
303
|
+
# Gets the delivery_method that Bugsnag will use to communicate with the
|
304
|
+
# notification endpoint.
|
305
|
+
#
|
306
|
+
# @return [Symbol]
|
307
|
+
def delivery_method
|
308
|
+
@delivery_method || @default_delivery_method || :thread_queue
|
309
|
+
end
|
310
|
+
|
311
|
+
##
|
312
|
+
# Sets the delivery_method that Bugsnag will use to communicate with the
|
313
|
+
# notification endpoint.
|
314
|
+
#
|
315
|
+
# The default delivery methods are ':thread_queue' and ':synchronous'.
|
316
|
+
#
|
317
|
+
# @param delivery_method [Symbol]
|
318
|
+
# @return [void]
|
319
|
+
def delivery_method=(delivery_method)
|
320
|
+
@delivery_method = delivery_method
|
321
|
+
end
|
322
|
+
|
323
|
+
##
|
324
|
+
# Used to set a new default delivery method that will be used if one is not
|
325
|
+
# set with #delivery_method.
|
326
|
+
#
|
327
|
+
# @api private
|
328
|
+
#
|
329
|
+
# @param delivery_method [Symbol]
|
330
|
+
# @return [void]
|
331
|
+
def default_delivery_method=(delivery_method)
|
332
|
+
@default_delivery_method = delivery_method
|
333
|
+
end
|
334
|
+
|
335
|
+
##
|
336
|
+
# Get the type of application executing the current code
|
337
|
+
#
|
338
|
+
# This is usually used to represent if you are running in a Rails server,
|
339
|
+
# Sidekiq job, Rake task etc... Bugsnag will automatically detect most
|
340
|
+
# application types for you
|
341
|
+
#
|
342
|
+
# @return [String, nil]
|
343
|
+
def app_type
|
344
|
+
@app_type || @detected_app_type
|
345
|
+
end
|
346
|
+
|
347
|
+
##
|
348
|
+
# Set the type of application executing the current code
|
349
|
+
#
|
350
|
+
# If an app_type is set, this will be used instead of the automatically
|
351
|
+
# detected app_type that Bugsnag would otherwise use
|
352
|
+
#
|
353
|
+
# @param app_type [String]
|
354
|
+
# @return [void]
|
355
|
+
def app_type=(app_type)
|
356
|
+
@app_type = app_type
|
357
|
+
end
|
358
|
+
|
359
|
+
##
|
360
|
+
# Get the detected app_type, which is used when one isn't set explicitly
|
361
|
+
#
|
362
|
+
# @api private
|
363
|
+
#
|
364
|
+
# @return [String, nil]
|
365
|
+
def detected_app_type
|
366
|
+
@detected_app_type
|
367
|
+
end
|
368
|
+
|
369
|
+
##
|
370
|
+
# Set the detected app_type, which is used when one isn't set explicitly
|
371
|
+
#
|
372
|
+
# This allows Bugsnag's integrations to say 'this is a Rails app' while
|
373
|
+
# allowing the user to overwrite this if they wish
|
374
|
+
#
|
375
|
+
# @api private
|
376
|
+
#
|
377
|
+
# @param app_type [String]
|
378
|
+
# @return [void]
|
379
|
+
def detected_app_type=(app_type)
|
380
|
+
@detected_app_type = app_type
|
103
381
|
end
|
104
382
|
|
105
|
-
|
383
|
+
##
|
384
|
+
# Indicates whether the notifier should send a notification based on the
|
385
|
+
# configured release stage.
|
386
|
+
#
|
387
|
+
# @return [Boolean]
|
388
|
+
def should_notify_release_stage?
|
106
389
|
@release_stage.nil? || @notify_release_stages.nil? || @notify_release_stages.include?(@release_stage)
|
107
390
|
end
|
108
391
|
|
392
|
+
##
|
393
|
+
# Tests whether the configured API key is valid.
|
394
|
+
#
|
395
|
+
# @return [Boolean]
|
396
|
+
def valid_api_key?
|
397
|
+
!api_key.nil? && api_key =~ API_KEY_REGEX
|
398
|
+
end
|
399
|
+
|
400
|
+
##
|
401
|
+
# Returns the array of data that will be automatically attached to every
|
402
|
+
# error notification.
|
403
|
+
#
|
404
|
+
# @return [Hash]
|
109
405
|
def request_data
|
110
406
|
Thread.current[THREAD_LOCAL_NAME] ||= {}
|
111
407
|
end
|
112
408
|
|
409
|
+
##
|
410
|
+
# Sets an entry in the array of data attached to every error notification.
|
411
|
+
#
|
412
|
+
# @param key [String, #to_s]
|
413
|
+
# @param value [Object]
|
414
|
+
# @return [void]
|
113
415
|
def set_request_data(key, value)
|
114
416
|
self.request_data[key] = value
|
115
417
|
end
|
116
418
|
|
419
|
+
##
|
420
|
+
# Unsets an entry in the array of data attached to every error notification.
|
421
|
+
#
|
422
|
+
# @param (see set_request_data)
|
423
|
+
# @return [void]
|
117
424
|
def unset_request_data(key, value)
|
118
425
|
self.request_data.delete(key)
|
119
426
|
end
|
120
427
|
|
428
|
+
##
|
429
|
+
# Clears the array of data attached to every error notification.
|
430
|
+
#
|
431
|
+
# @return [void]
|
121
432
|
def clear_request_data
|
122
433
|
Thread.current[THREAD_LOCAL_NAME] = nil
|
123
434
|
end
|
124
435
|
|
436
|
+
##
|
437
|
+
# Logs an info level message
|
438
|
+
#
|
439
|
+
# @param message [String, #to_s] The message to log
|
440
|
+
def info(message)
|
441
|
+
logger.info(PROG_NAME) { message }
|
442
|
+
end
|
443
|
+
|
444
|
+
##
|
445
|
+
# Logs a warning level message
|
446
|
+
#
|
447
|
+
# @param message [String, #to_s] The message to log
|
448
|
+
def warn(message)
|
449
|
+
logger.warn(PROG_NAME) { message }
|
450
|
+
end
|
451
|
+
|
452
|
+
##
|
453
|
+
# Logs an error level message
|
454
|
+
#
|
455
|
+
# @param message [String, #to_s] The message to log
|
456
|
+
def error(message)
|
457
|
+
logger.error(PROG_NAME) { message }
|
458
|
+
end
|
459
|
+
|
460
|
+
##
|
461
|
+
# Logs a debug level message
|
462
|
+
#
|
463
|
+
# @param message [String, #to_s] The message to log
|
464
|
+
def debug(message)
|
465
|
+
logger.debug(PROG_NAME) { message }
|
466
|
+
end
|
467
|
+
|
468
|
+
##
|
469
|
+
# Parses and sets proxy from a uri
|
470
|
+
#
|
471
|
+
# @param uri [String, #to_s] The URI to parse and extract proxy details from
|
472
|
+
# @return [void]
|
473
|
+
def parse_proxy(uri)
|
474
|
+
proxy = URI.parse(uri)
|
475
|
+
self.proxy_host = proxy.host
|
476
|
+
self.proxy_port = proxy.port
|
477
|
+
self.proxy_user = proxy.user
|
478
|
+
self.proxy_password = proxy.password
|
479
|
+
end
|
480
|
+
|
481
|
+
##
|
482
|
+
# Sets the maximum allowable amount of breadcrumbs
|
483
|
+
#
|
484
|
+
# @param new_max_breadcrumbs [Integer] the new maximum breadcrumb limit
|
485
|
+
# @return [void]
|
486
|
+
def max_breadcrumbs=(new_max_breadcrumbs)
|
487
|
+
@max_breadcrumbs = new_max_breadcrumbs
|
488
|
+
breadcrumbs.max_items = new_max_breadcrumbs
|
489
|
+
end
|
490
|
+
|
491
|
+
##
|
492
|
+
# Returns the current list of breadcrumbs
|
493
|
+
#
|
494
|
+
# This is a per-thread circular buffer, containing at most 'max_breadcrumbs'
|
495
|
+
# breadcrumbs
|
496
|
+
#
|
497
|
+
# @return [Bugsnag::Utility::CircularBuffer]
|
498
|
+
def breadcrumbs
|
499
|
+
request_data[:breadcrumbs] ||= Bugsnag::Utility::CircularBuffer.new(@max_breadcrumbs)
|
500
|
+
end
|
501
|
+
|
502
|
+
# The URL error notifications will be delivered to
|
503
|
+
# @!attribute notify_endpoint
|
504
|
+
# @return [String]
|
505
|
+
# @deprecated Use {#endpoints} instead
|
506
|
+
def notify_endpoint
|
507
|
+
@endpoints.notify
|
508
|
+
end
|
509
|
+
|
510
|
+
alias :endpoint :notify_endpoint
|
511
|
+
|
512
|
+
# Sets the notification endpoint
|
513
|
+
#
|
514
|
+
# @deprecated Use {#endpoints} instead
|
515
|
+
#
|
516
|
+
# @param new_notify_endpoint [String] The URL to deliver error notifications to
|
517
|
+
# @return [void]
|
518
|
+
def endpoint=(new_notify_endpoint)
|
519
|
+
warn("The 'endpoint' configuration option is deprecated. Set both endpoints with the 'endpoints=' method instead")
|
520
|
+
set_endpoints(new_notify_endpoint, session_endpoint) # Pass the existing session_endpoint through so it doesn't get overwritten
|
521
|
+
end
|
522
|
+
|
523
|
+
# The URL session notifications will be delivered to
|
524
|
+
# @!attribute session_endpoint
|
525
|
+
# @return [String]
|
526
|
+
# @deprecated Use {#endpoints} instead
|
527
|
+
def session_endpoint
|
528
|
+
@endpoints.sessions
|
529
|
+
end
|
530
|
+
|
531
|
+
##
|
532
|
+
# Sets the sessions endpoint
|
533
|
+
#
|
534
|
+
# @deprecated Use {#endpoints} instead
|
535
|
+
#
|
536
|
+
# @param new_session_endpoint [String] The URL to deliver session notifications to
|
537
|
+
# @return [void]
|
538
|
+
def session_endpoint=(new_session_endpoint)
|
539
|
+
warn("The 'session_endpoint' configuration option is deprecated. Set both endpoints with the 'endpoints=' method instead")
|
540
|
+
set_endpoints(notify_endpoint, new_session_endpoint) # Pass the existing notify_endpoint through so it doesn't get overwritten
|
541
|
+
end
|
542
|
+
|
543
|
+
##
|
544
|
+
# Sets the notification and session endpoints
|
545
|
+
#
|
546
|
+
# @param new_notify_endpoint [String] The URL to deliver error notifications to
|
547
|
+
# @param new_session_endpoint [String] The URL to deliver session notifications to
|
548
|
+
# @return [void]
|
549
|
+
# @deprecated Use {#endpoints} instead
|
550
|
+
def set_endpoints(new_notify_endpoint, new_session_endpoint)
|
551
|
+
self.endpoints = EndpointConfiguration.new(new_notify_endpoint, new_session_endpoint)
|
552
|
+
end
|
553
|
+
|
554
|
+
def endpoints=(endpoint_configuration)
|
555
|
+
result = EndpointValidator.validate(endpoint_configuration)
|
556
|
+
|
557
|
+
if result.valid?
|
558
|
+
@enable_events = true
|
559
|
+
@enable_sessions = true
|
560
|
+
else
|
561
|
+
warn(result.reason)
|
562
|
+
|
563
|
+
@enable_events = result.keep_events_enabled_for_backwards_compatibility?
|
564
|
+
@enable_sessions = false
|
565
|
+
end
|
566
|
+
|
567
|
+
# use the given endpoints even if they are invalid
|
568
|
+
@endpoints = endpoint_configuration
|
569
|
+
end
|
570
|
+
|
571
|
+
##
|
572
|
+
# Disables session tracking and delivery. Cannot be undone
|
573
|
+
#
|
574
|
+
# @return [void]
|
575
|
+
def disable_sessions
|
576
|
+
self.auto_capture_sessions = false
|
577
|
+
@enable_sessions = false
|
578
|
+
end
|
579
|
+
|
580
|
+
##
|
581
|
+
# Add the given block to the list of on_error callbacks
|
582
|
+
#
|
583
|
+
# The on_error callbacks will be called when an error is captured or reported
|
584
|
+
# and are passed a {Bugsnag::Report} object
|
585
|
+
#
|
586
|
+
# Returning false from an on_error callback will cause the error to be ignored
|
587
|
+
# and will prevent any remaining callbacks from being called
|
588
|
+
#
|
589
|
+
# @return [void]
|
590
|
+
def on_error(&block)
|
591
|
+
middleware.use(block)
|
592
|
+
end
|
593
|
+
|
594
|
+
##
|
595
|
+
# Add the given callback to the list of on_error callbacks
|
596
|
+
#
|
597
|
+
# The on_error callbacks will be called when an error is captured or reported
|
598
|
+
# and are passed a {Bugsnag::Report} object
|
599
|
+
#
|
600
|
+
# Returning false from an on_error callback will cause the error to be ignored
|
601
|
+
# and will prevent any remaining callbacks from being called
|
602
|
+
#
|
603
|
+
# @param callback [Proc, Method, #call]
|
604
|
+
# @return [void]
|
605
|
+
def add_on_error(callback)
|
606
|
+
middleware.use(callback)
|
607
|
+
end
|
608
|
+
|
609
|
+
##
|
610
|
+
# Remove the given callback from the list of on_error callbacks
|
611
|
+
#
|
612
|
+
# Note that this must be the same instance that was passed to
|
613
|
+
# {#add_on_error}, otherwise it will not be removed
|
614
|
+
#
|
615
|
+
# @param callback [Proc, Method, #call]
|
616
|
+
# @return [void]
|
617
|
+
def remove_on_error(callback)
|
618
|
+
middleware.remove(callback)
|
619
|
+
end
|
620
|
+
|
621
|
+
##
|
622
|
+
# Add the given callback to the list of on_breadcrumb callbacks
|
623
|
+
#
|
624
|
+
# The on_breadcrumb callbacks will be called when a breadcrumb is left and
|
625
|
+
# are passed the {Breadcrumbs::Breadcrumb Breadcrumb} object
|
626
|
+
#
|
627
|
+
# Returning false from an on_breadcrumb callback will cause the breadcrumb
|
628
|
+
# to be ignored and will prevent any remaining callbacks from being called
|
629
|
+
#
|
630
|
+
# @param callback [Proc, Method, #call]
|
631
|
+
# @return [void]
|
632
|
+
def add_on_breadcrumb(callback)
|
633
|
+
@on_breadcrumb_callbacks.add(callback)
|
634
|
+
end
|
635
|
+
|
636
|
+
##
|
637
|
+
# Remove the given callback from the list of on_breadcrumb callbacks
|
638
|
+
#
|
639
|
+
# Note that this must be the same instance that was passed to
|
640
|
+
# {add_on_breadcrumb}, otherwise it will not be removed
|
641
|
+
#
|
642
|
+
# @param callback [Proc, Method, #call]
|
643
|
+
# @return [void]
|
644
|
+
def remove_on_breadcrumb(callback)
|
645
|
+
@on_breadcrumb_callbacks.remove(callback)
|
646
|
+
end
|
647
|
+
|
648
|
+
##
|
649
|
+
# Add values to metadata
|
650
|
+
#
|
651
|
+
# @overload add_metadata(section, data)
|
652
|
+
# Merges data into the given section of metadata
|
653
|
+
# @param section [String, Symbol]
|
654
|
+
# @param data [Hash]
|
655
|
+
#
|
656
|
+
# @overload add_metadata(section, key, value)
|
657
|
+
# Sets key to value in the given section of metadata. If the value is nil
|
658
|
+
# the key will be deleted
|
659
|
+
# @param section [String, Symbol]
|
660
|
+
# @param key [String, Symbol]
|
661
|
+
# @param value
|
662
|
+
#
|
663
|
+
# @return [void]
|
664
|
+
def add_metadata(section, key_or_data, *args)
|
665
|
+
@mutex.synchronize do
|
666
|
+
@metadata_delegate.add_metadata(@metadata, section, key_or_data, *args)
|
667
|
+
end
|
668
|
+
end
|
669
|
+
|
670
|
+
##
|
671
|
+
# Clear values from metadata
|
672
|
+
#
|
673
|
+
# @overload clear_metadata(section)
|
674
|
+
# Clears the given section of metadata
|
675
|
+
# @param section [String, Symbol]
|
676
|
+
#
|
677
|
+
# @overload clear_metadata(section, key)
|
678
|
+
# Clears the key in the given section of metadata
|
679
|
+
# @param section [String, Symbol]
|
680
|
+
# @param key [String, Symbol]
|
681
|
+
#
|
682
|
+
# @return [void]
|
683
|
+
def clear_metadata(section, *args)
|
684
|
+
@mutex.synchronize do
|
685
|
+
@metadata_delegate.clear_metadata(@metadata, section, *args)
|
686
|
+
end
|
687
|
+
end
|
688
|
+
|
689
|
+
##
|
690
|
+
# Has the context been explicitly set?
|
691
|
+
#
|
692
|
+
# This is necessary to differentiate between the context not being set and
|
693
|
+
# the context being set to 'nil' explicitly
|
694
|
+
#
|
695
|
+
# @api private
|
696
|
+
# @return [Boolean]
|
697
|
+
def context_set?
|
698
|
+
defined?(@context) != nil
|
699
|
+
end
|
700
|
+
|
701
|
+
# TODO: These methods can be a simple attr_accessor when they replace the
|
702
|
+
# methods they are aliasing
|
703
|
+
# NOTE: they are not aliases as YARD doesn't allow documenting the non-alias
|
704
|
+
# as deprecated without also marking the alias as deprecated
|
705
|
+
|
706
|
+
# A list of which release stages should cause notifications to be sent
|
707
|
+
# @!attribute enabled_release_stages
|
708
|
+
# @return [Array<String>, nil]
|
709
|
+
def enabled_release_stages
|
710
|
+
@notify_release_stages
|
711
|
+
end
|
712
|
+
|
713
|
+
# @param release_stages [Array<String>, nil]
|
714
|
+
# @return [void]
|
715
|
+
def enabled_release_stages=(release_stages)
|
716
|
+
@notify_release_stages = release_stages
|
717
|
+
end
|
718
|
+
|
719
|
+
# A list of breadcrumb types that Bugsnag will collect automatically
|
720
|
+
# @!attribute enabled_breadcrumb_types
|
721
|
+
# @see Bugsnag::BreadcrumbType
|
722
|
+
# @return [Array<String>]
|
723
|
+
def enabled_breadcrumb_types
|
724
|
+
@enabled_automatic_breadcrumb_types
|
725
|
+
end
|
726
|
+
|
727
|
+
# @param breadcrumb_types [Array<String>]
|
728
|
+
# @return [void]
|
729
|
+
def enabled_breadcrumb_types=(breadcrumb_types)
|
730
|
+
@enabled_automatic_breadcrumb_types = breadcrumb_types
|
731
|
+
end
|
732
|
+
|
733
|
+
# Whether sessions should be tracked automatically
|
734
|
+
# @!attribute auto_track_sessions
|
735
|
+
# @return [Boolean]
|
736
|
+
def auto_track_sessions
|
737
|
+
@auto_capture_sessions
|
738
|
+
end
|
739
|
+
|
740
|
+
# @param track_sessions [Boolean]
|
741
|
+
# @return [void]
|
742
|
+
def auto_track_sessions=(track_sessions)
|
743
|
+
@auto_capture_sessions = track_sessions
|
744
|
+
end
|
745
|
+
|
125
746
|
private
|
126
747
|
|
748
|
+
attr_writer :scopes_to_filter
|
749
|
+
|
750
|
+
PROG_NAME = "[Bugsnag]"
|
751
|
+
|
127
752
|
def default_hostname
|
128
|
-
#
|
129
|
-
|
753
|
+
# Send the heroku dyno name instead of hostname if available
|
754
|
+
ENV["DYNO"] || Socket.gethostname;
|
130
755
|
end
|
131
756
|
end
|
132
757
|
end
|