Module: Datadog::Tracing::Distributed::DatadogTagsCodec

Defined in:
lib/datadog/tracing/distributed/datadog_tags_codec.rb

Overview

Encodes and decodes distributed ‘x-datadog-tags’ tags for transport to and from external processes.

Defined Under Namespace

Modules: RefineRegexp Classes: DecodingError, EncodingError

Constant Summary collapse

VALID_KEY_CHARS =

ASCII characters 32-126, except ‘,`, `=`, and ` `. At least one character.

/\A(?:(?![,= ])[\u0020-\u007E])+\Z/.freeze
VALID_VALUE_CHARS =

ASCII characters 32-126, except ‘,`. At least one character.

/\A(?:(?!,)[\u0020-\u007E])+\Z/.freeze

Class Method Summary collapse

Class Method Details

.decode(string) ⇒ Hash<String,String>

Deserializes a ‘x-datadog-tags`-formatted String into a Hash<String,String>.

Parameters:

  • string (String)

    tags as serialized by #encode

Returns:

  • (Hash<String,String>)

    decoded input as a hash of strings

Raises:

  • (DecodingError)

    if string does not conform to the ‘x-datadog-tags` format



54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/datadog/tracing/distributed/datadog_tags_codec.rb', line 54

def self.decode(string)
  result = Hash[string.split(',').map do |raw_tag|
    raw_tag.split('=', 2).tap do |raw_key, raw_value|
      key = raw_key.to_s
      value = raw_value.to_s

      raise DecodingError, "Invalid key: #{key}" unless VALID_KEY_CHARS.match?(key)
      raise DecodingError, "Invalid value: #{value}" unless VALID_VALUE_CHARS.match?(value)

      value.strip!
    end
  end]

  raise DecodingError, "Invalid empty tags: #{string}" if result.empty? && !string.empty?

  result
end

.encode(tags) ⇒ String

Serializes a Hash<String,String> into a ‘x-datadog-tags`-compatible String.

Parameters:

  • tags (Hash<String,String>)

    trace tag hash

Returns:

  • (String)

    serialized tags hash

Raises:

  • (EncodingError)

    if tags cannot be serialized to the ‘x-datadog-tags` format



33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/datadog/tracing/distributed/datadog_tags_codec.rb', line 33

def self.encode(tags)
  begin
    tags.map do |raw_key, raw_value|
      key = raw_key.to_s
      value = raw_value.to_s

      raise EncodingError, "Invalid key `#{key}` for value `#{value}`" unless VALID_KEY_CHARS.match?(key)
      raise EncodingError, "Invalid value `#{value}` for key `#{key}`" unless VALID_VALUE_CHARS.match?(value)

      "#{key}=#{value.strip}"
    end.join(',')
  rescue => e
    raise EncodingError, "Error encoding tags `#{tags}`: `#{e}`"
  end
end