From bf1b08927fd8c7e641d3421c26512c29c8c14a7d Mon Sep 17 00:00:00 2001 From: Jean-Francis Bastien Date: Mon, 2 Feb 2026 19:31:47 -0500 Subject: [PATCH 1/2] add a way to disable solid apm in test --- README.md | 12 ++++++++++++ lib/solid_apm.rb | 2 ++ lib/solid_apm/engine.rb | 6 ++++-- lib/solid_apm/middleware.rb | 8 +++++--- lib/solid_apm/railtie.rb | 10 ++++++++++ spec/lib/solid_apm/configuration_spec.rb | 19 +++++++++++++++++++ spec/lib/solid_apm/railtie_spec.rb | 13 +++++++++++++ spec/services/solid_apm/middleware_spec.rb | 19 ++++++++++++++++++- 8 files changed, 83 insertions(+), 6 deletions(-) create mode 100644 lib/solid_apm/railtie.rb create mode 100644 spec/lib/solid_apm/configuration_spec.rb create mode 100644 spec/lib/solid_apm/railtie_spec.rb diff --git a/README.md b/README.md index 457e335..81323c5 100644 --- a/README.md +++ b/README.md @@ -99,6 +99,18 @@ The sampling is done per-thread using a round-robin counter, ensuring even distr This is useful for high-traffic applications where you want to reduce the volume of APM data while still maintaining representative performance insights. +### Test Environment + +**SolidAPM is automatically disabled in the test +environment** to prevent test pollution and improve test performance. + +You can disable SolidAPM in other environments if needed: + +```ruby +# config/environments/staging.rb +SolidApm.enabled = false +``` + ### Transaction Name Filtering Filter specific transactions by name using exact string matches or regular expressions: diff --git a/lib/solid_apm.rb b/lib/solid_apm.rb index 953949a..fd5fae0 100644 --- a/lib/solid_apm.rb +++ b/lib/solid_apm.rb @@ -4,6 +4,7 @@ require 'apexcharts' require 'solid_apm/version' +require 'solid_apm/railtie' require 'solid_apm/engine' require 'solid_apm/sampler' require 'solid_apm/cleanup_service' @@ -13,6 +14,7 @@ module SolidApm mattr_accessor :mcp_server_config, default: {} mattr_accessor :silence_active_record_logger, default: true mattr_accessor :transaction_sampling, default: 1 + mattr_accessor :enabled, default: true mattr_accessor( :transaction_filters, default: [ /^SolidApm::/, diff --git a/lib/solid_apm/engine.rb b/lib/solid_apm/engine.rb index 2bc16c7..095404c 100644 --- a/lib/solid_apm/engine.rb +++ b/lib/solid_apm/engine.rb @@ -4,7 +4,9 @@ module SolidApm class Engine < ::Rails::Engine isolate_namespace SolidApm - config.app_middleware.use Middleware + initializer 'solid_apm.middleware', before: :build_middleware_stack do |app| + app.middleware.use SolidApm::Middleware if SolidApm.enabled + end initializer 'solid_apm.assets' do |app| # Add engine's assets to the load path for both Propshaft and Sprockets @@ -49,7 +51,7 @@ class Engine < ::Rails::Engine end config.after_initialize do - SpanSubscriber::Base.subscribe! + SpanSubscriber::Base.subscribe! if SolidApm.enabled end end end diff --git a/lib/solid_apm/middleware.rb b/lib/solid_apm/middleware.rb index b6a6fcb..47f605f 100644 --- a/lib/solid_apm/middleware.rb +++ b/lib/solid_apm/middleware.rb @@ -7,10 +7,12 @@ def initialize(app) end def call(env) + return @app.call(env) unless SolidApm.enabled + self.class.init_transaction status, headers, body = @app.call(env) - env['rack.after_reply'] ||= [] + env['rack.after_reply'] ||= [] env['rack.after_reply'] << ->() do self.class.call rescue StandardError => e @@ -25,8 +27,8 @@ def self.call SpanSubscriber::Base.transaction = nil if transaction.nil? || - transaction_filtered?(transaction.name) || - !Sampler.should_sample? + transaction_filtered?(transaction.name) || + !Sampler.should_sample? SpanSubscriber::Base.spans = nil return diff --git a/lib/solid_apm/railtie.rb b/lib/solid_apm/railtie.rb new file mode 100644 index 0000000..de07314 --- /dev/null +++ b/lib/solid_apm/railtie.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +module SolidApm + class Railtie < Rails::Railtie + config.before_initialize do + # Always disable in test environment to prevent test pollution + SolidApm.enabled = false if Rails.env.test? + end + end +end diff --git a/spec/lib/solid_apm/configuration_spec.rb b/spec/lib/solid_apm/configuration_spec.rb new file mode 100644 index 0000000..2df1912 --- /dev/null +++ b/spec/lib/solid_apm/configuration_spec.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe 'SolidApm configuration' do + describe '.enabled' do + it 'is disabled in test environment' do + # SolidAPM is always disabled in test to prevent pollution + expect(SolidApm.enabled).to be false + end + + it 'can be set to false' do + original = SolidApm.enabled + SolidApm.enabled = false + expect(SolidApm.enabled).to be false + SolidApm.enabled = original + end + end +end diff --git a/spec/lib/solid_apm/railtie_spec.rb b/spec/lib/solid_apm/railtie_spec.rb new file mode 100644 index 0000000..b058830 --- /dev/null +++ b/spec/lib/solid_apm/railtie_spec.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe SolidApm::Railtie do + describe 'test environment auto-disable' do + it 'is disabled in test environment' do + # Railtie always disables in test environment + expect(Rails.env.test?).to be true + expect(SolidApm.enabled).to be false + end + end +end diff --git a/spec/services/solid_apm/middleware_spec.rb b/spec/services/solid_apm/middleware_spec.rb index a95caea..48e18fc 100644 --- a/spec/services/solid_apm/middleware_spec.rb +++ b/spec/services/solid_apm/middleware_spec.rb @@ -1,6 +1,23 @@ # frozen_string_literal: true RSpec.describe SolidApm::Middleware do + describe 'when disabled' do + it 'passes through without tracking' do + original = SolidApm.enabled + SolidApm.enabled = false + + app = ->(_env) { [200, {}, ['OK']] } + middleware = described_class.new(app) + + status, _headers, _body = middleware.call({}) + + expect(status).to eq(200) + expect(SolidApm::SpanSubscriber::Base.transaction).to be_nil + + SolidApm.enabled = original + end + end + describe '.transaction_filtered?' do before do SolidApm.transaction_filters = [] @@ -74,4 +91,4 @@ end end end -end \ No newline at end of file +end From edb3ecdf8f455296efd4ddb1f79c843b7eca3cd9 Mon Sep 17 00:00:00 2001 From: Jean-Francis Bastien Date: Mon, 2 Feb 2026 19:33:28 -0500 Subject: [PATCH 2/2] spec --- spec/services/solid_apm/middleware_spec.rb | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/spec/services/solid_apm/middleware_spec.rb b/spec/services/solid_apm/middleware_spec.rb index 48e18fc..d52ab37 100644 --- a/spec/services/solid_apm/middleware_spec.rb +++ b/spec/services/solid_apm/middleware_spec.rb @@ -2,10 +2,15 @@ RSpec.describe SolidApm::Middleware do describe 'when disabled' do - it 'passes through without tracking' do + around do |example| original = SolidApm.enabled SolidApm.enabled = false + example.run + ensure + SolidApm.enabled = original + end + it 'passes through without tracking' do app = ->(_env) { [200, {}, ['OK']] } middleware = described_class.new(app) @@ -13,8 +18,6 @@ expect(status).to eq(200) expect(SolidApm::SpanSubscriber::Base.transaction).to be_nil - - SolidApm.enabled = original end end