如何导出 macOS 网络使用数据
如何导出和分析 macOS 网络使用数据:内置命令、常见格式与好用的一行命令。
- Developer tools
- macOS
- Bandwidth
- Tutorial
你终于抓到了那个尖峰。三天来你一直在想为什么家里互联网用量在随机时间跳,你终于在合适时刻有工具开着看到了它。然后呢?你想把这数据从实时 UI 拿出来,放进能分析、能跟同事分享、能跟服务器日志关联的东西里。导出 macOS 网络用量的能力比人们意识到的更重要,知道往哪看时 macOS 选项还不错。
这篇走一遍实操路径:短捕获用 nettop -L、系统侧网络事件用统一日志、CSV 用采样脚本,以及 ova 数据存在磁盘上的什么位置。
为什么要导出 macOS 网络用量
几个真实情况:
- 异常调查 — 你看到凌晨 3 点 2 GB 上传,想把整夜的源进程画成图。
- 容量规划 — 你在计费或限速连接上(Starlink Roam、酒店 Wi-Fi、移动共享网络),想知道留什么开着是安全的。
- 性能调试 — 服务器团队在问慢请求是什么时候开始的,你想把客户端网络用量叠在他们服务器日志上。
- 按项目带宽预算 — 你按小时给客户开账单,想做一次合理性检查,看他们的构建管线昨天上传了什么。
- 好奇 — 你只是想看看自己的数据。
对所有这些,"打开活动监视器盯着"不够。你需要数据落到磁盘,以你能操作的格式。
选项 1:nettop 日志模式
最简单的导出路径是内置的。nettop -L <count> 在日志模式下跑 <count> 个样本,把每个样本作为一行文本输出,然后退出。配合 -J 选列、-s 设间隔,你拿到能管道到文件的干净输出。
nettop -L 600 -s 1 -P -J bytes_in,bytes_out,interface,state \
> ~/Desktop/nettop-10min.txt那是 600 个样本、一秒间隔——十分钟捕获。每个样本列出每个活跃进程,带你要的列。
输出不算 CSV——每个样本一个表头、样本之间空行、进程名带空格。但能解析。短的 awk 或 Python 脚本会把它变成干净的表。
nettop 日志的限制
- 它只在跑的时候捕获。如果你想知道昨天发生了什么,没戏。
- 它默认报告自进程启动以来的累计;增量得自己算。
- 辅助进程显示成单独行(不归并)。
- 样本格式不是一等公民 CSV;准备写解析器。
对特定时间窗口的临时捕获——"我马上要 push 到 GitHub,捕获前后五分钟"——nettop -L 很好。要持续数据,你想要别的。
选项 2:统一日志
macOS 的统一日志从系统框架捕获结构化事件,包括网络。CFNetwork(URLSession 层)和 Network.framework 都为连接生命周期、TLS 握手、重试和失败发出日志行。事后可以提取。
要看现在有什么,查上一小时:
log show --last 1h --predicate 'subsystem == "com.apple.CFNetwork"' \
--info --debug要导出到文件:
log show --last 24h --predicate 'subsystem == "com.apple.CFNetwork"' \
--style compact > ~/Desktop/cfnetwork-day.log有用的谓词:
subsystem == "com.apple.CFNetwork"— URLSession 请求、TLS、重定向subsystem == "com.apple.network"— Network.framework 路径变化、连接状态process == "YourApp"— 限到一个应用eventMessage CONTAINS "443"— 在日志消息里做文本搜索
统一日志保留约最近几天的系统事件,看量。它不是为字节计数设计的——是为事件审计设计的。但如果你的问题是"到 api.example.com 的连接是不是 14:23 失败了",统一日志知道。
log show vs log stream
log show 读历史日志。log stream 看新事件实时。在你想留个终端跑着观察事件发生时用 log stream:
log stream --predicate 'subsystem == "com.apple.network"' --level debug用 >> 管道到文件做滚动捕获。
选项 3:自定义采样脚本
如果你想要按进程带宽的 CSV 输出——多数人的实际目标——20 行 shell 就能搭。思路:每 N 秒轮询、对累计字节数做差、输出 CSV。
#!/usr/bin/env bash
# Naive per-process bandwidth sampler.
INTERVAL=5
echo "timestamp,pid,process,delta_in,delta_out"
declare -A prev_in prev_out
while true; do
ts=$(date +%s)
while IFS=, read pid name in_bytes out_bytes; do
pi=${prev_in[$pid]:-0}
po=${prev_out[$pid]:-0}
di=$((in_bytes - pi))
do_=$((out_bytes - po))
if (( di > 0 || do_ > 0 )); then
echo "$ts,$pid,$name,$di,$do_"
fi
prev_in[$pid]=$in_bytes
prev_out[$pid]=$out_bytes
done < <(nettop -P -L 1 -J pid,interface,bytes_in,bytes_out 2>/dev/null \
| awk 'NR>2 {print $2","$1","$3","$4}')
sleep $INTERVAL
done这是个草图——生产代码会处理进程退出、辅助进程归并、日志轮转,以及 nettop 输出格式难解析的事实——但它展示了形态。你采样、做差、输出 CSV。如果想让它在睡眠后还活着,在 caffeinate 下跑或作为 launchd 代理。
看 ova 实战
一眼可瞄的菜单栏带宽监控——本地、签名、约 3 MB。
选项 4:ova 的本地数据库
一个专用带宽监控让你免于写上面那种脚本。ova 把 SQLite 数据库放在:
~/Library/Application Support/ova/内容是你在 UI 里看到的同一份时序数据:每个应用的入字节和出字节,约 1 Hz 采样,辅助进程归并到父应用下。本地,无云同步,无遥测。你拥有这个文件。
因为是 SQLite,任何能读 SQLite 的东西都能读:sqlite3 CLI、Python 的 sqlite3 模块、DB Browser for SQLite,或在 DuckDB 里快速一查。你可以:
- 一条命令导出整个历史到 CSV
- 跑聚合("这周哪个应用用了最多带宽,按小时")
- 跟你自己的日志连接(构建管线、服务器访问日志、日历事件)
- 备份到你常规备份目标
用 sqlite3 导到 CSV 的典型例子:
sqlite3 -header -csv \
~/Library/Application\ Support/ova/<file>.sqlite \
"SELECT timestamp, app, bytes_in, bytes_out FROM samples \
WHERE timestamp > strftime('%s','now','-7 days') \
ORDER BY timestamp" > ~/Desktop/last-week.csv实操配方、连接和隐私
一旦你有了 CSV——从任何源——几个查询就值回成本。
按周前列应用
SELECT app,
SUM(bytes_in) / (1024*1024) AS mb_down,
SUM(bytes_out) / (1024*1024) AS mb_up
FROM samples
WHERE timestamp > strftime('%s','now','-7 days')
GROUP BY app
ORDER BY (mb_down + mb_up) DESC
LIMIT 20;几乎总是讲一个清楚的故事。浏览器在顶、同步应用在中、系统服务在底。
按小时热图
SELECT strftime('%H', timestamp, 'unixepoch', 'localtime') AS hour,
SUM(bytes_in + bytes_out) / (1024*1024) AS mb
FROM samples
WHERE timestamp > strftime('%s','now','-30 days')
GROUP BY hour
ORDER BY hour;显示你的流量何时尖峰。多数人是早 9、下午 1、下午 4,加上一个夜里云同步的长尾。
异常检测
SELECT app,
date(timestamp, 'unixepoch', 'localtime') AS day,
SUM(bytes_out) / (1024*1024) AS mb_up
FROM samples
GROUP BY app, day
HAVING mb_up > 500
ORDER BY mb_up DESC;标记任何上传超过 500 MB 的应用-日。少数是正常的(到网络目标的 Time Machine、照片同步、大文件传输)。一整列不熟悉的应用值得调查。
组合源
最强的工作流同时用多个源。
- ova 做字节计数 — 谁用了多少、什么应用、什么时候
- 统一日志做事件 — 连接什么时候开始、失败、重试
tcpdump看线 — 真正神秘的时候
你可以按时间戳连接它们。如果 ova 显示 cloudd 在 3:14 AM 上传 200 MB,统一日志显示 cloudd 在同步什么,并且(如果你有抓包跑着)tcpdump 显示目的 IP 段确认是 iCloud。
关于隐私的一点
任何导出网络数据的东西都可能泄漏你不想分享的信息。主机名,甚至统一日志里的路径,都可能透露你用什么服务。在把日志发给同事或粘进聊天前:
- 如果 IP 地址会标识你家网络,去掉
- 涂掉透露个人服务的主机名
- 移除透露你不想宣传的应用的进程名
这也是为什么纯本地工具重要。ova 不把你数据送去任何地方——它待在你磁盘上。你导出什么是你的决定。
收尾
要导出 macOS 网络用量数据你有几条合理路径:短捕获用 nettop -L、事件审计用统一日志、要完全控制的话自定义采样脚本,以及像 ova 这种本地 SQLite 撑腰的监控做持续按应用计数。按你需要事件还是字节、以及你在乎多长一个窗口来选。
要低成本路径持续捕获并允许你后续查询,装 ova——约 3 MB,macOS 14+,Apple Silicon 和 Intel,约 1 Hz 采样。数据住在你 ~/Library/Application Support/ova/ 目录的 SQLite 里,所以任何你已经会的分析工具都能读它。