diff --git a/sdk_experimental/lib/opentelemetry/sdk/experimental.rb b/sdk_experimental/lib/opentelemetry/sdk/experimental.rb index 2f65647cb4..f6c8d85865 100644 --- a/sdk_experimental/lib/opentelemetry/sdk/experimental.rb +++ b/sdk_experimental/lib/opentelemetry/sdk/experimental.rb @@ -14,3 +14,4 @@ module Experimental end require 'opentelemetry/sdk/experimental/samplers_patch' +require 'opentelemetry/sdk/trace/propagation/trace_context/response_text_map_propagator' diff --git a/sdk_experimental/lib/opentelemetry/sdk/trace/propagation/trace_context/response_text_map_propagator.rb b/sdk_experimental/lib/opentelemetry/sdk/trace/propagation/trace_context/response_text_map_propagator.rb new file mode 100644 index 0000000000..15d74fe9b9 --- /dev/null +++ b/sdk_experimental/lib/opentelemetry/sdk/trace/propagation/trace_context/response_text_map_propagator.rb @@ -0,0 +1,62 @@ +# frozen_string_literal: true + +# Copyright The OpenTelemetry Authors +# +# SPDX-License-Identifier: Apache-2.0 + +unless OpenTelemetry::Trace::Propagation::TraceContext.const_defined?(:ResponseTextMapPropagator) + module OpenTelemetry + module Trace + module Propagation + module TraceContext + # Propagates trace response using the W3C Trace Context format + # https://w3c.github.io/trace-context/#traceresponse-header + class ResponseTextMapPropagator + TRACERESPONSE_KEY = 'traceresponse' + FIELDS = [TRACERESPONSE_KEY].freeze + + private_constant :TRACERESPONSE_KEY, :FIELDS + + # Inject trace context into the supplied carrier. + # + # @param [Carrier] carrier The mutable carrier to inject trace context into + # @param [Context] context The context to read trace context from + # @param [optional Setter] setter If the optional setter is provided, it + # will be used to write context into the carrier, otherwise the default + # text map setter will be used. + def inject(carrier, context: Context.current, setter: Context::Propagation.text_map_setter) + span_context = Trace.current_span(context).context + return unless span_context.valid? + + setter.set(carrier, TRACERESPONSE_KEY, TraceParent.from_span_context(span_context).to_s) + nil + end + + # Extract trace context from the supplied carrier. This is a no-op for + # this propagator, and will return the provided context. + # + # @param [Carrier] carrier The carrier to get the header from + # @param [optional Context] context Context to be updated with the trace context + # extracted from the carrier. Defaults to +Context.current+. + # @param [optional Getter] getter If the optional getter is provided, it + # will be used to read the header from the carrier, otherwise the default + # text map getter will be used. + # + # @return [Context] the original context. + def extract(carrier, context: Context.current, getter: Context::Propagation.text_map_getter) + context + end + + # Returns the predefined propagation fields. If your carrier is reused, you + # should delete the fields returned by this method before calling +inject+. + # + # @return [Array] a list of fields that will be used by this propagator. + def fields + FIELDS + end + end + end + end + end + end +end diff --git a/sdk_experimental/test/opentelemetry/sdk/trace/propagation/trace_context/response_text_map_propagator_test.rb b/sdk_experimental/test/opentelemetry/sdk/trace/propagation/trace_context/response_text_map_propagator_test.rb new file mode 100644 index 0000000000..07f92589d9 --- /dev/null +++ b/sdk_experimental/test/opentelemetry/sdk/trace/propagation/trace_context/response_text_map_propagator_test.rb @@ -0,0 +1,40 @@ +# frozen_string_literal: true + +# Copyright The OpenTelemetry Authors +# +# SPDX-License-Identifier: Apache-2.0 + +require 'test_helper' + +describe OpenTelemetry::Trace::Propagation::TraceContext::ResponseTextMapPropagator do + let(:traceresponse_key) { 'traceresponse' } + let(:propagator) do + OpenTelemetry::Trace::Propagation::TraceContext::ResponseTextMapPropagator.new + end + + let(:carrier) do + { + traceresponse_key => valid_traceresponse_header + } + end + let(:context) { OpenTelemetry::Context.empty } + let(:context_valid) do + span_context = OpenTelemetry::Trace::SpanContext.new(trace_id: ("\xff" * 16).b, span_id: ("\x11" * 8).b) + span = OpenTelemetry::Trace.non_recording_span(span_context) + OpenTelemetry::Trace.context_with_span(span) + end + + describe '#inject' do + it 'writes traceresponse into the carrier' do + carrier = {} + propagator.inject(carrier, context: context_valid) + _(carrier[traceresponse_key]).must_equal('00-ffffffffffffffffffffffffffffffff-1111111111111111-00') + end + + it "doesn't write if the context is not valid" do + carrier = {} + propagator.inject(carrier, context: context) + _(carrier).wont_include(traceresponse_key) + end + end +end