目录

SysWatch

SysWatch 是面向 Linux 6.6+ 的一次性系统异常观测与诊断工具。它以 C++17、libbpf 和 eBPF CO-RE 在固定 15 秒 competition 窗口内同时覆盖 syscall、CPU、块 I/O、内存和 futex 五个 collector,并输出结构化 DiagnosisReport 与数值 evidence。外部评测对 pressure/control 的 anomaly type、root-cause code、target 和 evidence 做精确机器判定;all-mode 最终验收标准为 24/24 PASS(12 TP + 12 TN)、零 FAIL/SKIP/INVALID 且 cleanup 全空。

SysWatch 提供可复核的异常分类和数值证据,不是持续事件追踪器。热点信号表示“值得继续调查”,不自动等价于系统资源饱和或已证明的因果关系。

核心能力

Collector 主要数据 诊断能力 归因边界
syscall syscall 计数、速率、热点 PID 与 syscall ID 识别高频系统调用行为 属于观察信号,不单独证明资源压力
cpu CPU 利用率、运行队列、任务 CPU 时间 识别系统级或任务级 CPU 饱和 任务归因依赖采集窗口内的可见进程
io block request 生命周期、设备吞吐与延迟 识别设备级 I/O 压力 按 major:minor 聚合,不提供 PID、路径或单请求追踪
memory /proc 系统指标、进程组匿名 RSS 与同窗 CPU 活动、cgroup v2 与可选 fault telemetry 识别系统、cgroup 或并行任务工作集压力 task 工作集归因要求同一 PID 实例、同一进程组与完整起止快照
lock futex wait/wake、等待时长与 PI 标识 区分普通 futex 等待压力和 PI 热锁 generic futex 无法可靠识别 mutex owner

所有 collector 都将采集结果归一化为 MetricSample;规则层只消费指标,报告层不直接读取 BPF map。这使采集、判定和展示可以分别测试与审计。

快速开始

环境要求

  • Linux 6.6+,并且 /sys/kernel/btf/vmlinux 可读;
  • Clang/LLVM、支持 C++17 的编译器、Make 与 pkg-config;
  • libbpf、libelf、zlib 和可用的 bpftool;
  • 加载 eBPF 所需的 root 权限或等效 capabilities。

当前实机验证环境为 openKylin 2.0 SP2(nile)、Linux 6.6.0-19-generic、x86_64。arm64 与跨机器可重复性尚未验证。

构建与测试

./scripts/check-env.sh
make clean
make
BPFTOOL=/path/to/a/working/bpftool make test

构建成功后生成 ./syswatch 和 ./syswatch-workload。

运行完整采集

sudo -n ./syswatch \
  --collect all \
  --duration 15 \
  --threshold-profile competition \
  --output markdown \
  --metrics-output /var/tmp/syswatch-metrics.json \
  > /var/tmp/syswatch-report.md

该命令会产生三类输出:

通道 内容
stdout 最终 JSON 或 Markdown 报告;示例中重定向到 /var/tmp/syswatch-report.md
stderr 每个 collector 的机器可读诊断摘要;连接 TTY 时附加中文综合判断
--metrics-output 规则执行前的原始 MetricSample JSON 数组,采用原子替换写入

退出码为 0 表示所有请求的 collector 成功,1 表示至少一个 collector 失败,130 表示采集被取消。失败时仍会先输出可用的 partial report,再通过 stderr 给出失败原因。

CLI 参考

Usage: ./syswatch [--duration SECONDS] [--interval SECONDS]
                  [--collect TYPE] [--output json|markdown]
                  [--threshold-profile default|competition]
                  [--metrics-output PATH] [--target-pid PID]
                  [--target-object OBJECT] [--cgroup PATH] [--help]
选项 说明
--collect syscall、cpu、io、memory、lock 或 all;默认 syscall
--duration 正整数采集秒数;默认 10
--interval 正整数等待分块秒数;默认 1;不是周期报告间隔
--output json 或 markdown;默认 json
--threshold-profile default 或 competition;默认 default
--metrics-output 将规则执行前的原始指标写入指定路径
--target-pid 仅让匹配 PID 的任务指标参与诊断;syscall 在采集侧过滤 TGID;all 中不用于 I/O
--target-object I/O 设备目标,格式为十进制 major:minor;all 中不再过滤其他 collector
--cgroup 为 memory 或 all 指定 cgroup v2 内存目标
--help 输出帮助并退出

设备级 I/O 示例:

sudo -n ./syswatch --collect io --duration 10 \
  --target-object 252:0 \
  --threshold-profile competition \
  --output json

诊断契约

共享采集窗口

--collect all 采用严格的 five-of-five 语义:syscall、CPU、I/O、memory、lock 必须全部成功 start 和 snapshot,且最终输出恰好包含五种 metric kind,命令才返回 0。

collector 先在禁用采集的状态下完成加载与 attach,再统一 arm 到同一个未来半开窗口 [start_ns, end_ns)。所有成功样本必须报告该公共窗口;窗口不一致会使对应 collector 失败,不会把各 collector 的最早开始和最晚结束拼接成一个表面上的总窗口。CPU 与 memory 的 proc/cgroup 计数在窗口两端进行有界采样,超过边界偏差预算时拒绝结果。memory 另在公共窗口起止读取任务匿名 RSS 与 CPU 累计 tick,并以 PID starttime、PGID 和 comm 校验同一进程实例;完整的稳定大工作集还必须具有同窗持续 CPU 活动才参与全采集任务归因,轻量父进程或 wrapper 不计入有效工作成员。

资源异常与观察信号

综合判断使用确定性的优先级规则,不宣称由相关性推导出因果关系。

类型 终端语义
CPU、I/O、memory 或 PI futex_hot_lock 可以参与主要问题和次要问题排序的资源异常
syscall_hotspot / excessive_syscall_rate 高频行为观察信号;有资源异常时显示为伴随信号
generic futex_wait_pressure 同一同步点存在长等待、并发 waiter 与 wake-one 交接证据;有资源异常时显示为伴随信号
none 当前窗口内没有达到该 collector 的阈值

典型终端输出如下:

综合判断:主要问题=CPU饱和(worker/PID 4242,CPU密集或忙循环) - 次要问题=无 - 伴随信号=syscall热点、futex等待压力
综合判断:未发现资源压力 - 观察信号=syscall热点、futex等待压力
综合判断:未发现达到阈值的异常

中文综合判断只在 stderr 直接连接 TTY 时显示。stderr 被重定向或通过管道传递时,仍保留 syswatch diagnosis: collector=... anomaly_type=... root_cause_code=... 行,但不输出中文综合判断。NO_COLOR 或 TERM=dumb 只关闭颜色。

Lock 归因边界

generic FUTEX_WAIT 只能证明等待队列压力,不能识别 mutex owner,因此报告为 futex_wait_pressure。只有样本含 futex_pi_lock_id=,并同时满足等待时长、并发 waiter 与交接等复合条件时,才报告可参与资源问题排序的 futex_hot_lock。collector 报告始终保留原始 anomaly type、root-cause code 和数值 evidence,便于后续关联分析。

架构

内核事件 + /proc + cgroup
           │
           ▼
      Collectors
           │ MetricSample
           ▼
   Deterministic Rules
           │ DiagnosisReport
           ├──────────────► JSON / Markdown Reporter
           └──────────────► Scenario Evaluator

仓库主要目录:

.
├── Makefile        构建与测试入口
├── include/        BPF 与用户态共享 ABI
├── src/bpf/        五类 eBPF 程序
├── src/user/       CLI、collector、规则与 reporter
├── tests/          单元、契约与脚本测试
├── scripts/        环境检查、场景和性能证据 runner
├── tools/          确定性 workload
├── scenarios/      场景 ground truth
├── examples/       synthetic 报告 fixture
└── docs/           架构、使用、评测与验证文档

I/O 请求通过 insert/issue/complete 关联,并在 per-CPU map 中按设备聚合;用户态负责检查健康状态和合并各 CPU 副本。完整设计与失败语义见架构说明。

验证状态

最终 all-mode 验收标准

外部矩阵必须以 clean commit/tree 和实测 executable identity 绑定唯一 authoritative summary。验收要求 24/24 PASS:12 个 pressure TP、12 个 control TN,零 FAIL/SKIP/INVALID,24 份 cleanup error 列表均为空。

固定 competition pressure workload

以下四条是评测消费者可见的精确 workload argv;180 秒是 workload 生命期 guard,SysWatch capture 仍固定为 15 秒:

/usr/local/bin/stress-ng --cpu 4 --cpu-method matrixprod --timeout 180s --metrics-brief
/usr/local/bin/fio --name=randrw-test --filename=/tmp/fio-test.img --size=4G --rw=randrw --rwmixread=70 --bs=4k --iodepth=64 --numjobs=4 --runtime=180 --time_based --group_reporting
/usr/local/bin/stress-ng --vm 4 --vm-bytes 80% --vm-keep --timeout 180s --metrics-brief
/usr/local/bin/stress-ng --mutex 8 --timeout 180s --metrics-brief

复现验证

基础场景会保存运行上下文、workload 日志、原始 metrics、报告和 evaluation。I/O 场景只应在隔离测试机上,针对 runner 拥有或已验证的 null_blk 设备运行:

sudo -n python3 scripts/scenarios/run_basic_suite.py \
  --syswatch ./syswatch \
  --workload ./syswatch-workload \
  --ground-truth scenarios/ground-truth.json \
  --output-root /var/tmp/syswatch-basic \
  --scenario io_pressure

题目 workload 固定使用 /tmp/fio-test.img。本主机 /tmp 只有 2.9 GiB 可用,不能满足安全的 4.5 GiB preflight;自动化主机运行因此使用题目允许的存储替代 ./.local/syswatch-fio-test.img,其仓库文件系统有 7.0 GiB 可用,并保持 4G 与其他 fio 选项完全不变。这是可复现的环境准备,不改变产品或 evaluator 契约。fresh clone 先创建被 .gitignore 覆盖的目录:

mkdir -p .local
sudo -n python3 scripts/scenarios/run_external_pressure_suite.py --syswatch ./syswatch --stress-ng /usr/local/bin/stress-ng --fio /usr/local/bin/fio --fio-file ./.local/syswatch-fio-test.img --ground-truth scenarios/external-pressure-ground-truth.json --output-root /var/tmp/syswatch-results/final-commit-20260810-external --scenario all --rounds 3 --collect-mode all

--collect-mode all 让题目八个 pressure/control 场景的每一轮都实际运行一个 syswatch --collect all。runner 将五份原始诊断完整保存为 all-reports.json;pressure 按目标 collector 校验 type/root/target/evidence,control 则检查同轮全部五份报告,任一禁止异常都会判为 FP,而不是只看选中的单份报告。

sudo -n python3 scripts/scenarios/run_all_smoke.py \
  --syswatch ./syswatch \
  --workload ./syswatch-workload \
  --output-root /var/tmp/syswatch-results/final-commit-20260810-all
sudo -n env FIO_BIN=/usr/local/bin/fio BPFTOOL_BIN=./bin/bpftool \
  ./scripts/measure-overhead.sh \
  --mode io --rounds 3 --duration 30 \
  --output-root /var/tmp/syswatch-results/final-commit-20260810-performance

三个待运行的 final 审计目标分别是 /var/tmp/syswatch-results/final-commit-20260810-external、/var/tmp/syswatch-results/final-commit-20260810-all 和 /var/tmp/syswatch-results/final-commit-20260810-performance;README 不预告其 external 计数、strict-all success 或性能数值。每个根只能接受唯一 run,且 summary 必须匹配最终 commit/tree、无 executable drift、authoritative=true、validation_errors=[]。更完整的判定与路径审计见评测说明。性能脚本提供 fio-only、fio + I/O、fio + all 的 A/B/C measurement capability;validity 与 target attainment 分开报告。

性能证据脚本可先以 dry-run 检查命令与目录布局;该模式不会加载模块或访问块设备:

DRY_RUN=1 ./scripts/measure-overhead.sh \
  --mode io \
  --rounds 3 \
  --duration 5 \
  --output-root /var/tmp/syswatch-overhead-dry-run

--allow-dirty-source 只用于开发排障;它允许 dirty tracked source 开始运行,但会永久把该次输出标记为 non-authoritative,因此不得用于上述三个最终根。

已知限制

  • SysWatch 是单次、有界窗口诊断工具,不负责持续监控、告警或历史存储。
  • I/O 结果是设备级聚合;requeue 使用重复 issue 近似,部分完成只在最终完成时聚合,P99 来自 16 桶直方图近似。
  • generic futex 等待没有可靠 owner 信息;不能把等待进程直接描述为持锁者。
  • page_fault_user 等可选 telemetry 缺失时,memory collector 可能只能给出系统级归因。
  • 任一 collector 的 fatal 健康问题、lost telemetry、窗口不一致或输出失败都会使本次采集失败,而不是静默生成完整结论。
  • 历史 Processed 1000001 insn verifier 故障及解决过程记录在 I/O verifier 问题记录。

文档

关于
142.5 MB
邀请码
    Gitlink(确实开源)
  • 加入我们
  • 官网邮箱:gitlink@ccf.org.cn
  • QQ群
  • QQ群
  • 公众号
  • 公众号

版权所有:中国计算机学会技术支持:开源发展技术委员会
京ICP备13000930号-9 京公网安备 11010802047560号