Update README.md
面向 openKylin 与现代 Linux 的自适应性能异常观测和根因诊断工具。系统平时只运行低开销的 baseline eBPF 探针;检测到 CPU、I/O、内存、锁竞争或系统调用异常后,按场景和目标对象租约加载详细探针,采集完成后自动卸载,并生成经过 JSON Schema 校验的 JSON 与 Markdown 诊断报告。
baseline
详细结果见 准确度验收结论 和 性能开销实验结论。
演示视频见:bilibili
本节按比赛评分细则列出可核查的实现、证据和复现入口。最终分值由评委依据现场结果判定;下文严格区分正式验收、开发实验、构建验证和运行时冒烟,不以功能声明代替实测证据。
sudo make accuracy-acceptance
schema_version: 1.2
aebpf validate-report <report.json>
aebpf render-report <report.json>
diagnostic-report.schema.json
doctor
suspected
busy_loop
locks
getpid
gettid
confirmed
aebpf validate-report
aebpf validate-acceptance
性能实验同时给出空载 no_agent、平时常驻 baseline_only、详细探针全程常驻和按租约弹性加载四种对照。下表是 2026-07-24 在 openKylin x86_64 上 5 个随机配对 block、65/65 次有效运行的开发实验结果;方括号为 95% 置信区间,业务变化均相对同一 block 的 no_agent。
no_agent
baseline_only
完整原始指标、BPF 执行时间、map、事件丢失和生命周期统计的解释见性能实验结论。该记录来自 dirty tree、单台 x86_64 主机、单一 fio 负载和 20 秒窗口,属于比赛演示/开发证据,不标记为 publication-ready;评委可用 sudo make overhead-smoke 检查管道,再按性能实验设计复现实验。
sudo make overhead-smoke
make build test
aebpf doctor
./scripts/bootstrap.sh --install-system
make smoke
sudo make smoke-runtime
SHA256SUMS
Linux 内核 sched / block / memory / futex / raw_syscalls | | eBPF maps / Ring Buffer / perf event v C++17 Agent 常驻 baseline -> 读取 /proc、/sys 和 BPF map -> 周期遥测 接收 LOAD/UNLOAD -> 目标过滤 -> 事件批处理 -> 租约卸载 | | HTTP/JSON(默认仅 loopback) v Python 诊断后端 指标派生 -> 滚动异常检测 -> 候选对象选择 -> 探针编排 事件校验/去重/关联 -> 根因门槛判断 -> JSON + Markdown 报告
默认链路如下:
LOAD
runqlat
oncpu
CPU_COMPUTE_HOTSPOT
CPU_SCHEDULER_PRESSURE
biolatency
BLOCK_IO_LATENCY
BLOCK_DEVICE_CONGESTION
mempressure
oomkill
MEMORY_ALLOCATION_PRESSURE
MEMORY_RECLAIM_PRESSURE
OOM_VICTIM_SELECTED
locksensor
FUTEX_WAIT_CONTENTION
syscall_hotspot
HIGH_FREQUENCY_SYSCALL_HOTSPOT
HIGH_LATENCY_SYSCALL_HOTSPOT
关键证据约束:
target_pid
target_syscall_id
poll
epoll_wait
futex
resolved
[unknown]
raw_syscalls
sched_switch
sched_wakeup
sched_wakeup_new
perf_event
block_rq_insert/issue/complete
mm_page_alloc
oom/mark_victim
raw_syscalls:sys_enter/sys_exit
pagefault
page_fault_user
tcpconnlat
connect()
sys_enter_connect/sys_exit_connect
pagefault 和 tcpconnlat 可以由 Agent 加载,也用于性能实验,但目前没有进入默认异常检测和根因报告闭环。
ai_adaptive_ebpf/ |-- aebpf # 统一 CLI 入口 |-- Makefile # 构建、测试、运行和实验入口 |-- config/default.yaml # 唯一默认运行配置 |-- agent/ | |-- src/ # C++17 Agent、协议、生命周期、符号化 | |-- rules.json # 后端失联时的本地 CPU/I/O 规则 | |-- probes/ # 生成的 *.bpf.o(不进入 Git) | `-- third_party/ # cpp-httplib、nlohmann/json 子模块 |-- bpf_probes/ # libbpf CO-RE 内核程序 |-- backend/aebpf/ # Flask 后端、检测器、编排和报告引擎 |-- schemas/ # 配置、命令、事件、报告和准确度证据 Schema |-- tests/ # Python unittest 与 C++ 测试程序 |-- scripts/ # 引导、负载、冒烟、准确度、性能和 VM 脚本 |-- packaging/ # systemd unit 和生产路径配置 |-- docs/ # 安装、配置、测试、限制和设计文档 |-- conclusion/ # 已提交的实验结论 |-- paper/ # 论文 LaTeX 与参考文献 `-- validation-results/ # 本机实验产物(不进入 Git)
后端主要模块:
detectors.py
engine.py
reports.py
report_markdown.py
protocol.py
doctor.py
compatibility.py
server.py
cli.py
Agent 主要模块:
agent.cpp/.hpp
bpf_manager.cpp/.hpp
command_protocol.cpp/.hpp
diagnostic_batch.cpp/.hpp
timer_manager.cpp/.hpp
stack_symbolizer.cpp/.hpp
推荐目标为 openKylin 2.0 SP2 或同类现代 Linux,内核 6.6+。最低工程要求:
/sys/kernel/btf/vmlinux
venv
CAP_BPF
CAP_PERFMON
CAP_SYS_ADMIN
stress-ng
fio
findmnt
shuf
sha256sum
Kernel lockdown、LSM、容器能力限制、受限 /proc/kallsyms 或缺失 tracepoint 都可能影响探针加载或符号解析。先运行 aebpf doctor,不要仅以编译成功代替目标内核 attach 验证。
/proc/kallsyms
git clone --recurse-submodules <repository-url> cd ai_adaptive_ebpf ./scripts/bootstrap.sh --install-system
bootstrap.sh 会安装或检查系统依赖,创建 .venv,安装 backend/requirements.txt 中固定版本的 Python 依赖,生成当前内核专用的 bpf_probes/vmlinux.h,并创建权限为 0600 的 .runtime/command-token。
bootstrap.sh
.venv
backend/requirements.txt
bpf_probes/vmlinux.h
0600
.runtime/command-token
已有系统依赖时使用:
git submodule update --init --recursive ./scripts/bootstrap.sh
只安装构建依赖而不安装 fio 和 stress-ng 时使用 ./scripts/bootstrap.sh --install-build-system。
./scripts/bootstrap.sh --install-build-system
make build make test make smoke
构建结果:
bpf_probes/*.bpf.c
agent/probes/*.bpf.o
agent/src/*.cpp
agent/agent
mkdir -p validation-results sudo make smoke-runtime
该测试启动临时后端和 Agent,确认 baseline 遥测到达,并逐一 LOAD/UNLOAD 默认启用的详细探针,检查丢失和拒绝计数。它验证“能加载”,不验证五类负载的诊断准确度。
一条命令运行后端与 Agent,并在结束时完成活动会话、导出报告数组:
sudo .venv/bin/python ./aebpf diagnose \ --config config/default.yaml \ --duration 180 \ --output reports/session.json
--duration 0 表示持续运行直到收到中断。单个报告会写入 reports/<report-id>.json 和同名 .md;--output 是本次进程所有报告的 JSON 数组。
--duration 0
reports/<report-id>.json
.md
--output
也可以分开运行:
# 终端 1 .venv/bin/python ./aebpf backend --config config/default.yaml # 终端 2 sudo .venv/bin/python ./aebpf agent --config config/default.yaml
从仓库根目录启动 Agent,确保相对路径形式的配置、规则和探针目录正确解析。
# 后端健康、活动诊断数量和遥测身份 curl -s http://127.0.0.1:5000/health | .venv/bin/python -m json.tool # Agent 中的探针会话、目标、剩余租约和 drain 状态 .venv/bin/python ./aebpf status --config config/default.yaml # 完成当前活动会话 curl -s -X POST http://127.0.0.1:5000/reports/finalize \ | .venv/bin/python -m json.tool # 校验和重新渲染报告 .venv/bin/python ./aebpf validate-report reports/<report-id>.json .venv/bin/python ./aebpf render-report reports/<report-id>.json
aebpf backend
aebpf agent
aebpf diagnose
aebpf status
--json
aebpf validate-config
schemas/config.schema.json
diagnose
aebpf render-report
查看参数:
.venv/bin/python ./aebpf --help .venv/bin/python ./aebpf <subcommand> --help .venv/bin/python ./aebpf --version
make bootstrap
make vmlinux
vmlinux.h
make probes
make agent
make build
make test
sudo make accuracy-scenarios
sudo make accuracy-development
sudo make overhead-experiment
make overhead-analyze OVERHEAD_RAW=...
raw.json
sudo make oncpu-validation
make fresh-clone-test
make run-backend
sudo make run-agent
make clean
另有 openkylin-vm-image、openkylin-vm-validation 和 openkylin-iso-full 用于 openKylin ISO/VM 验证。目标机验证步骤见 openKylin 验证说明。
openkylin-vm-image
openkylin-vm-validation
openkylin-iso-full
config/default.yaml 是规范默认配置。每次 CLI 调用都会使用 schemas/config.schema.json 校验,未知键、错误类型、越界值和启用但无探针的诊断项会被拒绝。
config/default.yaml
默认服务与会话参数:
127.0.0.1:5000
127.0.0.1:9091
默认绝对触发阈值:
cpu_busy_ratio
io_busy_ratio
memory_available_ratio
memory_available_drop_rate_per_second
context_switch_rate_per_cpu
futex_wait_rate_per_cpu
direct_reclaim_rate_per_second
kswapd_scan_rate_per_second
syscall_rate_per_second
slow_syscall_rate_per_second
阈值只负责打开诊断会话,不等价于根因确认。每类报告还有独立的事件质量、对象匹配和完整性门槛。系统调用与锁竞争的细分策略见 配置参考。
后端失联时,Agent 会执行 agent/rules.json 中的离线规则:CPU busy 超过 0.90 时加载 runqlat 60 秒,设备 I/O busy 超过 0.70 时加载 biolatency 60 秒。离线事件只保存在最多 10000 条的内存队列中,重启不持久化。
agent/rules.json
GET
/health
POST
/telemetry
/diag_data
/reports
/reports/finalize
后端请求体上限为 1 MiB。Agent 每批最多发送 1000 条或 768 KiB,内存事件队列最多 10000 条;丢失、拒绝和重复事件会分别计数。
Agent 提供认证的 POST /command 和 GET /status。命令协议支持 LOAD / UNLOAD,并实现:
POST /command
GET /status
UNLOAD
command_id
PROBE_BUSY
默认配置只监听 loopback,但传输仍是普通 HTTP。跨主机部署必须增加 TLS 或受认证代理,不要直接暴露 5000/9091。命令令牌、.runtime/、报告、日志、虚拟环境和主机生成的 BPF 对象不得提交到 Git。
.runtime/
JSON 是唯一事实来源,必须通过 schemas/diagnostic-report.schema.json(当前 schema_version: 1.2)。同名中文 Markdown 只从已校验 JSON 确定性生成,不调用大模型,也不读取额外运行时状态;状态、异常类型和根因使用中文解释,并保留原始代码便于程序对照。
schemas/diagnostic-report.schema.json
报告包含:
action
rationale
risk
verify
rollback
报告状态必须按证据解释:
insufficient_evidence
failed
suspected、insufficient_evidence 和 failed 都不能表述为已确认根因。Ring Buffer/Agent 队列丢失、后端拒绝、部分探针失败、卸载失败或更具体信号冲突会使结论降级。
测试分为代码级、内核加载级和真实场景级,三者不能互相替代。
当前套件包含 3 个 C++ 测试程序和 202 个 Python unittest 测试方法:
unittest
2026-07-29 本次 README 更新时的 WSL 验证结果为:3 个 C++ 测试程序通过,202 个 Python 测试通过,Ran 202 tests ... OK;测试入口同时验证了配置、报告 Schema、确定性 Markdown 渲染和四组场景样例。
Ran 202 tests ... OK
该目标执行 build、全部测试、doctor、默认配置校验、示例报告校验和关键脚本存在性检查。
sudo AEBPF_RUNTIME_EVIDENCE="$PWD/validation-results/runtime-smoke.json" \ make smoke-runtime
它验证真实内核上的 baseline、默认详细探针加载/卸载、目标参数、遥测传输和零丢失,不产生准确度结论。
脚本把源码复制到临时目录,排除 .venv、.runtime、构建物、报告和实验产物,然后重新 bootstrap、build、test 和校验示例报告,用于发现对本机生成文件的隐式依赖。
.runtime
先启动后端和 Agent,一次只运行一种负载,场景之间等待会话结束和主机恢复。常用入口:
# CPU stress-ng --cpu "$(nproc)" --cpu-method matrixprod --timeout 60s --metrics-brief # I/O:只在非生产、磁盘支持的测试路径运行 ./scripts/generate_io_load.sh # 锁 gcc -O2 -g -pthread scripts/contention.c -o /tmp/aebpf-contention /tmp/aebpf-contention convoy 60 8 # 系统调用频率/延迟/等待负例 gcc -O2 -g -pthread scripts/syscall_hotspot_workload.c -o /tmp/aebpf-syscall /tmp/aebpf-syscall --duration 60 --mode frequency /tmp/aebpf-syscall --duration 60 --mode latency /tmp/aebpf-syscall --duration 60 --mode wait
内存和高强度 I/O 测试可能触发 reclaim、swap、OOM 或显著业务抖动,只应在一次性虚拟机或专用测试机运行。完整步骤、预期根因和报告判定见 手动测试指南。
该目标每类只运行 1 次、单次 30 秒、不执行正常负例,可隔离 detector,用于快速调试。它会标记为 development evidence,不能通过正式准确度验收器,也不能替代发布验收。
sudo make accuracy-acceptance .venv/bin/python ./aebpf validate-acceptance \ validation-results/accuracy-acceptance.json (cd validation-results && \ sha256sum -c accuracy-acceptance-artifacts/SHA256SUMS)
正式门禁使用固定发布配置,所有 detector 同时启用;CPU、I/O、内存、锁和系统调用五类正例各重复 3 次,使用固定种子随机交错,并运行 90 秒正常事件循环负例。默认每次正例负载 120 秒、预热 35 秒、冷却 15 秒。
每个正例只有在以下条件全部满足时通过:
正常对照必须执行真实低频 poll/openat/newfstatat 工作负载且报告数组为空。suspected 和主动放弃确认不直接计为 false positive,但必须单独统计;意外 confirmed 才计入错误结论。
poll/openat/newfstatat
证据包包括:
2026-07-23 的 openKylin x86_64 记录:
该结论只覆盖已声明的五类受控场景和一个正常对照,不外推到混合异常、长期生产流量或未验收架构。主机生成的 validation-results/ 不进入 Git;提交内保留的是结论与证据索引,详见 准确度实验设计 和 准确度证据索引。
validation-results/
性能实验使用随机化配对 block。每个 repetition 以相同 fio 随机种子运行 13 种模式,顺序重新随机:
detailed:<probe>
always_on_detailed
elastic_leased
默认前台负载是 4 KiB direct random read、queue depth 32 的单 fio 线程。测试记录:
run_time_ns
run_cnt
该目标只执行 2 个 repetition、8 秒测量窗口,用于检查实验管道,结果不能作为发布数据。
在专用测试磁盘或明确的非生产测试文件上运行:
make build sudo ./scripts/overhead_experiment.py run \ --repetitions 5 \ --duration 60 \ --warmup 10 \ --cooldown 5 \ --elastic-seconds 6 \ --workload-file /path/on/dedicated-device/aebpf-overhead.fio \ --file-size 1G
可用 --cpus 2-5 固定 fio CPU 集,减少调度噪声。至少 5 个 repetition 且 clean repository 才满足工具的 publication_ready 基线;最终比赛/论文数据在时间允许时建议 10 个 repetition。
--cpus 2-5
publication_ready
默认输出为 validation-results/overhead-<UTC timestamp>/:
validation-results/overhead-<UTC timestamp>/
runs/.../fio.json
agent.log
summary.json
summary.md
中断后只有在同一次 boot 且 Agent、runner 和所有 probe object 哈希仍一致时才可继续:
sudo ./scripts/overhead_experiment.py run \ --resume validation-results/overhead-<timestamp>/raw.json
不重新运行负载即可重建统计:
./scripts/overhead_experiment.py analyze \ validation-results/overhead-<timestamp>/raw.json
不要接受 raw.json.status != complete、summary.json.complete != true、publication_ready == false 或重复次数不足的结果。map 的 capacity_estimate 不能当作实际常驻内存;未触发事件的 probe 也不能当作最坏开销,需同时查看 BPF run_cnt。
raw.json.status != complete
summary.json.complete != true
publication_ready == false
capacity_estimate
历史实验为 5 个 block、65/65 次有效运行,20 秒测量、10 秒 warm-up,弹性租约 2 秒:
弹性模式相对全程常驻,配对均值减少 16.45 ms/s BPF 执行时间和 52.43 MiB 时间加权 map,吞吐提高 10.40%,但 Agent CPU 增加 5.66 个百分点。该结果的 Git 记录为 1ae57ac... 且 dirty=true,因此属于开发/演示证据,不是 publication-ready 结论。完整置信区间与限制见 性能实验设计 和 实验结论。
1ae57ac...
dirty=true
兼容性证据分三级:
GitHub Actions 在 x86_64 和 ARM64 runner 上执行 build/test,并在 openKylin 2.0 容器中验证用户态依赖。容器共享宿主内核,因此不能证明 openKylin 内核 attach;完整 runtime job 需要带 openkylin 标签的 6.6+ self-hosted runner。
openkylin
目标机完整流程:
./scripts/bootstrap.sh --install-system make clean build test mkdir -p validation-results sudo AEBPF_RUNTIME_EVIDENCE="$PWD/validation-results/runtime-smoke.json" \ make smoke-runtime sudo make accuracy-scenarios AEBPF_RUNTIME_EVIDENCE="$PWD/validation-results/runtime-smoke.json" \ AEBPF_SCENARIO_EVIDENCE="$PWD/validation-results/accuracy-scenarios.json" \ ./scripts/compatibility-report.sh validation-results/openkylin-runtime.json
runtime 与 scenario 证据必须来自同一 host、boot、kernel 和 architecture。只有 openkylin_accuracy_runtime.status == pass 才能声明目标平台已完成准确度运行验证。详见 openKylin 验证说明。
openkylin_accuracy_runtime.status == pass
packaging/ 提供参考 unit 和生产路径配置:
packaging/
/opt/aebpf
/etc/aebpf
/var/lib/aebpf
aebpf
CAP_BPF CAP_PERFMON CAP_SYS_ADMIN
部署前应审查目标发行版的 systemd sandbox、kernel lockdown、LSM、报告目录权限和 TLS/代理配置。完整命令见 安装与部署。
test -r /sys/kernel/btf/vmlinux make vmlinux
若 BTF 不可读,需要切换到启用 BTF 的内核;不要从另一台不同内核的主机复制 vmlinux.h。
依次确认:
/health.telemetry_samples
.venv/bin/python ./aebpf doctor --config config/default.yaml --json sudo bpftool feature probe
记录发行版、uname -a、BTF、tracepoint、权限和 Agent/libbpf verifier 日志。容器内 root 不一定拥有宿主 BPF 能力。
uname -a
测试程序使用 -g -fno-omit-frame-pointer 且不要 strip。检查目标进程是否在采集结束前退出、/proc/<pid>/maps 是否可读,以及 /proc/kallsyms/debuginfo 是否受限。未解析帧是显式降级,不应被解释成某个具体函数。
-g -fno-omit-frame-pointer
strip
/proc/<pid>/maps
更多排查项见 故障排查。
snake_case
PascalCase
-Wall -Wextra -Wpedantic
tests/test_<feature>.py
probe_name
agent/third_party/
agent/probes/
本项目使用 MIT License。
版权所有:中国计算机学会技术支持:开源发展技术委员会 京ICP备13000930号-9 京公网安备 11010802047560号
Adaptive eBPF Diagnosis
面向 openKylin 与现代 Linux 的自适应性能异常观测和根因诊断工具。系统平时只运行低开销的
baselineeBPF 探针;检测到 CPU、I/O、内存、锁竞争或系统调用异常后,按场景和目标对象租约加载详细探针,采集完成后自动卸载,并生成经过 JSON Schema 校验的 JSON 与 Markdown 诊断报告。项目状态
详细结果见 准确度验收结论 和 性能开销实验结论。
演示视频见:bilibili
比赛评分点对照
本节按比赛评分细则列出可核查的实现、证据和复现入口。最终分值由评委依据现场结果判定;下文严格区分正式验收、开发实验、构建验证和运行时冒烟,不以功能声明代替实测证据。
功能完成度(40 分)
sudo make accuracy-acceptance一键运行五类各 3 次正例及正常负例;openKylin x86_64 已有 15/15 正例通过的验收结论。各类探针、对象和根因见诊断能力。schema_version: 1.2强制包含异常类型、时间窗口、关联对象、关键指标、按探针证据、疑似根因、证据链、建议、采集质量和追溯信息;JSON 为事实来源,中文 Markdown 由同一 JSON 确定性生成。aebpf validate-report <report.json>校验机器可解析性,使用aebpf render-report <report.json>复现 Markdown;字段定义见diagnostic-report.schema.json,实际输出见报告样例。doctor检查 BTF、架构、hook、权限和对象,兼容性报告分为 Build、Load、Scenario 三级。诊断准确性(30 分)
suspected与证据不足单独统计。busy_loop、实际块设备、内存压力进程/cgroup、locks范围内 futex 地址,以及真实getpid/gettid调用。confirmed。aebpf validate-report检查字段和引用完整性;运行aebpf validate-acceptance检查真值、对象、采集完整性、哈希和意外确认。报告状态语义见诊断报告。性能开销(15 分)
性能实验同时给出空载
no_agent、平时常驻baseline_only、详细探针全程常驻和按租约弹性加载四种对照。下表是 2026-07-24 在 openKylin x86_64 上 5 个随机配对 block、65/65 次有效运行的开发实验结果;方括号为 95% 置信区间,业务变化均相对同一 block 的no_agent。完整原始指标、BPF 执行时间、map、事件丢失和生命周期统计的解释见性能实验结论。该记录来自 dirty tree、单台 x86_64 主机、单一 fio 负载和 20 秒窗口,属于比赛演示/开发证据,不标记为 publication-ready;评委可用
sudo make overhead-smoke检查管道,再按性能实验设计复现实验。工程质量与开源规范(15 分)
make build test。aebpf doctor和快速开始流程。./scripts/bootstrap.sh --install-system、make smoke、sudo make smoke-runtime、sudo make accuracy-acceptance;高压负载只在专用测试机运行。SHA256SUMS。工作原理
默认链路如下:
baseline;加载失败会直接退出,避免在缺少基础观测时提供不完整服务。LOAD命令。诊断能力
runqlat、oncpuCPU_COMPUTE_HOTSPOT、CPU_SCHEDULER_PRESSUREbiolatencyBLOCK_IO_LATENCY、BLOCK_DEVICE_CONGESTIONmempressure、oomkillMEMORY_ALLOCATION_PRESSURE、MEMORY_RECLAIM_PRESSURE、OOM_VICTIM_SELECTEDlocksensorFUTEX_WAIT_CONTENTIONsyscall_hotspotHIGH_FREQUENCY_SYSCALL_HOTSPOT、HIGH_LATENCY_SYSCALL_HOTSPOT关键证据约束:
oncpu默认使用 49 Hz perf event 采样。只有样本量、用户栈捕获质量、符号解析覆盖率和 Top-1 热点集中度均达标时,才确认函数级CPU_COMPUTE_HOTSPOT。biolatency通过 request 指针关联 insert、issue 和 complete,可区分总延迟、队列延迟、队列深度和 I/O 错误;当前只归因到块设备,不归因到文件。mempressure采集 RSS 分类、页分配汇总、页缓存加入、direct reclaim 和 kswapd 活动;oomkill记录内核选中的 OOM victim。locksensor将高同步活动与业务性能退化分开。确认FUTEX_WAIT_CONTENTION还需要总等待、平均/P99、热点锁集中度以及外部提供的业务吞吐下降证据;缺少吞吐证据时保持suspected。syscall_hotspot的每个租约必须同时指定target_pid和target_syscall_id。poll、epoll_wait、futex、timer wait、child wait 等预期阻塞调用不会仅凭 enter-to-exit wall-clock 时间被确认为高延迟根因。resolved状态;符号不可用时显式输出[unknown],不会猜测函数名。探针清单
baselineraw_syscalls、futex syscall、sched_switchrunqlatsched_wakeup、sched_wakeup_new、sched_switchoncpuperf_eventbiolatencyblock_rq_insert/issue/completemempressuresched_switch、mm_page_alloc、filemap、vmscanoomkilloom/mark_victimlocksensorsyscall_hotspotraw_syscalls:sys_enter/sys_exitpagefaultpage_fault_usertcpconnlatconnect()调用延迟sys_enter_connect/sys_exit_connectpagefault和tcpconnlat可以由 Agent 加载,也用于性能实验,但目前没有进入默认异常检测和根因报告闭环。项目结构
后端主要模块:
detectors.py:确定性滚动异常检测器。engine.py:指标派生、冲突处理、对象选择、探针编排和会话恢复。reports.py:事件关联、根因门槛、采集完整性和结构化报告。report_markdown.py:从已校验 JSON 确定性渲染中文 Markdown。protocol.py:Agent 命令客户端、重试和 ACK 校验。doctor.py、compatibility.py:环境检查和兼容性证据。server.py、cli.py:HTTP 服务和统一命令行。Agent 主要模块:
agent.cpp/.hpp:线程管理、baseline 遥测、命令服务、离线规则和事件发送。bpf_manager.cpp/.hpp:BPF object 加载、map 参数注入、attach、poll、detach 和 drain。command_protocol.cpp/.hpp:命令认证、字段、白名单和幂等约束。diagnostic_batch.cpp/.hpp:事件批次数量和字节限制。timer_manager.cpp/.hpp:有限租约和 watchdog 卸载。stack_symbolizer.cpp/.hpp:用户/内核地址、ELF、DWARF、Build ID 和 kallsyms 符号化。环境要求
推荐目标为 openKylin 2.0 SP2 或同类现代 Linux,内核 6.6+。最低工程要求:
/sys/kernel/btf/vmlinux;venv和 pip;CAP_BPF、CAP_PERFMON,部分环境还需要CAP_SYS_ADMIN;stress-ng、fio、findmnt、shuf、sha256sum等工具。Kernel lockdown、LSM、容器能力限制、受限
/proc/kallsyms或缺失 tracepoint 都可能影响探针加载或符号解析。先运行aebpf doctor,不要仅以编译成功代替目标内核 attach 验证。快速开始
1. 初始化
bootstrap.sh会安装或检查系统依赖,创建.venv,安装backend/requirements.txt中固定版本的 Python 依赖,生成当前内核专用的bpf_probes/vmlinux.h,并创建权限为0600的.runtime/command-token。已有系统依赖时使用:
只安装构建依赖而不安装
fio和stress-ng时使用./scripts/bootstrap.sh --install-build-system。2. 构建与静态验证
构建结果:
bpf_probes/*.bpf.c->agent/probes/*.bpf.o;agent/src/*.cpp->agent/agent。3. 运行内核 attach 冒烟
该测试启动临时后端和 Agent,确认 baseline 遥测到达,并逐一 LOAD/UNLOAD 默认启用的详细探针,检查丢失和拒绝计数。它验证“能加载”,不验证五类负载的诊断准确度。
4. 启动诊断
一条命令运行后端与 Agent,并在结束时完成活动会话、导出报告数组:
--duration 0表示持续运行直到收到中断。单个报告会写入reports/<report-id>.json和同名.md;--output是本次进程所有报告的 JSON 数组。也可以分开运行:
从仓库根目录启动 Agent,确保相对路径形式的配置、规则和探针目录正确解析。
5. 查看状态和报告
CLI 与 Make 命令
CLI
aebpf backendaebpf agentaebpf diagnoseaebpf doctoraebpf status--json输出机器可读结果aebpf validate-configschemas/config.schema.json校验 YAMLaebpf validate-reportdiagnose导出的报告数组aebpf render-reportaebpf validate-acceptance查看参数:
Make targets
make bootstrapmake vmlinuxvmlinux.hmake probesmake agentmake buildmake testmake smokesudo make smoke-runtimesudo make accuracy-scenariossudo make accuracy-developmentsudo make accuracy-acceptancesudo make overhead-smokesudo make overhead-experimentmake overhead-analyze OVERHEAD_RAW=...raw.json重建统计sudo make oncpu-validationmake fresh-clone-testmake run-backendsudo make run-agentmake cleanvmlinux.h另有
openkylin-vm-image、openkylin-vm-validation和openkylin-iso-full用于 openKylin ISO/VM 验证。目标机验证步骤见 openKylin 验证说明。配置
config/default.yaml是规范默认配置。每次 CLI 调用都会使用schemas/config.schema.json校验,未知键、错误类型、越界值和启用但无探针的诊断项会被拒绝。默认服务与会话参数:
127.0.0.1:5000127.0.0.1:9091默认绝对触发阈值:
cpu_busy_ratioio_busy_ratiomemory_available_ratiomemory_available_drop_rate_per_secondcontext_switch_rate_per_cpufutex_wait_rate_per_cpudirect_reclaim_rate_per_secondkswapd_scan_rate_per_secondsyscall_rate_per_secondslow_syscall_rate_per_second阈值只负责打开诊断会话,不等价于根因确认。每类报告还有独立的事件质量、对象匹配和完整性门槛。系统调用与锁竞争的细分策略见 配置参考。
后端失联时,Agent 会执行
agent/rules.json中的离线规则:CPU busy 超过 0.90 时加载runqlat60 秒,设备 I/O busy 超过 0.70 时加载biolatency60 秒。离线事件只保存在最多 10000 条的内存队列中,重启不持久化。HTTP 接口与安全边界
后端接口
GET/healthPOST/telemetryPOST/diag_dataGET/reportsPOST/reports/finalize后端请求体上限为 1 MiB。Agent 每批最多发送 1000 条或 768 KiB,内存事件队列最多 10000 条;丢失、拒绝和重复事件会分别计数。
Agent 命令接口
Agent 提供认证的
POST /command和GET /status。命令协议支持LOAD/UNLOAD,并实现:0600的共享令牌和常量时间比较;command_id幂等缓存和冲突检测;PROBE_BUSY;默认配置只监听 loopback,但传输仍是普通 HTTP。跨主机部署必须增加 TLS 或受认证代理,不要直接暴露 5000/9091。命令令牌、
.runtime/、报告、日志、虚拟环境和主机生成的 BPF 对象不得提交到 Git。诊断报告
JSON 是唯一事实来源,必须通过
schemas/diagnostic-report.schema.json(当前schema_version: 1.2)。同名中文 Markdown 只从已校验 JSON 确定性生成,不调用大模型,也不读取额外运行时状态;状态、异常类型和根因使用中文解释,并保留原始代码便于程序对照。报告包含:
action、rationale、risk、verify、rollback的结构化处置建议。报告状态必须按证据解释:
confirmedsuspectedinsufficient_evidencefailedsuspected、insufficient_evidence和failed都不能表述为已确认根因。Ring Buffer/Agent 队列丢失、后端拒绝、部分探针失败、卸载失败或更具体信号冲突会使结论降级。测试
测试分为代码级、内核加载级和真实场景级,三者不能互相替代。
自动化测试
当前套件包含 3 个 C++ 测试程序和 202 个 Python
unittest测试方法:2026-07-29 本次 README 更新时的 WSL 验证结果为:3 个 C++ 测试程序通过,202 个 Python 测试通过,
Ran 202 tests ... OK;测试入口同时验证了配置、报告 Schema、确定性 Markdown 渲染和四组场景样例。静态 smoke
该目标执行 build、全部测试、doctor、默认配置校验、示例报告校验和关键脚本存在性检查。
运行时 smoke
它验证真实内核上的 baseline、默认详细探针加载/卸载、目标参数、遥测传输和零丢失,不产生准确度结论。
Fresh clone 测试
脚本把源码复制到临时目录,排除
.venv、.runtime、构建物、报告和实验产物,然后重新 bootstrap、build、test 和校验示例报告,用于发现对本机生成文件的隐式依赖。手动负载验证
先启动后端和 Agent,一次只运行一种负载,场景之间等待会话结束和主机恢复。常用入口:
内存和高强度 I/O 测试可能触发 reclaim、swap、OOM 或显著业务抖动,只应在一次性虚拟机或专用测试机运行。完整步骤、预期根因和报告判定见 手动测试指南。
准确度测试
开发检查
该目标每类只运行 1 次、单次 30 秒、不执行正常负例,可隔离 detector,用于快速调试。它会标记为 development evidence,不能通过正式准确度验收器,也不能替代发布验收。
正式验收
正式门禁使用固定发布配置,所有 detector 同时启用;CPU、I/O、内存、锁和系统调用五类正例各重复 3 次,使用固定种子随机交错,并运行 90 秒正常事件循环负例。默认每次正例负载 120 秒、预热 35 秒、冷却 15 秒。
每个正例只有在以下条件全部满足时通过:
confirmed,异常类型与根因码匹配预先声明的真值;confirmed报告。正常对照必须执行真实低频
poll/openat/newfstatat工作负载且报告数组为空。suspected和主动放弃确认不直接计为 false positive,但必须单独统计;意外confirmed才计入错误结论。证据包包括:
SHA256SUMS完整性清单和人类可读 Markdown 摘要。已接受的 x86_64 结果
2026-07-23 的 openKylin x86_64 记录:
suspected/insufficient_evidencesuspected报告该结论只覆盖已声明的五类受控场景和一个正常对照,不外推到混合异常、长期生产流量或未验收架构。主机生成的
validation-results/不进入 Git;提交内保留的是结论与证据索引,详见 准确度实验设计 和 准确度证据索引。性能测试
性能实验使用随机化配对 block。每个 repetition 以相同 fio 随机种子运行 13 种模式,顺序重新随机:
no_agent:只有 fio;baseline_only:Agent + baseline;detailed:<probe>:baseline 分别加一个详细探针;always_on_detailed:9 个详细探针在整个测量期常驻;elastic_leased:baseline 常驻,9 个详细探针只在受控租约内加载。默认前台负载是 4 KiB direct random read、queue depth 32 的单 fio 线程。测试记录:
run_time_ns、run_cnt和 ns/run;管道冒烟
该目标只执行 2 个 repetition、8 秒测量窗口,用于检查实验管道,结果不能作为发布数据。
正式运行
在专用测试磁盘或明确的非生产测试文件上运行:
可用
--cpus 2-5固定 fio CPU 集,减少调度噪声。至少 5 个 repetition 且 clean repository 才满足工具的publication_ready基线;最终比赛/论文数据在时间允许时建议 10 个 repetition。默认输出为
validation-results/overhead-<UTC timestamp>/:raw.json:不可变输入、随机计划、主机身份、对象哈希和每次运行;runs/.../fio.json、agent.log:逐次原始材料;summary.json:机器可读统计、完整性和 publication readiness;summary.md:核心模式、单探针、BPF program、map、事件和生命周期表。中断后只有在同一次 boot 且 Agent、runner 和所有 probe object 哈希仍一致时才可继续:
不重新运行负载即可重建统计:
不要接受
raw.json.status != complete、summary.json.complete != true、publication_ready == false或重复次数不足的结果。map 的capacity_estimate不能当作实际常驻内存;未触发事件的 probe 也不能当作最坏开销,需同时查看 BPFrun_cnt。2026-07-24 开发实验摘要
历史实验为 5 个 block、65/65 次有效运行,20 秒测量、10 秒 warm-up,弹性租约 2 秒:
弹性模式相对全程常驻,配对均值减少 16.45 ms/s BPF 执行时间和 52.43 MiB 时间加权 map,吞吐提高 10.40%,但 Agent CPU 增加 5.66 个百分点。该结果的 Git 记录为
1ae57ac...且dirty=true,因此属于开发/演示证据,不是 publication-ready 结论。完整置信区间与限制见 性能实验设计 和 实验结论。兼容性与 CI
兼容性证据分三级:
GitHub Actions 在 x86_64 和 ARM64 runner 上执行 build/test,并在 openKylin 2.0 容器中验证用户态依赖。容器共享宿主内核,因此不能证明 openKylin 内核 attach;完整 runtime job 需要带
openkylin标签的 6.6+ self-hosted runner。目标机完整流程:
runtime 与 scenario 证据必须来自同一 host、boot、kernel 和 architecture。只有
openkylin_accuracy_runtime.status == pass才能声明目标平台已完成准确度运行验证。详见 openKylin 验证说明。systemd 部署
packaging/提供参考 unit 和生产路径配置:/opt/aebpf;/etc/aebpf;/var/lib/aebpf;aebpf用户运行;CAP_BPF CAP_PERFMON CAP_SYS_ADMINcapability 集。部署前应审查目标发行版的 systemd sandbox、kernel lockdown、LSM、报告目录权限和 TLS/代理配置。完整命令见 安装与部署。
常见问题
缺少 BTF 或
vmlinux.h若 BTF 不可读,需要切换到启用 BTF 的内核;不要从另一台不同内核的主机复制
vmlinux.h。Agent 启动后没有报告
依次确认:
/health.telemetry_samples是否持续增长;aebpf status是否出现目标探针与正确 PID/cgroup/device/syscall;/reports/finalize;suspected或insufficient_evidence,以及 collection 是否完整。探针 attach 失败
记录发行版、
uname -a、BTF、tracepoint、权限和 Agent/libbpf verifier 日志。容器内 root 不一定拥有宿主 BPF 能力。栈无法解析
测试程序使用
-g -fno-omit-frame-pointer且不要strip。检查目标进程是否在采集结束前退出、/proc/<pid>/maps是否可读,以及/proc/kallsyms/debuginfo 是否受限。未解析帧是显式降级,不应被解释成某个具体函数。更多排查项见 故障排查。
已知边界
tcpconnlat尚未完整关联目标 IP、端口和 socket 元数据,也未进入默认网络诊断。pagefault有采样能力,但没有默认缺页异常类别和独立根因门槛。开发约定
snake_case、类名PascalCase,保持-Wall -Wextra -Wpedantic无警告。snake_case;新增测试命名为tests/test_<feature>.py。probe_name、Agent 白名单、JSON 命令、配置和后端决策中完全一致。agent/third_party/,除非明确升级 vendored dependency。vmlinux.h、agent/probes/、Agent 二进制或主机实验产物。make test;涉及 eBPF hook、命令协议或运行路径时再运行make smoke、sudo make smoke-runtime和对应场景。延伸文档
License
本项目使用 MIT License。