Skip to content

vladkens/macmon

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

79 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

macmon – Mac Monitor

A sudoless performance monitoring CLI tool for Apple Silicon processors.

donate

preview

Motivation

Apple Silicon processors don't provide an easy way to view live power consumption. I was interested in this data while testing local LLM models. asitop is a nice and simple TUI for quickly checking current metrics, but it reads data from powermetrics and requires root privileges. macmon uses a private macOS API to gather similar metrics (essentially the same as powermetrics), but runs without sudo. πŸŽ‰

🌟 Features

  • 🚫 Runs without sudo
  • ⚑ Real-time CPU / GPU / ANE power usage
  • πŸ“Š CPU utilization per cluster
  • πŸ’Ύ RAM / Swap usage
  • πŸ“ˆ Historical charts with average and max values
  • 🌑️ Average CPU / GPU temperature
  • 🎨 Switchable color themes (6 variants)
  • πŸͺŸ Can be displayed in a small window
  • πŸ¦€ Written in Rust

πŸ“₯ Installation

brew install macmon
sudo port install macmon
cargo install macmon
nix-env -i macmon

πŸš€ Usage

Usage: macmon [OPTIONS] [COMMAND]

Commands:
  pipe   Output metrics in JSON format
  serve  Serve metrics over HTTP
  debug  Print debug information
  help   Print this message or the help of the given subcommand(s)

Options:
  -i, --interval <INTERVAL>  Update interval in milliseconds [default: 1000]
  -h, --help                 Print help
  -V, --version              Print version

Controls:
  c - change color
  v - switch charts view: gauge / sparkline
  q - quit

🚰 Piping

You can use the pipe subcommand to output metrics in JSON format, which makes it suitable for piping into other tools or scripts. For example:

macmon pipe | jq

This command runs macmon in "pipe" mode and sends the output to jq for pretty-printing.

You can also specify the number of samples to collect using the -s or --samples parameter (default: 0, which runs indefinitely), and set the update interval in milliseconds using the -i or --interval parameter (default: 1000 ms). For example:

macmon pipe -s 10 -i 500 | jq

This will collect 10 samples with an update interval of 500 milliseconds.

Output

{
  "timestamp": "2025-02-24T20:38:15.427569+00:00",
  "temp": {
    "cpu_temp_avg": 43.73614,         // Celsius
    "gpu_temp_avg": 36.95167          // Celsius
  },
  "memory": {
    "ram_total": 25769803776,         // Bytes
    "ram_usage": 20985479168,         // Bytes
    "swap_total": 4294967296,         // Bytes
    "swap_usage": 2602434560          // Bytes
  },
  "ecpu_usage": [1181, 0.082656614],  // (Frequency MHz, Usage %)
  "pcpu_usage": [1974, 0.015181795],  // (Frequency MHz, Usage %)
  "cpu_usage_pct": 0.036854,          // Combined CPU usage (weighted by core count, 0–1)
  "gpu_usage": [461, 0.021497859],    // (Frequency MHz, Usage %)
  "cpu_power": 0.20486385,            // Watts
  "gpu_power": 0.017451683,           // Watts
  "ane_power": 0.0,                   // Watts
  "all_power": 0.22231553,            // Watts
  "sys_power": 5.876533,              // Watts
  "ram_power": 0.11635789,            // Watts
  "gpu_ram_power": 0.0009615385       // Watts (not sure what it means)
}

🌐 HTTP Server

You can use the serve subcommand to expose metrics over HTTP. This is useful for integrating with monitoring systems like Prometheus and Grafana.

macmon serve            # default port 9090, interval 1000ms
macmon serve -p 8080    # custom port
macmon serve -i 500     # sampling interval 500ms
macmon serve &          # run in background

Two endpoints are available:

Endpoint Format Description
GET /json JSON Current metrics snapshot (same format as pipe --soc-info)
GET /metrics Prometheus Metrics in Prometheus text format

Running as a background service (launchd)

To start macmon serve automatically on login and keep it running:

macmon serve --install              # install and start (default port 9090)
macmon serve --port 8080 --install  # with custom port
macmon serve --uninstall            # stop and remove

This creates a launchd agent at ~/Library/LaunchAgents/com.macmon.plist that auto-starts on login and restarts on crash.

Prometheus / Grafana setup

Add a scrape target to your prometheus.yml:

scrape_configs:
  - job_name: macmon
    static_configs:
      - targets: ["localhost:9090"]

For a ready-to-run local example with Prometheus + Grafana, see example-grafana:

macmon serve --port 9090
cd example-grafana
docker compose up -d

This example provisions:

  • Prometheus on http://localhost:9091
  • Grafana on http://localhost:9000
  • a prebuilt Macmon Overview dashboard

Grafana login:

  • username: macmon
  • password: macmon

Then import or build a Grafana dashboard querying metrics such as:

macmon_cpu_power_watts{chip="Apple M3 Pro"}
macmon_ecpu_usage_ratio{chip="Apple M3 Pro"}
macmon_memory_ram_used_bytes{chip="Apple M3 Pro"}

Prometheus output example

# HELP macmon_cpu_temp_celsius Average CPU temperature in Celsius
# TYPE macmon_cpu_temp_celsius gauge
macmon_cpu_temp_celsius{chip="Apple M3 Pro"} 47.3

# HELP macmon_cpu_power_watts CPU power consumption in Watts
# TYPE macmon_cpu_power_watts gauge
macmon_cpu_power_watts{chip="Apple M3 Pro"} 8.42

# HELP macmon_cpu_usage_ratio Combined CPU utilization (0–1), weighted by core count
# TYPE macmon_cpu_usage_ratio gauge
macmon_cpu_usage_ratio{chip="Apple M3 Pro"} 0.037

# HELP macmon_ecpu_usage_ratio Efficiency CPU cluster utilization (0–1)
# TYPE macmon_ecpu_usage_ratio gauge
macmon_ecpu_usage_ratio{chip="Apple M3 Pro"} 0.083

πŸ“š Library Usage

macmon can be used as a Rust library to collect Apple Silicon metrics in your own applications.

Add it to your Cargo.toml:

[dependencies]
macmon = { git = "https://github.com/vladkens/macmon" }

Then use the Sampler to collect metrics:

use macmon::Sampler;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let mut sampler = Sampler::new()?;

    // collect metrics over a 1000ms window
    let metrics = sampler.get_metrics(1000)?;

    println!("CPU power:  {:.2} W", metrics.cpu_power);
    println!("GPU power:  {:.2} W", metrics.gpu_power);
    println!("CPU temp:   {:.1} Β°C", metrics.temp.cpu_temp_avg);
    println!("RAM usage:  {} / {} bytes", metrics.memory.ram_usage, metrics.memory.ram_total);
    println!("eCPU:       {} MHz  {:.1}%", metrics.ecpu_usage.0, metrics.ecpu_usage.1 * 100.0);
    println!("pCPU:       {} MHz  {:.1}%", metrics.pcpu_usage.0, metrics.pcpu_usage.1 * 100.0);

    Ok(())
}

The get_metrics(duration_ms) call blocks for duration_ms milliseconds while sampling the hardware counters and returns a single averaged Metrics snapshot.

πŸ“¦ Build from Source

  1. Install Rust toolchain

  2. Clone the repo:

git clone https://github.com/vladkens/macmon.git && cd macmon
  1. Build and run:
cargo run -r

🀝 Contributing

We love contributions! Whether you have ideas, suggestions, or bug reports, feel free to open an issue or submit a pull request. Your input is essential to helping us improve macmon. πŸ’ͺ

πŸ“ License

macmon is distributed under the MIT License. For more details, check out the LICENSE file.

πŸ” See also


P.S. One more thing... Monitoring your Mac's performance with macmon is like having a personal trainer for your processor β€” keeping those cores in shape! πŸ’ͺ

About

πŸ¦€πŸŒ‘οΈ Real-time system monitor for Apple Silicon Macs (M1–M5). No sudo. TUI, JSON/Prometheus metrics server, and Rust library.

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors