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.



110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
# File 'lib/opentelemetry/exporter/zipkin/transformer.rb', line 110

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.

rubocop:disable Metrics/CyclomaticComplexity



94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
# File 'lib/opentelemetry/exporter/zipkin/transformer.rb', line 94

def add_conditional_tags(zipkin_span, span_data, tags, service_name) # rubocop:disable Metrics/CyclomaticComplexity
  dropped_attributes_count = span_data.total_recorded_attributes - span_data.attributes&.size.to_i
  dropped_events_count = span_data.total_recorded_events - span_data.events&.size.to_i
  dropped_links_count = span_data.total_recorded_links - span_data.links&.size.to_i
  tags['otel.dropped_attributes_count'] = dropped_attributes_count.to_s if dropped_attributes_count.positive?
  tags['otel.dropped_events_count'] = dropped_events_count.to_s if dropped_events_count.positive?
  tags['otel.dropped_links_count'] = dropped_links_count.to_s if dropped_links_count.positive?

  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_scope_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
77
78
79
# File 'lib/opentelemetry/exporter/zipkin/transformer.rb', line 73

def add_scope_tags(span_data, tags)
  tags['otel.scope.name'] = span_data.instrumentation_scope.name
  tags['otel.library.name'] = span_data.instrumentation_scope.name

  tags['otel.scope.version'] = span_data.instrumentation_scope.version
  tags['otel.library.version'] = span_data.instrumentation_scope.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.



81
82
83
84
85
86
87
88
89
90
91
92
# File 'lib/opentelemetry/exporter/zipkin/transformer.rb', line 81

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.



134
135
136
137
138
139
140
141
142
# File 'lib/opentelemetry/exporter/zipkin/transformer.rb', line 134

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



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
172
173
174
175
176
177
178
179
180
181
# File 'lib/opentelemetry/exporter/zipkin/transformer.rb', line 146

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_scope_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