Bloccs.Web.Telemetry.Metrics (bloccs_web v0.1.0)

Copy Markdown View Source

The pure functional core of the metrics collector: folds normalized bloccs telemetry into per-node rolling windows and renders a snapshot. No processes, no clock of its own — now (monotonic ms) is always passed in, so the whole thing is deterministically testable with synthetic events.

Normalized events (produced by Bloccs.Web.Telemetry.Handler):

  • {:start, node} — a message entered the node
  • {:stop, node, duration_ms, :ok | :failed} — it finished

  • {:exception, node} — it raised
  • {:event, node, kind} — retry / skipped / dropped / dispatch_error

A node's state (:idle | :running | :ok | :failed) drives the topology glyph; the windowed stats drive the metrics panel.

Summary

Functions

Render a {node => view} snapshot, pruning samples older than the window.

Types

event()

@type event() ::
  {:start, atom()}
  | {:stop, atom(), number(), :ok | :failed}
  | {:exception, atom()}
  | {:event, atom(), atom()}

node_state()

@type node_state() :: %{
  completed: non_neg_integer(),
  errors: non_neg_integer(),
  events: non_neg_integer(),
  samples: [{integer(), number()}],
  state: :idle | :running | :ok | :failed,
  last_at: integer() | nil
}

node_view()

@type node_view() :: %{
  state: atom(),
  completed: non_neg_integer(),
  errors: non_neg_integer(),
  error_rate: float(),
  throughput: float(),
  p50: number() | nil,
  p95: number() | nil
}

t()

@type t() :: %{optional(atom()) => node_state()}

Functions

apply(nodes, arg2, now)

@spec apply(t(), event(), integer()) :: t()

new()

@spec new() :: t()

snapshot(nodes, now)

@spec snapshot(t(), integer()) :: %{
  nodes: %{required(atom()) => node_view()},
  updated_at: integer()
}

Render a {node => view} snapshot, pruning samples older than the window.