From 5f98c68ce2ab608df282762ada1aabecf80244be Mon Sep 17 00:00:00 2001 From: Taylor Lodge Date: Wed, 20 Feb 2019 16:42:43 +1300 Subject: [PATCH 1/7] Add size method to Breadcrumb This calculates a rough size of the Breadcrumb, message length + 100. Assuming all the other fields roughly come out to 100 characters on average. The primary failing of this is that the metadata could be much larger, but calculating the size of the metadata could be costly. This handles the usecase needed by Vydia --- lib/raygun/breadcrumbs/breadcrumb.rb | 4 +++ spec/raygun/breadcrumbs/breadcrumb_spec.rb | 37 ++++++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/lib/raygun/breadcrumbs/breadcrumb.rb b/lib/raygun/breadcrumbs/breadcrumb.rb index 8395805..06f1ad8 100644 --- a/lib/raygun/breadcrumbs/breadcrumb.rb +++ b/lib/raygun/breadcrumbs/breadcrumb.rb @@ -25,6 +25,10 @@ def build_payload v != nil end] end + + def size + return message.length + 100 + end end end end diff --git a/spec/raygun/breadcrumbs/breadcrumb_spec.rb b/spec/raygun/breadcrumbs/breadcrumb_spec.rb index 67861b0..3f517aa 100644 --- a/spec/raygun/breadcrumbs/breadcrumb_spec.rb +++ b/spec/raygun/breadcrumbs/breadcrumb_spec.rb @@ -129,6 +129,43 @@ module Breadcrumbs expect(payload[:CustomData]).to eq(foo: 'bar') end end + + describe "#size" do + before do + Timecop.freeze + Store.initialize + end + after do + Timecop.return + Store.clear + end + + let(:message) { "This is a breadcrumb message" } + + let(:breadcrumb) do + Store.record( + message: message, + category: "test", + level: :info, + class_name: "HomeController", + method_name: "index", + line_number: 17, + metadata: { + foo: 'bar' + } + ) + + Store.stored[0] + end + + let(:size) { breadcrumb.size } + + it "returns the estimated size of the breadcrumb" do + # Can't check all the fields but message so assume a standard 100 length for all of them + # The message should be the bulk of large breadcrumbs anyway + expect(size).to eq(message.length + 100) + end + end end end end From 7999a4eca94e4f0d4ff8c6bff09365ce7bc9a2a9 Mon Sep 17 00:00:00 2001 From: Taylor Lodge Date: Thu, 21 Feb 2019 08:42:05 +1300 Subject: [PATCH 2/7] Keep a maximum of 100KB of the most recent breadcrumbs --- lib/raygun/client.rb | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/lib/raygun/client.rb b/lib/raygun/client.rb index 24a023a..d61364e 100644 --- a/lib/raygun/client.rb +++ b/lib/raygun/client.rb @@ -5,6 +5,7 @@ class Client ENV_IP_ADDRESS_KEYS = %w(action_dispatch.remote_ip raygun.remote_ip REMOTE_ADDR) NO_API_KEY_MESSAGE = "[RAYGUN] Just a note, you've got no API Key configured, which means we can't report exceptions. Specify your Raygun API key using Raygun#setup (find yours at https://app.raygun.io)" + MAX_BREADCRUMBS_SIZE = 100_000 include HTTParty @@ -214,7 +215,13 @@ def build_payload_hash(exception_instance, env = {}, user = nil) } } store = ::Raygun::Breadcrumbs::Store - error_details[:breadcrumbs] = store.stored.map(&:build_payload) if store.any? + breadcrumb_size = 0 + breadcrumbs_to_keep = store.stored.reverse.take_while do |crumb| + breadcrumb_size += crumb.size + + breadcrumb_size < MAX_BREADCRUMBS_SIZE + end.reverse + error_details[:breadcrumbs] = breadcrumbs_to_keep.map(&:build_payload) if store.any? Raygun.log('set details and breadcrumbs') From dbbc44f3f81cd44ad0d77739c7d4fa3ee756e24a Mon Sep 17 00:00:00 2001 From: Taylor Lodge Date: Thu, 21 Feb 2019 08:57:00 +1300 Subject: [PATCH 3/7] Add take_until_size method to Breadcrumbs::Store --- lib/raygun/breadcrumbs/store.rb | 10 ++++++++++ spec/raygun/breadcrumbs/store_spec.rb | 24 ++++++++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/lib/raygun/breadcrumbs/store.rb b/lib/raygun/breadcrumbs/store.rb index 3f1381d..505cd2f 100644 --- a/lib/raygun/breadcrumbs/store.rb +++ b/lib/raygun/breadcrumbs/store.rb @@ -47,6 +47,16 @@ def self.any? stored != nil && stored.length > 0 end + def self.take_until_size(size) + breadcrumb_size = 0 + + stored.reverse.take_while do |crumb| + breadcrumb_size += crumb.size + + breadcrumb_size < size + end.reverse + end + private def self.should_record?(crumb) diff --git a/spec/raygun/breadcrumbs/store_spec.rb b/spec/raygun/breadcrumbs/store_spec.rb index 7a9ce77..d3d457b 100644 --- a/spec/raygun/breadcrumbs/store_spec.rb +++ b/spec/raygun/breadcrumbs/store_spec.rb @@ -67,6 +67,30 @@ module Breadcrumbs end end + describe "#take_until_size" do + before do + subject.initialize + end + + it "takes the most recent breadcrumbs until the size limit is reached" do + subject.record(message: '1' * 100) + subject.record(message: '2' * 100) + subject.record(message: '3' * 100) + + crumbs = subject.take_until_size(500) + + expect(crumbs.length).to eq(2) + expect(crumbs[0].message).to eq('2' * 100) + expect(crumbs[1].message).to eq('3' * 100) + end + + it "does not crash with no recorded breadcrumbs" do + crumbs = subject.take_until_size(500) + + expect(crumbs).to eq([]) + end + end + context "adding a breadcrumb" do class Foo include ::Raygun::Breadcrumbs From 5511afa1d5c941aa53f08770cfde214afc45f74d Mon Sep 17 00:00:00 2001 From: Taylor Lodge Date: Thu, 21 Feb 2019 09:23:22 +1300 Subject: [PATCH 4/7] Update client to use take_until_size --- lib/raygun/client.rb | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/lib/raygun/client.rb b/lib/raygun/client.rb index d61364e..3c09b4a 100644 --- a/lib/raygun/client.rb +++ b/lib/raygun/client.rb @@ -215,13 +215,7 @@ def build_payload_hash(exception_instance, env = {}, user = nil) } } store = ::Raygun::Breadcrumbs::Store - breadcrumb_size = 0 - breadcrumbs_to_keep = store.stored.reverse.take_while do |crumb| - breadcrumb_size += crumb.size - - breadcrumb_size < MAX_BREADCRUMBS_SIZE - end.reverse - error_details[:breadcrumbs] = breadcrumbs_to_keep.map(&:build_payload) if store.any? + error_details[:breadcrumbs] = store.take_until_size(MAX_BREADCRUMBS_SIZE).map(&:build_payload) if store.any? Raygun.log('set details and breadcrumbs') From fc864b15164690db4ad2f56f9514d17cec0f5219 Mon Sep 17 00:00:00 2001 From: Taylor Lodge Date: Thu, 21 Feb 2019 09:26:20 +1300 Subject: [PATCH 5/7] Clear breadcrumbs during failsafe send --- lib/raygun.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/raygun.rb b/lib/raygun.rb index 0c21fc8..3c1aab8 100644 --- a/lib/raygun.rb +++ b/lib/raygun.rb @@ -152,6 +152,8 @@ def track_exception_sync(exception_instance, env, user, retry_count) env[:custom_data] ||= {} env[:custom_data].merge!(original_stacktrace: exception_instance.backtrace) + ::Raygun::Breadcrumbs::Store.clear + track_exception(new_exception, env, user, retry_count - 1) else raise e From 1c0fbbf048065b977489d097bee80d3dcecc1259 Mon Sep 17 00:00:00 2001 From: Taylor Lodge Date: Thu, 21 Feb 2019 09:33:23 +1300 Subject: [PATCH 6/7] Update gemspec to fix sqlite test error --- raygun4ruby.gemspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/raygun4ruby.gemspec b/raygun4ruby.gemspec index 66b173b..9f8f16d 100644 --- a/raygun4ruby.gemspec +++ b/raygun4ruby.gemspec @@ -37,7 +37,7 @@ Gem::Specification.new do |spec| spec.add_development_dependency "webmock" spec.add_development_dependency 'rails', "= 5.2" - spec.add_development_dependency 'sqlite3' + spec.add_development_dependency 'sqlite3', '~> 1.3.6' spec.add_development_dependency 'capybara' spec.add_development_dependency "rspec-rails" spec.add_development_dependency "launchy" From fda0d45fb19ff9f57ca5ab9df8436446d77da959 Mon Sep 17 00:00:00 2001 From: Taylor Lodge Date: Thu, 21 Feb 2019 09:40:47 +1300 Subject: [PATCH 7/7] Remove 'pry' import Fixes #145 --- lib/raygun.rb | 5 ----- 1 file changed, 5 deletions(-) diff --git a/lib/raygun.rb b/lib/raygun.rb index 3c1aab8..ec85912 100644 --- a/lib/raygun.rb +++ b/lib/raygun.rb @@ -6,11 +6,6 @@ require "rack" require "ostruct" -begin - require "pry" -rescue LoadError -end - require "raygun/version" require "raygun/configuration" require "raygun/client"