Skip to content

Commit

Permalink
fix: handle broken instrumentation case
Browse files Browse the repository at this point in the history
  • Loading branch information
robertlaurin committed May 8, 2024
1 parent 0315130 commit 0b666b9
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 0b666b9

Please sign in to comment.