Module: OpenTelemetry::Exporter::Zipkin::Transformer Private

Extended by:
Transformer
Included in:
Transformer
Defined in:
lib/opentelemetry/exporter/zipkin/transformer.rb

This module is part of a private API. You should avoid using this module if possible, as it may be removed or be changed in the future.

Instance Method Summary collapse

Instance Method Details

#add_annotations(zipkin_span, span_data) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
# File 'lib/opentelemetry/exporter/zipkin/transformer.rb', line 100

def add_annotations(zipkin_span, span_data)
  # Tried to follow the below
  # https://github.com/open-telemetry/opentelemetry-collector/blob/347cfa9ab21d47240128c58c9bafcc0014bc729d/translator/trace/zipkin/traces_to_zipkinv2.go#L172
  # https://github.com/open-telemetry/opentelemetry-collector/blob/347cfa9ab21d47240128c58c9bafcc0014bc729d/translator/trace/zipkin/traces_to_zipkinv2.go#L183-L191
  # https://github.com/open-telemetry/opentelemetry-specification/blob/cb16422a61219d4fd99b466a70e47cb8af9e26b1/specification/trace/sdk_exporters/zipkin.md#events
  return if span_data.events.nil? || span_data.events.empty?

  events = span_data.events.map do |event|
    if event.attributes.keys.length.zero?
      {
        timestamp: (event.timestamp / 1_000).to_s,
        value: event.name
      }
    else
      {
        timestamp: (event.timestamp / 1_000).to_s,
        value: { event.name => event.attributes.transform_values(&:to_s) }.to_json
      }
    end
  end

  zipkin_span[:annotations] = events.map(&:to_h) unless events.empty?
end

#add_conditional_tags(zipkin_span, span_data, tags, service_name) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



91
92
93
94
95
96
97
98
# File 'lib/opentelemetry/exporter/zipkin/transformer.rb', line 91

def add_conditional_tags(zipkin_span, span_data, tags, service_name)
  zipkin_span['tags'] = tags unless tags.empty?
  zipkin_span['kind'] = KIND_MAP[span_data.kind] unless span_data.kind.nil?
  zipkin_span['parentId'] = span_data.hex_parent_span_id unless span_data.parent_span_id == OpenTelemetry::Trace::INVALID_SPAN_ID
  zipkin_span['localEndpoint'] = endpoint_from_tags(tags, (span_data.attributes && span_data.attributes[SERVICE_NAME_ATTRIBUTE_KEY]) || service_name)
  # remote endpoint logic https://github.com/open-telemetry/opentelemetry-collector/blob/347cfa9ab21d47240128c58c9bafcc0014bc729d/translator/trace/zipkin/traces_to_zipkinv2.go#L284
  zipkin_span['remoteEndpoint'] = endpoint_from_tags(tags, nil)
end

#add_il_tags(span_data, tags) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



73
74
75
76
# File 'lib/opentelemetry/exporter/zipkin/transformer.rb', line 73

def add_il_tags(span_data, tags)
  tags['otel.library.name'] = span_data.instrumentation_library.name
  tags['otel.library.version'] = span_data.instrumentation_library.version
end

#add_status_tags(span_data, tags) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/opentelemetry/exporter/zipkin/transformer.rb', line 78

def add_status_tags(span_data, tags)
  if span_data.status&.code == OpenTelemetry::Trace::Status::ERROR
    # mark errors if we can, setting error key to description but falling back to an empty string
    # https://github.com/open-telemetry/opentelemetry-specification/blob/84b18b23339dcc0b1a9d48f976a1afd287417602/specification/trace/sdk_exporters/zipkin.md#status
    # https://github.com/openzipkin/zipkin-ruby/blob/7bedb4dd162c4cbeffc7b97dd06c8dbccbfbab62/lib/zipkin-tracer/trace.rb#L259
    # https://github.com/open-telemetry/opentelemetry-collector/blob/81c7cc53b7067fbf3db4e1671b13bbe2796eb56e/translator/trace/zipkin/traces_to_zipkinv2.go#L144
    tags[ERROR_TAG_KEY] = span_data.status.description || ''
    tags[STATUS_CODE_NAME] = STATUS_ERROR
  elsif span_data.status&.code == OpenTelemetry::Trace::Status::OK
    tags[STATUS_CODE_NAME] = STATUS_OK
  end
end

#aggregate_span_tags(span_data, tags) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



124
125
126
127
128
129
130
131
132
# File 'lib/opentelemetry/exporter/zipkin/transformer.rb', line 124

def aggregate_span_tags(span_data, tags)
  # convert attributes to strings
  # https://github.com/open-telemetry/opentelemetry-specification/blob/84b18b23339dcc0b1a9d48f976a1afd287417602/specification/trace/sdk_exporters/zipkin.md#attribute
  return tags if span_data.attributes.nil?

  tags = tags.merge(span_data.attributes)

  tags.transform_values!(&:to_s)
end

#endpoint_from_tags(tags, service_name = nil) ⇒ Object



136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
# File 'lib/opentelemetry/exporter/zipkin/transformer.rb', line 136

def endpoint_from_tags(tags, service_name = nil)
  endpoint = {}

  if service_name
    endpoint['serviceName'] = service_name
    endpoint['port'] = tags[ATTRIBUTE_NET_HOST_PORT].to_s if tags[ATTRIBUTE_NET_HOST_PORT]

    if tags[ATTRIBUTE_NET_HOST_IP]
      ip_addr = IPAddr.new(tags[ATTRIBUTE_NET_HOST_IP])

      # https://github.com/openzipkin/zipkin-api/blob/7692ca7be4dc3be9225db550d60c4d30e6e9ec59/zipkin2-api.yaml#L292
      # https://github.com/openzipkin/zipkin-api/blob/7692ca7be4dc3be9225db550d60c4d30e6e9ec59/zipkin2-api.yaml#L286
      if ip_addr.ipv6?
        endpoint['ipv6'] = ip_addr.to_s
      else
        endpoint['ipv4'] = ip_addr.to_s
      end
    end
  else
    endpoint['port'] = tags[ATTRIBUTE_NET_PEER_PORT].to_s if tags[ATTRIBUTE_NET_PEER_PORT]

    if tags[ATTRIBUTE_NET_PEER_IP]
      ip_addr = IPAddr.new(tags[ATTRIBUTE_NET_PEER_IP])

      # https://github.com/openzipkin/zipkin-api/blob/7692ca7be4dc3be9225db550d60c4d30e6e9ec59/zipkin2-api.yaml#L292
      # https://github.com/openzipkin/zipkin-api/blob/7692ca7be4dc3be9225db550d60c4d30e6e9ec59/zipkin2-api.yaml#L286
      if ip_addr.ipv6?
        endpoint['ipv6'] = ip_addr.to_s
      else
        endpoint['ipv4'] = ip_addr.to_s
      end
    end
  end

  endpoint
end

#to_zipkin_span(span_d, resource) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



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
# File 'lib/opentelemetry/exporter/zipkin/transformer.rb', line 40

def to_zipkin_span(span_d, resource)
  start_time = span_d.start_timestamp / 1_000
  duration = span_d.end_timestamp / 1_000 - start_time
  tags = {}
  service_name = DEFAULT_SERVICE_NAME
  resource.attribute_enumerator.select do |key, value|
    service_name = value if key == SERVICE_NAME_ATTRIBUTE_KEY
  end

  add_il_tags(span_d, tags)
  add_status_tags(span_d, tags)
  tags = aggregate_span_tags(span_d, tags)

  # TOOO: set debug flag? (is that represented in tracestate?)
  # https://github.com/openzipkin/b3-propagation#why-is-debug-encoded-as-x-b3-flags-1
  # https://github.com/openzipkin/zipkin-api/blob/7692ca7be4dc3be9225db550d60c4d30e6e9ec59/zipkin2-api.yaml#L475
  # TODO: shared key mapping

  zipkin_span = {
    name: span_d.name,
    traceId: span_d.hex_trace_id,
    id: span_d.hex_span_id,
    timestamp: start_time,
    duration: duration,
    debug: false
  }

  add_conditional_tags(zipkin_span, span_d, tags, service_name)
  add_annotations(zipkin_span, span_d)

  zipkin_span
end