From dd17b327a7b699e997e74ddc5dc510855f5cb97b Mon Sep 17 00:00:00 2001 From: Yohei Kitamura Date: Thu, 4 May 2023 19:18:29 -0400 Subject: [PATCH] Expose Lorekeeper::BacktraceCleaner (#37) --- CHANGELOG.md | 3 + README.md | 10 +- lib/lorekeeper.rb | 1 + lib/lorekeeper/backtrace_cleaner.rb | 61 ++++++++ lib/lorekeeper/json_logger.rb | 44 +----- lib/lorekeeper/version.rb | 2 +- spec/lib/lorekeeper/backtrace_cleaner_spec.rb | 139 ++++++++++++++++++ spec/lib/lorekeeper/json_logger_spec.rb | 126 +--------------- 8 files changed, 216 insertions(+), 170 deletions(-) create mode 100644 lib/lorekeeper/backtrace_cleaner.rb create mode 100644 spec/lib/lorekeeper/backtrace_cleaner_spec.rb diff --git a/CHANGELOG.md b/CHANGELOG.md index 49a9c5a..10b2f28 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +# 2.6.0 +* Expose Lorekeeper::BacktraceCleaner + # 2.5.0 * Update the backtrace cleaner in JSONLogger to remove web server and stdlib lines, and to strip the Rails.root prefix diff --git a/README.md b/README.md index f535f6f..e017dcb 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ When used without extra fields it outputs 20% faster than the standard Logger fo Add this line to your application's Gemfile: ```ruby -gem 'lorekeeper', '~> 1.7' +gem 'lorekeeper', '~> 2.0' ``` And then execute: @@ -210,6 +210,14 @@ end ``` +### Backtrace Cleaner + +The backtrace cleaner can be used independently: + +```ruby +Lorekeeper::BacktraceCleaner.instance.clean(backtrace) +``` + ## License diff --git a/lib/lorekeeper.rb b/lib/lorekeeper.rb index 3e9e79f..256e705 100644 --- a/lib/lorekeeper.rb +++ b/lib/lorekeeper.rb @@ -1,6 +1,7 @@ # frozen_string_literal: true require 'lorekeeper/version' +require 'lorekeeper/backtrace_cleaner' require 'lorekeeper/fast_logger' require 'lorekeeper/simple_logger' require 'lorekeeper/json_logger' diff --git a/lib/lorekeeper/backtrace_cleaner.rb b/lib/lorekeeper/backtrace_cleaner.rb new file mode 100644 index 0000000..e892341 --- /dev/null +++ b/lib/lorekeeper/backtrace_cleaner.rb @@ -0,0 +1,61 @@ +# frozen_string_literal: true + +require 'singleton' + +module Lorekeeper + class BacktraceCleaner + include Singleton + + def initialize + @backtrace_cleaner = set_backtrace_cleaner + @rails_root = defined?(Rails.root) ? Rails.root.to_s : nil + @rails_root_size = @rails_root.to_s.size + @gem_path = defined?(Gem.path) ? Gem.path : [] + @denylisted_fingerprint = denylisted_fingerprint + end + + def clean(backtrace) + backtrace = filter_rails_root_backtrace(backtrace) + @backtrace_cleaner&.clean(backtrace) || backtrace + end + + private + + DENYLISTED_FINGERPRINT = + %r{newrelic_rpm|active_support/callbacks.rb|zipkin-tracer|puma|phusion_passenger|opentelemetry}.freeze + + def denylisted_fingerprint + return DENYLISTED_FINGERPRINT unless ENV.key?('LOREKEEPER_DENYLIST') + + /#{ENV.fetch('LOREKEEPER_DENYLIST').split(',').map(&:strip).join('|')}/ + end + + def filter_rails_root_backtrace(backtrace) + return backtrace unless @rails_root + + last_index = nil + result = [] + backtrace.each_with_index do |line, idx| + if line.start_with?(@rails_root) && @gem_path.none? { |path| line.start_with?(path) } + result << line[@rails_root_size..] + last_index = idx + else + result << line + end + end + + last_index ? result[..last_index] : result + end + + def set_backtrace_cleaner + return nil unless defined?(ActiveSupport::BacktraceCleaner) + + cleaner = ActiveSupport::BacktraceCleaner.new + cleaner.remove_silencers! + cleaner.add_silencer do |line| + line.match?(@denylisted_fingerprint) || line.start_with?(RbConfig::CONFIG['rubylibdir']) + end + cleaner + end + end +end diff --git a/lib/lorekeeper/json_logger.rb b/lib/lorekeeper/json_logger.rb index 51348dc..183fe9b 100644 --- a/lib/lorekeeper/json_logger.rb +++ b/lib/lorekeeper/json_logger.rb @@ -9,11 +9,6 @@ class JSONLogger < FastLogger def initialize(file) reset_state @base_fields = { TIMESTAMP => '', MESSAGE => '', LEVEL => '' } - @backtrace_cleaner = set_backtrace_cleaner - @rails_root = defined?(Rails.root) ? Rails.root.to_s : nil - @rails_root_size = @rails_root.to_s.size - @gem_path = defined?(Gem.path) ? Gem.path : [] - @denylisted_fingerprint = denylisted_fingerprint super(file) end @@ -121,36 +116,7 @@ def json_message(message) # Cleaner defaults to newrelic, active_support/callbacks, zipkin-tracer, opentelemetry, web servers, # and stdlib now but can be configured by using LOREKEEPER_DENYLIST env var. def clean_backtrace(backtrace) - backtrace = filter_rails_root_backtrace(backtrace) - @backtrace_cleaner&.clean(backtrace) || backtrace - end - - def filter_rails_root_backtrace(backtrace) - return backtrace unless @rails_root - - last_index = nil - result = [] - backtrace.each_with_index do |line, idx| - if line.start_with?(@rails_root) && @gem_path.none? { |path| line.start_with?(path) } - result << line[@rails_root_size..] - last_index = idx - else - result << line - end - end - - last_index ? result[..last_index] : result - end - - def set_backtrace_cleaner - return nil unless defined?(ActiveSupport::BacktraceCleaner) - - cleaner = ActiveSupport::BacktraceCleaner.new - cleaner.remove_silencers! - cleaner.add_silencer do |line| - line.match?(@denylisted_fingerprint) || line.start_with?(RbConfig::CONFIG['rubylibdir']) - end - cleaner + Lorekeeper::BacktraceCleaner.instance.clean(backtrace) end THREAD_KEY = 'lorekeeper_jsonlogger_key' # Shared by all threads but unique by thread @@ -161,14 +127,6 @@ def set_backtrace_cleaner EXCEPTION = 'exception' STACK = 'stack' DATA = 'data' - DENYLISTED_FINGERPRINT = - %r{newrelic_rpm|active_support/callbacks.rb|zipkin-tracer|puma|phusion_passenger|opentelemetry}.freeze - - def denylisted_fingerprint - return DENYLISTED_FINGERPRINT unless ENV.key?('LOREKEEPER_DENYLIST') - - /#{ENV.fetch('LOREKEEPER_DENYLIST').split(',').map(&:strip).join('|')}/ - end def with_extra_fields(fields) state[:extra_fields] = fields diff --git a/lib/lorekeeper/version.rb b/lib/lorekeeper/version.rb index 40cb32b..2e37213 100644 --- a/lib/lorekeeper/version.rb +++ b/lib/lorekeeper/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true module Lorekeeper - VERSION = '2.5.0' + VERSION = '2.6.0' end diff --git a/spec/lib/lorekeeper/backtrace_cleaner_spec.rb b/spec/lib/lorekeeper/backtrace_cleaner_spec.rb new file mode 100644 index 0000000..d7faa2d --- /dev/null +++ b/spec/lib/lorekeeper/backtrace_cleaner_spec.rb @@ -0,0 +1,139 @@ +# frozen_string_literal: true + +require 'spec_helper' +require 'active_support' + +RSpec.describe Lorekeeper do + describe Lorekeeper::BacktraceCleaner do + let(:instance) { described_class.instance } + + around(:example) do |ex| + described_class.instance_variable_set(:@singleton__instance__, nil) + ex.run + described_class.instance_variable_set(:@singleton__instance__, nil) + end + + describe 'clean' do + let(:new_backtrace) do + [ + "/home/app/web/app/controllers/api/v2/users_controller.rb:39:in `show'", + "/ruby/2.5.0/gems/activesupport-4.2.11/lib/active_support/callbacks.rb:121:in `instance_exec'", + "/ruby/2.5.0/gems/activesupport-4.2.11/lib/active_support/callbacks.rb:121:in `block in run_callbacks'", + "/ruby/2.5.0/gems/newrelic_rpm-5.7.0.350/lib/new_relic/agent/instrumentation/middleware_tracing.rb:92:in + `call'", + "/ruby/2.5.0/gems/actionpack-4.2.11/lib/action_dispatch/middleware/cookies.rb:560:in `call'", + '/ruby/2.5.0/gems/newrelic_rpm-5.7.0.350/lib/new_relic/agent/instrumentation/middleware_tracing.rb' \ + ":92:in`call'", + "/ruby/2.5.0/gems/actionpack-4.2.11/lib/action_dispatch/middleware/callbacks.rb:29:in `block in call'", + "/ruby/2.5.0/gems/actionpack-4.2.11/lib/action_dispatch/middleware/callbacks.rb:27:in `call'", + '/ruby/2.5.0/gems/newrelic_rpm-5.7.0.350/lib/new_relic/agent/instrumentation/middleware_tracing.rb' \ + ":92:in `call'", + "/usr/local/rvm/rubies/ruby-2.7.6/lib/ruby/2.7.0/benchmark.rb:308:in `realtime'", + '/ruby/2.5.0/gems/zipkin-tracer-0.47.3/lib/zipkin-tracer/rack/zipkin-tracer.rb:29' \ + ":in `block (3 levels) in call'", + "/ruby/2.5.0/gems/zipkin-tracer-0.47.3/lib/zipkin-tracer/rack/zipkin-tracer.rb:51:in `trace!'", + '/ruby/2.5.0/gems/zipkin-tracer-0.47.3/lib/zipkin-tracer/rack/zipkin-tracer.rb:29' \ + ":in `block (2 levels) incall'", + "/ruby/2.5.0/gems/zipkin-tracer-0.47.3/lib/zipkin-tracer/zipkin_sender_base.rb:17:in `with_new_span'", + "/ruby/2.5.0/gems/zipkin-tracer-0.47.3/lib/zipkin-tracer/rack/zipkin-tracer.rb:27:in `block in call'", + "/ruby/2.5.0/gems/puma-5.3.2/lib/puma/configuration.rb:249:in `call'", + "/usr/lib/ruby/vendor_ruby/phusion_passenger/rack/thread_handler_extension.rb:107:in `process_request'", + "/ruby/2.5.0/gems/opentelemetry-api-1.0.1/lib/opentelemetry/trace/tracer.rb:29:in `block in in_span'", + "/home/app/web/app/controllers/api/v2/users_controller.rb:39:in `show'", + "/ruby/2.5.0/gems/actionpack-4.2.11/lib/action_dispatch/middleware/callbacks.rb:29:in `block in call'", + "/ruby/2.5.0/gems/actionpack-4.2.11/lib/action_dispatch/middleware/callbacks.rb:27:in `call'", + "/home/app/web/vendor/bundle/ruby/2.7.0/bin/rake:25:in `load'" + ] + end + + before do + allow(Gem).to receive(:path).and_return(['/ruby/2.5.0', '/home/app/web/vendor/bundle/ruby/2.7.0']) + stub_const('RbConfig::CONFIG', { 'rubylibdir' => '/usr/local/rvm/rubies/ruby-2.7.6/lib/ruby/2.7.0' }) + stub_const('Rails', double(root: '/home/app/web')) + end + + context 'Logging just an exception' do + let(:active_support_exception_v6) do + [ + "/app/controllers/api/v2/users_controller.rb:39:in `show'", + "actionpack (4.2.11) lib/action_dispatch/middleware/cookies.rb:560:in `call'", + "actionpack (4.2.11) lib/action_dispatch/middleware/callbacks.rb:29:in `block in call'", + "actionpack (4.2.11) lib/action_dispatch/middleware/callbacks.rb:27:in `call'", + "/app/controllers/api/v2/users_controller.rb:39:in `show'" + ] + end + let(:active_support_exception_less_than_v6) do + [ + "/app/controllers/api/v2/users_controller.rb:39:in `show'", + "/ruby/2.5.0/gems/actionpack-4.2.11/lib/action_dispatch/middleware/cookies.rb:560:in `call'", + "/ruby/2.5.0/gems/actionpack-4.2.11/lib/action_dispatch/middleware/callbacks.rb:29:in `block in call'", + "/ruby/2.5.0/gems/actionpack-4.2.11/lib/action_dispatch/middleware/callbacks.rb:27:in `call'", + "/app/controllers/api/v2/users_controller.rb:39:in `show'" + ] + end + let(:no_noise_backtrace) do + ActiveSupport::VERSION::MAJOR < 6 ? active_support_exception_less_than_v6 : active_support_exception_v6 + end + + it 'Does not log the lines matched with the denylist' do + expect(instance.clean(new_backtrace)).to eq(no_noise_backtrace) + end + + it 'Logs all backtraces when ActiveSupport::BacktraceCleaner and Rails.root are not defined' do + hide_const('ActiveSupport::BacktraceCleaner') + hide_const('Rails') + + expect(instance.clean(new_backtrace)).to eq(new_backtrace) + end + + it 'drops backtrace lines after the last line of Rails app logs' do + hide_const('ActiveSupport::BacktraceCleaner') + + expect(instance.clean([ + "/ruby/2.5.0/gems/activesupport-4.2.11/lib/active_support/callbacks.rb:121:in `instance_exec'", + "/home/app/web/app/controllers/api/v2/users_controller.rb:39:in `show'", + "/ruby/2.5.0/gems/actionpack-4.2.11/lib/action_dispatch/middleware/callbacks.rb:27:in `call'", + "/home/app/web/vendor/bundle/ruby/2.7.0/bin/rake:25:in `load'" + ])).to eq([ + "/ruby/2.5.0/gems/activesupport-4.2.11/lib/active_support/callbacks.rb:121:in `instance_exec'", + "/app/controllers/api/v2/users_controller.rb:39:in `show'" + ]) + end + + context 'with LOREKEEPER_DENYLIST env var' do + before do + allow(ENV).to receive(:key?).with('LOREKEEPER_DENYLIST').and_return(true) + allow(ENV).to receive(:fetch).with('LOREKEEPER_DENYLIST').and_return(lorekeeper_denylist) + end + let(:lorekeeper_denylist) { 'newrelic_rpm, active_support/callbacks.rb, zipkin-tracer, puma' } + let(:active_support_exception_v6) do + [ + "/app/controllers/api/v2/users_controller.rb:39:in `show'", + "actionpack (4.2.11) lib/action_dispatch/middleware/cookies.rb:560:in `call'", + "actionpack (4.2.11) lib/action_dispatch/middleware/callbacks.rb:29:in `block in call'", + "actionpack (4.2.11) lib/action_dispatch/middleware/callbacks.rb:27:in `call'", + "/usr/lib/ruby/vendor_ruby/phusion_passenger/rack/thread_handler_extension.rb:107:in `process_request'", + "opentelemetry-api (1.0.1) lib/opentelemetry/trace/tracer.rb:29:in `block in in_span'", + "/app/controllers/api/v2/users_controller.rb:39:in `show'" + ] + end + let(:active_support_exception_less_than_v6) do + [ + "/app/controllers/api/v2/users_controller.rb:39:in `show'", + "/ruby/2.5.0/gems/actionpack-4.2.11/lib/action_dispatch/middleware/cookies.rb:560:in `call'", + "/ruby/2.5.0/gems/actionpack-4.2.11/lib/action_dispatch/middleware/callbacks.rb:29:in `block in call'", + "/ruby/2.5.0/gems/actionpack-4.2.11/lib/action_dispatch/middleware/callbacks.rb:27:in `call'", + "/usr/lib/ruby/vendor_ruby/phusion_passenger/rack/thread_handler_extension.rb:107:in `process_request'", + "/ruby/2.5.0/gems/opentelemetry-api-1.0.1/lib/opentelemetry/trace/tracer.rb:29:in `block in in_span'", + "/app/controllers/api/v2/users_controller.rb:39:in `show'" + ] + end + + it 'Does not log the lines matched with the denylist' do + expect(instance.clean(new_backtrace)).to eq(no_noise_backtrace) + end + end + end + end + end +end diff --git a/spec/lib/lorekeeper/json_logger_spec.rb b/spec/lib/lorekeeper/json_logger_spec.rb index a5ab65f..90850a3 100644 --- a/spec/lib/lorekeeper/json_logger_spec.rb +++ b/spec/lib/lorekeeper/json_logger_spec.rb @@ -2,7 +2,6 @@ require 'spec_helper' require 'json' -require 'active_support' RSpec.describe Lorekeeper do describe Lorekeeper::JSONLogger do @@ -72,7 +71,7 @@ let(:exception_msg) { 'This is an exception' } let(:exception) { StandardError.new(exception_msg) } let(:expected) { base_message.merge(exception_data) } - let(:backtrace) { ['First line', 'Second line'] } + let(:backtrace) { ['First line', 'Second line', 'zipkin-tracer', 'opentelemetry'] } let(:stack) { ['First line', 'Second line'] } let(:exception_data) do base_message.merge( @@ -82,68 +81,12 @@ ) .merge(error_level) end - let(:new_backtrace) do - [ - "/home/app/web/app/controllers/api/v2/users_controller.rb:39:in `show'", - "/ruby/2.5.0/gems/activesupport-4.2.11/lib/active_support/callbacks.rb:121:in `instance_exec'", - "/ruby/2.5.0/gems/activesupport-4.2.11/lib/active_support/callbacks.rb:121:in `block in run_callbacks'", - "/ruby/2.5.0/gems/newrelic_rpm-5.7.0.350/lib/new_relic/agent/instrumentation/middleware_tracing.rb:92:in - `call'", - "/ruby/2.5.0/gems/actionpack-4.2.11/lib/action_dispatch/middleware/cookies.rb:560:in `call'", - '/ruby/2.5.0/gems/newrelic_rpm-5.7.0.350/lib/new_relic/agent/instrumentation/middleware_tracing.rb' \ - ":92:in`call'", - "/ruby/2.5.0/gems/actionpack-4.2.11/lib/action_dispatch/middleware/callbacks.rb:29:in `block in call'", - "/ruby/2.5.0/gems/actionpack-4.2.11/lib/action_dispatch/middleware/callbacks.rb:27:in `call'", - '/ruby/2.5.0/gems/newrelic_rpm-5.7.0.350/lib/new_relic/agent/instrumentation/middleware_tracing.rb' \ - ":92:in `call'", - "/usr/local/rvm/rubies/ruby-2.7.6/lib/ruby/2.7.0/benchmark.rb:308:in `realtime'", - '/ruby/2.5.0/gems/zipkin-tracer-0.47.3/lib/zipkin-tracer/rack/zipkin-tracer.rb:29' \ - ":in `block (3 levels) in call'", - "/ruby/2.5.0/gems/zipkin-tracer-0.47.3/lib/zipkin-tracer/rack/zipkin-tracer.rb:51:in `trace!'", - '/ruby/2.5.0/gems/zipkin-tracer-0.47.3/lib/zipkin-tracer/rack/zipkin-tracer.rb:29' \ - ":in `block (2 levels) incall'", - "/ruby/2.5.0/gems/zipkin-tracer-0.47.3/lib/zipkin-tracer/zipkin_sender_base.rb:17:in `with_new_span'", - "/ruby/2.5.0/gems/zipkin-tracer-0.47.3/lib/zipkin-tracer/rack/zipkin-tracer.rb:27:in `block in call'", - "/ruby/2.5.0/gems/puma-5.3.2/lib/puma/configuration.rb:249:in `call'", - "/usr/lib/ruby/vendor_ruby/phusion_passenger/rack/thread_handler_extension.rb:107:in `process_request'", - "/ruby/2.5.0/gems/opentelemetry-api-1.0.1/lib/opentelemetry/trace/tracer.rb:29:in `block in in_span'", - "/home/app/web/app/controllers/api/v2/users_controller.rb:39:in `show'", - "/ruby/2.5.0/gems/actionpack-4.2.11/lib/action_dispatch/middleware/callbacks.rb:29:in `block in call'", - "/ruby/2.5.0/gems/actionpack-4.2.11/lib/action_dispatch/middleware/callbacks.rb:27:in `call'", - "/home/app/web/vendor/bundle/ruby/2.7.0/bin/rake:25:in `load'" - ] - end before do exception.set_backtrace(backtrace) - allow(Gem).to receive(:path).and_return(['/ruby/2.5.0', '/home/app/web/vendor/bundle/ruby/2.7.0']) - stub_const('RbConfig::CONFIG', { 'rubylibdir' => '/usr/local/rvm/rubies/ruby-2.7.6/lib/ruby/2.7.0' }) - stub_const('Rails', double(root: '/home/app/web')) end context 'Logging just an exception' do - let(:active_support_exception_v6) do - [ - "/app/controllers/api/v2/users_controller.rb:39:in `show'", - "actionpack (4.2.11) lib/action_dispatch/middleware/cookies.rb:560:in `call'", - "actionpack (4.2.11) lib/action_dispatch/middleware/callbacks.rb:29:in `block in call'", - "actionpack (4.2.11) lib/action_dispatch/middleware/callbacks.rb:27:in `call'", - "/app/controllers/api/v2/users_controller.rb:39:in `show'" - ] - end - let(:active_support_exception_less_than_v6) do - [ - "/app/controllers/api/v2/users_controller.rb:39:in `show'", - "/ruby/2.5.0/gems/actionpack-4.2.11/lib/action_dispatch/middleware/cookies.rb:560:in `call'", - "/ruby/2.5.0/gems/actionpack-4.2.11/lib/action_dispatch/middleware/callbacks.rb:29:in `block in call'", - "/ruby/2.5.0/gems/actionpack-4.2.11/lib/action_dispatch/middleware/callbacks.rb:27:in `call'", - "/app/controllers/api/v2/users_controller.rb:39:in `show'" - ] - end - let(:no_noise_backtrace) do - ActiveSupport::VERSION::MAJOR < 6 ? active_support_exception_less_than_v6 : active_support_exception_v6 - end - it 'Falls back to ERROR if if the specified level is not recognized' do logger.exception(exception, nil, nil, :critical) expect(io.received_message).to eq(exception_data) @@ -173,73 +116,6 @@ base_message.merge('level' => 'info') ]) end - - it 'Does not log the lines matched with the denylist' do - exception.set_backtrace(new_backtrace) - logger.exception(exception) - expect(io.received_message).to eq(exception_data.merge('stack' => no_noise_backtrace)) - end - - it 'Logs all backtraces when ActiveSupport::BacktraceCleaner and Rails.root are not defined' do - hide_const('ActiveSupport::BacktraceCleaner') - hide_const('Rails') - - exception.set_backtrace(new_backtrace) - logger.exception(exception) - expect(io.received_message).to eq(exception_data.merge('stack' => new_backtrace)) - end - - it 'drops backtrace lines after the last line of Rails app logs' do - hide_const('ActiveSupport::BacktraceCleaner') - - exception.set_backtrace([ - "/ruby/2.5.0/gems/activesupport-4.2.11/lib/active_support/callbacks.rb:121:in `instance_exec'", - "/home/app/web/app/controllers/api/v2/users_controller.rb:39:in `show'", - "/ruby/2.5.0/gems/actionpack-4.2.11/lib/action_dispatch/middleware/callbacks.rb:27:in `call'", - "/home/app/web/vendor/bundle/ruby/2.7.0/bin/rake:25:in `load'" - ]) - logger.exception(exception) - expect(io.received_message).to eq(exception_data.merge('stack' => [ - "/ruby/2.5.0/gems/activesupport-4.2.11/lib/active_support/callbacks.rb:121:in `instance_exec'", - "/app/controllers/api/v2/users_controller.rb:39:in `show'" - ])) - end - - context 'with LOREKEEPER_DENYLIST env var' do - before do - allow(ENV).to receive(:key?).with('LOREKEEPER_DENYLIST').and_return(true) - allow(ENV).to receive(:fetch).with('LOREKEEPER_DENYLIST').and_return(lorekeeper_denylist) - end - let(:lorekeeper_denylist) { 'newrelic_rpm, active_support/callbacks.rb, zipkin-tracer, puma' } - let(:active_support_exception_v6) do - [ - "/app/controllers/api/v2/users_controller.rb:39:in `show'", - "actionpack (4.2.11) lib/action_dispatch/middleware/cookies.rb:560:in `call'", - "actionpack (4.2.11) lib/action_dispatch/middleware/callbacks.rb:29:in `block in call'", - "actionpack (4.2.11) lib/action_dispatch/middleware/callbacks.rb:27:in `call'", - "/usr/lib/ruby/vendor_ruby/phusion_passenger/rack/thread_handler_extension.rb:107:in `process_request'", - "opentelemetry-api (1.0.1) lib/opentelemetry/trace/tracer.rb:29:in `block in in_span'", - "/app/controllers/api/v2/users_controller.rb:39:in `show'" - ] - end - let(:active_support_exception_less_than_v6) do - [ - "/app/controllers/api/v2/users_controller.rb:39:in `show'", - "/ruby/2.5.0/gems/actionpack-4.2.11/lib/action_dispatch/middleware/cookies.rb:560:in `call'", - "/ruby/2.5.0/gems/actionpack-4.2.11/lib/action_dispatch/middleware/callbacks.rb:29:in `block in call'", - "/ruby/2.5.0/gems/actionpack-4.2.11/lib/action_dispatch/middleware/callbacks.rb:27:in `call'", - "/usr/lib/ruby/vendor_ruby/phusion_passenger/rack/thread_handler_extension.rb:107:in `process_request'", - "/ruby/2.5.0/gems/opentelemetry-api-1.0.1/lib/opentelemetry/trace/tracer.rb:29:in `block in in_span'", - "/app/controllers/api/v2/users_controller.rb:39:in `show'" - ] - end - - it 'Does not log the lines matched with the denylist' do - exception.set_backtrace(new_backtrace) - logger.exception(exception) - expect(io.received_message).to eq(exception_data.merge('stack' => no_noise_backtrace)) - end - end end context 'Logging an exception with custom level' do