-module(lightspeed@ops@telemetry). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]). -define(FILEPATH, "src/lightspeed/ops/telemetry.gleam"). -export([from_session_event/1, receive_span/5, span_status_label/1, metric_line/1]). -export_type([tag/0, metric/0, span_status/0, span/0]). -if(?OTP_RELEASE >= 27). -define(MODULEDOC(Str), -moduledoc(Str)). -define(DOC(Str), -doc(Str)). -else. -define(MODULEDOC(Str), -compile([])). -define(DOC(Str), -compile([])). -endif. ?MODULEDOC(" Metrics and tracing primitives for production observability.\n"). -type tag() :: {tag, binary(), binary()}. -type metric() :: {counter, binary(), integer(), list(tag())} | {gauge, binary(), integer(), list(tag())}. -type span_status() :: span_ok | {span_error, binary()}. -type span() :: {span, binary(), binary(), integer(), integer(), span_status(), list(tag())}. -file("src/lightspeed/ops/telemetry.gleam", 36). ?DOC(" Translate one session telemetry event into metric points.\n"). -spec from_session_event(lightspeed@agent@session:telemetry_event()) -> list(metric()). from_session_event(Event) -> case Event of {session_mounted, Session_id, Route} -> [{counter, <<"lightspeed.session.mounted_total"/utf8>>, 1, [{tag, <<"session_id"/utf8>>, Session_id}, {tag, <<"route"/utf8>>, Route}]}]; {session_rehydrated, Session_id@1, Route@1} -> [{counter, <<"lightspeed.session.rehydrated_total"/utf8>>, 1, [{tag, <<"session_id"/utf8>>, Session_id@1}, {tag, <<"route"/utf8>>, Route@1}]}]; {session_remounted, Session_id@2, Route@2} -> [{counter, <<"lightspeed.session.remounted_total"/utf8>>, 1, [{tag, <<"session_id"/utf8>>, Session_id@2}, {tag, <<"route"/utf8>>, Route@2}]}]; {counter_updated, Session_id@3, Value} -> [{counter, <<"lightspeed.session.counter_updates_total"/utf8>>, 1, [{tag, <<"session_id"/utf8>>, Session_id@3}]}, {gauge, <<"lightspeed.session.counter_value"/utf8>>, Value, [{tag, <<"session_id"/utf8>>, Session_id@3}]}]; {patch_queued, Session_id@4, _} -> [{counter, <<"lightspeed.session.patch_queued_total"/utf8>>, 1, [{tag, <<"session_id"/utf8>>, Session_id@4}]}]; {patch_acked, Session_id@5, _} -> [{counter, <<"lightspeed.session.patch_acked_total"/utf8>>, 1, [{tag, <<"session_id"/utf8>>, Session_id@5}]}]; {heartbeat_received, Session_id@6, _} -> [{counter, <<"lightspeed.session.heartbeat_received_total"/utf8>>, 1, [{tag, <<"session_id"/utf8>>, Session_id@6}]}]; {heartbeat_timed_out, Session_id@7, _} -> [{counter, <<"lightspeed.session.heartbeat_timeout_total"/utf8>>, 1, [{tag, <<"session_id"/utf8>>, Session_id@7}]}]; {session_crashed, Session_id@8, _} -> [{counter, <<"lightspeed.session.crashed_total"/utf8>>, 1, [{tag, <<"session_id"/utf8>>, Session_id@8}]}]; {session_restarted, Session_id@9} -> [{counter, <<"lightspeed.session.restarted_total"/utf8>>, 1, [{tag, <<"session_id"/utf8>>, Session_id@9}]}]; {session_shutdown, Session_id@10, _} -> [{counter, <<"lightspeed.session.shutdown_total"/utf8>>, 1, [{tag, <<"session_id"/utf8>>, Session_id@10}]}]; {ownership_rejected, Session_id@11, _} -> [{counter, <<"lightspeed.session.ownership_rejected_total"/utf8>>, 1, [{tag, <<"session_id"/utf8>>, Session_id@11}]}]; {event_ignored, Session_id@12, Event_name} -> [{counter, <<"lightspeed.session.event_ignored_total"/utf8>>, 1, [{tag, <<"session_id"/utf8>>, Session_id@12}, {tag, <<"event_name"/utf8>>, Event_name}]}] end. -file("src/lightspeed/ops/telemetry.gleam", 132). ?DOC(" Build a receive span for transport traces.\n"). -spec receive_span(binary(), binary(), integer(), integer(), span_status()) -> span(). receive_span(Session_id, Frame_tag, Start_ms, End_ms, Status) -> {span, <<"lightspeed.transport.receive"/utf8>>, Session_id, Start_ms, End_ms, Status, [{tag, <<"frame_tag"/utf8>>, Frame_tag}]}. -file("src/lightspeed/ops/telemetry.gleam", 150). ?DOC(" Convert span status to a stable label.\n"). -spec span_status_label(span_status()) -> binary(). span_status_label(Status) -> case Status of span_ok -> <<"ok"/utf8>>; {span_error, _} -> <<"error"/utf8>> end. -file("src/lightspeed/ops/telemetry.gleam", 177). -spec render_tags(list(tag())) -> binary(). render_tags(Tags) -> case Tags of [] -> <<""/utf8>>; [{tag, Key, Value}] -> <<<>/binary, Value@1/binary>>/binary, ","/utf8>>/binary, (render_tags(Rest))/binary>> end. -file("src/lightspeed/ops/telemetry.gleam", 158). ?DOC(" Render one metric as a log-friendly line.\n"). -spec metric_line(metric()) -> binary(). metric_line(Metric) -> case Metric of {counter, Name, Value, Tags} -> <<<<<<<<<<"counter "/utf8, Name/binary>>/binary, " "/utf8>>/binary, (erlang:integer_to_binary(Value))/binary>>/binary, " "/utf8>>/binary, (render_tags(Tags))/binary>>; {gauge, Name@1, Value@1, Tags@1} -> <<<<<<<<<<"gauge "/utf8, Name@1/binary>>/binary, " "/utf8>>/binary, (erlang:integer_to_binary(Value@1))/binary>>/binary, " "/utf8>>/binary, (render_tags(Tags@1))/binary>> end.