How to Monitor System Status in Real-Time with Mole

Use the mo status sub-command to launch a live terminal dashboard that continuously samples hardware and OS metrics every second, or add --json for programmatic output.

Mole is an open-source CLI tool that provides comprehensive system monitoring capabilities through an elegant terminal interface. To monitor system status in real-time with Mole, you invoke the dedicated status sub-command which orchestrates data collection and visualization through a reactive architecture built on the Bubble Tea framework.

Architecture Overview

The real-time monitor in cmd/status/main.go implements a Model-Update-View pattern using Charm's Bubble Tea library. The system consists of four primary components that handle event loops, data aggregation, storage, and rendering.

The Bubble Tea Event Loop

The model struct in cmd/status/main.go drives the application lifecycle through three core methods: Init(), Update(), and View(). When you execute mo status, the newModel() function instantiates a Collector and loads user preferences (such as the "cat hidden" setting) from ~/.config/mole/status_prefs.

The event loop begins with Init() scheduling an immediate tickMsg via tickAfter(0). The Update() method handles incoming messages, including window resize events, keyboard input, and periodic ticks.

The Collector Subsystem

Located in cmd/status/metrics.go, the Collector struct manages concurrent data gathering through dedicated goroutines. It aggregates results into an immutable MetricsSnapshot struct that contains fields for CPU, GPU, memory, disks, network, battery, thermal states, and sensor data.

The collector implements a collectCmd() method that orchestrates various collect* helper functions defined across metric-specific files like cmd/status/metrics_cpu.go and cmd/status/metrics_memory.go. Each collector includes fallback logic—for example, parsing uptime output when native APIs are unavailable—to ensure resilience across different macOS versions.

Data Flow and Refresh Cycle

The refresh mechanism relies on a time.Ticker with a constant refreshInterval of one second. The data flow follows this sequence:

  1. Tick Trigger: The Update() handler receives a tickMsg and invokes collector.collectCmd()
  2. Concurrent Collection: All metric gatherers run simultaneously, populating a MetricsSnapshot
  3. State Update: Upon receiving a metricsMsg, the model stores the snapshot, updates lastUpdated, and marks the view as ready
  4. Next Tick: The handler schedules the subsequent collection via tickAfter(refreshInterval)
  5. Rendering: The View() method in cmd/status/view.go transforms the snapshot into TUI cards and header information

Interactive Features and Controls

The terminal UI provides real-time visualization with adaptive layout and interactive elements.

Keyboard Navigation

While the dashboard is active, you can control the interface using these keys:

  • q, Esc, or Ctrl+C: Quit the application
  • k: Toggle the animated Mole mascot visibility (preference persists across sessions)

The renderHeader, renderCard, and getMoleFrame functions in cmd/status/view.go handle the visual presentation, including animated ASCII art that responds to terminal width changes.

Adaptive Layout

The buildCards function dynamically arranges metrics into columns based on available terminal real estate. Ring buffers maintain fixed-size histories for sparkline graphs without unbounded memory growth, ensuring the UI remains responsive even during extended monitoring sessions.

JSON Mode for Automation

When you need to monitor system status in real-time with Mole for scripting or integration purposes, bypass the TUI using JSON output mode.

Mole automatically detects non-interactive environments—when stdout is not a TTY—or respects the explicit --json flag. In this mode, the application skips Bubble Tea initialization and prints the current MetricsSnapshot as structured JSON to stdout.


# Output raw metrics for processing with jq

mo status --json | jq '.cpu.usage, .memory.used_percent'

When piped to another command, the tool automatically emits JSON even without the flag:

mo status | sed -n '1,5p'

Cross-Platform Data Collection

Mole delegates heavy lifting to gopsutil (github.com/shirou/gopsutil/v4), which abstracts OS-specific syscalls for CPU, memory, disk I/O, and network statistics across macOS, Linux, and Windows.

Apple Silicon Optimization

For macOS systems, collectCPU() in cmd/status/metrics_cpu.go executes sysctl commands to detect performance versus efficiency core counts via hw.perflevel0 and hw.perflevel1 parameters. This provides accurate topology information specific to Apple Silicon architectures.

Resilient Metric Gathering

Each collector implements defensive programming patterns. If gopsutil returns errors or native commands like sysctl are unavailable, the system falls back to alternative parsing methods or returns sensible defaults, ensuring the dashboard never crashes due to missing hardware sensors or permission restrictions.

Programmatic Integration

You can embed Mole's monitoring capabilities into your own Go applications by importing the collector package directly.

import "github.com/tw93/Mole/cmd/status"

func main() {
    c := status.NewCollector()
    snap, err := c.CollectOnce()
    if err != nil { 
        log.Fatal(err) 
    }
    fmt.Printf("Health: %d, CPU: %.1f%%\n", snap.HealthScore, snap.CPU.Usage)
}

This approach instantiates a Collector and calls CollectOnce() to retrieve a single MetricsSnapshot without entering the interactive TUI loop.

Summary

  • Command: Execute mo status to launch the real-time dashboard with 1-second refresh intervals
  • Architecture: Bubble Tea model drives the UI while a Collector goroutine gathers metrics concurrently
  • Output Modes: Interactive TUI with animated mascot, or JSON mode via --json flag for automation
  • Data Sources: Cross-platform metrics via gopsutil with macOS-specific enhancements for Apple Silicon
  • Key Files: Entry point at cmd/status/main.go, collection logic in cmd/status/metrics.go, rendering in cmd/status/view.go

Frequently Asked Questions

How do I exit the Mole status dashboard?

Press q, Esc, or Ctrl+C to terminate the application. The Bubble Tea model in cmd/status/main.go handles these key events in the Update() method, triggering a graceful shutdown that preserves your "cat hidden" preference to disk.

Can I use Mole status monitoring in shell scripts?

Yes. Append the --json flag or pipe the output to automatically receive structured JSON instead of the TUI. The shouldUseJSONOutput function in cmd/status/main.go detects non-terminal stdout and emits the current MetricsSnapshot as parseable JSON, making it ideal for integration with jq or other CLI tools.

What metrics does Mole collect in real-time?

According to the MetricsSnapshot struct in cmd/status/metrics.go, Mole gathers CPU usage and core topology, GPU statistics, memory and swap utilization, and disk I/O rates. Additional collectors in files like cmd/status/metrics_network.go track network speeds, IP addresses, battery health, thermal states, and hardware sensors. The system aggregates these into a single snapshot every second for display or JSON export.

Why does the Mole dashboard update every second?

The refresh rate is controlled by the refreshInterval constant defined as time.Second in cmd/status/main.go. This interval balances real-time accuracy with system overhead, while the Bubble Tea framework ensures efficient rendering only when new data arrives via the metricsMsg channel.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →