Class: Datadog::Tracing::Distributed::Propagation
- Inherits:
-
Object
- Object
- Datadog::Tracing::Distributed::Propagation
- Defined in:
- lib/datadog/tracing/distributed/propagation.rb
Overview
Provides extraction and injection of distributed trace data.
Direct Known Subclasses
Contrib::GRPC::Distributed::Propagation, Contrib::HTTP::Distributed::Propagation, Contrib::Sidekiq::Distributed::Propagation
Instance Method Summary collapse
-
#extract(data) ⇒ Object
extract returns TraceDigest containing the distributed trace information.
-
#initialize(propagation_styles:) ⇒ Propagation
constructor
DEV: This class should receive the value for DEV: ‘Datadog.configuration.tracing.distributed_tracing.propagation_inject_style` DEV: at initialization time, instead of constantly reading global values.
-
#inject!(digest, data) ⇒ Boolean?
inject! populates the env with span ID, trace ID and sampling priority.
Constructor Details
#initialize(propagation_styles:) ⇒ Propagation
DEV: This class should receive the value for DEV: ‘Datadog.configuration.tracing.distributed_tracing.propagation_inject_style` DEV: at initialization time, instead of constantly reading global values. DEV: This means this class should be reconfigured on `Datadog.configure` calls, thus DEV: singleton instances should not used as they will become stale.
19 20 21 22 23 24 25 26 27 |
# File 'lib/datadog/tracing/distributed/propagation.rb', line 19 def initialize(propagation_styles:) @propagation_styles = propagation_styles # We need to make sure propagation_style option is evaluated. # Our options are lazy evaluated and it happens that propagation_style has the after_set callback # that affect Datadog.configuration.tracing.distributed_tracing.propagation_inject_style and # Datadog.configuration.tracing.distributed_tracing.propagation_extract_style # By calling it here, we make sure if the customers has set any value either via code or ENV variable is applied. ::Datadog.configuration.tracing.distributed_tracing.propagation_style end |
Instance Method Details
#extract(data) ⇒ Object
extract returns TraceDigest containing the distributed trace information. sampling priority defined in data.
This method will never raise errors, but instead log them to ‘Datadog.logger`.
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 |
# File 'lib/datadog/tracing/distributed/propagation.rb', line 80 def extract(data) return unless data return if data.empty? extracted_trace_digest = nil config = ::Datadog.configuration.tracing.distributed_tracing config.propagation_extract_style.each do |style| propagator = @propagation_styles[style] next if propagator.nil? begin if extracted_trace_digest # Return if we are only inspecting the first valid style. next if config.propagation_extract_first # Continue parsing styles to find the W3C `tracestate` header, if present. # `tracestate` must always be propagated, as it might contain pass-through data that we don't control. # @see https://www.w3.org/TR/2021/REC-trace-context-1-20211123/#mutating-the-tracestate-field next if style != Configuration::Ext::Distributed::PROPAGATION_STYLE_TRACE_CONTEXT if (tracecontext_digest = propagator.extract(data)) # Only parse if it represent the same trace as the successfully extracted one next unless tracecontext_digest.trace_id == extracted_trace_digest.trace_id # Preserve the `tracestate` extracted_trace_digest = extracted_trace_digest.merge( trace_state: tracecontext_digest.trace_state, trace_state_unknown_fields: tracecontext_digest.trace_state_unknown_fields ) end else extracted_trace_digest = propagator.extract(data) end rescue => e ::Datadog.logger.error( "Error extracting distributed trace data. Cause: #{e} Location: #{Array(e.backtrace).first}" ) end end extracted_trace_digest end |
#inject!(digest, data) ⇒ Boolean?
inject! populates the env with span ID, trace ID and sampling priority
This method will never raise errors, but instead log them to ‘Datadog.logger`.
DEV-2.0: inject! should work without arguments, injecting the active_trace’s digest DEV-2.0: and returning a new Hash with the injected data. DEV-2.0: inject! should also accept either a ‘trace` or a `digest`, as a `trace` DEV-2.0: argument is the common use case, but also allows us to set error tags in the `trace` DEV-2.0: if needed. DEV-2.0: Ideally, we’d have a separate stream to report tracer errors and never DEV-2.0: touch the active span.
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 |
# File 'lib/datadog/tracing/distributed/propagation.rb', line 45 def inject!(digest, data) if digest.nil? ::Datadog.logger.debug('Cannot inject distributed trace data: digest is nil.') return nil end digest = digest.to_digest if digest.respond_to?(:to_digest) result = false # Inject all configured propagation styles ::Datadog.configuration.tracing.distributed_tracing.propagation_inject_style.each do |style| propagator = @propagation_styles[style] begin if propagator propagator.inject!(digest, data) result = true end rescue => e result = nil ::Datadog.logger.error( "Error injecting distributed trace data. Cause: #{e} Location: #{Array(e.backtrace).first}" ) end end result end |