:telemetry integration for raster_ex_ratatui.
Mirrors the shape of ExRatatui.Telemetry one layer up: events fire at the boundaries this package controls (surface lifecycle, rasterisation, the consumer's push/2, input forwarding) rather than at the runtime layer ex_ratatui already instruments. Both trees fire concurrently while a surface runs; attach handlers to whichever is needed.
Events
All events are prefixed with :raster_ex_ratatui.
Span events (:start / :stop / :exception)
| Event | Description | Metadata |
|---|---|---|
[:raster_ex_ratatui, :frame, :raster] | RasterExRatatui.Raster.apply/2 on the diffs waiting from the app server. | :surface, :mod, :pid; :stop adds :diffs (how many were folded into this call), :cells, :regions, :patches |
[:raster_ex_ratatui, :frame, :push] | The consumer's RasterExRatatui.Surface.push/2 call. | :surface, :mod, :pid, :push_mode |
:surface is the surface module, :mod the app module, and :pid the surface process, which tells apart several surfaces running the same modules.
:start events carry %{monotonic_time: integer, system_time: integer} as measurements. :stop events add :duration (native units). On exception the metadata gains :kind, :reason, and :stacktrace.
Single events
| Event | Description | Measurements | Metadata |
|---|---|---|---|
[:raster_ex_ratatui, :surface, :start] | The surface built its raster and started the app server. | %{system_time: integer} | :surface, :mod, :pid, :size, :grid_size |
[:raster_ex_ratatui, :surface, :stop] | The surface is terminating. | %{system_time: integer} | :surface, :mod, :pid, :reason |
[:raster_ex_ratatui, :app, :exit] | The app server exited; :action is what the surface does about it per its on_app_exit: option, :stop or :restart. | %{system_time: integer} | :surface, :mod, :pid, :reason, :action |
[:raster_ex_ratatui, :input, :forward] | An event was forwarded to the app server. | %{system_time: integer} | :surface, :mod, :pid, :event |
Attaching a default logger
RasterExRatatui.Telemetry.attach_default_logger(level: :info)That attaches a handler logging every :stop and single event. Detach with detach_default_logger/0.
Summary
Functions
Attaches a logger that prints every raster_ex_ratatui telemetry event. Useful during development; detach with detach_default_logger/0.
Detaches the logger attached with attach_default_logger/1.
Emits a single :telemetry event rooted at [:raster_ex_ratatui | event].
Watches one surface for seconds and reports how it keeps up: for the raster and push spans, how many ran, and their median, 90th percentile, and slowest duration in milliseconds, plus the surface's mailbox length before and after. Meant for an IEx session on the device.
Wraps fun in a :telemetry span rooted at [:raster_ex_ratatui | event].
Functions
@spec attach_default_logger(keyword()) :: :ok | {:error, :already_exists}
Attaches a logger that prints every raster_ex_ratatui telemetry event. Useful during development; detach with detach_default_logger/0.
Options
:level— log level (default::debug).:events— list of full event names to attach (default: every:stop,:exception, and single event).
@spec detach_default_logger() :: :ok | {:error, :not_found}
Detaches the logger attached with attach_default_logger/1.
Emits a single :telemetry event rooted at [:raster_ex_ratatui | event].
:system_time is added to the measurements when not already present.
Examples
iex> RasterExRatatui.Telemetry.execute([:input, :forward], %{}, %{mod: MyApp})
:ok
@spec probe(GenServer.server(), number(), keyword()) :: %{ raster: map() | nil, push: map() | nil, mailbox: {non_neg_integer(), non_neg_integer()} }
Watches one surface for seconds and reports how it keeps up: for the raster and push spans, how many ran, and their median, 90th percentile, and slowest duration in milliseconds, plus the surface's mailbox length before and after. Meant for an IEx session on the device.
RasterExRatatui.Telemetry.probe(MyDevice.Surface, 10)
raster: n=56 in 10s median=42.6ms p90=65.0ms max=70.8ms
push: n=56 in 10s median=12.8ms p90=15.2ms max=27.2ms
surface mailbox: 0 -> 0Reading it: raster is the cost of turning renders into pixels and push the cost of the device write, so their sum bounds the frame rate; a raster count well below the app's render rate means renders were folded together (see [:raster_ex_ratatui, :frame, :raster]'s :diffs); a mailbox that grows during the probe means the surface is falling behind.
Returns the same figures as a map, %{raster: stats | nil, push: stats | nil, mailbox: {before, after}}, where stats is %{n:, median:, p90:, max:} in milliseconds. Pass print: false to skip the report.
Wraps fun in a :telemetry span rooted at [:raster_ex_ratatui | event].
fun returns {result, stop_meta}; result is returned and stop_meta is merged over meta for the :stop event, which is how counts known only after the work (patches produced, for instance) reach handlers.
Examples
iex> RasterExRatatui.Telemetry.span([:frame, :raster], %{mod: MyApp}, fn -> {:done, %{patches: 3}} end)
:done