Module: Bitfab::Otel::Encoder

Defined in:
lib/bitfab/otel.rb

Overview

Turns finished carrier spans into the OTLP/JSON shapes Bitfab ingests.

Class Method Summary collapse

Class Method Details

.encode_request(envelope, spans) ⇒ Object



713
714
715
# File 'lib/bitfab/otel.rb', line 713

def encode_request(envelope, spans)
  envelope.head + spans.map(&:encoded).join(",") + envelope.tail
end

.encode_span(span) ⇒ Object



683
684
685
686
687
688
# File 'lib/bitfab/otel.rb', line 683

def encode_span(span)
  encoded = JSON.generate(span_to_otlp(span))
  payload = span.attributes&.fetch(PAYLOAD_ATTRIBUTE, nil)
  ref = payload&.instance_variable_get(CARRIER_REF_IVAR)
  EncodedSpan.new(encoded, encoded.bytesize, ref)
end

.request_envelope(first) ⇒ Object



704
705
706
707
708
709
710
711
# File 'lib/bitfab/otel.rb', line 704

def request_envelope(first)
  scope = first.instrumentation_scope
  resource = JSON.generate({"attributes" => attributes(first.resource.attribute_enumerator.to_h)})
  scope_json = JSON.generate({"name" => scope.name, "version" => scope.version || ""})
  head = %({"resourceSpans":[{"resource":#{resource},"scopeSpans":[{"scope":#{scope_json},"spans":[)
  tail = "]}]}]}"
  RequestEnvelope.new(head, tail, (head + tail).bytesize)
end

.span_to_otlp(span) ⇒ Object



717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
# File 'lib/bitfab/otel.rb', line 717

def span_to_otlp(span)
  result = {
    "traceId" => span.hex_trace_id,
    "spanId" => span.hex_span_id,
    "name" => span.name,
    "kind" => SPAN_KINDS.fetch(span.kind, 1),
    "startTimeUnixNano" => (span.start_timestamp || 0).to_s,
    "endTimeUnixNano" => (span.end_timestamp || 0).to_s,
    "attributes" => attributes(span.attributes),
    "droppedAttributesCount" => dropped_count(span.total_recorded_attributes, span.attributes),
    "droppedEventsCount" => dropped_count(span.total_recorded_events, span.events),
    "droppedLinksCount" => dropped_count(span.total_recorded_links, span.links),
    "status" => status(span.status),
    "flags" => span.trace_flags.sampled? ? 1 : 0
  }
  result["parentSpanId"] = span.hex_parent_span_id unless span.parent_span_id == INVALID_SPAN_ID
  tracestate = span.tracestate&.to_s
  result["traceState"] = tracestate unless tracestate.nil? || tracestate.empty?
  result
end

.trim_span(span) ⇒ Object



690
691
692
693
694
695
696
697
698
699
700
701
702
# File 'lib/bitfab/otel.rb', line 690

def trim_span(span)
  carrier = JSON.parse(span.encoded)
  attribute = carrier.fetch("attributes").find { |entry| entry["key"] == PAYLOAD_ATTRIBUTE }
  return nil if attribute.nil?

  value = attribute.fetch("value")
  payload = JSON.parse(value.fetch("stringValue"))
  value["stringValue"] = Serialize.safe_generate(payload)
  encoded = JSON.generate(carrier)
  EncodedSpan.new(encoded, encoded.bytesize)
rescue KeyError, JSON::ParserError, TypeError
  nil
end