增加终端控制台
WholeProject 是面向 Linux/openKylin 的轻量级系统异常诊断工具。项目通过 eBPF、procfs 和 sysfs 采集运行证据,对 CPU、I/O、内存、锁和系统调用五类异常进行窗口化分析、规则诊断、候选对象确认、跨领域因果排序,并输出可机器解析的 JSON 根因报告。
本仓库的原始赛题要求保留在社区赛题说明中。本文档只描述当前代码能够证明的功能,不把环境跳过、能力缺失或未完成的实机验证写成通过。
vmlinux.h
CAP_BPF
CAP_PERFMON
CAP_SYS_ADMIN
/sys/kernel/btf/vmlinux
源码编译依赖 CMake 3.16+、支持 C++17 的编译器、clang/LLVM、make、libelf 和 zlib 开发文件。当前生产验证器、运维 Python 工具和完整 Python 合同测试均使用 Python 3.10 语法,因此涉及这些工具或完整工程检查时最低要求为 Python 3.10+;个别简单脚本可能在更低版本运行,但不属于受支持的版本合同。完整工程检查还使用 clang-format、shfmt 和 shellcheck。压力复现可能使用 fio,其余主要负载由仓库脚本自身生成。
clang-format
shfmt
shellcheck
fio
在 openKylin/Debian 系系统上,可根据系统仓库中的实际包名安装:
sudo apt update sudo apt install build-essential cmake clang llvm make python3 pkg-config libelf-dev zlib1g-dev bpftool fio clang-format shfmt shellcheck
推荐使用新增的中文一键入口:
bash scripts/一键工程验收.sh
只构建正式程序:
cmake -S . -B build cmake --build build --target diagnose --parallel "$(nproc)"
项目原有入口 ./build.sh --clean 会配置、构建、运行完整 CTest 和静态门禁。中文文档路径相关测试已经迁移完成,标准全量测试命令为:
./build.sh --clean
ctest --test-dir build --output-on-failure
查看命令行帮助:
./build/diagnose --help
运行 10 个采集窗口后退出:
sudo ./build/diagnose 10
持续运行,收到 SIGINT 或 SIGTERM 后停止:
SIGINT
SIGTERM
sudo ./build/diagnose
指定目标进程并启用详细日志:
sudo env DIAG_TARGET_PID=1234 DIAG_VERBOSE=1 ./build/diagnose 30
运行时只有一个位置参数 RUN_CYCLES,有效范围为 1~2147483647;省略时持续运行。采集窗口、目标进程、报告目录、动态基线和深采门控通过环境变量配置。
RUN_CYCLES
普通用户从任意当前目录均可启动控制台,脚本只在加载 eBPF、安装依赖和管理本项目服务时请求 sudo:
sudo
bash /path/to/WholeProject0721/scripts/终端控制台.sh
主菜单固定提供五项功能:
build/diagnose
DIAG_TARGET_PID
diag_stress.sh run
控制台的普通报告浏览优先读取 /var/lib/wholeproject/report,随后回退项目 report/。场景复现使用项目 report/diagnosis/<领域>/<运行ID>/summary.json 作为本轮成功证据,并严格核对 RESULT、WORKLOAD_RESULT、DIAGNOSIS_RESULT、DIAGNOSE_EXIT 和 SUMMARY_PATH。若 wholeproject-diagnose.service 正在运行,控制台会明确询问是否仅在本轮停止;只有用户确认后才停止,并在成功、失败、超时、Ctrl+C 或控制台退出时恢复原有运行状态。原服务未运行时不会被自动启动。
/var/lib/wholeproject/report
report/
report/diagnosis/<领域>/<运行ID>/summary.json
RESULT
WORKLOAD_RESULT
DIAGNOSIS_RESULT
DIAGNOSE_EXIT
SUMMARY_PATH
wholeproject-diagnose.service
日志默认写入 ${XDG_STATE_HOME:-$HOME/.local/state}/wholeproject-console/,目录为 0755、文件为 0644。设置 NO_COLOR=1 或重定向输出时不会产生 ANSI 颜色控制符。完整工程验收仍使用独立的 scripts/一键工程验收.sh,不在控制台菜单中。
${XDG_STATE_HOME:-$HOME/.local/state}/wholeproject-console/
0755
0644
NO_COLOR=1
scripts/一键工程验收.sh
先检查当前机器可安全使用的压力规模:
bash scripts/diag_stress.sh inspect --dry-run
一键执行五领域诊断级复现:
sudo -E bash scripts/一键五场景复现.sh
单独复现某一领域:
sudo -E ./scripts/diag_stress.sh run cpu --level diagnosis sudo -E ./scripts/diag_stress.sh run memory --level diagnosis sudo -E ./scripts/diag_stress.sh run io --level diagnosis sudo -E ./scripts/diag_stress.sh run lock --level diagnosis sudo -E ./scripts/diag_stress.sh run syscall --level diagnosis
上述 run 命令保留原有“独立 diagnose 验收”语义,控制台的场景复现使用同一入口。
run
项目负责:
项目不负责:
CPU_PROCESS_USAGE_HIGH
CPU_BUSY_LOOP_SUSPECT
IO_DEVICE_LATENCY_HIGH
IO_WRITEBACK_STALL
MEM_RSS_GROWTH_HIGH
MEM_OOM_RISK
LOCK_MUTEX_CONTENTION_HIGH
LOCK_HOTSPOT_DOMINANCE
SYSCALL_LATENCY_HIGH
SYSCALL_FD_CHURN_HIGH
规则覆盖的完整事实来源是 src/diagnosis/rules/、config/rule-coverage-manifest.json 和 tests/fixtures/rules/。部分规则只能通过回放验证,部分规则会因运行时能力不足输出 UNSUPPORTED 或能力阻断状态;不能仅凭规则文件存在宣称实机已覆盖。
src/diagnosis/rules/
config/rule-coverage-manifest.json
tests/fixtures/rules/
UNSUPPORTED
WholeProject0721/ ├── src/app/ 程序入口、配置、生命周期和报告编排 ├── src/collector/ebpf/ eBPF 程序、加载、Map、ring buffer、领域采集器 ├── src/collector/system/ procfs/sysfs/cgroup 系统采样器 ├── src/diagnosis/ 规则、基线、事件、因果分析和报告生成 ├── include/ 对应公共接口和数据合同 ├── config/ 场景清单、规则合同和 JSON Schema ├── scripts/ 构建、验证、压力、性能和验收脚本 ├── tests/ 单元、契约、集成、回放和静态测试 ├── packaging/systemd/ 后台服务单元与环境配置示例 ├── third_party/ libbpf、bpftool、json.hpp 和 vmlinux.h ├── report/ 已生成的结构化诊断结果 └── docs/ 中文工程文档
详细模块关系和数据流见系统设计说明。
DIAG_RUNTIME_ROOT
DIAG_REPORT_DIR
report/diagnosis/
DIAG_REPORT_RUN_ID
DIAG_REPORT_FOCUS_DOMAIN
DIAG_LOG_LANGUAGE
zh_CN
en_US
DIAG_VERBOSE
DIAG_HEALTH_SUMMARY_WINDOWS
DIAG_WINDOW_MS
DIAG_BURST_SUBWINDOW_MS
DIAG_SHORT_PULSE_MODE
DIAG_PID_HINTS
DIAG_RULE_TRACE
DIAG_BASELINE_MODE
robust
DIAG_BASELINE_STATE_PATH
/var/lib/wholeproject/baseline-production.json
DIAG_BASELINE_PERSISTENCE
DIAG_PERF_PROFILE
DIAG_PERF_DOMAINS
门控阈值、动态基线、测试专用变量和压力脚本变量见参数配置说明。生产环境不要默认启用名称含 TEST_FORCE 的变量。
TEST_FORCE
默认诊断报告根为 report/diagnosis/。生产程序先读取正式诊断结果中的主根因领域,再建立独立运行目录;压力脚本传入的场景名只用于运行标识和复核期望,不决定正式分类。
report/ ├── diagnosis/ │ ├── cpu|memory|io|lock|syscall/<运行标识>/ │ ├── multi-domain/<运行标识>/ │ ├── no-anomaly/<运行标识>/ │ └── unknown/<运行标识>/ │ ├── summary.json │ ├── diagnose-rca-timeline-batch-*.json │ ├── evidence/ │ ├── logs/ │ └── run-meta.json ├── performance/ └── tests/
每个运行目录的主要文件为:
diagnose-rca-timeline-batch-*.json
diagnose.rca.timeline.batch.v1
summary.json
diagnose.rca.summary.v1
run-meta.json
正式运行、报告迁移和服务生成的报告目录使用 0755,普通报告文件使用 0644:所有本机用户均可读取和遍历这些报告,但只有文件属主可以修改。diagnose_summary 是当前例外:它重建并覆盖的 summary.json 为 0600。基线状态和服务环境文件也保持 0600。
diagnose_summary
0600
正式报告包含异常类型、关联对象、异常时间窗口、关键指标与阈值、疑似根因、置信度、证据质量、建议、采集会话和时间源等信息。报告 JSON Schema 位于 config/schemas/。当前摘要 Schema 会校验顶层必需字段、摘要版本和若干基本类型,但对 异常类型、关联对象、关键指标、疑似根因、异常时间窗口 和 证据状态 等内部对象只约束为 object,不是这些内部字段的完整合同;内部字段仍应以当前写入器和验证器为准。
config/schemas/
异常类型
关联对象
关键指标
疑似根因
异常时间窗口
证据状态
验证单领域报告:
python3 scripts/validate_timeline_reports.py \ --report-dir report/diagnosis/cpu/<运行标识> \ --require-domain cpu --require-summary
验证器至少需要一个 --require-domain;不传领域会退出失败。
--require-domain
当前工作区不把固定运行 ID 的报告作为现有样例证据。下面是依据当前 diagnose.rca.summary.v1、摘要版本 1.1 和写入器字段生成方式整理的示意片段;为便于直接校验,它保留了 Schema 要求的全部顶层字段,但不代表仓库中某次实际运行,PID、时间和数值仅用于说明结构:
1.1
{ "schema": "diagnose.rca.summary.v1", "generated_at_ms": 1785386424177, "collector_session_ids": [3816054232836], "source_reports": ["diagnose-rca-timeline-batch-example-1.json"], "diagnosis_count": 1, "诊断数量": 1, "摘要版本": "1.1", "运行标识": "example-cpu-run", "生成时间": "2026-07-30T12:40:24.177+08:00", "是否发现异常": true, "异常场景": { "代码": "cpu", "名称": "CPU 异常", "主领域": "cpu", "关联领域": [], "分类依据": "依据正式诊断结果中的主根因领域分类" }, "异常类型": [ { "规则标识": "CPU_PROCESS_USAGE_HIGH", "规则中文名称": "进程 CPU 使用率过高", "中文名称": "高 CPU 占用进程异常", "中文名称状态": "已配置", "严重程度": "高", "原始严重程度": "high", "原始异常类型": "cpu_hot_process" } ], "关联对象": [ { "对象类型": "进程", "原始对象类型": "process", "进程号": 1234, "线程号": null, "原始关联对象": "process:1234", "关联说明": "来自正式报告的关联对象" } ], "异常时间窗口": { "开始时间": "2026-07-30T12:40:08.331+08:00", "结束时间": "2026-07-30T12:40:22.338+08:00", "持续时间毫秒": 14007, "时钟源": "CLOCK_MONOTONIC", "原始开始时间纳秒": 58238400897639, "原始结束时间纳秒": 58252408435330 }, "关键指标": [ { "中文名称": "进程 CPU 使用率", "中文名称状态": "已配置", "原始字段": "process_cpu_pct", "单位": "%", "数据质量": "有效", "原始数据质量": "valid", "数值": 100.1, "参考阈值": 70.0, "判断": "观测值满足正式诊断规则的异常条件" } ], "疑似根因": [ { "结论": "疑似:自动发现的进程占用了大量 CPU 资源", "根因类型": "process_cpu_saturation", "置信程度": "中", "置信度原值": 75, "依据": [ "正式诊断规则 CPU_PROCESS_USAGE_HIGH 已满足条件", "进程 CPU 使用率(process_cpu_pct)构成关键指标证据" ] } ], "建议性分析结论": [ "检查自动发现的高 CPU 占用进程", "使用 cgroup 或 CPU 亲和性进行限制", "降低计算并发度或增加 CPU 资源" ], "证据状态": { "充分程度": "基本充分", "原始充分程度": "sufficient", "缺失信息": [], "详细证据是否截断": false }, "详细报告": ["diagnose-rca-timeline-batch-example-1.json"], "待补齐中文名称": [] }
摘要保留 PID/TID、规则 ID、原始字段和值用于复核,但不会复制完整证据链。原始时间线仍是正式证据来源。多主领域进入 multi-domain/;无法可靠分类进入 unknown/ 并说明原因;没有满足规则条件的事件进入 no-anomaly/,不得据此推断未检查领域健康。
multi-domain/
unknown/
no-anomaly/
历史报告先预览再迁移:
python3 scripts/migrate_reports.py --report-root report python3 scripts/migrate_reports.py --report-root report --apply
--apply 先复制并校验且保留原文件;仅显式增加 --move --confirm 才会删除校验成功的历史原文件。
--apply
--move --confirm
inspect --dry-run
UMask=0077
项目 CMake 注册的测试覆盖采集器、规则、基线、事件生命周期、报告、回放、压力编排、模式校验、中文文档合同和评审索引。推荐评委执行:
需要 root 的运行验证:
sudo -E bash scripts/verify_openkylin.sh
该验证脚本会生成环境、构建、内核能力、bpftool、dmesg 和运行日志。顶层退出码不能代替对内部 PASS、CHECK、SKIP 的逐项阅读。
PASS
CHECK
SKIP
测试步骤、输入输出、预期结果和退出码见测试与复现说明。跳过项必须单独报告且不计为通过。
PARTIAL
TIMEOUT
GAP
LICENSE
具体安装限制、运行降级条件和复现检查方法分别见安装部署说明、使用说明和测试与复现说明。
仓库包含 libbpf、bpftool、nlohmann/json、Linux UAPI 兼容头和生成的 vmlinux.h。这些组件分别保留其源文件中的 SPDX 或版权信息。首方项目许可证尚未由维护者确认,因此本文档不替维护者选择许可证,也不把第三方许可证自动套用于全部首方代码。
发布前必须由维护者确认首方版权主体、年份和许可证,并补齐项目根许可证文本以及第三方离线许可证包。详见第三方组件与开源合规说明。
版权所有:中国计算机学会技术支持:开源发展技术委员会 京ICP备13000930号-9 京公网安备 11010802047560号
WholeProject:基于 eBPF 的系统异常观测与根因定位工具
WholeProject 是面向 Linux/openKylin 的轻量级系统异常诊断工具。项目通过 eBPF、procfs 和 sysfs 采集运行证据,对 CPU、I/O、内存、锁和系统调用五类异常进行窗口化分析、规则诊断、候选对象确认、跨领域因果排序,并输出可机器解析的 JSON 根因报告。
本仓库的原始赛题要求保留在社区赛题说明中。本文档只描述当前代码能够证明的功能,不把环境跳过、能力缺失或未完成的实机验证写成通过。
快速开始
目标环境
vmlinux.h目录,但目录存在不等于全部平台均已实机验收。CAP_BPF、CAP_PERFMON、CAP_SYS_ADMIN等能力。/sys/kernel/btf/vmlinux、tracefs/debugfs、bpffs 和所需内核探针必须可用。依赖
源码编译依赖 CMake 3.16+、支持 C++17 的编译器、clang/LLVM、make、libelf 和 zlib 开发文件。当前生产验证器、运维 Python 工具和完整 Python 合同测试均使用 Python 3.10 语法,因此涉及这些工具或完整工程检查时最低要求为 Python 3.10+;个别简单脚本可能在更低版本运行,但不属于受支持的版本合同。完整工程检查还使用
clang-format、shfmt和shellcheck。压力复现可能使用fio,其余主要负载由仓库脚本自身生成。在 openKylin/Debian 系系统上,可根据系统仓库中的实际包名安装:
构建
推荐使用新增的中文一键入口:
只构建正式程序:
项目原有入口
./build.sh --clean会配置、构建、运行完整 CTest 和静态门禁。中文文档路径相关测试已经迁移完成,标准全量测试命令为:运行
查看命令行帮助:
运行 10 个采集窗口后退出:
持续运行,收到
SIGINT或SIGTERM后停止:指定目标进程并启用详细日志:
运行时只有一个位置参数
RUN_CYCLES,有效范围为 1~2147483647;省略时持续运行。采集窗口、目标进程、报告目录、动态基线和深采门控通过环境变量配置。中文终端控制台
普通用户从任意当前目录均可启动控制台,脚本只在加载 eBPF、安装依赖和管理本项目服务时请求
sudo:主菜单固定提供五项功能:
build/diagnose60 秒,也可设置时长或DIAG_TARGET_PIDdiag_stress.sh run运行独立诊断验收;若后台服务正在运行,先经用户确认临时停止,结束后恢复控制台的普通报告浏览优先读取
/var/lib/wholeproject/report,随后回退项目report/。场景复现使用项目report/diagnosis/<领域>/<运行ID>/summary.json作为本轮成功证据,并严格核对RESULT、WORKLOAD_RESULT、DIAGNOSIS_RESULT、DIAGNOSE_EXIT和SUMMARY_PATH。若wholeproject-diagnose.service正在运行,控制台会明确询问是否仅在本轮停止;只有用户确认后才停止,并在成功、失败、超时、Ctrl+C 或控制台退出时恢复原有运行状态。原服务未运行时不会被自动启动。日志默认写入
${XDG_STATE_HOME:-$HOME/.local/state}/wholeproject-console/,目录为0755、文件为0644。设置NO_COLOR=1或重定向输出时不会产生 ANSI 颜色控制符。完整工程验收仍使用独立的scripts/一键工程验收.sh,不在控制台菜单中。五领域复现入口
先检查当前机器可安全使用的压力规模:
一键执行五领域诊断级复现:
单独复现某一领域:
上述
run命令保留原有“独立 diagnose 验收”语义,控制台的场景复现使用同一入口。项目目标与职责边界
项目负责:
项目不负责:
功能概览
CPU_PROCESS_USAGE_HIGH、CPU_BUSY_LOOP_SUSPECTIO_DEVICE_LATENCY_HIGH、IO_WRITEBACK_STALLMEM_RSS_GROWTH_HIGH、MEM_OOM_RISKLOCK_MUTEX_CONTENTION_HIGH、LOCK_HOTSPOT_DOMINANCESYSCALL_LATENCY_HIGH、SYSCALL_FD_CHURN_HIGH规则覆盖的完整事实来源是
src/diagnosis/rules/、config/rule-coverage-manifest.json和tests/fixtures/rules/。部分规则只能通过回放验证,部分规则会因运行时能力不足输出UNSUPPORTED或能力阻断状态;不能仅凭规则文件存在宣称实机已覆盖。工程结构
详细模块关系和数据流见系统设计说明。
运行与配置
常用正式配置
DIAG_TARGET_PIDDIAG_RUNTIME_ROOTDIAG_REPORT_DIRreport/diagnosis/DIAG_REPORT_RUN_IDDIAG_REPORT_FOCUS_DOMAINDIAG_LOG_LANGUAGEzh_CNzh_CN或en_USDIAG_VERBOSEDIAG_HEALTH_SUMMARY_WINDOWSDIAG_WINDOW_MSDIAG_BURST_SUBWINDOW_MSDIAG_SHORT_PULSE_MODEDIAG_PID_HINTSDIAG_RULE_TRACEDIAG_BASELINE_MODErobustDIAG_BASELINE_STATE_PATH/var/lib/wholeproject/baseline-production.jsonDIAG_BASELINE_PERSISTENCEDIAG_PERF_PROFILEDIAG_PERF_DOMAINS门控阈值、动态基线、测试专用变量和压力脚本变量见参数配置说明。生产环境不要默认启用名称含
TEST_FORCE的变量。输出合同
默认诊断报告根为
report/diagnosis/。生产程序先读取正式诊断结果中的主根因领域,再建立独立运行目录;压力脚本传入的场景名只用于运行标识和复核期望,不决定正式分类。每个运行目录的主要文件为:
diagnose-rca-timeline-batch-*.json:完整批次,外层模式为diagnose.rca.timeline.batch.v1;summary.json:UTF-8 中文人类可读摘要,模式为diagnose.rca.summary.v1,只投影正式报告证据;run-meta.json:运行标识、实际分类、配置关注领域和相对路径;正式运行、报告迁移和服务生成的报告目录使用
0755,普通报告文件使用0644:所有本机用户均可读取和遍历这些报告,但只有文件属主可以修改。diagnose_summary是当前例外:它重建并覆盖的summary.json为0600。基线状态和服务环境文件也保持0600。正式报告包含异常类型、关联对象、异常时间窗口、关键指标与阈值、疑似根因、置信度、证据质量、建议、采集会话和时间源等信息。报告 JSON Schema 位于
config/schemas/。当前摘要 Schema 会校验顶层必需字段、摘要版本和若干基本类型,但对异常类型、关联对象、关键指标、疑似根因、异常时间窗口和证据状态等内部对象只约束为 object,不是这些内部字段的完整合同;内部字段仍应以当前写入器和验证器为准。验证单领域报告:
验证器至少需要一个
--require-domain;不传领域会退出失败。摘要示意片段
当前工作区不把固定运行 ID 的报告作为现有样例证据。下面是依据当前
diagnose.rca.summary.v1、摘要版本1.1和写入器字段生成方式整理的示意片段;为便于直接校验,它保留了 Schema 要求的全部顶层字段,但不代表仓库中某次实际运行,PID、时间和数值仅用于说明结构:摘要保留 PID/TID、规则 ID、原始字段和值用于复核,但不会复制完整证据链。原始时间线仍是正式证据来源。多主领域进入
multi-domain/;无法可靠分类进入unknown/并说明原因;没有满足规则条件的事件进入no-anomaly/,不得据此推断未检查领域健康。历史报告先预览再迁移:
--apply先复制并校验且保留原文件;仅显式增加--move --confirm才会删除校验成功的历史原文件。权限与安全
inspect --dry-run,不要直接在生产业务主机运行。UMask=0077保护基线状态和其他私有文件,但运行根目录及报告目录为0755、报告文件为0644,便于所有本机用户只读复核;安装说明见后台服务安装说明。测试与验收
项目 CMake 注册的测试覆盖采集器、规则、基线、事件生命周期、报告、回放、压力编排、模式校验、中文文档合同和评审索引。推荐评委执行:
需要 root 的运行验证:
该验证脚本会生成环境、构建、内核能力、bpftool、dmesg 和运行日志。顶层退出码不能代替对内部
PASS、CHECK、SKIP的逐项阅读。测试步骤、输入输出、预期结果和退出码见测试与复现说明。跳过项必须单独报告且不计为通过。
文档索引
限制与故障排查
DIAG_TARGET_PID能获得更稳定的进程级证据。PARTIAL、UNSUPPORTED、TIMEOUT、GAP、SKIP和CHECK不是通过结论。LICENSE,不得擅自推断首方代码许可证;第三方许可信息见合规说明。具体安装限制、运行降级条件和复现检查方法分别见安装部署说明、使用说明和测试与复现说明。
开源与第三方声明
仓库包含 libbpf、bpftool、nlohmann/json、Linux UAPI 兼容头和生成的
vmlinux.h。这些组件分别保留其源文件中的 SPDX 或版权信息。首方项目许可证尚未由维护者确认,因此本文档不替维护者选择许可证,也不把第三方许可证自动套用于全部首方代码。发布前必须由维护者确认首方版权主体、年份和许可证,并补齐项目根许可证文本以及第三方离线许可证包。详见第三方组件与开源合规说明。