目录

WholeProject:基于 eBPF 的系统异常观测与根因定位工具

WholeProject 是面向 Linux/openKylin 的轻量级系统异常诊断工具。项目通过 eBPF、procfs 和 sysfs 采集运行证据,对 CPU、I/O、内存、锁和系统调用五类异常进行窗口化分析、规则诊断、候选对象确认、跨领域因果排序,并输出可机器解析的 JSON 根因报告。

本仓库的原始赛题要求保留在社区赛题说明中。本文档只描述当前代码能够证明的功能,不把环境跳过、能力缺失或未完成的实机验证写成通过。

快速开始

目标环境

  • Linux 内核 6.6 及以上;评审目标为 openKylin。
  • x86_64 已在当前工作区完成编译测试。构建系统还包含 arm、arm64、aarch64、riscv、riscv64、loongarch、loongarch64、powerpc 和 s390x 的 vmlinux.h 目录,但目录存在不等于全部平台均已实机验收。
  • 运行 eBPF 诊断通常需要 root,或具备内核允许的 CAP_BPFCAP_PERFMONCAP_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-formatshfmtshellcheck。压力复现可能使用 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 和静态门禁。中文文档路径相关测试已经迁移完成,标准全量测试命令为:

ctest --test-dir build --output-on-failure

运行

查看命令行帮助:

./build/diagnose --help

运行 10 个采集窗口后退出:

sudo ./build/diagnose 10

持续运行,收到 SIGINTSIGTERM 后停止:

sudo ./build/diagnose

指定目标进程并启用详细日志:

sudo env DIAG_TARGET_PID=1234 DIAG_VERBOSE=1 ./build/diagnose 30

运行时只有一个位置参数 RUN_CYCLES,有效范围为 1~2147483647;省略时持续运行。采集窗口、目标进程、报告目录、动态基线和深采门控通过环境变量配置。

中文终端控制台

普通用户从任意当前目录均可启动控制台,脚本只在加载 eBPF、安装依赖和管理本项目服务时请求 sudo

bash /path/to/WholeProject0721/scripts/终端控制台.sh

主菜单固定提供五项功能:

选项 功能 实际行为
1 快速诊断 默认运行 build/diagnose 60 秒,也可设置时长或 DIAG_TARGET_PID
2 场景复现 调用 diag_stress.sh run 运行独立诊断验收;若后台服务正在运行,先经用户确认临时停止,结束后恢复
3 一键部署 检测并安装缺失依赖,构建程序,安装、启动并验证 systemd 服务
4 性能监控 按秒显示服务、PID、CPU、RSS、线程、FD 和最新报告
5 报告查看 显示最新中文摘要,或按六类目录浏览报告

控制台的普通报告浏览优先读取 /var/lib/wholeproject/report,随后回退项目 report/。场景复现使用项目 report/diagnosis/<领域>/<运行ID>/summary.json 作为本轮成功证据,并严格核对 RESULTWORKLOAD_RESULTDIAGNOSIS_RESULTDIAGNOSE_EXITSUMMARY_PATH。若 wholeproject-diagnose.service 正在运行,控制台会明确询问是否仅在本轮停止;只有用户确认后才停止,并在成功、失败、超时、Ctrl+C 或控制台退出时恢复原有运行状态。原服务未运行时不会被自动启动。

日志默认写入 ${XDG_STATE_HOME:-$HOME/.local/state}/wholeproject-console/,目录为 0755、文件为 0644。设置 NO_COLOR=1 或重定向输出时不会产生 ANSI 颜色控制符。完整工程验收仍使用独立的 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 验收”语义,控制台的场景复现使用同一入口。

项目目标与职责边界

项目负责:

  • 采集 CPU、I/O、内存、锁和系统调用领域的内核态与用户态证据;
  • 建立带序列号、时间范围、质量和损失语义的采集窗口;
  • 使用规则、动态基线、候选确认和时间因果分析定位异常对象及疑似根因;
  • 输出时间线批次报告和精简摘要;
  • 提供回放、压力场景、契约检查、性能采集和 openKylin 验证工具。

项目不负责:

  • 在内核不支持探针、权限不足或证据丢失时伪造确定性结论;
  • 把压力脚本生成的样本直接当作所有硬件和发行版的准确率证明;
  • 自动修复被诊断的业务程序或系统配置;
  • 替代审计、安全取证或长期指标存储平台。

功能概览

领域 主要观测内容 示例规则或结论
CPU 进程/线程占用、运行队列、调度等待、上下文切换、频率和中断压力 CPU_PROCESS_USAGE_HIGHCPU_BUSY_LOOP_SUSPECT
I/O 请求时延、P99、队列、慢突发、写回、错误和超时 IO_DEVICE_LATENCY_HIGHIO_WRITEBACK_STALL
内存 可用内存、RSS 增长、缺页、回收、交换和 OOM 事件 MEM_RSS_GROWTH_HIGHMEM_OOM_RISK
mutex/futex 等待、热点锁、长尾等待和调用栈聚集 LOCK_MUTEX_CONTENTION_HIGHLOCK_HOTSPOT_DOMINANCE
系统调用 调用频率、耗时、P99、错误、重试、FD 变化和热点栈 SYSCALL_LATENCY_HIGHSYSCALL_FD_CHURN_HIGH

规则覆盖的完整事实来源是 src/diagnosis/rules/config/rule-coverage-manifest.jsontests/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_TARGET_PID 0/未设置 指定目标进程 空字符串等同未设置;当前实现按十进制数字前缀解析且未校验尾随字符,详见参数说明和已知限制
DIAG_RUNTIME_ROOT 编译时项目根目录 稳定部署运行根目录 必须为绝对路径,否则回退
DIAG_REPORT_DIR 运行根下的 report/diagnosis/ 选择诊断报告根目录 只能位于报告根目录内部;生产默认启用分类布局
DIAG_REPORT_RUN_ID 自动生成 为编排脚本指定安全运行标识 非字母数字、点、下划线和连字符会被替换,最长 96 字符;并发冲突不覆盖
DIAG_REPORT_FOCUS_DOMAIN 不限定 优先输出领域 cpu、io、memory/mem、lock、syscall
DIAG_LOG_LANGUAGE zh_CN 日志语言 zh_CNen_US
DIAG_VERBOSE 0 详细日志 非空且不为 0 时开启
DIAG_HEALTH_SUMMARY_WINDOWS 60 健康摘要间隔 1~3600 个窗口
DIAG_WINDOW_MS 2000 主采集窗口 100~10000 毫秒
DIAG_BURST_SUBWINDOW_MS 100 burst 子窗口 10~1000 毫秒且不大于主窗口
DIAG_SHORT_PULSE_MODE 0 短脉冲预设 1 时预设为 500/50 毫秒,显式配置优先
DIAG_PID_HINTS 补充候选 PID 逗号分隔的正整数列表,任一非法则忽略整组
DIAG_RULE_TRACE 0 输出规则追踪 仅 1 开启
DIAG_BASELINE_MODE robust 动态基线模式 robust、shadow、legacy;生产默认 robust
DIAG_BASELINE_STATE_PATH /var/lib/wholeproject/baseline-production.json 基线持久化文件 读取时校验普通文件、属主、0600 权限和大小
DIAG_BASELINE_PERSISTENCE 开启 是否持久化基线 仅 0 关闭
DIAG_PERF_PROFILE 普通运行 性能采集档位 core_l0_only、auto_gate_single_domain、five_domain_deep
DIAG_PERF_DOMAINS 由档位决定 性能档位领域 cpu、io、memory/mem、lock、syscall

门控阈值、动态基线、测试专用变量和压力脚本变量见参数配置说明。生产环境不要默认启用名称含 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:UTF-8 中文人类可读摘要,模式为 diagnose.rca.summary.v1,只投影正式报告证据;
  • run-meta.json:运行标识、实际分类、配置关注领域和相对路径;
  • 压力场景运行目录:保存诊断日志、工作负载日志、管线追踪、资源采样和复核结果。

正式运行、报告迁移和服务生成的报告目录使用 0755,普通报告文件使用 0644:所有本机用户均可读取和遍历这些报告,但只有文件属主可以修改。diagnose_summary 是当前例外:它重建并覆盖的 summary.json0600。基线状态和服务环境文件也保持 0600

正式报告包含异常类型、关联对象、异常时间窗口、关键指标与阈值、疑似根因、置信度、证据质量、建议、采集会话和时间源等信息。报告 JSON Schema 位于 config/schemas/。当前摘要 Schema 会校验顶层必需字段、摘要版本和若干基本类型,但对 异常类型关联对象关键指标疑似根因异常时间窗口证据状态 等内部对象只约束为 object,不是这些内部字段的完整合同;内部字段仍应以当前写入器和验证器为准。

验证单领域报告:

python3 scripts/validate_timeline_reports.py \
  --report-dir report/diagnosis/cpu/<运行标识> \
  --require-domain cpu --require-summary

验证器至少需要一个 --require-domain;不传领域会退出失败。

摘要示意片段

当前工作区不把固定运行 ID 的报告作为现有样例证据。下面是依据当前 diagnose.rca.summary.v1、摘要版本 1.1 和写入器字段生成方式整理的示意片段;为便于直接校验,它保留了 Schema 要求的全部顶层字段,但不代表仓库中某次实际运行,PID、时间和数值仅用于说明结构:

{
  "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/,不得据此推断未检查领域健康。

历史报告先预览再迁移:

python3 scripts/migrate_reports.py --report-root report
python3 scripts/migrate_reports.py --report-root report --apply

--apply 先复制并校验且保留原文件;仅显式增加 --move --confirm 才会删除校验成功的历史原文件。

权限与安全

  • 先运行无特权构建和测试,再使用 root 做最小范围的 eBPF 与压力验证。
  • 压力测试会消耗 CPU、内存、磁盘或文件描述符;必须先执行 inspect --dry-run,不要直接在生产业务主机运行。
  • I/O 场景只应使用脚本规划的临时目录,不要把块设备或业务数据目录作为测试目标。
  • 内存场景默认保留安全余量,不以主动触发 OOM 为目标。
  • 后台服务仍使用 UMask=0077 保护基线状态和其他私有文件,但运行根目录及报告目录为 0755、报告文件为 0644,便于所有本机用户只读复核;安装说明见后台服务安装说明

测试与验收

项目 CMake 注册的测试覆盖采集器、规则、基线、事件生命周期、报告、回放、压力编排、模式校验、中文文档合同和评审索引。推荐评委执行:

bash scripts/一键工程验收.sh

需要 root 的运行验证:

sudo -E bash scripts/verify_openkylin.sh

该验证脚本会生成环境、构建、内核能力、bpftool、dmesg 和运行日志。顶层退出码不能代替对内部 PASSCHECKSKIP 的逐项阅读。

测试步骤、输入输出、预期结果和退出码见测试与复现说明。跳过项必须单独报告且不计为通过。

文档索引

限制与故障排查

  • root、BTF、tracefs、内核符号或探针缺失会导致功能降级、能力阻断或运行失败。
  • 无目标模式依赖低成本候选发现;指定 DIAG_TARGET_PID 能获得更稳定的进程级证据。
  • PARTIALUNSUPPORTEDTIMEOUTGAPSKIPCHECK 不是通过结论。
  • 部分架构只有构建素材,没有随包实机结果。
  • 仓库当前没有由权利人确认的项目级 LICENSE,不得擅自推断首方代码许可证;第三方许可信息见合规说明。
  • 中文文档迁移后,测试、脚本和配置必须只引用实际存在的当前路径;路径残留由全量测试和评审索引测试阻断。

具体安装限制、运行降级条件和复现检查方法分别见安装部署说明使用说明测试与复现说明

开源与第三方声明

仓库包含 libbpf、bpftool、nlohmann/json、Linux UAPI 兼容头和生成的 vmlinux.h。这些组件分别保留其源文件中的 SPDX 或版权信息。首方项目许可证尚未由维护者确认,因此本文档不替维护者选择许可证,也不把第三方许可证自动套用于全部首方代码。

发布前必须由维护者确认首方版权主体、年份和许可证,并补齐项目根许可证文本以及第三方离线许可证包。详见第三方组件与开源合规说明

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

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