From b7fae15b6a96f03b12e3ff7cb05cc43d3cd4a4e9 Mon Sep 17 00:00:00 2001 From: Jordan Raine Date: Mon, 10 Jun 2019 07:58:31 -0700 Subject: [PATCH 1/6] Allow vendor_path to be configured MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This allows developers to set the vendor path regular expression, used to determine whether or not a line in the stacktrace appears in the project stacktrace or the full trace. ```ruby Bugsnag.configure do |config| config.vendor_path = /(^(vendor\/|\.bundle\/|extensions\/|private_gems\/))/ end ``` By default, lines within `vendor/` or `.bundle/` are consider “out of project”. This is a good default for most Rails projects but there are other directories we’d also like to ignore. For example, patches to gems or the framework. If left as “in project”, these lines cause multiple issues to be grouped together because the first line in the stacktrace always points to the same patch line. Right now, we’ve side stepped this by reaching into the gem and redefining `Bugsnag::Stacktrace::VENDOR_PATH` but it would be wonderful if this was a configurable option like any other. --- CHANGELOG.md | 7 +++++++ lib/bugsnag/configuration.rb | 11 ++++++++++ lib/bugsnag/stacktrace.rb | 2 +- spec/configuration_spec.rb | 11 ++++++++++ spec/stacktrace_spec.rb | 39 ++++++++++++++++++++++++++++++++++++ 5 files changed, 69 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d651459f4..59138e01a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,13 @@ Changelog ========= +## TBD + +### Enhancements + +* Add option to configure what file paths are included in the project stacktrace (`vendor_path`) + | [#544](https://github.com/bugsnag/bugsnag-ruby/pull/544) + ## 6.11.1 (22 Jan 2019) ### Fixes diff --git a/lib/bugsnag/configuration.rb b/lib/bugsnag/configuration.rb index b51880887..14bdbd873 100644 --- a/lib/bugsnag/configuration.rb +++ b/lib/bugsnag/configuration.rb @@ -63,6 +63,10 @@ class Configuration # @return [Integer] the maximum allowable amount of breadcrumbs per thread attr_reader :max_breadcrumbs + ## + # @return [Regexp] matching file paths within the project + attr_writer :vendor_path + API_KEY_REGEX = /[0-9a-f]{32}/i THREAD_LOCAL_NAME = "bugsnag_req_data" @@ -173,6 +177,13 @@ def should_notify_release_stage? @release_stage.nil? || @notify_release_stages.nil? || @notify_release_stages.include?(@release_stage) end + ## + # Regex used to mark stacktrace lines as within the project. Lines marked + # as "out of project" will only appear in the full trace. + def vendor_path + @vendor_path || Bugsnag::Stacktrace::VENDOR_PATH + end + ## # Tests whether the configured API key is valid. def valid_api_key? diff --git a/lib/bugsnag/stacktrace.rb b/lib/bugsnag/stacktrace.rb index 42a82461d..b9b22769d 100644 --- a/lib/bugsnag/stacktrace.rb +++ b/lib/bugsnag/stacktrace.rb @@ -46,7 +46,7 @@ def initialize(backtrace, configuration) if defined?(@configuration.project_root) && @configuration.project_root.to_s != '' trace_hash[:inProject] = true if file.start_with?(@configuration.project_root.to_s) file.sub!(/#{@configuration.project_root}\//, "") - trace_hash.delete(:inProject) if file.match(VENDOR_PATH) + trace_hash.delete(:inProject) if file.match(@configuration.vendor_path) end diff --git a/spec/configuration_spec.rb b/spec/configuration_spec.rb index aa8cbb08d..d2504878a 100644 --- a/spec/configuration_spec.rb +++ b/spec/configuration_spec.rb @@ -396,4 +396,15 @@ def debug(name, &block) expect(second_array).to eq([1, 2]) end end + + describe "vendor_path" do + it "should have the default vendor path" do + expect(subject.vendor_path).to eq(Bugsnag::Stacktrace::VENDOR_PATH) + end + + it "should have the defined vendor path" do + subject.vendor_path = /foo/ + expect(subject.vendor_path).to eq(/foo/) + end + end end diff --git a/spec/stacktrace_spec.rb b/spec/stacktrace_spec.rb index 57895f2b2..7ad0c8170 100644 --- a/spec/stacktrace_spec.rb +++ b/spec/stacktrace_spec.rb @@ -87,4 +87,43 @@ }) } end + + describe "#vendor_cache" do + let(:configuration) do + configuration = Bugsnag::Configuration.new + configuration.project_root = "/foo/bar" + configuration + end + + let(:backtrace) do + [ + "/foo/bar/app/models/user.rb:1:in `something'", + "/foo/bar/other_vendor/lib/dont.rb:1:in `to_s'", + "/foo/bar/vendor/lib/ignore_me.rb:1:in `to_s'", + "/foo/bar/.bundle/lib/ignore_me.rb:1:in `to_s'", + ] + end + + def out_project_trace(stacktrace) + stacktrace.to_a.map do |trace_line| + trace_line[:file] if !trace_line[:inProject] + end.compact + end + + it "marks vendor/ and .bundle/ as out-project by default" do + stacktrace = Bugsnag::Stacktrace.new(backtrace, configuration) + + expect(out_project_trace(stacktrace)).to eq([ + "vendor/lib/ignore_me.rb", + ".bundle/lib/ignore_me.rb", + ]) + end + + it "allows vendor_path to be configured" do + configuration.vendor_path = /other_vendor\// + stacktrace = Bugsnag::Stacktrace.new(backtrace, configuration) + + expect(out_project_trace(stacktrace)).to eq(["other_vendor/lib/dont.rb"]) + end + end end From ac66e41aaa14e3713d55254f14ae82df481b451a Mon Sep 17 00:00:00 2001 From: Ted Yang Date: Fri, 24 Jan 2020 14:54:14 -0800 Subject: [PATCH 2/6] remove TBD Changelog (will add back later) --- CHANGELOG.md | 7 ------- 1 file changed, 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 59138e01a..d651459f4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,13 +1,6 @@ Changelog ========= -## TBD - -### Enhancements - -* Add option to configure what file paths are included in the project stacktrace (`vendor_path`) - | [#544](https://github.com/bugsnag/bugsnag-ruby/pull/544) - ## 6.11.1 (22 Jan 2019) ### Fixes From 592d92647708e8b793bdba555fef0afc7cb7be34 Mon Sep 17 00:00:00 2001 From: Ted Yang Date: Fri, 24 Jan 2020 15:08:19 -0800 Subject: [PATCH 3/6] 1. Move the `VENDOR_PATH` from Bugsnag::Stacktrace to Bugsnag::Configuration (and rename it to DEFAULT_VENDOR_PATH). 2. Add `attr_accessor :vendor_path` to Bugsnag::Configuration and initialize it with DEFAULT_VENDOR_PATH. --- lib/bugsnag/configuration.rb | 19 ++++++++++--------- lib/bugsnag/stacktrace.rb | 3 --- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/lib/bugsnag/configuration.rb b/lib/bugsnag/configuration.rb index 85620e671..db2ab5748 100644 --- a/lib/bugsnag/configuration.rb +++ b/lib/bugsnag/configuration.rb @@ -64,8 +64,8 @@ class Configuration attr_reader :max_breadcrumbs ## - # @return [Regexp] matching file paths within the project - attr_writer :vendor_path + # @return [Regexp] matching file paths out of project + attr_accessor :vendor_path API_KEY_REGEX = /[0-9a-f]{32}/i THREAD_LOCAL_NAME = "bugsnag_req_data" @@ -85,6 +85,9 @@ class Configuration DEFAULT_MAX_BREADCRUMBS = 25 + # Path to vendored code. Used to mark file paths as out of project. + DEFAULT_VENDOR_PATH = /^(vendor\/|\.bundle\/)/ + alias :track_sessions :auto_capture_sessions alias :track_sessions= :auto_capture_sessions= @@ -129,6 +132,11 @@ def initialize parse_proxy(proxy_uri) end + # Set up vendor_path regex to mark stacktrace file paths as out of project. + # Stacktrace lines that matches regex will be marked as "out of project" + # will only appear in the full trace. + self.vendor_path = DEFAULT_VENDOR_PATH + # Set up logging self.logger = Logger.new(STDOUT) self.logger.level = Logger::INFO @@ -180,13 +188,6 @@ def should_notify_release_stage? @release_stage.nil? || @notify_release_stages.nil? || @notify_release_stages.include?(@release_stage) end - ## - # Regex used to mark stacktrace lines as within the project. Lines marked - # as "out of project" will only appear in the full trace. - def vendor_path - @vendor_path || Bugsnag::Stacktrace::VENDOR_PATH - end - ## # Tests whether the configured API key is valid. def valid_api_key? diff --git a/lib/bugsnag/stacktrace.rb b/lib/bugsnag/stacktrace.rb index b9b22769d..1eb0259e0 100644 --- a/lib/bugsnag/stacktrace.rb +++ b/lib/bugsnag/stacktrace.rb @@ -7,9 +7,6 @@ class Stacktrace # e.g. "org.jruby.Ruby.runScript(Ruby.java:807)" JAVA_BACKTRACE_REGEX = /^(.*)\((.*)(?::([0-9]+))?\)$/ - # Path to vendored code. Used to mark file paths as out of project. - VENDOR_PATH = /^(vendor\/|\.bundle\/)/ - ## # Process a backtrace and the configuration into a parsed stacktrace. def initialize(backtrace, configuration) From a1a9fdea71c2c3a1c6458b082c2cc83c31fb17b8 Mon Sep 17 00:00:00 2001 From: Ted Yang Date: Fri, 24 Jan 2020 15:12:56 -0800 Subject: [PATCH 4/6] Update spec since Bugsnag::Stacktrace::VENDOR_PATH becomes Bugsnag::Configuration::DEFAULT_VENDOR_PATH --- spec/configuration_spec.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/spec/configuration_spec.rb b/spec/configuration_spec.rb index 296a18de7..5db5e5f23 100644 --- a/spec/configuration_spec.rb +++ b/spec/configuration_spec.rb @@ -428,12 +428,12 @@ def debug(name, &block) end end - describe "vendor_path" do - it "should have the default vendor path" do - expect(subject.vendor_path).to eq(Bugsnag::Stacktrace::VENDOR_PATH) + describe "#vendor_path" do + it "returns the default vendor path" do + expect(subject.vendor_path).to eq(Bugsnag::Configuration::DEFAULT_VENDOR_PATH) end - it "should have the defined vendor path" do + it "returns the defined vendor path" do subject.vendor_path = /foo/ expect(subject.vendor_path).to eq(/foo/) end From 02adbb7f921537a667f1782b1e424daed6fb59de Mon Sep 17 00:00:00 2001 From: Ted Yang Date: Fri, 24 Jan 2020 15:24:12 -0800 Subject: [PATCH 5/6] Update specs to be more descriptive --- spec/stacktrace_spec.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/stacktrace_spec.rb b/spec/stacktrace_spec.rb index 7ad0c8170..f17b2dff3 100644 --- a/spec/stacktrace_spec.rb +++ b/spec/stacktrace_spec.rb @@ -88,7 +88,7 @@ } end - describe "#vendor_cache" do + context "with configurable vendor_path" do let(:configuration) do configuration = Bugsnag::Configuration.new configuration.project_root = "/foo/bar" @@ -119,7 +119,7 @@ def out_project_trace(stacktrace) ]) end - it "allows vendor_path to be configured" do + it "allows vendor_path to be configured and filters out backtrace file paths" do configuration.vendor_path = /other_vendor\// stacktrace = Bugsnag::Stacktrace.new(backtrace, configuration) From 379db59a817013df9a6233557da5fbb03f575cb3 Mon Sep 17 00:00:00 2001 From: Ted Yang Date: Fri, 24 Jan 2020 15:29:16 -0800 Subject: [PATCH 6/6] Add Changelog message --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0f2e3f840..e6bf3190b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,13 @@ Changelog ========= +## TBD + +### Enhancements + +* Add configurable `vendor_path` to configure what file paths are out of project stacktrace. + | [#544](https://github.com/bugsnag/bugsnag-ruby/pull/544) + ## 6.12.1 (05 Sep 2019) ### Fixes