class OpenTelemetry::Propagator::OTTrace::TextMapPropagator

Propagates context using OTTrace header format

Constants

BAGGAGE_HEADER_PREFIX
FIELDS
INVALID_BAGGAGE_HEADER_VALUE_CHARS
PADDING
SAMPLED_HEADER
SPAN_ID_HEADER
TRACE_ID_64_BIT_WIDTH
TRACE_ID_HEADER
VALID_BAGGAGE_HEADER_NAME_CHARS

github.com/open-telemetry/opentelemetry-specification/blob/14d123c121b6caa53bffd011292c42a181c9ca26/specification/context/api-propagators.md#textmap-propagator0

VALID_SPAN_ID_REGEX
VALID_TRACE_ID_REGEX

Public Instance Methods

extract(carrier, context: Context.current, getter: Context::Propagation.text_map_getter) click to toggle source

Extract OTTrace context from the supplied carrier and set the active span in the given context. The original context will be returned if OTTrace cannot be extracted from the carrier.

@param [Carrier] carrier The carrier to get the header from. @param [optional Context] context The context to be updated with extracted context @param [optional Getter] getter If the optional getter is provided, it

will be used to read the header from the carrier, otherwise the default
getter will be used.

@return [Context] Updated context with active span derived from the header, or the original

context if parsing fails.
# File lib/opentelemetry/propagator/ottrace/text_map_propagator.rb, line 49
def extract(carrier, context: Context.current, getter: Context::Propagation.text_map_getter)
  trace_id = optionally_pad_trace_id(getter.get(carrier, TRACE_ID_HEADER))
  span_id = getter.get(carrier, SPAN_ID_HEADER)
  sampled = getter.get(carrier, SAMPLED_HEADER)

  return context unless valid?(trace_id: trace_id, span_id: span_id)

  span_context = Trace::SpanContext.new(
    trace_id: Array(trace_id).pack('H*'),
    span_id: Array(span_id).pack('H*'),
    trace_flags: sampled == 'true' ? Trace::TraceFlags::SAMPLED : Trace::TraceFlags::DEFAULT,
    remote: true
  )

  span = OpenTelemetry::Trace.non_recording_span(span_context)
  Trace.context_with_span(span, parent_context: set_baggage(carrier: carrier, context: context, getter: getter))
end
fields() click to toggle source

Returns the predefined propagation fields. If your carrier is reused, you should delete the fields returned by this method before calling inject.

@return [Array<String>] a list of fields that will be used by this propagator.

# File lib/opentelemetry/propagator/ottrace/text_map_propagator.rb, line 86
def fields
  FIELDS
end
inject(carrier, context: Context.current, setter: Context::Propagation.text_map_setter) click to toggle source

@param [Object] carrier to update with context. @param [optional Context] context The active Context. @param [optional Setter] setter If the optional setter is provided, it

will be used to write context into the carrier, otherwise the default
setter will be used.
# File lib/opentelemetry/propagator/ottrace/text_map_propagator.rb, line 72
def inject(carrier, context: Context.current, setter: Context::Propagation.text_map_setter)
  span_context = Trace.current_span(context).context
  return unless span_context.valid?

  inject_span_context(span_context: span_context, carrier: carrier, setter: setter)
  inject_baggage(context: context, carrier: carrier, setter: setter)

  nil
end

Private Instance Methods

baggage() click to toggle source
# File lib/opentelemetry/propagator/ottrace/text_map_propagator.rb, line 120
def baggage
  OpenTelemetry::Baggage
end
inject_baggage(context:, carrier:, setter:) click to toggle source
# File lib/opentelemetry/propagator/ottrace/text_map_propagator.rb, line 130
def inject_baggage(context:, carrier:, setter:)
  baggage.values(context: context)
         .select { |key, value| valid_baggage_entry?(key, value) }
         .each { |key, value| setter.set(carrier, "#{BAGGAGE_HEADER_PREFIX}#{key}", value) }
end
inject_span_context(span_context:, carrier:, setter:) click to toggle source
# File lib/opentelemetry/propagator/ottrace/text_map_propagator.rb, line 124
def inject_span_context(span_context:, carrier:, setter:)
  setter.set(carrier, TRACE_ID_HEADER, span_context.hex_trace_id[TRACE_ID_64_BIT_WIDTH, TRACE_ID_64_BIT_WIDTH])
  setter.set(carrier, SPAN_ID_HEADER, span_context.hex_span_id)
  setter.set(carrier, SAMPLED_HEADER, span_context.trace_flags.sampled?.to_s)
end
optionally_pad_trace_id(trace_id) click to toggle source
# File lib/opentelemetry/propagator/ottrace/text_map_propagator.rb, line 96
def optionally_pad_trace_id(trace_id)
  if trace_id&.length == 16
    "#{PADDING}#{trace_id}"
  else
    trace_id
  end
end
set_baggage(carrier:, context:, getter:) click to toggle source
# File lib/opentelemetry/propagator/ottrace/text_map_propagator.rb, line 104
def set_baggage(carrier:, context:, getter:)
  baggage.build(context: context) do |builder|
    prefix = BAGGAGE_HEADER_PREFIX
    getter.keys(carrier).each do |carrier_key|
      baggage_key = carrier_key.start_with?(prefix) && carrier_key[prefix.length..-1]
      next unless baggage_key
      next unless VALID_BAGGAGE_HEADER_NAME_CHARS =~ baggage_key

      value = getter.get(carrier, carrier_key)
      next unless INVALID_BAGGAGE_HEADER_VALUE_CHARS !~ value

      builder.set_value(baggage_key, value)
    end
  end
end
valid?(trace_id:, span_id:) click to toggle source
# File lib/opentelemetry/propagator/ottrace/text_map_propagator.rb, line 92
def valid?(trace_id:, span_id:)
  !(VALID_TRACE_ID_REGEX !~ trace_id || VALID_SPAN_ID_REGEX !~ span_id)
end
valid_baggage_entry?(key, value) click to toggle source
# File lib/opentelemetry/propagator/ottrace/text_map_propagator.rb, line 136
def valid_baggage_entry?(key, value)
  VALID_BAGGAGE_HEADER_NAME_CHARS =~ key && INVALID_BAGGAGE_HEADER_VALUE_CHARS !~ value
end