diff --git a/lib/instana/instrumentation/grpc.rb b/lib/instana/instrumentation/grpc.rb index 647ab823..40180747 100644 --- a/lib/instana/instrumentation/grpc.rb +++ b/lib/instana/instrumentation/grpc.rb @@ -39,7 +39,7 @@ module GRPCCientInstrumentation current_span.record_exception(e) raise ensure - current_span.finish + current_span&.finish end end end @@ -83,7 +83,7 @@ module GRPCServerInstrumentation current_span.record_exception(e) raise ensure - current_span.finish if ::Instana.tracer.tracing? + current_span&.finish end end end diff --git a/lib/instana/trace.rb b/lib/instana/trace.rb index 1efc6df3..0e3bfa32 100644 --- a/lib/instana/trace.rb +++ b/lib/instana/trace.rb @@ -63,7 +63,7 @@ def with_span(span) # # @return [Span] def non_recording_span(span_context) - Span.new(span_context: span_context) + OpenTelemetry::Trace::Span.new(span_context: span_context) end end end diff --git a/lib/instana/trace/tracer.rb b/lib/instana/trace/tracer.rb index ebb89d72..712e4f5d 100644 --- a/lib/instana/trace/tracer.rb +++ b/lib/instana/trace/tracer.rb @@ -323,7 +323,7 @@ def clear! # with_parent=current context, start_timestamp=current time. # def start_span(name, with_parent: nil, attributes: nil, links: nil, start_timestamp: ::Instana::Util.now_in_ms, kind: nil) # rubocop:disable Metrics/ParameterLists - return if !::Instana.agent.ready? || !::Instana.config[:tracing][:enabled] + return Instana::Trace.non_recording_span(with_parent) if !::Instana.agent.ready? || !::Instana.config[:tracing][:enabled] with_parent ||= OpenTelemetry::Context.current name ||= 'empty' diff --git a/test/instrumentation/aws_test.rb b/test/instrumentation/aws_test.rb index 69f57bb2..7c6a2dbd 100644 --- a/test/instrumentation/aws_test.rb +++ b/test/instrumentation/aws_test.rb @@ -238,4 +238,30 @@ def test_lambda_with_500_status refute_nil lambda_span[:stack] assert_equal 30, lambda_span[:stack].length # default limit is 30 in span.add_stack end + + def test_no_error_is_raised_and_no_spans_are_created_when_agent_is_not_ready + error = nil + + ::Instana.agent.stub(:ready?, false) do + dynamo = Aws::DynamoDB::Client.new( + region: "local", + access_key_id: "placeholder", + secret_access_key: "placeholder", + endpoint: "http://localhost:8000" + ) + + assert_silent do + dynamo.get_item( + table_name: 'sample_table', + key: { s: 'sample_item' } + ) + rescue StandardError => e + error = e + end + end + + # Should not raise instrumentation errors, only the expected AWS error + assert error.is_a?(Aws::DynamoDB::Errors::ServiceError) + assert_empty ::Instana.processor.queued_spans + end end diff --git a/test/instrumentation/bunny_test.rb b/test/instrumentation/bunny_test.rb index 98500c8e..ef60abfe 100644 --- a/test/instrumentation/bunny_test.rb +++ b/test/instrumentation/bunny_test.rb @@ -2,6 +2,8 @@ require 'test_helper' +Warning[:deprecated] = false if Gem::Version.new(RUBY_VERSION) > Gem::Version.new('3.4') + class BunnyTest < Minitest::Test # rubocop:disable Metrics/ClassLength def setup skip unless defined?(::Bunny) @@ -792,4 +794,22 @@ def test_pop_error_handling_with_logging assert error_raised, "Exception should be raised and logged in pop" end + + def test_no_error_is_raised_and_no_spans_are_created_when_agent_is_not_ready + skip unless defined?(::Bunny) + clear_all! + + error = nil + + ::Instana.agent.stub(:ready?, false) do + assert_silent do + @exchange.publish('test message', routing_key: @queue.name) + rescue StandardError => e + error = e + end + end + + assert_nil error + assert_empty ::Instana.processor.queued_spans + end end diff --git a/test/instrumentation/dalli_test.rb b/test/instrumentation/dalli_test.rb index 9f39fe2c..1c286df1 100644 --- a/test/instrumentation/dalli_test.rb +++ b/test/instrumentation/dalli_test.rb @@ -3,6 +3,8 @@ require 'test_helper' +Warning[:deprecated] = false if Gem::Version.new(RUBY_VERSION) > Gem::Version.new('4.0') + class DalliTest < Minitest::Test def setup @memcached_host = ENV['MEMCACHED_HOST'] || '127.0.0.1:11211' @@ -322,4 +324,20 @@ def test_get_error_logging assert_equal 'instana_test', second_span[:data][:memcache][:namespace] assert second_span[:data][:memcache].key?(:error) end + + def test_no_error_is_raised_and_no_spans_are_created_when_agent_is_not_ready + clear_all! + error = nil + + ::Instana.agent.stub(:ready?, false) do + assert_silent do + @dc.set(:instana, :test_value) + rescue StandardError => e + error = e + end + end + + assert_nil error + assert_empty ::Instana.processor.queued_spans + end end diff --git a/test/instrumentation/excon_test.rb b/test/instrumentation/excon_test.rb index 3708784b..2bb8e9e6 100644 --- a/test/instrumentation/excon_test.rb +++ b/test/instrumentation/excon_test.rb @@ -201,4 +201,29 @@ def test_basic_get_no_tracing connection = Excon.new(url) connection.get(:path => '/?basic_get') end + + def test_no_error_is_raised_and_no_spans_are_created_when_agent_is_not_ready + clear_all! + error = nil + + # A slight hack but webmock chokes with pipelined requests. + # Delete their excon middleware + Excon.defaults[:middlewares].delete ::WebMock::HttpLibAdapters::ExconAdapter + Excon.defaults[:middlewares].delete ::Excon::Middleware::Mock + + url = "http://127.0.0.1:6511" + + ::Instana.agent.stub(:ready?, false) do + connection = Excon.new(url) + + assert_silent do + connection.get(:path => '/?basic_get') + rescue StandardError => e + error = e + end + end + + assert_nil error + assert_empty ::Instana.processor.queued_spans + end end diff --git a/test/instrumentation/graphql_test.rb b/test/instrumentation/graphql_test.rb index cd8b1c9b..380bb896 100644 --- a/test/instrumentation/graphql_test.rb +++ b/test/instrumentation/graphql_test.rb @@ -286,4 +286,30 @@ def test_mutation assert_equal :'graphql.server', query_span[:n] assert_equal expected_data, query_span[:data][:graphql] end + + def test_no_error_is_raised_and_no_spans_are_created_when_agent_is_not_ready + clear_all! + error = nil + + query = "query FirstTwoTaskSamples { + tasks(after: \"\", first: 2) { + nodes { + action + } + } + }" + + ::Instana.agent.stub(:ready?, false) do + assert_silent do + + Schema.execute(query) + rescue StandardError => e + error = e + + end + end + + assert_nil error + assert_empty ::Instana.processor.queued_spans + end end diff --git a/test/instrumentation/grpc_test.rb b/test/instrumentation/grpc_test.rb index 85d3e734..4c8d31bb 100644 --- a/test/instrumentation/grpc_test.rb +++ b/test/instrumentation/grpc_test.rb @@ -417,4 +417,25 @@ def test_bidi_streamer_failure assert_equal server_span[:p], client_span[:s] assert_equal client_span[:p], sdk_span[:s] end + + def test_no_error_is_raised_and_no_spans_are_created_when_agent_is_not_ready + clear_all! + error = nil + ::Instana.agent.stub(:ready?, false) do + assert_silent do + begin + client_stub.ping( + PingPongService::PingRequest.new(message: 'Hello World') + ) + rescue StandardError => e + error = e + end + end + end + + sleep 0.2 + + assert_nil error + assert_empty ::Instana.processor.queued_spans + end end diff --git a/test/instrumentation/mongo_test.rb b/test/instrumentation/mongo_test.rb index 3be181f5..74a7f082 100644 --- a/test/instrumentation/mongo_test.rb +++ b/test/instrumentation/mongo_test.rb @@ -65,4 +65,21 @@ def test_mongo_as_root_exit_span assert_equal insert_data[:peer], {hostname: "127.0.0.1", port: 27017} assert insert_data[:json].include?("insert") end + + def test_mongo_no_error_is_raised_and_no_spans_are_created_when_agent_is_not_ready + error = nil + + ::Instana.agent.stub(:ready?, false) do + client = Mongo::Client.new('mongodb://127.0.0.1:27017/instana') + + assert_silent do + client[:people].delete_many({ name: /$S*/ }) + rescue StandardError => e + error = e + end + end + + assert_nil error + assert_empty ::Instana.processor.queued_spans + end end diff --git a/test/instrumentation/net_http_test.rb b/test/instrumentation/net_http_test.rb index 41b389e8..2b7dd2ea 100644 --- a/test/instrumentation/net_http_test.rb +++ b/test/instrumentation/net_http_test.rb @@ -217,4 +217,23 @@ def test_request_with_5xx_response WebMock.disable_net_connect! end + + def test_no_error_is_raised_and_no_spans_are_created_when_agent_is_not_ready + clear_all! + error = nil + WebMock.allow_net_connect! + + ::Instana.agent.stub(:ready?, false) do + assert_silent do + Net::HTTP.get(URI('http://127.0.0.1:6511/')) + rescue StandardError => e + error = e + end + end + + assert_nil error + assert_empty ::Instana.processor.queued_spans + + WebMock.disable_net_connect! + end end diff --git a/test/instrumentation/rack_test.rb b/test/instrumentation/rack_test.rb index 47b4ae10..686a4b28 100644 --- a/test/instrumentation/rack_test.rb +++ b/test/instrumentation/rack_test.rb @@ -412,4 +412,21 @@ def test_five_zero_x_trace assert_equal :rack, first_span[:n] assert_equal 1, first_span[:ec] end + + def test_no_error_is_raised_and_no_spans_are_created_when_agent_is_not_ready + clear_all! + error = nil + + ::Instana.agent.stub(:ready?, false) do + assert_silent do + get '/mrlobster' + rescue StandardError => e + error = e + end + end + + assert_nil error + assert last_response.ok? + assert_empty ::Instana.processor.queued_spans + end end diff --git a/test/instrumentation/rails_action_cable_test.rb b/test/instrumentation/rails_action_cable_test.rb index 9dba00b4..29944f76 100644 --- a/test/instrumentation/rails_action_cable_test.rb +++ b/test/instrumentation/rails_action_cable_test.rb @@ -132,4 +132,26 @@ def mock_connection connection.define_singleton_method(:transmit) { |*_args, **_kwargs| true } connection end + + def test_no_error_is_raised_and_no_spans_are_created_when_agent_is_not_ready + skip unless defined?(::ActionCable::Connection::Base) + clear_all! + error = nil + + ::Instana.agent.stub(:ready?, false) do + connection = mock_connection + channel_klass = Class.new(ActionCable::Channel::Base) + + assert_silent do + channel_klass + .new(connection, :test) + .send(:transmit, 'Sample message', via: nil) + rescue StandardError => e + error = e + end + end + + assert_nil error + assert_empty ::Instana.processor.queued_spans + end end diff --git a/test/instrumentation/rails_action_controller_test.rb b/test/instrumentation/rails_action_controller_test.rb index 53f1c5ee..29730fec 100644 --- a/test/instrumentation/rails_action_controller_test.rb +++ b/test/instrumentation/rails_action_controller_test.rb @@ -215,4 +215,21 @@ def test_log assert_equal "Warn", log_span[:level] assert_equal "This is a test warning", log_span[:message] end + + def test_no_error_is_raised_and_no_spans_are_created_when_agent_is_not_ready + clear_all! + error = nil + + ::Instana.agent.stub(:ready?, false) do + assert_silent do + get '/base/world' + rescue StandardError => e + error = e + end + end + + assert_nil error + assert last_response.ok? + assert_empty ::Instana.processor.queued_spans + end end diff --git a/test/instrumentation/rails_action_mailer_test.rb b/test/instrumentation/rails_action_mailer_test.rb index dd296592..ec07d837 100644 --- a/test/instrumentation/rails_action_mailer_test.rb +++ b/test/instrumentation/rails_action_mailer_test.rb @@ -63,4 +63,20 @@ def test_mailer_as_root_exit_span assert_equal 'RailsActionMailerTest::TestMailer', mail_span[:data][:actionmailer][:class] assert_equal 'sample_email', mail_span[:data][:actionmailer][:method] end + + def test_no_error_is_raised_and_no_spans_are_created_when_agent_is_not_ready + clear_all! + error = nil + + ::Instana.agent.stub(:ready?, false) do + assert_silent do + TestMailer.sample_email.deliver_now + rescue StandardError => e + error = e + end + end + + assert_nil error + assert_empty ::Instana.processor.queued_spans + end end diff --git a/test/instrumentation/rails_action_view_test.rb b/test/instrumentation/rails_action_view_test.rb index 07f7dc0e..825c1d4a 100644 --- a/test/instrumentation/rails_action_view_test.rb +++ b/test/instrumentation/rails_action_view_test.rb @@ -151,4 +151,21 @@ def test_render_collection assert_equal :collection, span[:data][:render][:type] assert_equal 'blocks/block', span[:data][:render][:name] end + + def test_no_error_is_raised_and_no_spans_are_created_when_agent_is_not_ready + clear_all! + error = nil + + ::Instana.agent.stub(:ready?, false) do + assert_silent do + get '/render_view' + rescue StandardError => e + error = e + end + end + + assert_nil error + assert last_response.ok? + assert_empty ::Instana.processor.queued_spans + end end diff --git a/test/instrumentation/rails_active_job_test.rb b/test/instrumentation/rails_active_job_test.rb index 78cc1735..ddbbf51f 100644 --- a/test/instrumentation/rails_active_job_test.rb +++ b/test/instrumentation/rails_active_job_test.rb @@ -62,4 +62,19 @@ def test_enqueue_perform assert_equal client_span[:t], server_span[:t] assert_equal client_span[:s], server_span[:p] end + + def test_no_error_is_raised_and_no_spans_are_created_when_agent_is_not_ready + error = nil + + ::Instana.agent.stub(:ready?, false) do + assert_silent do + SampleJob.perform_now("test_agent_not_ready") + rescue StandardError => e + error = e + end + end + + assert_nil error + assert_empty ::Instana.processor.queued_spans + end end diff --git a/test/instrumentation/rails_active_record_database_missing_test.rb b/test/instrumentation/rails_active_record_database_missing_test.rb index 98fc109d..853e822d 100644 --- a/test/instrumentation/rails_active_record_database_missing_test.rb +++ b/test/instrumentation/rails_active_record_database_missing_test.rb @@ -10,6 +10,7 @@ def setup skip unless ENV['DATABASE_URL'] clear_all! @old_url = ENV['DATABASE_URL'] + SQLite3::Database.new('/tmp/test.db') ENV['DATABASE_URL'] = 'sqlite3:///tmp/test.db' @@ -41,4 +42,22 @@ def test_error_on_missing_database assert_equal 1, span[:ec] assert span[:data][:activerecord][:error].include?("SQLite3::ReadOnlyException: attempt to write a readonly database") end + + def test_no_error_is_raised_and_no_spans_are_created_when_agent_is_not_ready + error = nil + + ::Instana.agent.stub(:ready?, false) do + assert_silent do + b = Block.new + Block.create(name: 'test', color: 'green') + b.save! + FileUtils.rm('/tmp/test.db') + rescue StandardError => e + error = e + end + end + + assert_nil error + assert_empty ::Instana.processor.queued_spans + end end diff --git a/test/instrumentation/rails_active_record_test.rb b/test/instrumentation/rails_active_record_test.rb index afbc39ad..d5057e6e 100644 --- a/test/instrumentation/rails_active_record_test.rb +++ b/test/instrumentation/rails_active_record_test.rb @@ -113,4 +113,21 @@ def test_raw_error assert_equal 1, span[:ec] end + + def test_no_error_is_raised_and_no_spans_are_created_when_agent_is_not_ready + skip unless ENV['DATABASE_URL'] + clear_all! + error = nil + + ::Instana.agent.stub(:ready?, false) do + assert_silent do + Block.create(name: 'test', color: 'green') + rescue StandardError => e + error = e + end + end + + assert_nil error + assert_empty ::Instana.processor.queued_spans + end end diff --git a/test/instrumentation/redis_test.rb b/test/instrumentation/redis_test.rb index 3a3d90d0..93c52f58 100644 --- a/test/instrumentation/redis_test.rb +++ b/test/instrumentation/redis_test.rb @@ -153,6 +153,24 @@ def assert_redis_trace(command, with_error: nil) assert data[:log].key?(:message) end end + + def test_no_error_is_raised_and_no_spans_are_created_when_agent_is_not_ready + clear_all! + error = nil + + ::Instana.agent.stub(:ready?, false) do + assert_silent do + begin + @redis_client.set('hello', 'world') + rescue StandardError => e + error = e + end + end + end + + assert_nil error + assert_empty ::Instana.processor.queued_spans + end end class RedisSpanFilteringTest < Minitest::Test diff --git a/test/instrumentation/resque_test.rb b/test/instrumentation/resque_test.rb index 5c752330..5f83b0b9 100644 --- a/test/instrumentation/resque_test.rb +++ b/test/instrumentation/resque_test.rb @@ -185,4 +185,20 @@ def test_worker_error_job assert_equal "Exception: Silly Rabbit, Trix are for kids.", resque_span[:data][:'resque-worker'][:error] assert_equal Array, resque_span[:stack].class end + + def test_no_error_is_raised_and_no_spans_are_created_when_agent_is_not_ready + clear_all! + error = nil + + ::Instana.agent.stub(:ready?, false) do + assert_silent do + ::Resque.enqueue(FastJob) + rescue StandardError => e + error = e + end + end + + assert_nil error + assert_empty ::Instana.processor.queued_spans + end end diff --git a/test/instrumentation/rest_client_test.rb b/test/instrumentation/rest_client_test.rb index 0ec6b0d0..5877a5ea 100644 --- a/test/instrumentation/rest_client_test.rb +++ b/test/instrumentation/rest_client_test.rb @@ -103,4 +103,25 @@ def test_basic_get_as_root_exit_span WebMock.disable_net_connect! end + + def test_no_error_is_raised_and_no_spans_are_created_when_agent_is_not_ready + clear_all! + error = nil + WebMock.allow_net_connect! + + url = "http://127.0.0.1:6511/" + + ::Instana.agent.stub(:ready?, false) do + assert_silent do + RestClient.get url + rescue StandardError => e + error = e + end + end + + assert_nil error + assert_empty ::Instana.processor.queued_spans + + WebMock.disable_net_connect! + end end diff --git a/test/instrumentation/sequel_test.rb b/test/instrumentation/sequel_test.rb index 9d46f414..b2d26058 100644 --- a/test/instrumentation/sequel_test.rb +++ b/test/instrumentation/sequel_test.rb @@ -108,4 +108,21 @@ def test_raw_error span = find_first_span_by_name(spans, :sequel) assert_equal 1, span[:ec] end + + def test_no_error_is_raised_and_no_spans_are_created_when_agent_is_not_ready + skip unless ENV['DATABASE_URL'] + clear_all! + error = nil + + ::Instana.agent.stub(:ready?, false) do + assert_silent do + @model.insert(name: 'test', color: 'blue') + rescue StandardError => e + error = e + end + end + + assert_nil error + assert_empty ::Instana.processor.queued_spans + end end diff --git a/test/instrumentation/shoryuken_test.rb b/test/instrumentation/shoryuken_test.rb index 82d2db1d..e1548833 100644 --- a/test/instrumentation/shoryuken_test.rb +++ b/test/instrumentation/shoryuken_test.rb @@ -44,4 +44,24 @@ def test_start_trace assert_equal 'entry', span[:data][:sqs][:sort] assert_equal 'http://example.com', span[:data][:sqs][:queue] end + + def test_no_error_is_raised_and_no_spans_are_created_when_agent_is_not_ready + clear_all! + error = nil + + message = OpenStruct.new( + queue_url: 'http://example.com' + ) + + ::Instana.agent.stub(:ready?, false) do + assert_silent do + @middleware.call(nil, nil, message, nil) {} + rescue StandardError => e + error = e + end + end + + assert_nil error + assert_empty ::Instana.processor.queued_spans + end end diff --git a/test/instrumentation/sidekiq-client_test.rb b/test/instrumentation/sidekiq-client_test.rb index cab387ca..735939f3 100644 --- a/test/instrumentation/sidekiq-client_test.rb +++ b/test/instrumentation/sidekiq-client_test.rb @@ -167,4 +167,27 @@ def remove_sidekiq_exception_middleware end end end + + def test_no_error_is_raised_and_no_spans_are_created_when_agent_is_not_ready + clear_all! + error = nil + + ::Instana.agent.stub(:ready?, false) do + disable_redis_instrumentation + assert_silent do + ::Sidekiq::Client.push( + 'queue' => 'some_random_queue', + 'class' => ::SidekiqJobOne, + 'args' => [1, 2, 3], + 'retry' => false + ) + rescue StandardError => e + error = e + end + enable_redis_instrumentation + end + + assert_nil error + assert_empty ::Instana.processor.queued_spans + end end diff --git a/test/instrumentation/sidekiq-worker_test.rb b/test/instrumentation/sidekiq-worker_test.rb index b1ac9646..8f2bf175 100644 --- a/test/instrumentation/sidekiq-worker_test.rb +++ b/test/instrumentation/sidekiq-worker_test.rb @@ -177,4 +177,36 @@ def assert_client_span(client_span, job) assert client_span[:data][:'sidekiq-client'][:'redis-url'] assert_equal job.name, client_span[:data][:'sidekiq-client'][:job] end + + def test_no_error_is_raised_and_no_spans_are_created_when_agent_is_not_ready + clear_all! + error = nil + $sidekiq_mode = :server + inject_instrumentation + + ::Instana.agent.stub(:ready?, false) do + disable_redis_instrumentation + ::Sidekiq.redis_pool.with do |redis| + redis.sadd('queues'.freeze, 'important') + redis.lpush( + 'queue:important', + <<-JSON + { + "class":"SidekiqJobOne", + "args":[1,2,3], + "queue":"important", + "jid":"123456789" + } + JSON + ) + end + enable_redis_instrumentation + sleep 1 + end + + assert_nil error + assert_empty ::Instana.processor.queued_spans + + $sidekiq_mode = :client + end end