TermUI.Widgets.ClusterDashboard (TermUI v1.0.0)

View Source

ClusterDashboard widget for visualizing distributed Erlang clusters.

ClusterDashboard displays cluster connectivity, node health metrics, cross-node process registries, and connection events. It provides tools for monitoring and debugging distributed BEAM applications.

Usage

ClusterDashboard.new(
  update_interval: 2000,
  show_health_metrics: true,
  show_pg_groups: true
)

Features

  • Connected nodes list with status indicators
  • Node health metrics (CPU, memory, scheduler utilization)
  • Cross-node process registry (:global names)
  • PG group membership visualization
  • Network partition detection and alerts
  • Node connection/disconnection event log
  • RPC interface for remote node inspection

Keyboard Controls

  • Up/Down: Navigate node/item list
  • PageUp/PageDown: Scroll by page
  • Enter: Toggle details panel
  • r: Refresh now
  • g: Show :global names view
  • p: Show :pg groups view
  • n: Show nodes view
  • e: Show events view
  • i: Inspect selected node (RPC details)
  • Escape: Close details

Refresh and node-event integration

init/1 captures an initial snapshot. The Elm runtime does not invoke this widget's mount/1 or handle_info/2. An embedded root should schedule a Command.interval/2, call ClusterDashboard.refresh/1 from update/2, and explicitly forward node events if it enables :net_kernel monitoring. A custom host can instead own the widget lifecycle and message routing.

Summary

Functions

Check if cluster is distributed.

Get currently selected node.

Creates new ClusterDashboard widget props.

Get node count.

Force refresh the cluster data.

Perform RPC call to a node with timeout.

Set the update interval.

Types

node_event()

@type node_event() :: %{
  node: node(),
  event: :nodeup | :nodedown,
  timestamp: DateTime.t()
}

node_info()

@type node_info() :: %{
  node: node(),
  status: node_status(),
  connected_at: DateTime.t() | nil,
  metrics: map() | nil
}

node_status()

@type node_status() :: :connected | :disconnected | :local

view_mode()

@type view_mode() :: :nodes | :globals | :pg_groups | :events

Functions

distributed?(state)

@spec distributed?(map()) :: boolean()

Check if cluster is distributed.

get_selected_node(state)

@spec get_selected_node(map()) :: node_info() | nil

Get currently selected node.

new(opts \\ [])

@spec new(keyword()) :: map()

Creates new ClusterDashboard widget props.

Options

  • :update_interval - Refresh interval metadata in ms (default: 2000); embedded roots must schedule refresh messages
  • :show_health_metrics - Fetch and show CPU/memory/load (default: true)
  • :show_pg_groups - Show :pg process groups (default: true)
  • :show_global_names - Show :global registered names (default: true)
  • :on_node_select - Callback when node is selected

node_count(state)

@spec node_count(map()) :: non_neg_integer()

Get node count.

refresh(state)

@spec refresh(map()) :: {:ok, map()}

Force refresh the cluster data.

rpc_call(node, module, function, args)

@spec rpc_call(node(), module(), atom(), list()) :: term() | {:error, term()}

Perform RPC call to a node with timeout.

set_interval(state, interval)

@spec set_interval(map(), non_neg_integer()) :: {:ok, map()}

Set the update interval.

This cancels/schedules a :refresh message in the calling process. Use it only when that host routes the message to handle_info/2; an embedded Elm root should own a Command.interval/2 instead.