Module: Datadog::HTTPPropagator

Includes:
Ext::DistributedTracing
Defined in:
lib/ddtrace/propagation/http_propagator.rb

Overview

HTTPPropagator helps extracting and injecting HTTP headers.

Constant Summary collapse

PROPAGATION_STYLES =
{ PROPAGATION_STYLE_B3 => DistributedTracing::Headers::B3,
PROPAGATION_STYLE_B3_SINGLE_HEADER => DistributedTracing::Headers::B3Single,
PROPAGATION_STYLE_DATADOG => DistributedTracing::Headers::Datadog }.freeze

Constants included from Ext::DistributedTracing

Ext::DistributedTracing::B3_HEADER_SAMPLED, Ext::DistributedTracing::B3_HEADER_SINGLE, Ext::DistributedTracing::B3_HEADER_SPAN_ID, Ext::DistributedTracing::B3_HEADER_TRACE_ID, Ext::DistributedTracing::GRPC_METADATA_ORIGIN, Ext::DistributedTracing::GRPC_METADATA_PARENT_ID, Ext::DistributedTracing::GRPC_METADATA_SAMPLING_PRIORITY, Ext::DistributedTracing::GRPC_METADATA_TRACE_ID, Ext::DistributedTracing::HTTP_HEADER_ORIGIN, Ext::DistributedTracing::HTTP_HEADER_PARENT_ID, Ext::DistributedTracing::HTTP_HEADER_SAMPLING_PRIORITY, Ext::DistributedTracing::HTTP_HEADER_TRACE_ID, Ext::DistributedTracing::ORIGIN_KEY, Ext::DistributedTracing::PROPAGATION_EXTRACT_STYLE_ENV, Ext::DistributedTracing::PROPAGATION_INJECT_STYLE_ENV, Ext::DistributedTracing::PROPAGATION_STYLE_B3, Ext::DistributedTracing::PROPAGATION_STYLE_B3_SINGLE_HEADER, Ext::DistributedTracing::PROPAGATION_STYLE_DATADOG, Ext::DistributedTracing::SAMPLING_PRIORITY_KEY

Class Method Summary collapse

Class Method Details

.extract(env) ⇒ Object

extract returns a context containing the span ID, trace ID and sampling priority defined in env.


35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/ddtrace/propagation/http_propagator.rb', line 35

def self.extract(env)
  context = nil
  dd_context = nil

  ::Datadog.configuration.distributed_tracing.propagation_extract_style.each do |style|
    propagator = PROPAGATION_STYLES[style]
    next if propagator.nil?

    # Extract context
    # DEV: `propagator.extract` will return `nil`, where `HTTPPropagator#extract` will not
    extracted_context = propagator.extract(env)
    # Skip this style if no valid headers were found
    next if extracted_context.nil?

    # Keep track of the Datadog extract context, we want to return
    #   this one if we have one
    dd_context = extracted_context if extracted_context && style == PROPAGATION_STYLE_DATADOG

    # No previously extracted context, use the one we just extracted
    if context.nil?
      context = extracted_context
    else
      unless context.trace_id == extracted_context.trace_id && context.span_id == extracted_context.span_id
        # Return an empty/new context if we have a mismatch in values extracted
        msg = "#{context.trace_id} != #{extracted_context.trace_id} && " \
              "#{context.span_id} != #{extracted_context.span_id}"
        ::Datadog.logger.debug("Cannot extract context from HTTP: extracted contexts differ, #{msg}".freeze)
        # DEV: This will return from `self.extract` not this `each` block
        return ::Datadog::Context.new
      end
    end
  end

  # Return the extracted context if we found one or else a new empty context
  # Always return the Datadog context if one exists since it has more
  #   information than the B3 headers e.g. origin, expanded priority
  #   sampling values, etc
  dd_context || context || ::Datadog::Context.new
end

.inject!(context, env) ⇒ Object

inject! popolates the env with span ID, trace ID and sampling priority


19
20
21
22
23
24
25
26
27
28
29
30
31
# File 'lib/ddtrace/propagation/http_propagator.rb', line 19

def self.inject!(context, env)
  # Prevent propagation from being attempted if context provided is nil.
  if context.nil?
    ::Datadog.logger.debug('Cannot inject context into env to propagate over HTTP: context is nil.'.freeze)
    return
  end

  # Inject all configured propagation styles
  ::Datadog.configuration.distributed_tracing.propagation_inject_style.each do |style|
    propagator = PROPAGATION_STYLES[style]
    propagator.inject!(context, env) unless propagator.nil?
  end
end