bugsnag 6.10.0 → 6.11.0

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 (55) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop_todo.yml +4 -0
  3. data/CHANGELOG.md +20 -0
  4. data/Gemfile +1 -0
  5. data/README.md +1 -0
  6. data/VERSION +1 -1
  7. data/features/fixtures/docker-compose.yml +13 -0
  8. data/features/fixtures/rails3/app/app/controllers/breadcrumbs_controller.rb +19 -0
  9. data/features/fixtures/rails3/app/app/controllers/session_tracking_controller.rb +10 -6
  10. data/features/fixtures/rails3/app/config/initializers/bugsnag.rb +8 -2
  11. data/features/fixtures/rails3/app/config/routes.rb +1 -0
  12. data/features/fixtures/rails4/app/Gemfile +5 -1
  13. data/features/fixtures/rails4/app/app/controllers/breadcrumbs_controller.rb +26 -0
  14. data/features/fixtures/rails4/app/app/controllers/mongo_controller.rb +23 -0
  15. data/features/fixtures/rails4/app/app/controllers/session_tracking_controller.rb +9 -5
  16. data/features/fixtures/rails4/app/app/jobs/application_job.rb +2 -0
  17. data/features/fixtures/rails4/app/app/jobs/notify_job.rb +5 -0
  18. data/features/fixtures/rails4/app/app/models/mongo_model.rb +6 -0
  19. data/features/fixtures/rails4/app/config/initializers/bugsnag.rb +7 -1
  20. data/features/fixtures/rails4/app/config/mongoid.yml +22 -0
  21. data/features/fixtures/rails4/app/config/routes.rb +2 -0
  22. data/features/fixtures/rails5/app/Gemfile +4 -0
  23. data/features/fixtures/rails5/app/app/controllers/breadcrumbs_controller.rb +24 -0
  24. data/features/fixtures/rails5/app/app/controllers/mongo_controller.rb +22 -0
  25. data/features/fixtures/rails5/app/app/controllers/session_tracking_controller.rb +9 -5
  26. data/features/fixtures/rails5/app/app/jobs/notify_job.rb +5 -0
  27. data/features/fixtures/rails5/app/app/models/mongo_model.rb +6 -0
  28. data/features/fixtures/rails5/app/config/initializers/bugsnag.rb +7 -1
  29. data/features/fixtures/rails5/app/config/mongoid.yml +23 -0
  30. data/features/fixtures/rails5/app/config/routes.rb +11 -1
  31. data/features/rails_features/auto_capture_sessions.feature +55 -5
  32. data/features/rails_features/breadcrumbs.feature +135 -0
  33. data/features/rails_features/mongo_breadcrumbs.feature +100 -0
  34. data/features/steps/ruby_notifier_steps.rb +6 -0
  35. data/lib/bugsnag.rb +59 -3
  36. data/lib/bugsnag/breadcrumbs/breadcrumb.rb +76 -0
  37. data/lib/bugsnag/breadcrumbs/breadcrumbs.rb +14 -0
  38. data/lib/bugsnag/breadcrumbs/validator.rb +59 -0
  39. data/lib/bugsnag/configuration.rb +103 -6
  40. data/lib/bugsnag/integrations/mongo.rb +132 -0
  41. data/lib/bugsnag/integrations/rails/rails_breadcrumbs.rb +118 -0
  42. data/lib/bugsnag/integrations/railtie.rb +28 -1
  43. data/lib/bugsnag/middleware/breadcrumbs.rb +21 -0
  44. data/lib/bugsnag/report.rb +30 -1
  45. data/lib/bugsnag/session_tracker.rb +1 -0
  46. data/lib/bugsnag/utility/circular_buffer.rb +62 -0
  47. data/spec/breadcrumbs/breadcrumb_spec.rb +93 -0
  48. data/spec/breadcrumbs/validator_spec.rb +200 -0
  49. data/spec/bugsnag_spec.rb +230 -0
  50. data/spec/configuration_spec.rb +176 -2
  51. data/spec/integrations/mongo_spec.rb +262 -0
  52. data/spec/report_spec.rb +149 -0
  53. data/spec/session_tracker_spec.rb +24 -2
  54. data/spec/utility/circular_buffer_spec.rb +98 -0
  55. metadata +27 -2
@@ -0,0 +1,76 @@
1
+ module Bugsnag::Breadcrumbs
2
+ class Breadcrumb
3
+ # @return [String] the breadcrumb name
4
+ attr_accessor :name
5
+
6
+ # @return [String] the breadcrumb type
7
+ attr_accessor :type
8
+
9
+ # @return [Hash, nil] metadata hash containing strings, numbers, or booleans, or nil
10
+ attr_accessor :meta_data
11
+
12
+ # @return [Boolean] set to `true` if the breadcrumb was automatically generated
13
+ attr_reader :auto
14
+
15
+ # @return [Time] a Time object referring to breadcrumb creation time
16
+ attr_reader :timestamp
17
+
18
+ ##
19
+ # Creates a breadcrumb
20
+ #
21
+ # This will not have been validated, which must occur before this is attached to a report
22
+ #
23
+ # @api private
24
+ #
25
+ # @param name [String] the breadcrumb name
26
+ # @param type [String] the breadcrumb type from Bugsnag::Breadcrumbs::VALID_BREADCRUMB_TYPES
27
+ # @param meta_data [Hash, nil] a hash containing strings, numbers, or booleans, or nil
28
+ # @param auto [Symbol] set to `:auto` if the breadcrumb is automatically generated
29
+ def initialize(name, type, meta_data, auto)
30
+ @should_ignore = false
31
+ self.name = name
32
+ self.type = type
33
+ self.meta_data = meta_data
34
+
35
+ # Use the symbol comparison to improve readability of breadcrumb creation
36
+ @auto = auto == :auto
37
+
38
+ # Store it as a timestamp for now
39
+ @timestamp = Time.now.utc
40
+ end
41
+
42
+ ##
43
+ # Flags the breadcrumb to be ignored
44
+ #
45
+ # Ignored breadcrumbs will not be attached to a report
46
+ def ignore!
47
+ @should_ignore = true
48
+ end
49
+
50
+ ##
51
+ # Checks if the `ignore!` method has been called
52
+ #
53
+ # Ignored breadcrumbs will not be attached to a report
54
+ #
55
+ # @return [True] if `ignore!` has been called
56
+ # @return [nil] if `ignore` has not been called
57
+ def ignore?
58
+ @should_ignore
59
+ end
60
+
61
+ ##
62
+ # Outputs the breadcrumb data in a formatted hash
63
+ #
64
+ # These adhere to the breadcrumb format as defined in the Bugsnag error reporting API
65
+ #
66
+ # @return [Hash] Hash representation of the breadcrumb
67
+ def to_h
68
+ {
69
+ :name => @name,
70
+ :type => @type,
71
+ :metaData => @meta_data,
72
+ :timestamp => @timestamp.iso8601
73
+ }
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,14 @@
1
+ module Bugsnag::Breadcrumbs
2
+ MAX_NAME_LENGTH = 30
3
+
4
+ VALID_BREADCRUMB_TYPES = [
5
+ ERROR_BREADCRUMB_TYPE = "error",
6
+ MANUAL_BREADCRUMB_TYPE = "manual",
7
+ NAVIGATION_BREADCRUMB_TYPE = "navigation",
8
+ REQUEST_BREADCRUMB_TYPE = "request",
9
+ PROCESS_BREADCRUMB_TYPE = "process",
10
+ LOG_BREADCRUMB_TYPE = "log",
11
+ USER_BREADCRUMB_TYPE = "user",
12
+ STATE_BREADCRUMB_TYPE = "state"
13
+ ].freeze
14
+ end
@@ -0,0 +1,59 @@
1
+ require 'bugsnag/breadcrumbs/breadcrumbs'
2
+
3
+ module Bugsnag::Breadcrumbs
4
+ ##
5
+ # Validates a given breadcrumb before it is stored
6
+ class Validator
7
+ ##
8
+ # @param configuration [Bugsnag::Configuration] The current configuration
9
+ def initialize(configuration)
10
+ @configuration = configuration
11
+ end
12
+
13
+ ##
14
+ # Validates a given breadcrumb.
15
+ #
16
+ # @param breadcrumb [Bugsnag::Breadcrumbs::Breadcrumb] the breadcrumb to be validated
17
+ def validate(breadcrumb)
18
+ # Check name length
19
+ if breadcrumb.name.size > Bugsnag::Breadcrumbs::MAX_NAME_LENGTH
20
+ @configuration.warn("Breadcrumb name trimmed to length #{Bugsnag::Breadcrumbs::MAX_NAME_LENGTH}. Original name: #{breadcrumb.name}")
21
+ breadcrumb.name = breadcrumb.name.slice(0...Bugsnag::Breadcrumbs::MAX_NAME_LENGTH)
22
+ end
23
+
24
+ # Check meta_data hash doesn't contain complex values
25
+ breadcrumb.meta_data = breadcrumb.meta_data.select do |k, v|
26
+ if valid_meta_data_type?(v)
27
+ true
28
+ else
29
+ @configuration.warn("Breadcrumb #{breadcrumb.name} meta_data #{k}:#{v} has been dropped for having an invalid data type")
30
+ false
31
+ end
32
+ end
33
+
34
+ # Check type is valid, set to manual otherwise
35
+ unless Bugsnag::Breadcrumbs::VALID_BREADCRUMB_TYPES.include?(breadcrumb.type)
36
+ @configuration.warn("Invalid type: #{breadcrumb.type} for breadcrumb: #{breadcrumb.name}, defaulting to #{Bugsnag::Breadcrumbs::MANUAL_BREADCRUMB_TYPE}")
37
+ breadcrumb.type = Bugsnag::Breadcrumbs::MANUAL_BREADCRUMB_TYPE
38
+ end
39
+
40
+ # If auto is true, check type is in enabled_automatic_breadcrumb_types
41
+ return unless breadcrumb.auto && !@configuration.enabled_automatic_breadcrumb_types.include?(breadcrumb.type)
42
+
43
+ @configuration.warn("Automatic breadcrumb of type #{breadcrumb.type} ignored: #{breadcrumb.name}")
44
+ breadcrumb.ignore!
45
+ end
46
+
47
+ private
48
+
49
+ ##
50
+ # Tests whether the meta_data types are non-complex objects.
51
+ #
52
+ # Acceptable types are String, Numeric, TrueClass, FalseClass, and nil.
53
+ #
54
+ # @param value [Object] the object to be type checked
55
+ def valid_meta_data_type?(value)
56
+ value.nil? || value.is_a?(String) || value.is_a?(Numeric) || value.is_a?(FalseClass) || value.is_a?(TrueClass)
57
+ end
58
+ end
59
+ end
@@ -8,6 +8,9 @@ require "bugsnag/middleware/ignore_error_class"
8
8
  require "bugsnag/middleware/suggestion_data"
9
9
  require "bugsnag/middleware/classify_error"
10
10
  require "bugsnag/middleware/session_data"
11
+ require "bugsnag/middleware/breadcrumbs"
12
+ require "bugsnag/utility/circular_buffer"
13
+ require "bugsnag/breadcrumbs/breadcrumbs"
11
14
 
12
15
  module Bugsnag
13
16
  class Configuration
@@ -22,7 +25,6 @@ module Bugsnag
22
25
  attr_accessor :app_version
23
26
  attr_accessor :app_type
24
27
  attr_accessor :meta_data_filters
25
- attr_accessor :endpoint
26
28
  attr_accessor :logger
27
29
  attr_accessor :middleware
28
30
  attr_accessor :internal_middleware
@@ -35,12 +37,38 @@ module Bugsnag
35
37
  attr_accessor :ignore_classes
36
38
  attr_accessor :auto_capture_sessions
37
39
  attr_accessor :track_sessions
38
- attr_accessor :session_endpoint
40
+
41
+ ##
42
+ # @return [String] URL error notifications will be delivered to
43
+ attr_reader :notify_endpoint
44
+ alias :endpoint :notify_endpoint
45
+
46
+ ##
47
+ # @return [String] URL session notifications will be delivered to
48
+ attr_reader :session_endpoint
49
+
50
+ ##
51
+ # @return [Boolean] whether any sessions types will be delivered
52
+ attr_reader :enable_sessions
53
+
54
+ ##
55
+ # @return [Array<String>] strings indicating allowable automatic breadcrumb types
56
+ attr_accessor :enabled_automatic_breadcrumb_types
57
+
58
+ ##
59
+ # @return [Array<#call>] callables to be run before a breadcrumb is logged
60
+ attr_accessor :before_breadcrumb_callbacks
61
+
62
+ ##
63
+ # @return [Integer] the maximum allowable amount of breadcrumbs per thread
64
+ attr_reader :max_breadcrumbs
39
65
 
40
66
  API_KEY_REGEX = /[0-9a-f]{32}/i
41
67
  THREAD_LOCAL_NAME = "bugsnag_req_data"
42
- DEFAULT_ENDPOINT = "https://notify.bugsnag.com"
68
+
69
+ DEFAULT_NOTIFY_ENDPOINT = "https://notify.bugsnag.com"
43
70
  DEFAULT_SESSION_ENDPOINT = "https://sessions.bugsnag.com"
71
+ DEFAULT_ENDPOINT = DEFAULT_NOTIFY_ENDPOINT
44
72
 
45
73
  DEFAULT_META_DATA_FILTERS = [
46
74
  /authorization/i,
@@ -51,6 +79,8 @@ module Bugsnag
51
79
  "rack.request.form_vars"
52
80
  ].freeze
53
81
 
82
+ DEFAULT_MAX_BREADCRUMBS = 25
83
+
54
84
  alias :track_sessions :auto_capture_sessions
55
85
  alias :track_sessions= :auto_capture_sessions=
56
86
 
@@ -62,12 +92,23 @@ module Bugsnag
62
92
  self.send_environment = false
63
93
  self.send_code = true
64
94
  self.meta_data_filters = Set.new(DEFAULT_META_DATA_FILTERS)
65
- self.endpoint = DEFAULT_ENDPOINT
66
95
  self.hostname = default_hostname
67
96
  self.timeout = 15
68
97
  self.notify_release_stages = nil
69
- self.auto_capture_sessions = false
70
- self.session_endpoint = DEFAULT_SESSION_ENDPOINT
98
+ self.auto_capture_sessions = true
99
+
100
+ # All valid breadcrumb types should be allowable initially
101
+ self.enabled_automatic_breadcrumb_types = Bugsnag::Breadcrumbs::VALID_BREADCRUMB_TYPES.dup
102
+ self.before_breadcrumb_callbacks = []
103
+
104
+ # Store max_breadcrumbs here instead of outputting breadcrumbs.max_items
105
+ # to avoid infinite recursion when creating breadcrumb buffer
106
+ @max_breadcrumbs = DEFAULT_MAX_BREADCRUMBS
107
+
108
+ # These are set exclusively using the "set_endpoints" method
109
+ @notify_endpoint = DEFAULT_NOTIFY_ENDPOINT
110
+ @session_endpoint = DEFAULT_SESSION_ENDPOINT
111
+ @enable_sessions = true
71
112
 
72
113
  # SystemExit and SignalException are common Exception types seen with
73
114
  # successful exits and are not automatically reported to Bugsnag
@@ -95,6 +136,7 @@ module Bugsnag
95
136
  self.internal_middleware.use Bugsnag::Middleware::SuggestionData
96
137
  self.internal_middleware.use Bugsnag::Middleware::ClassifyError
97
138
  self.internal_middleware.use Bugsnag::Middleware::SessionData
139
+ self.internal_middleware.use Bugsnag::Middleware::Breadcrumbs
98
140
 
99
141
  self.middleware = Bugsnag::MiddlewareStack.new
100
142
  self.middleware.use Bugsnag::Middleware::Callbacks
@@ -190,6 +232,61 @@ module Bugsnag
190
232
  self.proxy_password = proxy.password
191
233
  end
192
234
 
235
+ ##
236
+ # Sets the maximum allowable amount of breadcrumbs
237
+ #
238
+ # @param [Integer] the new maximum breadcrumb limit
239
+ def max_breadcrumbs=(new_max_breadcrumbs)
240
+ @max_breadcrumbs = new_max_breadcrumbs
241
+ breadcrumbs.max_items = new_max_breadcrumbs
242
+ end
243
+
244
+ ##
245
+ # Returns the breadcrumb circular buffer
246
+ #
247
+ # @return [Bugsnag::Utility::CircularBuffer] a thread based circular buffer containing breadcrumbs
248
+ def breadcrumbs
249
+ request_data[:breadcrumbs] ||= Bugsnag::Utility::CircularBuffer.new(@max_breadcrumbs)
250
+ end
251
+
252
+ # Sets the notification endpoint
253
+ #
254
+ # @param new_notify_endpoint [String] The URL to deliver error notifications to
255
+ #
256
+ # @deprecated Use {#set_endpoints} instead
257
+ def endpoint=(new_notify_endpoint)
258
+ warn("The 'endpoint' configuration option is deprecated. The 'set_endpoints' method should be used instead")
259
+ set_endpoints(new_notify_endpoint, session_endpoint) # Pass the existing session_endpoint through so it doesn't get overwritten
260
+ end
261
+
262
+ ##
263
+ # Sets the sessions endpoint
264
+ #
265
+ # @param new_session_endpoint [String] The URL to deliver session notifications to
266
+ #
267
+ # @deprecated Use {#set_endpoints} instead
268
+ def session_endpoint=(new_session_endpoint)
269
+ warn("The 'session_endpoint' configuration option is deprecated. The 'set_endpoints' method should be used instead")
270
+ set_endpoints(notify_endpoint, new_session_endpoint) # Pass the existing notify_endpoint through so it doesn't get overwritten
271
+ end
272
+
273
+ ##
274
+ # Sets the notification and session endpoints
275
+ #
276
+ # @param new_notify_endpoint [String] The URL to deliver error notifications to
277
+ # @param new_session_endpoint [String] The URL to deliver session notifications to
278
+ def set_endpoints(new_notify_endpoint, new_session_endpoint)
279
+ @notify_endpoint = new_notify_endpoint
280
+ @session_endpoint = new_session_endpoint
281
+ end
282
+
283
+ ##
284
+ # Disables session tracking and delivery. Cannot be undone
285
+ def disable_sessions
286
+ self.auto_capture_sessions = false
287
+ @enable_sessions = false
288
+ end
289
+
193
290
  private
194
291
 
195
292
  PROG_NAME = "[Bugsnag]"
@@ -0,0 +1,132 @@
1
+ require 'mongo'
2
+ require 'bugsnag/breadcrumbs/breadcrumbs'
3
+
4
+ module Bugsnag
5
+ ##
6
+ # Subscribes to, and creates breadcrumbs from, mongo_ruby_driver events
7
+ #
8
+ # @api private
9
+ class MongoBreadcrumbSubscriber
10
+ MONGO_MESSAGE_PREFIX = "Mongo query "
11
+ MONGO_EVENT_PREFIX = "mongo."
12
+ MONGO_COMMAND_KEY = :bugsnag_mongo_commands
13
+ MAX_FILTER_DEPTH = 5
14
+
15
+ ##
16
+ # Listens to the 'started' event, storing the command for later usage
17
+ #
18
+ # @param event [Mongo::Event::Base] the mongo_ruby_driver generated event
19
+ def started(event)
20
+ leave_command(event)
21
+ end
22
+
23
+ ##
24
+ # Listens to the 'succeeded' event, leaving a breadcrumb
25
+ #
26
+ # @param event [Mongo::Event::Base] the mongo_ruby_driver generated event
27
+ def succeeded(event)
28
+ leave_mongo_breadcrumb("succeeded", event)
29
+ end
30
+
31
+ ##
32
+ # Listens to the 'failed' event, leaving a breadcrumb
33
+ #
34
+ # @param event [Mongo::Event::Base] the mongo_ruby_driver generated event
35
+ def failed(event)
36
+ leave_mongo_breadcrumb("failed", event)
37
+ end
38
+
39
+ private
40
+
41
+ ##
42
+ # Generates breadcrumb data from an event
43
+ #
44
+ # @param event_name [String] the type of event
45
+ # @param event [Mongo::Event::Base] the mongo_ruby_driver generated event
46
+ def leave_mongo_breadcrumb(event_name, event)
47
+ message = MONGO_MESSAGE_PREFIX + event_name
48
+ meta_data = {
49
+ :event_name => MONGO_EVENT_PREFIX + event_name,
50
+ :command_name => event.command_name,
51
+ :database_name => event.database_name,
52
+ :operation_id => event.operation_id,
53
+ :request_id => event.request_id,
54
+ :duration => event.duration
55
+ }
56
+ if (command = pop_command(event.request_id))
57
+ collection_key = event.command_name == "getMore" ? "collection" : event.command_name
58
+ meta_data[:collection] = command[collection_key]
59
+ unless command["filter"].nil?
60
+ filter = sanitize_filter_hash(command["filter"])
61
+ meta_data[:filter] = JSON.dump(filter)
62
+ end
63
+ end
64
+ meta_data[:message] = event.message if defined?(event.message)
65
+
66
+ Bugsnag.leave_breadcrumb(message, meta_data, Bugsnag::Breadcrumbs::PROCESS_BREADCRUMB_TYPE, :auto)
67
+ end
68
+
69
+ ##
70
+ # Removes values from filter hashes, replacing them with '?'
71
+ #
72
+ # @param filter_hash [Hash] the filter hash for the mongo transaction
73
+ # @param depth [Integer] the current filter depth
74
+ #
75
+ # @return [Hash] the filtered hash
76
+ def sanitize_filter_hash(filter_hash, depth = 0)
77
+ filter_hash.each_with_object({}) do |(key, value), output|
78
+ output[key] = sanitize_filter_value(value, depth)
79
+ end
80
+ end
81
+
82
+ ##
83
+ # Transforms a value element into a useful, redacted, version
84
+ #
85
+ # @param value [Object] the filter value
86
+ # @param depth [Integer] the current filter depth
87
+ #
88
+ # @return [Array, Hash, String] the sanitized value
89
+ def sanitize_filter_value(value, depth)
90
+ depth += 1
91
+ if depth >= MAX_FILTER_DEPTH
92
+ '[MAX_FILTER_DEPTH_REACHED]'
93
+ elsif value.is_a?(Array)
94
+ value.map { |array_value| sanitize_filter_value(array_value, depth) }
95
+ elsif value.is_a?(Hash)
96
+ sanitize_filter_hash(value, depth)
97
+ else
98
+ '?'
99
+ end
100
+ end
101
+
102
+ ##
103
+ # Stores the mongo command in the request data by the request_id
104
+ #
105
+ # @param event [Mongo::Event::Base] the mongo_ruby_driver generated event
106
+ def leave_command(event)
107
+ event_commands[event.request_id] = event.command
108
+ end
109
+
110
+ ##
111
+ # Removes and retrieves a stored command from the request data
112
+ #
113
+ # @param request_id [String] the id of the mongo_ruby_driver event
114
+ #
115
+ # @return [Hash, nil] the requested command, or nil if not found
116
+ def pop_command(request_id)
117
+ event_commands.delete(request_id)
118
+ end
119
+
120
+ ##
121
+ # Provides access to a thread-based mongo event command hash
122
+ #
123
+ # @return [Hash] the hash of mongo event commands
124
+ def event_commands
125
+ Bugsnag.configuration.request_data[MONGO_COMMAND_KEY] ||= {}
126
+ end
127
+ end
128
+ end
129
+
130
+ ##
131
+ # Add the subscriber to the global Mongo monitoring object
132
+ Mongo::Monitoring::Global.subscribe(Mongo::Monitoring::COMMAND, Bugsnag::MongoBreadcrumbSubscriber.new)
@@ -0,0 +1,118 @@
1
+ require "bugsnag/breadcrumbs/breadcrumbs"
2
+
3
+ module Bugsnag::Rails
4
+ DEFAULT_RAILS_BREADCRUMBS = [
5
+ {
6
+ :id => "perform_action.action_cable",
7
+ :message => "Perform ActionCable",
8
+ :type => Bugsnag::Breadcrumbs::PROCESS_BREADCRUMB_TYPE,
9
+ :allowed_data => [
10
+ :channel_class,
11
+ :action
12
+ ]
13
+ },
14
+ {
15
+ :id => "perform_start.active_job",
16
+ :message => "Start perform ActiveJob",
17
+ :type => Bugsnag::Breadcrumbs::PROCESS_BREADCRUMB_TYPE,
18
+ :allowed_data => []
19
+ },
20
+ {
21
+ :id => "cache_read.active_support",
22
+ :message => "Read cache",
23
+ :type => Bugsnag::Breadcrumbs::PROCESS_BREADCRUMB_TYPE,
24
+ :allowed_data => [
25
+ :key,
26
+ :hit,
27
+ :super_operation
28
+ ]
29
+ },
30
+ {
31
+ :id => "cache_fetch_hit.active_support",
32
+ :message => "Fetch cache hit",
33
+ :type => Bugsnag::Breadcrumbs::PROCESS_BREADCRUMB_TYPE,
34
+ :allowed_data => [
35
+ :key
36
+ ]
37
+ },
38
+ {
39
+ :id => "sql.active_record",
40
+ :message => "ActiveRecord SQL query",
41
+ :type => Bugsnag::Breadcrumbs::PROCESS_BREADCRUMB_TYPE,
42
+ :allowed_data => [
43
+ :name,
44
+ :connection_id,
45
+ :cached
46
+ ]
47
+ },
48
+ {
49
+ :id => "start_processing.action_controller",
50
+ :message => "Controller started processing",
51
+ :type => Bugsnag::Breadcrumbs::REQUEST_BREADCRUMB_TYPE,
52
+ :allowed_data => [
53
+ :controller,
54
+ :action,
55
+ :method,
56
+ :path
57
+ ]
58
+ },
59
+ {
60
+ :id => "process_action.action_controller",
61
+ :message => "Controller action processed",
62
+ :type => Bugsnag::Breadcrumbs::REQUEST_BREADCRUMB_TYPE,
63
+ :allowed_data => [
64
+ :controller,
65
+ :action,
66
+ :method,
67
+ :status,
68
+ :db_runtime
69
+ ]
70
+ },
71
+ {
72
+ :id => "redirect_to.action_controller",
73
+ :message => "Controller redirect",
74
+ :type => Bugsnag::Breadcrumbs::REQUEST_BREADCRUMB_TYPE,
75
+ :allowed_data => [
76
+ :status,
77
+ :location
78
+ ]
79
+ },
80
+ {
81
+ :id => "halted_callback.action_controller",
82
+ :message => "Controller halted via callback",
83
+ :type => Bugsnag::Breadcrumbs::REQUEST_BREADCRUMB_TYPE,
84
+ :allowed_data => [
85
+ :filter
86
+ ]
87
+ },
88
+ {
89
+ :id => "render_template.action_view",
90
+ :message => "ActionView template rendered",
91
+ :type => Bugsnag::Breadcrumbs::REQUEST_BREADCRUMB_TYPE,
92
+ :allowed_data => [
93
+ :identifier,
94
+ :layout
95
+ ]
96
+ },
97
+ {
98
+ :id => "render_partial.action_view",
99
+ :message => "ActionView partial rendered",
100
+ :type => Bugsnag::Breadcrumbs::REQUEST_BREADCRUMB_TYPE,
101
+ :allowed_data => [
102
+ :identifier
103
+ ]
104
+ },
105
+ {
106
+ :id => "deliver.action_mailer",
107
+ :message => "ActionMail delivered",
108
+ :type => Bugsnag::Breadcrumbs::REQUEST_BREADCRUMB_TYPE,
109
+ :allowed_data => [
110
+ :mailer,
111
+ :message_id,
112
+ :from,
113
+ :date,
114
+ :perform_deliveries
115
+ ]
116
+ }
117
+ ]
118
+ end