Class: Datadog::Tracing::Distributed::Baggage

Inherits:
Object
  • Object
show all
Defined in:
lib/datadog/tracing/distributed/baggage.rb

Overview

W3C Baggage propagator implementation. The baggage header is propagated through ‘baggage`.

Constant Summary collapse

BAGGAGE_KEY =
'baggage'
DD_TRACE_BAGGAGE_MAX_ITEMS =
64
DD_TRACE_BAGGAGE_MAX_BYTES =
8192
SAFE_CHARACTERS_KEY =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789$!#&'*+-.^_`|~"
SAFE_CHARACTERS_VALUE =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789$!#&'()*+-./:<>?@[]^_`{|}~"

Instance Method Summary collapse

Constructor Details

#initialize(fetcher:, baggage_key: BAGGAGE_KEY) ⇒ Baggage

Returns a new instance of Baggage.



23
24
25
26
27
28
29
# File 'lib/datadog/tracing/distributed/baggage.rb', line 23

def initialize(
  fetcher:,
  baggage_key: BAGGAGE_KEY
)
  @baggage_key = baggage_key
  @fetcher = fetcher
end

Instance Method Details

#extract(data) ⇒ Object



67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/datadog/tracing/distributed/baggage.rb', line 67

def extract(data)
  fetcher = @fetcher.new(data)
  data = fetcher[@baggage_key]
  return unless data

  baggage = parse_baggage_header(fetcher[@baggage_key])
  return unless baggage

  TraceDigest.new(
    baggage: baggage,
  )
end

#inject!(digest, data) ⇒ Object



31
32
33
34
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
# File 'lib/datadog/tracing/distributed/baggage.rb', line 31

def inject!(digest, data)
  return if digest.nil? || digest.baggage.nil?

  baggage_items = digest.baggage.reject { |k, v| k.nil? || v.nil? }
  return if baggage_items.empty?

  begin
    if baggage_items.size > DD_TRACE_BAGGAGE_MAX_ITEMS
      ::Datadog.logger.warn('Baggage item limit exceeded, dropping excess items')
      baggage_items = baggage_items.first(DD_TRACE_BAGGAGE_MAX_ITEMS)
    end

    encoded_items = []
    total_size = 0

    baggage_items.each do |key, value|
      item = "#{encode_item(key, SAFE_CHARACTERS_KEY)}=#{encode_item(value, SAFE_CHARACTERS_VALUE)}"
      item_size = item.bytesize + (encoded_items.empty? ? 0 : 1) # +1 for comma if not first item
      if total_size + item_size > DD_TRACE_BAGGAGE_MAX_BYTES
        ::Datadog.logger.warn('Baggage header size exceeded, dropping excess items')
        break # stop adding items when size limit is reached
      end
      encoded_items << item
      total_size += item_size
    end

    # edge case where a single item is too large
    return if encoded_items.empty?

    header_value = encoded_items.join(',')
    data[@baggage_key] = header_value
  rescue => e
    ::Datadog.logger.warn("Failed to encode and inject baggage header: #{e.message}")
  end
end