CodeNameRaven.Display behaviour (raven_observer_display_sdk v0.2.0)

Copy Markdown

The display behaviour for a Raven integration.

Handles the dashboard panel: rendering, layout hints, data preparation before the render cycle, and optional user interaction handling.

Relationship to Monitor

CodeNameRaven.Monitor defines the collection side — collect/2, healthy?/1, metrics/1, and the collection lifecycle. CodeNameRaven.Display defines the display side — what the panel looks like, how large it is, and how it responds to user interaction. The two can live in the same module or in separate modules:

Single-module (common case):

defmodule Integrations.Http do
  use CodeNameRaven.Monitor
  use CodeNameRaven.Display, size_hint: :small

  @impl CodeNameRaven.Monitor
  def collect(params, state), do: ...

  @impl CodeNameRaven.Monitor
  def healthy?(result), do: ...

  @impl CodeNameRaven.Display
  def render(assigns) do
    ~H"..."
  end
end

Two-module (collection/display separation):

# Collection side — may run on any node, including headless collectors
defmodule Integrations.Database do
  use CodeNameRaven.Monitor

  @impl true
  def collect(params, state), do: ...

  @impl true
  def healthy?(result), do: ...
end

# Display side — runs only on nodes with raven_web
defmodule Integrations.Database.Panel do
  use CodeNameRaven.Display, size_hint: :large

  @impl true
  def render(assigns) do
    ~H"..."
  end
end

CodeNameRaven.Monitor never provides a display default of any kind — no render/1, no category/0, nothing. A module gets a working panel only by adding use CodeNameRaven.Display itself, whether bundled alongside Monitor in the same module or as a companion module. There is no implicit shim and no backwards-compatibility path between the two behaviours.

Callbacks

Summary

Callbacks

Returns the category this integration belongs to.

Declares which Monitor module(s) this display knows how to render.

Returns the API version this display module was written against.

Builds the display's initial subscriber state.

Returns the human-readable name for this integration.

Handles a metric event from a watched monitor.

Handles a status event from a watched monitor.

Handles a LiveView event routed from the dashboard to this panel.

Returns a structured layout specification for the panel.

Enriches the assigns map before render/1 is called.

Renders the integration's dashboard panel.

Declares the preferred panel size for the dashboard layout engine.

Functions

Returns the current Display API version of the SDK.

Returns true if the display module's declared display_api_version/0 falls within the supported range of this SDK.

Returns true if the given module implements the Display behaviour.

Returns true if the given module has actually opted into the Display.Server subscriber runtime (display_init/1, on_metric/3, on_status/3) — narrower than display_module?/1.

Returns the minimum Display API version supported by the SDK.

Types

category()

@type category() :: atom()

size_hint()

@type size_hint() :: :small | :medium | :large | :full

Callbacks

category()

@callback category() :: category()

Returns the category this integration belongs to.

Used to group integrations in the catalogue UI. Use a built-in category atom or define your own. The default is :custom.

compatible_monitors()

@callback compatible_monitors() :: [module()]

Declares which Monitor module(s) this display knows how to render.

Used by the instance-configuration UI to filter which monitors can be added to a watch-list for this display — not consulted for any automatic, type-wide enablement.

The default is an empty list.

display_api_version()

@callback display_api_version() :: pos_integer()

Returns the API version this display module was written against.

Defaults to 2. Used by the host application to verify compatibility with the currently running version of raven_sdk_display.

display_init(params)

@callback display_init(params :: map()) :: {:ok, term()} | {:error, String.t()}

Builds the display's initial subscriber state.

Called once when a configured Display instance starts, before it begins receiving metric/status messages from the DataBus. The returned state is threaded through display_on_metric/3/display_on_status/3 and is what those callbacks accumulate into over the instance's lifetime.

The default returns an empty map.

display_name()

@callback display_name() :: String.t()

Returns the human-readable name for this integration.

Shown in the monitor catalogue and as the default panel title. The default derives a name from the module name (e.g. Integrations.Http"Http").

display_on_metric(metric, params, state)

@callback display_on_metric(metric :: term(), params :: map(), state :: term()) ::
  {:ok, term()}

Handles a metric event from a watched monitor.

Called only for monitors on this Display instance's watch-list — the runtime filters everything else before this callback is reached. metric is a CodeNameRaven.DataBus.MonitorMetric struct at runtime — not typed as such here since raven_sdk does not (yet) publish CodeNameRaven.DataBus. Return the updated subscriber state.

The default leaves state unchanged.

display_on_status(status, params, state)

@callback display_on_status(status :: term(), params :: map(), state :: term()) ::
  {:ok, term()}

Handles a status event from a watched monitor.

Same watch-list filtering as display_on_metric/3. status is a CodeNameRaven.DataBus.MonitorStatus struct at runtime, same caveat as display_on_metric/3. Return the updated subscriber state.

The default leaves state unchanged.

handle_ui_event(event, params, socket)

@callback handle_ui_event(
  event :: String.t(),
  params :: map(),
  socket :: Phoenix.LiveView.Socket.t()
) :: {:noreply, Phoenix.LiveView.Socket.t()}

Handles a LiveView event routed from the dashboard to this panel.

Called when the dashboard LiveView receives a phx-click or phx-change event scoped to this panel. Receives the event name, the event params, and the current socket. Return {:noreply, socket} to update state and re-render.

The default is a no-op that leaves the socket unchanged.

layout()

@callback layout() :: map() | nil

Returns a structured layout specification for the panel.

Used by the layout engine for placement control beyond the coarse size hint. Return nil (the default) to let the engine derive placement from size_hint/0 alone. Reserved for future layout engine extensions — the shape of this map is not yet stable.

prepare_assigns(assigns)

@callback prepare_assigns(assigns :: map()) :: map()

Enriches the assigns map before render/1 is called.

Called once per dashboard tick, outside the render cycle. Use this to fetch data (DB queries, sample reads) that should not happen on every render pass. The returned map is passed directly to render/1.

The default is the identity function.

render(assigns)

@callback render(assigns :: map()) :: Phoenix.LiveView.Rendered.t()

Renders the integration's dashboard panel.

Called by the LiveView dashboard. Receives the assigns map built by Raven and enriched by prepare_assigns/1. Compose from CodeNameRaven.MonitorComponents or write raw HEEx.

This callback has no useful default — it must be implemented.

size_hint()

@callback size_hint() :: size_hint()

Declares the preferred panel size for the dashboard layout engine.

The engine uses this as a hint, not a hard constraint.

  • :small — compact status indicator; one or two values
  • :medium — a handful of metrics; default
  • :large — multiple metric groups or a chart
  • :full — full dashboard width; complex or multi-section displays

Functions

current_display_api_version()

@spec current_display_api_version() :: pos_integer()

Returns the current Display API version of the SDK.

display_api_version_supported?(module)

@spec display_api_version_supported?(module()) :: boolean()

Returns true if the display module's declared display_api_version/0 falls within the supported range of this SDK.

display_module?(module)

@spec display_module?(module()) :: boolean()

Returns true if the given module implements the Display behaviour.

Mirrors CodeNameRaven.Monitor.monitor_module?/1 — checks for render/1, the one truly-required Display callback, the same way Monitor checks for collect/2/healthy?/1.

display_server_module?(module)

@spec display_server_module?(module()) :: boolean()

Returns true if the given module has actually opted into the Display.Server subscriber runtime (display_init/1, on_metric/3, on_status/3) — narrower than display_module?/1.

The two checks usually agree — use CodeNameRaven.Display provides both render/1 and display_init/1 together. They can diverge for a module that hand-writes render/1 itself without the macro (implementing the behaviour directly rather than use-ing it) — display_module?/1 would see it as renderable, but it never got display_init/1. Use this check wherever a real Display.Server instance is about to be started for the module (e.g. bundled-default auto-fill, which needs display_init/1 to exist or Display.Server.init/1 crashes) — not the dashboard-card-rendering check display_module?/1 is for.

min_supported_display_api_version()

@spec min_supported_display_api_version() :: pos_integer()

Returns the minimum Display API version supported by the SDK.