monitor

package
v0.21.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 10, 2026 License: MIT Imports: 17 Imported by: 0

Documentation

Overview

Package monitor implements a real-time TUI dashboard for remote host metrics.

The dashboard displays CPU, RAM, GPU, and network statistics for configured remote hosts, with color-coded status indicators and responsive layout that adapts to terminal size.

Architecture

The package uses the Bubble Tea framework, which follows The Elm Architecture (Model-Update-View pattern):

  • Model: Holds application state (hosts, metrics, selection, layout mode)
  • Update: Processes messages (keystrokes, tick events, new metrics)
  • View: Renders the current state to a string for display

Key Components

Model       - The Bubble Tea model containing all dashboard state
Collector   - Gathers metrics from remote hosts via SSH in parallel
Pool        - Manages SSH connection pool for reuse between refresh cycles
History     - Ring buffer storage for historical metrics (sparkline graphs)

Message Flow

The dashboard operates on a tick-based refresh cycle:

  1. tickMsg fires at the configured interval (default 1s)
  2. collectCmd() launches parallel SSH commands to gather metrics
  3. metricsMsg arrives with results, updating Model.metrics
  4. View() re-renders the dashboard with new data

Layout Modes

The dashboard adapts to terminal width with four layout modes:

LayoutMinimal  (<80 cols)  - Metrics only, no graphs
LayoutCompact  (80-120)    - Inline graphs, abbreviated labels
LayoutStandard (120-160)   - Full cards, possibly 2 columns
LayoutWide     (160+)      - Two-column layout with extra detail

Connection Pool

The Pool type maintains persistent SSH connections to avoid reconnection overhead on each refresh. It handles:

  • Connection reuse and health checking
  • Platform detection (Linux vs macOS) for parser selection
  • Automatic reconnection on connection failure

History and Sparklines

The History type stores metric values in ring buffers for sparkline rendering. Each host tracks:

  • CPU percentage history
  • RAM percentage history
  • GPU percentage history (if available)
  • Network throughput history per interface

Default history size is 600 samples (10 minutes at 1s refresh).

Keyboard Shortcuts

Navigation and control is handled via keybindings defined in keybindings.go:

q, Ctrl+C   - Quit
r           - Force refresh
s           - Cycle sort order (name/CPU/RAM/GPU)
j/k, ↑/↓    - Navigate host list
Enter       - Expand host detail view
Esc         - Collapse / go back
?           - Toggle help overlay

Index

Constants

View Source
const (
	BreakpointCompact  = 80
	BreakpointStandard = 120
	BreakpointWide     = 160
)

Width breakpoints for layout modes

View Source
const (
	HeightMinimal  = 24
	HeightStandard = 40
)

Height breakpoints for layout adjustments

View Source
const (
	// Background colors (glassmorphism-inspired)
	ColorDarkBg    = lipgloss.Color("#0A0A0F") // Deep void
	ColorSurfaceBg = lipgloss.Color("#12121A") // Dark surface
	ColorBorder    = lipgloss.Color("#2A2A4A") // Glass border (purple tint)

	// Semantic colors for metrics - gen-z synthwave gradient
	ColorHealthy  = lipgloss.Color("#00FFFF") // Neon cyan - chill vibes
	ColorWarning  = lipgloss.Color("#BF40FF") // Neon purple - getting spicy
	ColorCritical = lipgloss.Color("#FF2E97") // Hot pink - main character energy

	// Text colors
	ColorTextPrimary   = lipgloss.Color("#FFFFFF") // Pure white
	ColorTextSecondary = lipgloss.Color("#B4B4D0") // Lavender gray
	ColorTextMuted     = lipgloss.Color("#6B6B8D") // Purple-gray

	// Accent colors - neon pink primary, cyan secondary
	ColorAccent    = lipgloss.Color("#FF2E97") // Neon pink
	ColorAccentDim = lipgloss.Color("#BF40FF") // Neon purple

	// Graph colors
	ColorGraph = lipgloss.Color("#00FFFF") // Neon cyan
)

Dashboard color palette - Gen Z Electric Synthwave

View Source
const (
	WarningThreshold  = 70.0
	CriticalThreshold = 90.0
)

Thresholds for metric severity levels

View Source
const (
	LatencyFast     = 50.0  // < 50ms is excellent (LAN/nearby)
	LatencyNormal   = 200.0 // < 200ms is normal (VPN/regional)
	LatencyDegraded = 500.0 // >= 500ms is degraded (slow/intercontinental)
)

Latency thresholds in milliseconds for actual SSH network latency. These thresholds apply to the SSH probe round-trip time, not metrics collection time.

View Source
const (
	GPUTempWarning  = 70 // >= 70C is warm
	GPUTempCritical = 80 // >= 80C is hot
)

GPU temperature thresholds in Celsius.

View Source
const (
	StatusConnecting  = "◐" // Half-filled (used as fallback when animation not available)
	StatusIdle        = "◉" // Filled target - ready for work
	StatusRunning     = "⣿" // Braille full (used as fallback when animation not available)
	StatusUnreachable = "◌" // Dashed circle
	StatusSlow        = "◔" // Partially filled
)

Status indicator characters - cyber glyphs

View Source
const ConnectingTextSlowdown = 7

ConnectingTextSlowdown controls how many spinner frames pass before advancing the connecting text animation. At 150ms spinner interval, 7 gives ~1s per text frame.

View Source
const DefaultHistorySize = 600

DefaultHistorySize is the default number of data points to retain per metric. With a 1-second refresh interval, 600 points gives 10 minutes of history.

View Source
const OutputSeparator = "---"

Separator used to split batched command output.

Variables

View Source
var (
	// Container styles
	DashboardStyle = lipgloss.NewStyle().
					Background(ColorDarkBg)

	HeaderStyle = lipgloss.NewStyle().
				Foreground(ColorTextPrimary).
				Background(ColorSurfaceBg).
				Bold(true).
				Padding(0, 1)

	FooterStyle = lipgloss.NewStyle().
				Foreground(ColorTextMuted).
				Padding(0, 1)

	// Card styles - no background set here, each line handles its own
	// Note: No horizontal padding here - renderCardLine handles symmetric padding
	CardStyle = lipgloss.NewStyle().
				Border(lipgloss.RoundedBorder()).
				BorderForeground(ColorBorder).
				MarginRight(1).
				MarginBottom(1)

	CardSelectedStyle = CardStyle.
						BorderForeground(ColorAccent)

	// Text styles
	HostNameStyle = lipgloss.NewStyle().
					Foreground(ColorTextPrimary).
					Bold(true)

	LabelStyle = lipgloss.NewStyle().
				Foreground(ColorTextSecondary)

	ValueStyle = lipgloss.NewStyle().
				Foreground(ColorTextPrimary)

	// Status indicator styles
	StatusConnectingStyle = lipgloss.NewStyle().
							Foreground(ColorTextSecondary)

	StatusIdleStyle = lipgloss.NewStyle().
					Foreground(ColorHealthy)

	StatusRunningStyle = lipgloss.NewStyle().
						Foreground(ColorWarning)

	StatusSlowStyle = lipgloss.NewStyle().
					Foreground(ColorWarning)

	StatusUnreachableStyle = lipgloss.NewStyle().
							Foreground(ColorCritical)

	// Status text styles (for the "- idle", "- running" suffix)
	StatusTextStyle = lipgloss.NewStyle().
					Foreground(ColorTextMuted)

	StatusRunningTextStyle = lipgloss.NewStyle().
							Foreground(ColorWarning)
)

Base styles for the dashboard

View Source
var ConnectingSpinnerFrames = []string{"◐", "◓", "◑", "◒"}

ConnectingSpinnerFrames are the animation frames for the connecting state Rotates through half-circle positions for a smooth spin effect

View Source
var ConnectingTextFrames = []string{
	"Linking up",
	"Linking up.",
	"Linking up..",
	"Linking up...",
}

ConnectingTextFrames are the animated text frames for the connecting message. Cycles through dot progression for a calm, non-frantic loading indicator.

View Source
var RunningSpinnerFrames = []string{"⣾", "⣽", "⣻", "⢿", "⡿", "⣟", "⣯", "⣷"}

RunningSpinnerFrames are the animation frames for the running/locked state Uses braille dots for a subtle "working" animation

View Source
var SpinnerColorFrames = []lipgloss.Color{
	lipgloss.Color("#FFAA00"),
	lipgloss.Color("#FF8800"),
	lipgloss.Color("#FFCC00"),
	lipgloss.Color("#FFAA00"),
	lipgloss.Color("#FF9900"),
	lipgloss.Color("#FFBB00"),
	lipgloss.Color("#FFAA00"),
	lipgloss.Color("#FF7700"),
}

SpinnerColorFrames defines the gen-z color cycling for animated spinners Cycles through neon colors for a vibrant effect

Functions

func BuildMetricsCommand

func BuildMetricsCommand(platform Platform) string

BuildMetricsCommand returns a single batched command that collects all metrics for the specified platform. This allows collecting all metrics in a single SSH exec.

func CompactProgressBar

func CompactProgressBar(width int, percent float64) string

CompactProgressBar renders a minimal progress bar without brackets.

func CompactProgressBarWithThresholds

func CompactProgressBarWithThresholds(width int, percent float64, warning, critical int) string

CompactProgressBarWithThresholds renders a minimal progress bar using custom thresholds.

func FormatRate

func FormatRate(bytesPerSecond float64) string

FormatRate formats a bytes-per-second rate as a human-readable string.

func GPUTempColor added in v0.16.0

func GPUTempColor(temp int) lipgloss.Color

GPUTempColor returns the appropriate color for a GPU temperature in Celsius. Cyan < 70C (normal), Purple 70-79C (warm), Pink >= 80C (hot).

func GPUTempStyle added in v0.16.0

func GPUTempStyle(temp int) lipgloss.Style

GPUTempStyle returns a style with the appropriate foreground color for GPU temperature.

func GetRunningSpinner added in v0.11.6

func GetRunningSpinner(frameIndex int) (string, lipgloss.Style)

GetRunningSpinner returns the spinner character and style for the running state.

func GetSpinnerColor added in v0.11.6

func GetSpinnerColor(frameIndex int) lipgloss.Color

GetSpinnerColor returns the color for the current spinner frame index. Used for gen-z style color cycling on animated spinners.

func LatencyColor added in v0.13.0

func LatencyColor(ms float64) lipgloss.Color

LatencyColor returns the appropriate color for a latency value in milliseconds. Green < 50ms, Cyan 50-200ms, Yellow 200-500ms, Red >= 500ms.

func LatencyQualityText added in v0.13.0

func LatencyQualityText(ms float64) string

LatencyQualityText returns a human-readable quality label for the latency.

func LatencyStyle added in v0.13.0

func LatencyStyle(ms float64) lipgloss.Style

LatencyStyle returns a style with the appropriate foreground color for latency.

func MetricColor

func MetricColor(percent float64) lipgloss.Color

MetricColor returns the appropriate color for a percentage-based metric. Uses threshold-based coloring: green < 70%, yellow 70-90%, red > 90%.

func MetricColorWithThresholds

func MetricColorWithThresholds(percent float64, warning, critical int) lipgloss.Color

MetricColorWithThresholds returns the appropriate color for a percentage-based metric using the provided warning and critical threshold values.

func MetricStyle

func MetricStyle(percent float64) lipgloss.Style

MetricStyle returns a style with the appropriate foreground color for the metric.

func MetricStyleWithThresholds

func MetricStyleWithThresholds(percent float64, warning, critical int) lipgloss.Style

MetricStyleWithThresholds returns a style with the appropriate foreground color using custom warning and critical thresholds.

func PlatformDetectCommand

func PlatformDetectCommand() string

PlatformDetectCommand returns the command to detect the platform type.

func ProgressBar

func ProgressBar(width int, percent float64) string

ProgressBar renders a progress bar with the given width and percentage. Uses bracketless Gen Z style with threshold-based coloring.

func RenderBrailleSparkline added in v0.2.0

func RenderBrailleSparkline(data []float64, width, height int, baseColor lipgloss.Color) string

RenderBrailleSparkline renders a sparkline graph using braille characters. Each character represents 2 horizontal data points with 4 vertical levels. This gives much higher resolution than standard block characters. Colors transition from green to yellow to red based on value (btop-style gradient).

Parameters:

  • data: values to plot (will be normalized to 0-100 range if not already)
  • width: number of braille characters (each represents 2 data points)
  • height: number of rows (each row represents 4 vertical levels)
  • baseColor: fallback color (used for non-percentage data)

func RenderBrailleSparklineWithColorFunc added in v0.13.0

func RenderBrailleSparklineWithColorFunc(data []float64, width, height int, baseColor lipgloss.Color, colorFunc ColorFunc) string

RenderBrailleSparklineWithColorFunc renders a sparkline with custom per-column coloring. If colorFunc is provided, it's called with each column's max value to determine color. If colorFunc is nil, falls back to default behavior (MetricColor for percentages, baseColor otherwise).

func RenderBrailleSparklineWithOptions added in v0.13.0

func RenderBrailleSparklineWithOptions(data []float64, width, height int, baseColor lipgloss.Color, colorFunc ColorFunc, forceZeroMin bool) string

RenderBrailleSparklineWithOptions renders a sparkline with full control over coloring and scaling. forceZeroMin: when true, forces the Y-axis to start at 0 instead of the data's minimum. This is important for metrics like latency where 0 is a meaningful baseline.

func RenderBrailleSparklineWithScale added in v0.13.0

func RenderBrailleSparklineWithScale(data []float64, width, height int, baseColor lipgloss.Color) (string, float64)

RenderBrailleSparklineWithScale renders a sparkline and returns the max value used for scaling. This is useful for non-percentage data where the scale isn't obvious.

func RenderCleanSparkline added in v0.2.0

func RenderCleanSparkline(data []float64, width int, color lipgloss.Color) string

RenderCleanSparkline renders a single-row sparkline with a consistent accent color. This provides a cleaner, less noisy visualization than multi-row braille graphs. Each character represents one data point using block characters (▁▂▃▄▅▆▇█).

func RenderColoredMiniSparkline added in v0.2.0

func RenderColoredMiniSparkline(data []float64, width int) string

RenderColoredMiniSparkline renders a sparkline with threshold-based coloring.

func RenderGradientBar added in v0.3.0

func RenderGradientBar(width int, percent float64, _ lipgloss.Color) string

RenderGradientBar renders a horizontal bar with gradient fill. Colors transition from green to yellow to red based on position.

func RenderGraphWithYAxis added in v0.13.0

func RenderGraphWithYAxis(data []float64, graphWidth, height int, baseColor lipgloss.Color, formatValue func(float64) string, minLabelWidth int, colorFunc ColorFunc, forceZeroMin bool) string

RenderGraphWithYAxis renders a braille sparkline with y-axis labels on the left. Returns the complete graph with scale markers showing max at top and 0 at bottom. The formatValue function converts values to display strings (e.g., "1856ms", "5.2 MB/s"). The minLabelWidth parameter ensures consistent width across different graphs. The colorFunc parameter allows custom per-column coloring (nil uses default behavior). forceZeroMin forces the Y-axis to start at 0 (important for latency where 0 is meaningful).

func RenderLoadAvg

func RenderLoadAvg(loadAvg [3]float64) string

RenderLoadAvg renders the system load average with time period labels.

func RenderMiniSparkline added in v0.2.0

func RenderMiniSparkline(data []float64, width int) string

RenderMiniSparkline renders a single-row sparkline using block characters. This is more compact than braille and good for inline display in cards.

Parameters:

  • data: values to plot
  • width: number of characters

func RenderTimeSeriesGraph added in v0.2.0

func RenderTimeSeriesGraph(data []float64, width, height int, color lipgloss.Color) string

RenderTimeSeriesGraph renders a multi-row time series graph showing historical data. Each column represents one time point, rendered vertically with block characters. Height is the number of rows (typically 3-5 for good visibility).

func ResampleDataWithMode added in v0.13.0

func ResampleDataWithMode(data []float64, targetSize int, mode ResampleMode) []float64

ResampleDataWithMode resamples data using the specified mode for downsampling. Exported so callers can pre-smooth data (e.g., latency) before rendering.

func SectionBorder added in v0.2.0

func SectionBorder() string

SectionBorder renders the left border character for section content.

func SectionContentLine added in v0.3.0

func SectionContentLine(content string, width int) string

SectionContentLine renders a content line with left and right borders, properly padded to width. Format: │ content │

func SectionFooter added in v0.2.0

func SectionFooter(width int) string

SectionFooter renders the bottom border of a section. Format: ╰────────────────────────────────────────────────────╯

func SectionHeader added in v0.2.0

func SectionHeader(title, value string, width int) string

SectionHeader renders a section header with the title on the left and value on the right. Format: ╭─ Title ────────────────────────────────────── Value ╮

func SmoothWithMovingAverage added in v0.13.0

func SmoothWithMovingAverage(data []float64, windowSize int) []float64

SmoothWithMovingAverage applies a rolling average to smooth data while preserving shape. Each point becomes the average of itself and its neighbors within the window. Window size of 5 is typical - smooths noise while keeping trends visible.

func ThinProgressBar added in v0.2.0

func ThinProgressBar(width int, percent float64) string

ThinProgressBar renders a minimal line-based progress bar using thin characters. Uses ━ for filled segments and ─ for empty segments.

func ThinProgressBarWithThresholds added in v0.2.0

func ThinProgressBarWithThresholds(width int, percent float64, warning, critical int) string

ThinProgressBarWithThresholds renders a thin progress bar with custom thresholds.

Types

type CPUMetrics

type CPUMetrics struct {
	Percent float64
	Cores   int
	LoadAvg [3]float64
}

CPUMetrics contains CPU usage information.

type Collector

type Collector struct {
	// contains filtered or unexported fields
}

Collector gathers system metrics from multiple remote hosts.

func NewCollector

func NewCollector(hosts map[string]config.Host) *Collector

NewCollector creates a new metrics collector for the specified hosts.

func (*Collector) Close

func (c *Collector) Close()

Close closes all connections in the pool.

func (*Collector) Collect

func (c *Collector) Collect() (map[string]*HostMetrics, map[string]string, map[string]*HostLockInfo)

Collect gathers metrics from all configured hosts in parallel. Returns a map of alias -> metrics, a map of alias -> error message, and a map of alias -> lock info. Hosts that fail to connect will have nil metrics and an error message.

func (*Collector) CollectOne

func (c *Collector) CollectOne(alias string) (*HostMetrics, error)

CollectOne gathers metrics from a single host.

func (*Collector) CollectStreaming added in v0.12.0

func (c *Collector) CollectStreaming(ctx context.Context) <-chan HostResult

CollectStreaming gathers metrics from all hosts, streaming results as each completes. Returns a channel that will receive HostResult for each host as it completes. The channel is closed when all hosts have been processed. This allows the UI to update independently per host instead of waiting for all hosts.

func (*Collector) CollectStreamingHosts added in v0.13.0

func (c *Collector) CollectStreamingHosts(ctx context.Context, hostList []string) <-chan HostResult

CollectStreamingHosts collects metrics from only the specified hosts. This is useful for implementing backoff - skip hosts that are in backoff period.

func (*Collector) Hosts

func (c *Collector) Hosts() []string

Hosts returns the list of host aliases being monitored.

func (*Collector) SetLockConfig added in v0.11.6

func (c *Collector) SetLockConfig(lockCfg config.LockConfig)

SetLockConfig configures lock checking for the collector. If set, the collector will check lock status for each host during collection.

func (*Collector) SetTimeout

func (c *Collector) SetTimeout(timeout time.Duration)

SetTimeout sets the per-host collection timeout.

type ColorFunc added in v0.13.0

type ColorFunc func(value float64) lipgloss.Color

ColorFunc is a function that returns a color based on a data value. Used for custom coloring in sparklines (e.g., latency thresholds).

type GPUMetrics

type GPUMetrics struct {
	Name        string
	Percent     float64
	MemoryUsed  int64
	MemoryTotal int64
	Temperature int
	PowerWatts  int
}

GPUMetrics contains GPU usage information (typically from nvidia-smi).

type History

type History struct {
	// contains filtered or unexported fields
}

History manages metric history for multiple hosts using ring buffers. It provides thread-safe access to historical data for sparkline rendering.

func NewHistory

func NewHistory(size int) *History

NewHistory creates a new history tracker with the specified buffer size.

func (*History) Clear

func (h *History) Clear(alias string)

Clear removes all history for the specified host.

func (*History) ClearAll

func (h *History) ClearAll()

ClearAll removes all history.

func (*History) Count

func (h *History) Count(alias string) int

Count returns the number of data points stored for a host's CPU metric.

func (*History) GetCPUHistory

func (h *History) GetCPUHistory(alias string, count int) []float64

GetCPUHistory returns the last count CPU percentage values for the specified host. Returns fewer values if not enough history is available.

func (*History) GetGPUHistory

func (h *History) GetGPUHistory(alias string, count int) []float64

GetGPUHistory returns the last count GPU percentage values for the specified host. Returns nil if the host has no GPU history.

func (*History) GetLatencyHistory added in v0.13.0

func (h *History) GetLatencyHistory(alias string, count int) []float64

GetLatencyHistory returns the last count latency values (in milliseconds) for the specified host.

func (*History) GetNetworkHistory

func (h *History) GetNetworkHistory(alias, iface string, count int) (bytesIn, bytesOut []float64)

GetNetworkHistory returns the last count network bytes values for the specified interface. Returns bytesIn and bytesOut slices.

func (*History) GetNetworkRateHistory added in v0.3.0

func (h *History) GetNetworkRateHistory(alias string, count int, intervalSec float64) []float64

GetNetworkRateHistory returns historical network rate values as percentages (0-100). Uses log scale to make small rates visible. Returns combined in+out rates.

func (*History) GetNetworkRateHistoryLinear added in v0.13.0

func (h *History) GetNetworkRateHistoryLinear(alias string, count int, intervalSec float64) []float64

GetNetworkRateHistoryLinear returns historical network rates as actual bytes/sec values. Unlike GetNetworkRateHistory which uses log-scale percentages, this returns raw rates for use with y-axis labels where linear scaling is needed.

func (*History) GetNetworkRates added in v0.2.0

func (h *History) GetNetworkRates(alias string, intervalSec float64) []NetworkRate

GetNetworkRates calculates network throughput rates for all interfaces of a host. The intervalSec parameter is the time between samples (typically the refresh interval). Returns rates in bytes per second.

func (*History) GetPeakNetworkRate added in v0.13.0

func (h *History) GetPeakNetworkRate(alias string, count int, intervalSec float64) float64

GetPeakNetworkRate returns the peak combined network rate (in + out) from history. This is useful for determining a stable y-axis scale for graphs.

func (*History) GetRAMHistory

func (h *History) GetRAMHistory(alias string, count int) []float64

GetRAMHistory returns the last count RAM percentage values for the specified host. Returns fewer values if not enough history is available.

func (*History) GetTotalNetworkRate added in v0.2.0

func (h *History) GetTotalNetworkRate(alias string, intervalSec float64) (bytesInPerSec, bytesOutPerSec float64)

GetTotalNetworkRate returns the combined throughput across all non-loopback interfaces.

func (*History) Push

func (h *History) Push(alias string, metrics *HostMetrics)

Push adds a new metrics sample for the specified host.

func (*History) PushLatency added in v0.13.0

func (h *History) PushLatency(alias string, latency float64)

PushLatency adds a latency measurement for the specified host.

type HostConnectionState added in v0.12.0

type HostConnectionState struct {
	Attempts    int       // number of consecutive failures
	LastError   string    // most recent error message
	Connected   bool      // has successfully connected at least once
	LastAttempt time.Time // when last attempt started
	NextRetry   time.Time // when to next attempt connection (for backoff)
}

HostConnectionState tracks connection attempts and errors per host.

type HostLockInfo added in v0.11.6

type HostLockInfo struct {
	IsLocked bool      // True if a lock is held on this host
	Holder   string    // Description of who holds the lock (user@host)
	Started  time.Time // When the lock was acquired
	Command  string    // Command being executed (if available)
}

HostLockInfo contains lock status for a host.

func (HostLockInfo) Duration added in v0.11.6

func (l HostLockInfo) Duration() time.Duration

Duration returns how long the lock has been held.

func (HostLockInfo) FormatDuration added in v0.11.6

func (l HostLockInfo) FormatDuration() string

FormatDuration returns a human-readable duration string (e.g., "2m30s").

type HostMetrics

type HostMetrics struct {
	Timestamp time.Time
	CPU       CPUMetrics
	RAM       RAMMetrics
	GPU       *GPUMetrics // nil if no GPU
	Network   []NetworkInterface
	Processes []ProcessInfo
	System    SystemInfo
}

HostMetrics contains all collected metrics from a remote host.

type HostResult added in v0.12.0

type HostResult struct {
	Alias        string        // Host alias
	Metrics      *HostMetrics  // Collected metrics (nil on error)
	Error        error         // Error if collection failed
	LockInfo     *HostLockInfo // Lock status (nil if not checked or error)
	ConnectedVia string        // SSH alias used to connect (e.g., "m4-tailscale")
	Latency      time.Duration // Actual SSH round-trip latency (from a lightweight probe)
}

HostResult is the result of collecting metrics from a single host. Used for streaming results from CollectStreaming.

type HostStatus

type HostStatus int

HostStatus represents the connection state of a host.

const (
	StatusConnectingState HostStatus = iota
	StatusIdleState                  // Online, not running any task
	StatusRunningState               // Online, actively running a task (locked)
	StatusSlowState
	StatusUnreachableState
)

func (HostStatus) String

func (s HostStatus) String() string

String returns a human-readable status string.

type LayoutMode

type LayoutMode int

LayoutMode represents the responsive layout mode based on terminal size.

const (
	// LayoutMinimal is for terminals < 80 columns: metrics only, no graphs, single column
	LayoutMinimal LayoutMode = iota
	// LayoutCompact is for terminals 80-120 columns: inline graphs, abbreviated labels, single column
	LayoutCompact
	// LayoutStandard is for terminals 120-160 columns: full cards, possibly 2 columns
	LayoutStandard
	// LayoutWide is for terminals 160+ columns: two-column layout with more detail
	LayoutWide
)

type Model

type Model struct {
	// contains filtered or unexported fields
}

Model is the Bubble Tea model for the monitoring dashboard.

func NewModel

func NewModel(collector *Collector, interval, timeout time.Duration, hostOrder []string) Model

NewModel creates a new dashboard model with the given collector. hostOrder is the priority order from config (default host first, then fallbacks). If nil, hosts are sorted alphabetically. timeout is the per-host collection timeout (0 uses default of 8s).

func (Model) CanShowExtendedInfo

func (m Model) CanShowExtendedInfo() bool

CanShowExtendedInfo returns true if the terminal is tall enough for extra details.

func (Model) ConnectingSpinner added in v0.10.0

func (m Model) ConnectingSpinner() string

ConnectingSpinner returns the current spinner character for the connecting animation.

func (Model) ConnectingSubtext added in v0.10.0

func (m Model) ConnectingSubtext() string

ConnectingSubtext returns the current animated subtext for connecting state.

func (Model) ConnectingText added in v0.10.0

func (m Model) ConnectingText() string

ConnectingText returns the current animated "Connecting" text.

func (*Model) HandleKeyMsg

func (m *Model) HandleKeyMsg(msg tea.KeyMsg) (bool, tea.Cmd)

HandleKeyMsg processes keyboard input and returns updated model state and command. Returns true if the key was handled, false otherwise.

func (Model) Init

func (m Model) Init() tea.Cmd

Init starts the tick timer and triggers an initial metrics collection.

func (Model) LayoutMode

func (m Model) LayoutMode() LayoutMode

LayoutMode returns the current layout mode based on terminal width.

func (Model) OnlineCount

func (m Model) OnlineCount() int

OnlineCount returns the number of hosts that are online (idle or running).

func (Model) RunningSpinner added in v0.11.6

func (m Model) RunningSpinner() (string, lipgloss.Style)

RunningSpinner returns the current spinner character and style for the running animation. Uses braille dots with gen-z color cycling for a vibrant "working" effect.

func (Model) SecondsSinceUpdate

func (m Model) SecondsSinceUpdate() int

SecondsSinceUpdate returns how many seconds have passed since the last update.

func (Model) SelectedHost

func (m Model) SelectedHost() string

SelectedHost returns the alias of the currently selected host.

func (Model) ShowFooter

func (m Model) ShowFooter() bool

ShowFooter returns true if the terminal is tall enough to show the footer.

func (Model) Update

func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd)

Update handles messages and updates the model state.

func (Model) View

func (m Model) View() string

View renders the dashboard.

type NetworkInterface

type NetworkInterface struct {
	Name       string
	BytesIn    int64
	BytesOut   int64
	PacketsIn  int64
	PacketsOut int64
}

NetworkInterface contains network I/O statistics for a single interface.

type NetworkRate added in v0.2.0

type NetworkRate struct {
	Interface      string
	BytesInPerSec  float64
	BytesOutPerSec float64
}

NetworkRate represents calculated network throughput for an interface.

type Platform

type Platform string

Platform represents the operating system type of a remote host.

const (
	// PlatformLinux indicates a Linux host.
	PlatformLinux Platform = "linux"
	// PlatformDarwin indicates a macOS host.
	PlatformDarwin Platform = "darwin"
	// PlatformUnknown indicates an unknown platform.
	PlatformUnknown Platform = "unknown"
)

func ParsePlatform

func ParsePlatform(unameOutput string) Platform

ParsePlatform converts uname output to a Platform value.

type Pool

type Pool struct {
	// contains filtered or unexported fields
}

Pool manages a pool of SSH connections for reuse between refresh cycles. It keeps connections alive to avoid the overhead of reconnecting on each metrics collection.

func NewPool

func NewPool(hosts map[string]config.Host, timeout time.Duration) *Pool

NewPool creates a new SSH connection pool with host configurations.

func (*Pool) Close

func (p *Pool) Close()

Close closes all connections in the pool and clears it.

func (*Pool) CloseOne

func (p *Pool) CloseOne(alias string)

CloseOne closes and removes a specific connection from the pool.

func (*Pool) Get

func (p *Pool) Get(alias string) (*sshutil.Client, error)

Get retrieves an existing connection for the given alias, or creates a new one. Connections are reused without preemptive health checks - if a connection has died, the caller will get an error when they try to use it and should call CloseOne() to remove it from the pool, then retry. The alias is looked up in the hosts config to get the actual SSH addresses to try. Multiple SSH addresses are tried in parallel - the first to connect wins, but earlier addresses in the list are preferred if they connect within a short window.

func (*Pool) GetConnectedVia added in v0.12.0

func (p *Pool) GetConnectedVia(alias string) string

GetConnectedVia returns the SSH alias that was used to connect to the given host. Returns empty string if no connection exists for this alias.

func (*Pool) GetWithPlatform

func (p *Pool) GetWithPlatform(alias string) (*sshutil.Client, Platform, error)

GetWithPlatform retrieves a connection and its detected platform. If the platform hasn't been detected yet, it detects it and caches the result.

func (*Pool) Return

func (p *Pool) Return(alias string, _ *sshutil.Client)

Return returns a connection to the pool for reuse. This is a no-op since we keep connections in the map, but it updates last used time.

func (*Pool) Size

func (p *Pool) Size() int

Size returns the number of connections in the pool.

type ProcSortOrder added in v0.2.0

type ProcSortOrder int

ProcSortOrder determines how processes are sorted in the table.

const (
	ProcSortByCPU ProcSortOrder = iota
	ProcSortByMemory
	ProcSortByPID
)

type ProcessInfo added in v0.2.0

type ProcessInfo struct {
	PID     int
	User    string
	CPU     float64 // percentage
	Memory  float64 // percentage
	Time    string  // elapsed time (format varies by platform)
	Command string  // truncated command line
}

ProcessInfo contains information about a running process.

type RAMMetrics

type RAMMetrics struct {
	UsedBytes  int64
	TotalBytes int64
	Cached     int64
	Available  int64
}

RAMMetrics contains memory usage information.

type ResampleMode added in v0.13.0

type ResampleMode int

ResampleMode controls how data is combined when downsampling.

const (
	// ResampleMax preserves peaks by taking the max value in each bucket.
	// Good for CPU/RAM where spikes are important to see.
	ResampleMax ResampleMode = iota
	// ResampleAvg smooths data by averaging values in each bucket.
	// Good for latency where you want to see the trend, not individual spikes.
	ResampleAvg
)

type SortOrder

type SortOrder int

SortOrder defines how hosts are sorted in the dashboard.

const (
	SortByDefault SortOrder = iota // Online first, then config order (default host, fallbacks)
	SortByName
	SortByCPU
	SortByRAM
	SortByGPU
)

func (SortOrder) Next

func (s SortOrder) Next() SortOrder

Next cycles to the next sort order.

func (SortOrder) String

func (s SortOrder) String() string

String returns a human-readable label for the sort order.

type SystemInfo

type SystemInfo struct {
	Hostname string
	OS       string
	Kernel   string
	Uptime   time.Duration
}

SystemInfo contains general system information.

type ViewMode

type ViewMode int

ViewMode defines the current display mode of the dashboard.

const (
	ViewList ViewMode = iota
	ViewDetail
)

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL