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
- .encode_request(envelope, spans) ⇒ Object
- .encode_span(span) ⇒ Object
- .error?(payload) ⇒ Boolean
- .request_envelope(first) ⇒ Object
- .span_name(operation, payload) ⇒ Object
- .span_to_otlp(span) ⇒ Object
- .timestamp(payload, field) ⇒ Object
- .trim_span(span) ⇒ Object
Class Method Details
.encode_request(envelope, spans) ⇒ Object
669 670 671 |
# File 'lib/bitfab/otel.rb', line 669 def encode_request(envelope, spans) envelope.head + spans.map(&:encoded).join(",") + envelope.tail end |
.encode_span(span) ⇒ Object
641 642 643 644 |
# File 'lib/bitfab/otel.rb', line 641 def encode_span(span) encoded = JSON.generate(span_to_otlp(span)) EncodedSpan.new(encoded, encoded.bytesize) end |
.error?(payload) ⇒ Boolean
720 721 722 723 724 725 726 |
# File 'lib/bitfab/otel.rb', line 720 def error?(payload) raw_span = payload["rawSpan"] return true if raw_span.is_a?(Hash) && !raw_span.dig("span_data", "error").nil? errors = payload["errors"] errors.is_a?(Array) && !errors.empty? end |
.request_envelope(first) ⇒ Object
660 661 662 663 664 665 666 667 |
# File 'lib/bitfab/otel.rb', line 660 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_name(operation, payload) ⇒ Object
694 695 696 697 698 699 700 701 702 703 |
# File 'lib/bitfab/otel.rb', line 694 def span_name(operation, payload) raw_span = payload["rawSpan"] if operation == "external_span" && raw_span.is_a?(Hash) name = raw_span.dig("span_data", "name") return name if name.is_a?(String) end return payload["traceFunctionKey"] if payload["traceFunctionKey"].is_a?(String) "bitfab.#{operation}" end |
.span_to_otlp(span) ⇒ Object
673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 |
# File 'lib/bitfab/otel.rb', line 673 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. || 0).to_s, "endTimeUnixNano" => (span. || 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 |
.timestamp(payload, field) ⇒ Object
705 706 707 708 709 710 711 712 713 714 715 716 717 718 |
# File 'lib/bitfab/otel.rb', line 705 def (payload, field) raw = payload.dig("rawSpan", field) if payload["rawSpan"].is_a?(Hash) if raw.nil? raw_trace = payload["externalTrace"] || payload["rawTrace"] raw = raw_trace[field] if raw_trace.is_a?(Hash) end return Time.now unless raw.is_a?(String) begin Time.iso8601(raw) rescue ArgumentError Time.now end end |
.trim_span(span) ⇒ Object
646 647 648 649 650 651 652 653 654 655 656 657 658 |
# File 'lib/bitfab/otel.rb', line 646 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 |