mcpField
M
macbook-metrics-setup

macbook-metrics-setup

github.com/davidondrej云与 DevOps4.2k96 次安装今天更新
代码仓库

关于 macbook-metrics-setup

macbook-metrics-setup 是一份构建 Mac 本地指标采集器的方案,面向希望自行掌控长期系统数据的用户。它说明如何以低开销将系统采样存入 SQLite,并通过 launchd 定时采集和同步备份。

主要功能

  1. 01每分钟采集系统指标
  2. 02将数据存入 SQLite
  3. 03提供采集、诊断和报告命令
  4. 04使用 launchd 定时运行采集
  5. 05定时备份数据库到私有 GitHub 仓库

适用场景

  1. 01长期记录 Mac 系统资源变化
  2. 02检查采集器和采样器是否正常
  3. 03查看指定时段的指标摘要
  4. 04将数据库快照备份到私有仓库

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/davidondrej/skills --skill macbook-metrics-setup

安装后在 Claude Code 中输入/macbook-metrics-setup确认已加载。

详细介绍

MacBook 指标设置

如何构建一个低开销、长期运行且完全由你掌控的 Mac 指标采集器。 无需云服务、无需遥测、无需账号——一个二进制文件、一个 SQLite 文件、两个 launchd 作业、一个私有 GitHub 仓库。

理念(构建前请先阅读)

  1. 仅限本地且确定。 采集器绝不进行网络调用,绝不使用大模型,绝不发送分析数据。任何人都应该能够 阅读代码,并准确预知它会写入什么。
  2. 数据存放在仓库之外,位于 ~/Library/Application Support/<project>/,因此重新安装和 Git 操作都不会触及测量数据。
  3. 低开销是硬性要求。 每分钟采样一次,使用 release 构建和 LowPriorityIO——监控程序绝不能成为负载来源。
  4. 未公开接口的读取结果必须允许为空,并在出错时明确报错。 GPU 利用率和 SMC 温度读取使用私有接口,任何 macOS 更新都可能导致其失效;将它们存储为可空列并显示错误, 绝不伪造数值。
  5. 决策都要记录下来。 每项架构选择都要在 docs/adr/ 中编写 ADR; 每项架构变更都要在 docs/database/ 中编写带编号的 SQL 文件。Agent 和人都要遵循 ADR,将其视为契约。
  6. 按进程跟踪为可选功能。 默认采集系统范围的数据;监控特定应用(例如 Electron IDE)则是 独立且隔离的采集器,只有通过其专属 ADR 才会添加。

仓库结构

Sources/<ProjectLib>/     # samplers, SQLite storage, report generation
Sources/<project-cli>/    # thin CLI: collect | doctor | report
launchd/                  # plist templates with __PLACEHOLDER__ tokens
scripts/                  # install.sh, uninstall.sh, sync.sh
docs/adr/                 # numbered architecture decision records
docs/database/            # numbered SQL migrations
backups/                  # git-tracked SQLite snapshots (written by sync)

Swift + SwiftPM 是自然之选(原生 IOKit/Mach API、零依赖),但这种架构也适用于任何编译型语言。

数据采集

  • 采样系统范围的 CPU %、GPU %、内存(已用/固定/压缩/ 压力)、交换空间、磁盘容量 + IO 字节/操作计数器、网络字节/数据包 计数器、电池、热状态、温度、风扇 RPM。
  • 将累计的 OS 计数器(磁盘/网络)存储为每个时间间隔的增量。
  • 每分钟向 SQLite(WAL 模式)写入一行。一年只有约 50 万行—— 添加一张 15 分钟汇总表,以便快速生成长期报告。
  • CLI 子命令:collect(采样一次并退出)、doctor(打印实时读数, 采样器故障时明确报错)、report --hours N(文本摘要)。

两个 launchd 作业

两者都是位于 ~/Library/LaunchAgents/ 中的用户 LaunchAgent——无需 root,也无需 守护进程。模板保存在仓库中;install.sh 会填充占位符。

1. 采集器——每隔 60 秒运行一次二进制文件并执行 collect: RunAtLoad true、StartInterval 60、ProcessType Background、 LowPriorityIO true,标准输出/错误输出写入 ~/Library/Logs/<project>/。 进程运行不到一秒便退出;launchd 负责调度(launchctl list 显示 PID - 且状态为 0 即表示运行正常)。

2. GitHub 同步——每隔 3 小时运行一次 scripts/sync.sh (StartInterval 10800),该脚本会:

# snapshot safely while the DB is live, then normalize for git
sqlite3 "$db_path" ".backup '$tmp'"
sqlite3 "$tmp" 'PRAGMA journal_mode=DELETE;'   # fold WAL into one file
mv -f "$tmp" backups/metrics.sqlite3
# commit ONLY the backups path, skip if unchanged, push to a PRIVATE repo
git add backups && git commit -m "Backup metrics database $(date '+%Y-%m-%d %H:%M')" -- backups
git push origin HEAD

绝不要用 cp 复制正在使用的 WAL 数据库——始终使用 sqlite3 .backup。 保持仓库私有:指标会暴露你的日常活动模式。

install.sh 模式

swift build -c release
# run the binary from Application Support, NOT the repo build dir,
# so rebuilds/branch switches never break the running job
install -m 755 .build/release/<project> "$data_dir/bin/"
install -m 644 launchd/<label>.plist ~/Library/LaunchAgents/
sed -i '' -e "s|__EXECUTABLE__|$binary|" ... "$agent_path"   # fill placeholders
plutil -lint "$agent_path"                                    # validate before loading
launchctl bootout "gui/$UID" "$agent_path" 2>/dev/null || true  # idempotent reinstall
launchctl bootstrap "gui/$UID" "$agent_path"

uninstall.sh 执行相反操作:bootout 两个 Agent,并移除 plist 文件。 使用类似 com.<yourname>.<project> 的反向 DNS 标签。

验证安装

launchctl list | grep <project>          # exit status 0 = last run OK
sqlite3 "$db" "SELECT datetime(MAX(timestamp),'unixepoch','localtime') FROM raw_samples;"
# must be under a minute old; also run the doctor verb

如果采样停止:首先检查 ~/Library/Logs/<project>/stderr.log。

可选:隔离的单应用监控器

要监控某个应用(例如出现内存泄漏的 Electron IDE),请添加一个独立的可选采集器,并为其配置专属的架构、安装脚本和 ADR。通过 bundle 路径查找该应用的进程(绝不要按名称子串查找),使用 proc_pid_rusage/proc_pidinfo 读取每个进程的 CPU/RSS/磁盘 IO——开销低且无需 root——也绝不要在循环中启动 ps(这本身就是已知的卡顿来源)。

评论

支持 Markdown