Skip to content

Commit

Permalink
Merge d1e5f06 into 9de4e2b
Browse files Browse the repository at this point in the history
  • Loading branch information
Cawllec authored Dec 7, 2018
2 parents 9de4e2b + d1e5f06 commit c448f13
Show file tree
Hide file tree
Showing 3 changed files with 165 additions and 0 deletions.
32 changes: 32 additions & 0 deletions lib/bugsnag/configuration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
require "bugsnag/middleware/suggestion_data"
require "bugsnag/middleware/classify_error"
require "bugsnag/middleware/session_data"
require "bugsnag/utility/circular_buffer"
require "bugsnag/breadcrumbs/breadcrumbs"

module Bugsnag
class Configuration
Expand Down Expand Up @@ -36,6 +38,9 @@ class Configuration
attr_accessor :auto_capture_sessions
attr_accessor :track_sessions
attr_accessor :session_endpoint
attr_accessor :automatic_breadcrumb_types

attr_reader :max_breadcrumbs

API_KEY_REGEX = /[0-9a-f]{32}/i
THREAD_LOCAL_NAME = "bugsnag_req_data"
Expand All @@ -51,6 +56,8 @@ class Configuration
"rack.request.form_vars"
].freeze

DEFAULT_MAX_BREADCRUMBS = 25

alias :track_sessions :auto_capture_sessions
alias :track_sessions= :auto_capture_sessions=

Expand All @@ -68,6 +75,12 @@ def initialize
self.notify_release_stages = nil
self.auto_capture_sessions = false
self.session_endpoint = DEFAULT_SESSION_ENDPOINT
# All valid breadcrumb types should be allowable initially
self.automatic_breadcrumb_types = Bugsnag::Breadcrumbs::VALID_BREADCRUMB_TYPES.clone

# Store max_breadcrumbs here instead of outputting breadcrumbs.max_items
# to avoid infinite recursion when creating breadcrumb buffer
@max_breadcrumbs = DEFAULT_MAX_BREADCRUMBS

# SystemExit and Interrupt are common Exception types seen with successful
# exits and are not automatically reported to Bugsnag
Expand Down Expand Up @@ -190,6 +203,25 @@ def parse_proxy(uri)
self.proxy_password = proxy.password
end

##
# Sets the maximum allowable amount of breadcrumbs
def max_breadcrumbs=(new_max_breadcrumbs)
@max_breadcrumbs = new_max_breadcrumbs
breadcrumbs.max_items = new_max_breadcrumbs
end

##
# Returns the breadcrumb circular buffer
def breadcrumbs
request_data[:breadcrumbs] ||= Bugsnag::Utility::CircularBuffer.new(@max_breadcrumbs)
end

##
# Stores callbacks that will be run before a breadcrumb is left
def before_breadcrumb_callbacks
@before_breadcrumb_callbacks ||= []
end

private

PROG_NAME = "[Bugsnag]"
Expand Down
35 changes: 35 additions & 0 deletions lib/bugsnag/utility/circular_buffer.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
module Bugsnag::Utility
class CircularBuffer
include Enumerable

attr_reader :max_items

def initialize(max_items = 25)
@max_items = max_items
@buffer = []
end

def <<(item)
@buffer << item
trim_buffer
self
end

def each(&block)
@buffer.each(&block)
end

def max_items=(new_max_items)
@max_items = new_max_items
trim_buffer
end

private

def trim_buffer
trim_size = @buffer.size - @max_items
trim_size = 0 if trim_size < 0
@buffer.shift(trim_size)
end
end
end
98 changes: 98 additions & 0 deletions spec/utility/circular_buffer_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
# encoding: utf-8

require 'spec_helper'
require 'bugsnag/utility/circular_buffer'

RSpec.describe Bugsnag::Utility::CircularBuffer do
describe "#initialize" do
it "contains no items" do
buffer = Bugsnag::Utility::CircularBuffer.new

expect(buffer.to_a).to eq([])
end
end

describe "#max_items" do
it "defaults to 25" do
buffer = Bugsnag::Utility::CircularBuffer.new

expect(buffer.max_items).to equal 25
end

it "can be set during #initialize" do
buffer = Bugsnag::Utility::CircularBuffer.new(10)

expect(buffer.max_items).to equal 10
end
end

describe "#max_items=" do
it "changes #max_items" do
buffer = Bugsnag::Utility::CircularBuffer.new(10)
buffer.max_items = 17

expect(buffer.max_items).to equal(17)
end

it "shifts any excess items when reduced" do
buffer = Bugsnag::Utility::CircularBuffer.new(10)
(0...10).each { |x| buffer << x }
buffer.max_items = 3

expect(buffer.to_a).to eq([7, 8, 9])
end

it "increases the maximum capacity" do
buffer = Bugsnag::Utility::CircularBuffer.new(3)
buffer << 1
buffer << 2
buffer << 3

expect(buffer.to_a).to eq([1, 2, 3])

buffer.max_items = 5
buffer << 4
buffer << 5

expect(buffer.to_a).to eq([1, 2, 3, 4, 5])
end
end

describe "#<<" do
it "adds items to the buffer" do
buffer = Bugsnag::Utility::CircularBuffer.new
buffer << 1
expect(buffer.to_a).to eq([1])
end

it "shifts items it #max_items is exceeded" do
buffer = Bugsnag::Utility::CircularBuffer.new(5)
(0...10).each { |x| buffer << x }

expect(buffer.to_a).to eq([5, 6, 7, 8, 9])
end

it "can be chained" do
buffer = Bugsnag::Utility::CircularBuffer.new
buffer << 1 << 2 << 3 << 4 << 5

expect(buffer.to_a).to eq([1, 2, 3, 4, 5])
end
end

describe "#each" do
it "can be iterated over" do
buffer = Bugsnag::Utility::CircularBuffer.new
buffer << 1
buffer << 2
buffer << 3

output = []
buffer.each do |x|
output << x
end

expect(output).to eq([1, 2, 3])
end
end
end

0 comments on commit c448f13

Please sign in to comment.