diff --git a/instrumentation/rack/lib/opentelemetry/instrumentation/rack/middlewares/event_handler.rb b/instrumentation/rack/lib/opentelemetry/instrumentation/rack/middlewares/event_handler.rb index 4b283a4b9..353b3dd6a 100644 --- a/instrumentation/rack/lib/opentelemetry/instrumentation/rack/middlewares/event_handler.rb +++ b/instrumentation/rack/lib/opentelemetry/instrumentation/rack/middlewares/event_handler.rb @@ -42,7 +42,7 @@ module Middlewares class EventHandler include ::Rack::Events::Abstract - TOKEN_KEY = 'otel.context.token' + RACK_OTEL_CONTEXT_KEY = 'otel.rack.context.token' GOOD_HTTP_STATUSES = (100..499) # Creates a server span for this current request using the incoming parent context @@ -58,7 +58,7 @@ def on_start(request, _) span = create_span(parent_context, request) span_ctx = OpenTelemetry::Trace.context_with_span(span, parent_context: parent_context) rack_ctx = OpenTelemetry::Instrumentation::Rack.context_with_span(span, parent_context: span_ctx) - request.env[TOKEN_KEY] = OpenTelemetry::Context.attach(rack_ctx) + request.env[RACK_OTEL_CONTEXT_KEY] = [OpenTelemetry::Context.attach(rack_ctx), rack_ctx] rescue StandardError => e OpenTelemetry.handle_error(exception: e) end @@ -194,10 +194,11 @@ def request_span_attributes(env) end def detach_context(request) - return nil unless request.env[TOKEN_KEY] + return nil unless request.env[RACK_OTEL_CONTEXT_KEY] - OpenTelemetry::Trace.current_span.finish - OpenTelemetry::Context.detach(request.env[TOKEN_KEY]) + token, rack_ctx = request.env[RACK_OTEL_CONTEXT_KEY] + OpenTelemetry::Trace.current_span(rack_ctx).finish + OpenTelemetry::Context.detach(token) rescue StandardError => e OpenTelemetry.handle_error(exception: e) end diff --git a/instrumentation/rack/test/opentelemetry/instrumentation/rack/middlewares/event_handler_test.rb b/instrumentation/rack/test/opentelemetry/instrumentation/rack/middlewares/event_handler_test.rb index 63b0e98ec..a70b486c0 100644 --- a/instrumentation/rack/test/opentelemetry/instrumentation/rack/middlewares/event_handler_test.rb +++ b/instrumentation/rack/test/opentelemetry/instrumentation/rack/middlewares/event_handler_test.rb @@ -67,6 +67,27 @@ instrumentation.install(config) end + # Simulating buggy instrumentation that starts a span, sets the ctx + # but fails to detach or close the span + describe 'broken instrumentation' do + let(:service) do + lambda do |_env| + span = OpenTelemetry.tracer_provider.tracer('buggy').start_span('I never close') + OpenTelemetry::Context.attach(OpenTelemetry::Trace.context_with_span(span)) + [200, { 'Content-Type' => 'text/plain' }, response_body] + end + end + + it 'still closes the rack span' do + assert_raises OpenTelemetry::Context::DetachError do + get uri, {}, headers + end + _(finished_spans.size).must_equal 1 + _(rack_span.name).must_equal 'HTTP GET' + OpenTelemetry::Context.clear + end + end + describe '#call' do before do get uri, {}, headers