# How to Monitor System Status in Real-Time with Mole

> Easily monitor system status in real-time using Mole. Launch a live dashboard with `mo status` or get programmatic output with `--json` for continuous hardware and OS metric sampling.

- Repository: [Tw93/Mole](https://github.com/tw93/Mole)
- Tags: how-to-guide
- Published: 2026-03-20

---

**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`](https://github.com/tw93/Mole/blob/main/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`](https://github.com/tw93/Mole/blob/main/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`](https://github.com/tw93/Mole/blob/main/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`](https://github.com/tw93/Mole/blob/main/cmd/status/metrics_cpu.go) and [`cmd/status/metrics_memory.go`](https://github.com/tw93/Mole/blob/main/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`](https://github.com/tw93/Mole/blob/main/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`](https://github.com/tw93/Mole/blob/main/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.

```bash

# 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:

```bash
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`](https://github.com/tw93/Mole/blob/main/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.

```go
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`](https://github.com/tw93/Mole/blob/main/cmd/status/main.go), collection logic in [`cmd/status/metrics.go`](https://github.com/tw93/Mole/blob/main/cmd/status/metrics.go), rendering in [`cmd/status/view.go`](https://github.com/tw93/Mole/blob/main/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`](https://github.com/tw93/Mole/blob/main/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`](https://github.com/tw93/Mole/blob/main/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`](https://github.com/tw93/Mole/blob/main/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`](https://github.com/tw93/Mole/blob/main/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`](https://github.com/tw93/Mole/blob/main/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.