diff --git a/instrumentation/rack/lib/opentelemetry/instrumentation/rack/instrumentation.rb b/instrumentation/rack/lib/opentelemetry/instrumentation/rack/instrumentation.rb index 91e1f9f330..ef56da1b94 100644 --- a/instrumentation/rack/lib/opentelemetry/instrumentation/rack/instrumentation.rb +++ b/instrumentation/rack/lib/opentelemetry/instrumentation/rack/instrumentation.rb @@ -26,6 +26,7 @@ class Instrumentation < OpenTelemetry::Instrumentation::Base option :record_frontend_span, default: false, validate: :boolean option :untraced_endpoints, default: [], validate: :array option :url_quantization, default: nil, validate: :callable + option :propagate_with_link, default: nil, validate: :callable option :untraced_requests, default: nil, validate: :callable option :response_propagators, default: [], validate: :array # This option is only valid for applications using Rack 2.0 or greater 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 338bd95dd1..d9eb011b69 100644 --- a/instrumentation/rack/lib/opentelemetry/instrumentation/rack/middlewares/event_handler.rb +++ b/instrumentation/rack/lib/opentelemetry/instrumentation/rack/middlewares/event_handler.rb @@ -55,7 +55,15 @@ def on_start(request, _) return if untraced_request?(request.env) parent_context = extract_remote_context(request) - span = create_span(parent_context, request) + links = nil + + fn = propagate_with_link + if fn && fn.call(request.env) + links = prepare_span_links(parent_context) + parent_context = OpenTelemetry::Context.empty + end + + span = create_span(parent_context, request, links) request.env[TOKENS_KEY] = register_current_span(span) rescue StandardError => e OpenTelemetry.handle_error(exception: e) @@ -224,6 +232,10 @@ def url_quantization config[:url_quantization] end + def propagate_with_link + config[:propagate_with_link] + end + def response_propagators config[:response_propagators] end @@ -253,17 +265,23 @@ def register_current_span(span) contexts.map { |context| OpenTelemetry::Context.attach(context) } end - def create_span(parent_context, request) + def create_span(parent_context, request, links) span = tracer.start_span( create_request_span_name(request), with_parent: parent_context, kind: :server, - attributes: request_span_attributes(request.env) + attributes: request_span_attributes(request.env), + links: links, ) request_start_time = OpenTelemetry::Instrumentation::Rack::Util::QueueTime.get_request_start(request.env) span.add_event('http.proxy.request.started', timestamp: request_start_time) unless request_start_time.nil? span end + + def prepare_span_links(ctx) + span_context = OpenTelemetry::Trace.current_span(ctx).context + span_context.valid? ? [OpenTelemetry::Trace::Link.new(span_context)] : [] + end end end end