目录

SysDiag-eBPF

SysDiag-eBPF 是一款面向 openKylin / Linux Kernel 6.6+ 的轻量级系统异常观测与根因定位工具。项目基于 eBPF 低侵入采集内核与用户态行为指标,结合规则引擎、可选 LLM 辅助说明和 Agent 本地校验评判,输出可回溯、可复现、可机器解析的诊断报告。

本项目面向“中国研究生操作系统开源创新大赛”社区赛题“基于 eBPF 的系统异常观测与根因定位工具”,覆盖 CPU、I/O、内存、锁竞争、系统调用热点五类典型异常场景,并提供 CLI、Web UI、复现实验脚本和 Markdown / JSON / YAML 报告输出能力。

  • 版本:0.9.0
  • 推荐系统:openKylin,Linux Kernel 6.6+

作品简介

在云计算、边缘计算和桌面系统负载复杂化的背景下,CPU 异常占用、I/O 延迟抖动、内存回收压力、锁竞争和系统调用热点常常具有短时、突发、定位链路长的特点。传统日志和静态监控难以及时给出细粒度根因。

SysDiag-eBPF 的设计目标是:

  1. 通过 eBPF tracepoint 和内核 map 聚合方式实时采集关键系统事件。
  2. 将原始事件转化为可解释指标,例如 CPU 使用率、run queue、I/O P99、page fault、futex 等待、syscall 错误率等。
  3. 使用规则引擎生成正式诊断结论,包含异常类型、关联对象、关键指标、时间窗口、证据链、疑似根因和建议。
  4. 使用 LLM 辅助报告提升中文可读性,但不替代规则引擎结论。
  5. 使用 Agent 评判层进行补充发现,并通过本地白名单、指标存在性和弱规则门控降低幻觉风险。
  6. 提供 Web UI 进行可视化配置和报告查看,降低评测和演示使用门槛。

核心功能

功能 说明
CPU 异常观测 采集 CPU 使用率、loadavg、run queue、sched_switch rate、Top N 进程/线程
I/O 延迟观测 采集 block I/O 延迟、P95/P99、await、设备平均/峰值队列深度、设备名等指标
内存压力观测 采集可用内存、RSS 增长、major/minor fault、vmscan、内存抖动和 OOM 风险
锁竞争观测 基于 futex enter/exit 输出 Top N 热点、等待次数、平均/最大等待时间、进程/线程和 user stack id
系统调用热点 基于 raw_syscalls 统计热点 syscall、高耗时 syscall、错误率和 user stack id
规则诊断 输出正式诊断,规则结论可回溯到采集指标和证据链
LLM 辅助 可选生成中文摘要和运维建议,正式结论仍以规则引擎为准
主动诊断 Agent 基于 Eino 受限查询已有证据、校验进程或执行短时补采,候选发现必须通过本地校验
结构化报告 支持 Markdown、JSON、YAML 三种输出格式
Web UI 提供检测范围选择、采集时长配置、运行进度、诊断摘要和报告查看

系统架构

SysDiag-eBPF
├── 采集层
│   ├── bpf/*.bpf.c              # eBPF 程序
│   ├── pkg/ebpf                 # bpf2go 生成绑定与 probe 加载
│   └── pkg/collector            # CPU / Memory / I/O / Lock / Syscall 采集插件
├── 指标层
│   └── model.MetricSet          # 聚合后的系统指标与标签
├── 诊断层
│   ├── pkg/analyzer             # 规则引擎,输出正式诊断
│   ├── pkg/agent                # Eino runtime、证据库、预算和工具网关
│   ├── pkg/agentjudge           # Agent 评判与本地 validator
│   └── pkg/llm                  # OpenAI 兼容接口的辅助报告生成
├── 报告层
│   └── pkg/reporter             # Markdown / JSON / YAML reporter
└── 交互层
    ├── cmd/sysdiag              # CLI
    └── cmd/sysdiag-ui           # Web UI

诊断优先级:

规则引擎正式诊断 > Agent 本地校验通过的补充发现 > LLM/Agent 文字建议

环境要求

项目 要求
操作系统 openKylin 2.0+,或其他 Linux 发行版
内核版本 Linux Kernel 6.6+
架构 x86_64,鼓励支持 ARM64 / RISC-V
BTF 建议存在 /sys/kernel/btf/vmlinux
权限 root,或具备 CAP_BPF / CAP_PERFMON / CAP_SYS_ADMIN
编译工具 Go 1.21+、clang、llvm、bpftool、libbpf-dev
复现工具 stress-ng、fio
LLM 可选,兼容 OpenAI API 格式

安装说明

1. 获取代码

git clone https://gitee.com/wjjhelloworld/e-bpf.git
cd e-bpf

2. 安装依赖

openKylin 环境推荐:

sudo ./scripts/setup_openkylin.sh

通用 Linux 用户态工具链安装:

./scripts/install_env.sh
source ~/.sysdiag_env.sh

3. 环境检查

make build
./sysdiag check-env

如果检查失败,请重点确认:

  • 当前用户是否具备 root 或必要 capability。
  • /sys/kernel/btf/vmlinux 是否存在。
  • clang、llvm、bpftool、go 是否可用。
  • tracefs/debugfs 是否挂载。

编译说明

常规编译

make build
make build-ui

生成文件:

./sysdiag       # CLI 工具
./sysdiag-ui    # Web UI 工具

修改 eBPF 程序后的编译

只要修改了 bpf/*.bpf.c,必须先重新生成 eBPF 对象和 Go 绑定:

make generate
make build

make generate 会执行:

go generate ./pkg/ebpf/...

它会将 bpf/*.bpf.c 编译并嵌入到 pkg/ebpf/*_bpfel.o 和 pkg/ebpf/*_bpfel.go 中。否则 Go 程序运行时可能仍加载旧的 eBPF 字节码。

运行说明

1. 查看版本

./sysdiag version

2. 检查运行环境

./sysdiag check-env

3. 采集指标但不生成诊断

sudo ./sysdiag observe --duration 30 --plugins cpu,memory,io,lock,syscall

4. 生成 Markdown 诊断报告

sudo ./sysdiag diagnose \
  --duration 60 \
  --plugins cpu,memory,io,lock,syscall \
  --format markdown \
  --output report.md

5. 生成 JSON / YAML 诊断报告

sudo ./sysdiag diagnose --duration 60 --plugins cpu,memory,io,lock,syscall --format json --output report.json
sudo ./sysdiag diagnose --duration 60 --plugins cpu,memory,io,lock,syscall --format yaml --output report.yaml

6. 启用 LLM 辅助和主动诊断 Agent

sudo ./sysdiag diagnose \
  --duration 60 \
  --plugins cpu,memory,io,lock,syscall \
  --llm \
  --agent-judge \
  --format markdown \
  --output ai_report.md

LLM 配置示例:

cp config/llm.env.example config/llm.env

编辑 config/llm.env,填写:

SYSDIAG_LLM_PROVIDER=openai-compatible
SYSDIAG_LLM_BASE_URL=https://api.example.com/v1
SYSDIAG_LLM_API_KEY=your_api_key
SYSDIAG_LLM_MODEL=deepseek-chat

Demo 一键启动

项目提供 demo/run_demo.sh,用于自动检查运行环境、构建 sysdiag 和 sysdiag-ui、启动 Web UI,并在图形环境中打开默认浏览器。

首次运行前赋予脚本可执行权限:

chmod +x demo/run_demo.sh

在项目根目录执行:

./demo/run_demo.sh

脚本启动成功后,访问:

http://127.0.0.1:8080

如果已经完成构建,可跳过编译步骤:

./demo/run_demo.sh --skip-build

如果运行环境不支持自动打开浏览器,或只需要启动服务,可使用:

./demo/run_demo.sh --no-browser

构建日志、Web UI 启动日志和进程号保存在 demo/output/。脚本结束时会显示对应的停止命令,可使用输出的进程号停止 Web UI:

sudo kill <进程号>

Demo 需要在 Linux 或 openKylin 环境中运行。在线 eBPF 诊断通常需要 BTF 和管理员权限;脚本会在启动前检查相关环境并输出提示。

Web UI 运行说明

Web UI 是 CLI 的可视化封装,后端仍调用 sysdiag diagnose,诊断逻辑与 CLI 保持一致。

诊断摘要会区分“正式异常”“疑似环境噪声”和“未发现异常”三种状态。只有正式异常使用红色告警;浏览器、Web UI 等活动造成的疑似噪声使用黄色“需复核”提示,并保留完整证据链供评委检查。

1. 编译 Web UI

make build
make build-ui

2. 启动 Web UI

sudo ./sysdiag-ui

默认监听:

http://127.0.0.1:8080

3. 指定 sysdiag 路径

如果 sysdiag 不在 sysdiag-ui 同目录,可使用:

sudo SYSDIAG_BIN=/path/to/sysdiag ./sysdiag-ui

4. Web UI 支持能力

  • 选择检测范围:CPU、Memory、I/O、Lock、Syscall。
  • 设置采集时长:30s、60s、120s 或自定义。
  • 选择报告格式:Markdown、JSON、YAML。
  • 开启或关闭 LLM 辅助。
  • 开启或关闭 Agent 评判。
  • 查看预估运行进度,并在任务完成后查看命令日志。
  • 展示诊断摘要、关键指标、相关进程和报告路径。
  • 在线查看或下载报告。

命令参数

参数 示例 说明
--duration --duration 60 观测窗口,单位秒
--plugins --plugins cpu,io 启用插件,支持 cpu、memory、io、lock、syscall
--format --format markdown 报告格式,支持 markdown、json、yaml
--output --output report.md 报告输出路径
--llm --llm 启用 LLM 辅助报告
--agent-judge --agent-judge 启用受限主动诊断 Agent

--agent-judge 现在启动 Eino ChatModelAgent。Agent 只能调用 query_metrics、get_process_snapshot 和 collect_metrics,默认最多 4 次模型调用、5 次工具调用、2 次补采,单次补采最长 10 秒。

离线回放已保存任务

./sysdiag replay --input report.json --format markdown --output replay-report.md

回放不加载 eBPF 探针,也不重新调用模型,只使用 JSON 报告中的请求、指标、证据、工具轨迹和校验结果重新生成报告。

Makefile 快捷命令

命令 说明
make generate 根据 bpf/*.bpf.c 重新生成 eBPF 对象和 Go 绑定
make build 生成 ./sysdiag
make build-ui 生成 ./sysdiag-ui
make test 执行 go test ./...
make run 全插件运行 60 秒诊断并生成 report.md
make run-llm 启用 LLM 的 60 秒诊断
make benchmark 执行性能开销测试
make clean 清理二进制、报告和生成物

异常复现实验

项目提供 5 类标准异常复现脚本,建议在两个终端中分别运行压测和诊断。

场景 终端 1:构造异常 终端 2:执行诊断 预期诊断
CPU 异常 ./scripts/run_cpu_case.sh sudo ./sysdiag diagnose --duration 60 --plugins cpu --output cpu_report.md CPU_HIGH_USAGE
I/O 抖动/拥塞 ./scripts/run_io_case.sh sudo ./sysdiag diagnose --duration 60 --plugins io --output io_report.md IO_LATENCY_SPIKE 或 IO_QUEUE_CONGESTION;设备无实际退化时允许不报警
内存压力/访问抖动 ./scripts/run_memory_case.sh sudo ./sysdiag diagnose --duration 60 --plugins memory --output memory_report.md MEMORY_PRESSURE 或 MEMORY_ACCESS_CHURN
锁竞争 ./scripts/run_lock_case.sh sudo ./sysdiag diagnose --duration 60 --plugins lock --output lock_report.md LOCK_CONTENTION
系统调用热点 ./scripts/run_syscall_case.sh sudo ./sysdiag diagnose --duration 60 --plugins syscall --output syscall_report.md SYSCALL_HOTSPOT

顺序执行全部场景:

./scripts/run_all_cases.sh

性能开销测试

sudo ./scripts/benchmark_overhead.sh overhead_report.md

测试内容包括:

  • 工具运行前后 CPU 占用变化。
  • 工具自身内存占用。
  • I/O 压测场景下平均时延和 P99 时延变化。
  • 吞吐变化。

性能结果会写入 overhead_report.md,可作为比赛说明书“实验测试”章节材料。

诊断报告说明

Markdown 报告默认包含:

  1. 摘要:正式异常和疑似环境噪声分类。
  2. 主机信息:hostname、kernel、architecture。
  3. 观测窗口:start、end、duration。
  4. 诊断结果:异常类型、严重等级、置信度、关联对象、关键指标、证据链、疑似根因、建议。
  5. 原始指标:即使规则未命中也保留各插件采集值和数据源,便于回溯漏报原因。
  6. 性能开销:benchmark 后补充。
  7. 后续章节按启用功能动态编号:可选 LLM 辅助报告、Agent 校验结果、调查轨迹与预算使用量,以及工具版本附录。

报告中会保留浏览器、Web UI、工具自身活动等疑似环境噪声提示,但不默认过滤,便于评委复核证据链。

正式诊断类型

类型 场景 主要证据
CPU_HIGH_USAGE CPU 异常占用 CPU 使用率、run queue、loadavg、sched_switch、Top N 进程/线程
IO_LATENCY_SPIKE I/O 延迟抖动 I/O P95/P99、await、设备信息
IO_QUEUE_CONGESTION I/O 队列拥塞 /proc/diskstats 周期采样的平均/峰值在途请求数
MEMORY_PRESSURE 内存压力 可用内存比例、RSS 增长、major/minor fault、vmscan
MEMORY_ACCESS_CHURN 内存访问抖动 可用内存充足时的高 page fault、进程级 major fault 和文件映射访问
LOCK_CONTENTION 锁竞争 Top N futex 热点、等待次数、平均等待、最大等待、进程/线程、user stack id
SYSCALL_HOTSPOT 系统调用热点 syscall 频率、热点调用、错误率、耗时、user stack id

主动诊断 Agent 说明

Agent 是建议层,不替代规则引擎正式诊断。规则报告会在模型调用前原子落盘;模型配置错误、超时、工具失败或预算耗尽时,任务会以 completed_with_agent_error 结束并保留基础报告。其补充发现必须经过本地校验:

  • 异常类型必须在 POSSIBLE_* 白名单内。
  • 证据 ID 必须真实存在、状态可用,且插件和实体与发现一致。
  • 置信度必须达到阈值。
  • 弱规则门控必须通过。
  • 初始证据按诊断价值压缩到 70 条,为补充采集预留 30 条证据额度。
  • 本地校验会比较同一指标和实体在初始窗口与最新补采窗口中的变化,并使用最新窗口执行弱规则门控。

当前允许的 Agent 补充发现类型包括:

POSSIBLE_CPU_PRESSURE
POSSIBLE_SCHEDULING_DELAY
POSSIBLE_MEMORY_PRESSURE
POSSIBLE_RECLAIM_THRASHING
POSSIBLE_OOM_RISK
POSSIBLE_IO_DEGRADATION
POSSIBLE_IO_QUEUEING
POSSIBLE_LOCK_CONTENTION
POSSIBLE_SYSCALL_HOTSPOT
POSSIBLE_SYSCALL_LATENCY
POSSIBLE_SYSCALL_ERRORS

被拒绝或降级的 Agent 发现会写入报告,便于追踪模型输出和本地校验过程。

每份 JSON/YAML 报告还会保存 TaskID、观测窗口、采集状态、证据 ID、关键标签、实体身份、跨窗口趋势、工具调用轨迹、预算使用量、终止原因和未解决问题。

项目目录

e-bpf/
├── bpf/                 # eBPF C 程序
├── cmd/
│   ├── sysdiag/         # CLI 入口
│   └── sysdiag-ui/      # Web UI 入口
├── config/              # LLM 配置示例
├── docs/                # 安装、设计、运维和答辩文档
├── examples/            # systemd 示例
├── pkg/
│   ├── agentjudge/      # Agent 评判与本地校验
│   ├── agent/           # Eino runtime、evidence、policy、tools
│   ├── analyzer/        # 规则诊断引擎
│   ├── collector/       # 采集插件
│   ├── ebpf/            # eBPF 加载和 bpf2go 生成文件
│   ├── llm/             # LLM 客户端
│   ├── model/           # 指标与报告数据结构
│   ├── reporter/        # Markdown / JSON / YAML 输出
│   └── utils/           # /proc、磁盘、环境工具
├── scripts/             # 安装、复现、部署、benchmark 脚本
├── Makefile
└── README.md

License

eBPF 程序采用 GPL-2.0 / BSD-3-Clause 双许可;Go 用户态代码按本仓库约定执行。

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

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