目录

ebpf-sysdiag

ebpf-sysdiag 是一个基于 libbpf CO-RE 的轻量级 Linux 系统异常观测与根因定位工具。项目目标是在 openKylin 以及其他 BTF 可用的 Linux 内核上,以尽量低的运行时开销采集关键异常证据,并输出可复核的结构化诊断报告。

当前版本覆盖 5 类典型系统异常:

  • CPU 调度延迟:观测任务从 wakeup 到真正运行之间的 runqueue 延迟。
  • 块设备 I/O 延迟:观测 block request 从 issue 到 complete 的设备层时延。
  • 内存抖动/OOM 风险:观测用户态缺页、进程 RSS、系统可用内存和回收活动。
  • futex/锁竞争:观测 futex 系统调用等待时间,用于识别用户态锁竞争表象。
  • 慢系统调用:观测 syscall enter 到 syscall exit 的调用延迟。

项目不是一个全量 APM agent,也不是一个永久驻留的 metrics exporter。它更适合在异常窗口内按需运行,用最小探针集合保留证据,辅助 SRE、系统工程师、内核开发者和 eBPF 诊断赛题开发者快速判断问题方向。

当前状态

当前代码已经在 zh21 机器上完成一次真实环境验证:

  • 主机:zh21
  • 工作目录:~/work/ebpf-sysdiag
  • 内核:Linux 7.0.0-rc3
  • 架构:x86_64
  • BTF:/sys/kernel/btf/vmlinux 可读
  • clang:可用
  • libbpf:可用
  • bpftool:系统默认 /usr/sbin/bpftool 是 Ubuntu 包装器;项目会自动解析到可用的真实二进制,例如 /usr/lib/linux-tools-6.8.0-111/bpftool

验证命令:

cd ~/work/ebpf-sysdiag
make clean
make
sudo -n build/ebpf-sysdiag --scenario all --duration 1 --output json

验证结果:

  • 默认 make clean && make 编译成功。
  • 不需要手工指定 BPFTOOL=/path/to/bpftool,Makefile 会自动寻找可用 bpftool。
  • --scenario all 能正常加载 eBPF 程序并输出 JSON。
  • cpuiomemorylocksyscall 五个单独场景均能独立运行并以 0 退出。

设计目标

低侵入

采集侧只在必要位置挂载 tracepoint/raw tracepoint,默认只在 BPF 侧完成过滤、采样和阈值判断后才向用户态提交事件。这样可以避免高频路径把大量无效事件复制到用户态。

可移植

默认构建使用 libbpf skeleton 和 CO-RE。只要目标内核提供 /sys/kernel/btf/vmlinux,BPF 程序就可以基于 BTF 做重定位。项目也保留 NO_CORE=1 兼容路径,供无 BTF 环境做功能验证。

可解释

每条诊断结论都包含:

  • 异常类型
  • 影响对象
  • 时间窗口
  • 置信度
  • 摘要
  • 证据列表
  • 建议动作

诊断结果不是只给一个结论字符串,而是保留指标值、阈值和上下文,方便人工复核。

资源自限

默认运行时约束:

  • 采样轮询间隔不低于 100 ms
  • RSS 上限默认 200 MB
  • CPU 预算目标默认不超过单核 5%
  • 每个已加载 BPF 对象使用 8 MB ring buffer
  • 高负载下可通过 --sample-rate 降采样

分层解耦

采集层、加载层、事件解析层、分析层、输出层分离。每个场景的 BPF object 独立编译、独立加载,便于定位 verifier、attach 或 tracepoint 兼容问题。

总体架构

运行路径如下:

tracepoint/raw_tracepoint
  -> BPF 侧过滤、采样、阈值判断
  -> BPF ringbuf
  -> 用户态事件解析
  -> 滑动窗口聚合
  -> 场景 detector 插件
  -> JSON/YAML/Markdown 报告

模块分层:

CLI/config
  -> loader
  -> BPF collectors
  -> ringbuf parser
  -> analysis engine
  -> detector plugins
  -> output formatters

核心目录:

.
├── bpf/                         # BPF 程序和 BPF 公共头文件
│   ├── cpu_sched.bpf.c           # CPU 调度延迟采集
│   ├── block_io.bpf.c            # 块 I/O 延迟采集
│   ├── memory.bpf.c              # 内存抖动/OOM 风险采集
│   ├── lock_futex.bpf.c          # futex 等待采集
│   ├── syscall.bpf.c             # 慢 syscall 采集
│   ├── maps.bpf.h                # ringbuf/config/state/drop maps
│   ├── filters.bpf.h             # BPF 侧过滤和采样
│   ├── common.bpf.h              # BPF 公共 helper
│   └── nocore_types.bpf.h        # tracepoint ctx 兼容结构
├── include/                      # 用户态公共头文件和数据结构
├── src/
│   ├── loader.c                  # libbpf skeleton 加载、attach、ringbuf 注册
│   ├── event_parser.c            # 原始 ringbuf 数据解析
│   ├── config.c                  # CLI 和扁平配置文件解析
│   ├── resource_guard.c          # RSS/CPU 资源守护
│   ├── analysis/
│   │   ├── engine.c              # 时间窗口聚合
│   │   └── detectors/            # 场景诊断插件
│   └── output/                   # JSON/YAML/Markdown 输出
├── config/                       # 示例配置
├── tests/
│   ├── reproduce/                # 异常复现脚本
│   └── integration/              # 场景集成测试脚本
├── tools/                        # BTF/bpftool/环境检测和构建辅助脚本
├── scripts/                      # 依赖安装、性能基线、环境采集
├── docs/                         # 设计、兼容性、性能、盲区等补充文档
├── Makefile
├── DESIGN.md
└── TEST.md

赛题要求与实现文件对应表

这一节用于快速定位“赛题要求”在项目中的实现位置。后续逐项优化时,建议先改 BPF 采集,再改公共事件结构,再改用户态聚合和 detector,最后补配置、测试和文档。

异常场景实现入口

赛题场景 当前诊断类型 主要实现入口
CPU 异常占用或调度延迟 cpu_sched_latency / cpu_intensive_compute / cpu_busy_loop / cpu_thread_contention bpf/cpu_sched.bpf.csrc/analysis/detectors/cpu_detector.ctests/reproduce/cpu_runqueue_delay.sh
I/O 延迟抖动或阻塞等待 block_io_latency bpf/block_io.bpf.csrc/analysis/detectors/io_detector.ctests/reproduce/io_latency_fio.sh
内存抖动或 OOM 风险 memory_jitter_oom_risk bpf/memory.bpf.csrc/analysis/detectors/memory_detector.ctests/reproduce/memory_pressure.sh
锁竞争导致性能退化 lock_futex_contention bpf/lock_futex.bpf.csrc/analysis/detectors/lock_detector.ctests/reproduce/futex_contention.c
高频或高耗时系统调用热点 syscall_latency bpf/syscall.bpf.csrc/analysis/detectors/syscall_detector.ctests/reproduce/syscall_storm.sh

公共链路实现入口

能力 主要文件 修改说明
公共事件、阈值和结果结构 include/diag_types.h 定义事件类型、事件结构、阈值结构和 diag_result。新增赛题输出字段或 detector 阈值时必须同步这里。
BPF skeleton 加载和 attach src/loader.c 每个场景的 *_bpf__open/load/attach 都在这里。新增场景、降级或按场景禁用逻辑时修改这里。
ringbuf 事件解析 src/event_parser.c 将 BPF ringbuf 原始数据转换为 struct diag_event。新增事件类型必须补 switch 分支。
时间窗口聚合 src/analysis/engine.c 将事件聚合到 diag_window_snapshot。新增指标、计数、P99 近似或目标选择逻辑时修改这里。
detector 根因判断 src/analysis/detectors/*.c 每类异常的识别规则、证据链、root_cause 和建议结论都在对应 detector 中。
结构化输出 src/output/json_output.csrc/output/yaml_output.csrc/output/markdown_output.c 赛题要求的 JSON/YAML/Markdown 输出在这里实现。新增顶层字段必须同步三个格式。
CLI 和配置 src/config.cconfig/*.yaml --scenario--pid--comm、采样率和各类阈值配置入口。
评委复核入口 tests/integration/*tests/reproduce/* 每个场景的复现和基础验证脚本。优化某个场景后必须同步对应脚本。

按场景修改时的推荐顺序

  1. 修改 bpf/<scenario>.bpf.c,确认采集点、过滤和阈值触发逻辑。
  2. 如新增事件或字段,修改 include/diag_types.h
  3. 如新增 tracepoint ctx,修改 bpf/nocore_types.bpf.h
  4. 修改 src/event_parser.c,保证 ringbuf 事件能解析。
  5. 修改 src/analysis/engine.csrc/analysis/detectors/detector.h,补窗口聚合字段。
  6. 修改 src/analysis/detectors/<scenario>_detector.c,实现根因判断、证据链和建议。
  7. 修改 src/config.cconfig/<scenario>.yamlconfig/default.yaml,同步阈值。
  8. 如新增顶层输出字段,修改 src/output/*
  9. 修改 tests/reproduce/tests/integration/,保证能复现并自动校验。
  10. 修改 README、docs/diagnosis_rules.mdTEST.md,保证文档和实际行为一致。

五类诊断场景

CPU 异常占用与调度延迟

目标:定位 CPU 密集计算、busy loop、线程过量竞争以及线程已经被唤醒但长时间没有被调度运行的问题。常见原因包括用户态计算热点、线程池过度并发、CPU 饱和、runqueue 过长、cgroup CPU quota 限制、CPU 亲和性配置异常等。

采集点:

  • tracepoint/sched/sched_wakeup
  • tracepoint/sched/sched_switch

核心逻辑:

  1. sched_wakeup 记录目标 pid 的唤醒时间戳。
  2. sched_switch 看到该 pid 真正切入 CPU 时计算 now - wake_ts
  3. 同时在 sched_switch 重建任务 on-CPU runtime、上下文切换次数和 voluntary/involuntary switch。
  4. 用户态按 comm 聚合热点线程组,区分 cpu_intensive_computecpu_busy_loopcpu_thread_contentioncpu_sched_latency

输出证据:

  • cpu_runtime_percent
  • cpu_runtime_total_us
  • cpu_runtime_max_us
  • context_switch_rate
  • context_switch_count
  • involuntary_context_switches
  • voluntary_context_switches
  • runqueue_delay_max_us
  • runqueue_delay_avg_us
  • runqueue_delay_event_count
  • affected_threads
  • affected_pid

默认阈值:

cpu_runq_delay_us_p99: 5000 us
cpu_context_switch_rate: 1000

当前限制:

  • 当前实现按 pid 记录 wakeup 时间,极短生命周期任务可能错过。
  • wake_cpu 暂未完整归因,仅保留目标 CPU 和切换上下文信息。
  • CPU 饱和、quota、亲和性问题需要结合系统指标进一步确认。

块设备 I/O 延迟

目标:定位块设备请求从提交到完成之间的高延迟,常见原因包括设备队列拥塞、磁盘/云盘抖动、I/O throttling、文件系统写回压力等。

采集点:

  • tracepoint/block/block_rq_issue
  • tracepoint/block/block_rq_complete

核心逻辑:

  1. block_rq_issue 记录请求时间戳、pid/tid、comm。
  2. dev + sector 构造请求 key。
  3. block_rq_complete 计算 issue-to-complete 延迟。
  4. 延迟超过 io_block_latency_us_p99 后输出 DIAG_EVT_IO_LAT
  5. 用户态优先将 target 归因为块设备 major:minor,把提交请求时的 pid/comm 作为辅助证据,避免把写回或完成路径误判为业务根因。
  6. 用户态对慢 I/O 延迟做直方图聚合,输出 block_latency_p99_us 近似值、慢 I/O 速率和队列深度估算。
  7. 对 issuer 做窗口聚合,优先选择业务进程,避免异步 I/O 场景下最后一个 kworker 覆盖 fio 等真实压力源。

输出证据:

  • block_latency_max_us
  • block_latency_p99_us
  • block_latency_avg_us
  • slow_io_count
  • slow_io_rate_per_sec
  • queue_depth_estimate
  • observed_bytes
  • device_major
  • device_minor
  • issuer_pid

默认阈值:

io_block_latency_us_p99: 500 us
io_min_count: 100

当前限制:

  • 默认路径使用 typed tracepoint,设备名字段暂不完整填充,主要提供 major/minor、bytes 和延迟。
  • 当前是设备层归因,不直接给出 VFS 文件路径。
  • block_latency_p99_us 是基于已上报慢请求的直方图近似,不等价于 fio 对所有完成 I/O 统计出的精确 P99。
  • queue_depth_estimate 基于慢请求总耗时和窗口时长估算,用于判断队列拥堵趋势,不替代块层真实 inflight 计数。
  • 对合并、重排、跨层缓存命中的请求,归因粒度仍需结合 iostat/fio/blktrace 类工具复核。

内存抖动与 OOM 风险

目标:捕获用户态缺页、匿名页增长、可用内存下降、kswapd/direct reclaim 等信号,用于识别内存抖动、持续内存增长和 OOM 风险。该场景按赛题样例重点关注“高内存占用 + 频繁缺页 + 可用内存下降/回收活跃”的组合证据,而不是单独看到 page fault 就报异常。

采集点:

  • tracepoint/kmem/mm_page_alloc
  • tracepoint/exceptions/page_fault_user
  • tracepoint/vmscan/mm_vmscan_kswapd_wake
  • tracepoint/vmscan/mm_vmscan_direct_reclaim_begin
  • 用户态读取 /proc/meminfo/proc/<pid>/statm

核心逻辑:

  1. mm_page_alloc 记录页分配 order、gfp flags 和估算字节数。
  2. page_fault_user 记录用户态缺页地址和错误码。
  3. vmscan tracepoint 记录 kswapd 唤醒和 direct reclaim 起点。
  4. 用户态窗口内聚合缺页数量、分配量和回收事件数。
  5. 出报告前读取系统 MemAvailable 占比,并扫描 /proc 选取当前 RSS 最高的候选进程,避免全局 page fault 被最后一个无关进程覆盖。
  6. 对选中的目标 comm 再次聚合同名进程 RSS,用于覆盖 stress-ng --vm 4 这类多 worker 场景。
  7. 缺页按窗口持续时间换算为 page_fault_rate_per_sec,检测器要求至少出现大额分配、高 RSS、进程组 RSS、回收活动或低可用内存之一;page fault 只作为辅助证据。

输出证据:

  • page_fault_events
  • page_fault_rate_per_sec
  • allocated_bytes
  • process_rss_bytes
  • process_group_rss_bytes
  • process_group_count
  • system_mem_available_percent
  • reclaim_events
  • affected_pid

默认阈值:

memory_page_fault_rate: 1000/sec      # 用户态缺页速率阈值
memory_alloc_rate: 65536 bytes       # BPF 侧单次页分配过滤阈值
memory_alloc_bytes: 67108864 bytes   # 窗口累计分配量阈值,默认 64 MB
memory_rss_bytes: 536870912 bytes    # 目标进程 RSS 阈值,默认 512 MB
memory_reclaim_events: 5
memory_available_percent: 30

当前限制:

  • 当前版本不采集内核调用栈和用户调用栈。
  • 当前通过 vmscan 事件识别 reclaim 活跃,但不进一步拆分 reclaim、compaction、swap 的完整调用链。
  • memory_alloc_rate 在 BPF 侧用于过滤较大分配,不等同于完整进程分配速率。
  • top RSS 进程是用户态快照推断,用于提高赛题样例中的根因定位准确性;在多进程同时高 RSS 时仍需结合 cgroup 或业务上下文复核。

futex/锁竞争

目标:用 futex syscall 的等待时间识别用户态锁竞争表象。典型场景包括 pthread mutex 临界区过长、线程池同步热点、条件变量等待异常等。

采集点:

  • tracepoint/syscalls/sys_enter_futex
  • tracepoint/syscalls/sys_exit_futex

核心逻辑:

  1. sys_enter_futex 记录 pid/tid、futex 地址、op、开始时间。
  2. sys_exit_futex 计算 futex syscall 持续时间。
  3. 超过 lock_futex_wait_us_p99 后输出 DIAG_EVT_FUTEX_WAIT
  4. 用户态 detector 聚合最大等待时间和等待次数。

输出证据:

  • futex_wait_max_us
  • futex_wait_count
  • affected_pid

默认阈值:

lock_futex_wait_us_p99: 10000 us
lock_min_wait_count: 50

当前限制:

  • futex 等待时间只能说明锁等待表象,不能直接识别锁 owner。
  • 如需 owner 归因,应增加 pthread_mutex_lock/pthread_mutex_unlock uprobe 或业务锁埋点。
  • 条件变量、信号量、parking lot 等同步机制都可能落到 futex,需结合 uaddr 和调用栈进一步拆分。

慢系统调用

目标:定位进入内核后耗时过长的系统调用,常见原因包括 I/O 阻塞、锁等待、网络等待、文件系统慢路径、资源限制等。

采集点:

  • tracepoint/raw_syscalls/sys_enter
  • tracepoint/raw_syscalls/sys_exit

核心逻辑:

  1. 在 syscall enter 记录 syscall id、pid/tid、comm、开始时间。
  2. 在 syscall exit 计算调用耗时和返回值。
  3. 超过 syscall_latency_us_p99 后输出 DIAG_EVT_SYSCALL_LAT
  4. BPF 侧额外按 pid + syscall id 计数,高频调用每达到 syscall_rate 发出一次聚合事件。
  5. 用户态按进程聚合并选择高频或高耗时最突出的 syscall 热点,同时过滤常驻 daemon 的 idle wait 类慢阻塞噪声。

输出证据:

  • syscall_latency_max_us
  • syscall_latency_avg_us
  • syscall_event_count
  • syscall_id
  • affected_pid

默认阈值:

syscall_latency_us_p99: 5000 us
syscall_rate: 10000

当前限制:

  • 当前输出保留 syscall id,但 syscall name 字段暂未映射。
  • raw syscall 只能说明“进入内核后的耗时”,根因仍需与 I/O、锁、网络等证据关联。
  • 对极高频 syscall 建议配合 --sample-rate 使用。

依赖要求

内核要求

默认 CO-RE 构建要求:

  • Linux 内核启用 BPF 基础能力。
  • /sys/kernel/btf/vmlinux 可读。
  • 目标 tracepoint 存在。

建议内核配置至少包含:

CONFIG_BPF=y
CONFIG_BPF_SYSCALL=y
CONFIG_BPF_JIT=y
CONFIG_BPF_EVENTS=y
CONFIG_TRACEPOINTS=y
CONFIG_FTRACE_SYSCALLS=y
CONFIG_DEBUG_INFO_BTF=y

不同发行版配置名称可能略有差异。可以用项目内脚本先做检查:

tools/detect_kernel_features.sh
tools/check_btf.sh

用户态依赖

需要:

  • clang
  • llvm
  • make
  • gcc 或兼容 C 编译器
  • pkg-config
  • bpftool
  • libbpf 开发包
  • libelf 开发包
  • zlib 开发包

openKylin/Ubuntu/Debian 类系统可尝试:

scripts/install_deps_openkylin.sh

该脚本实际安装:

clang llvm make gcc pkg-config bpftool libbpf-dev libelf-dev zlib1g-dev linux-tools-common

权限要求

加载 BPF 程序通常需要:

  • root;或
  • CAP_BPFCAP_PERFMONCAP_SYS_ADMIN 等等价权限组合,具体取决于内核版本和发行版策略。

最直接的运行方式是:

sudo build/ebpf-sysdiag --scenario all --duration 60 --output json

bpftool 自动发现

一些 Ubuntu/openKylin 环境中的 /usr/sbin/bpftool 不是实际二进制,而是根据当前内核版本寻找 linux-tools-$(uname -r) 的包装器。自编译内核或者 rc 内核上,经常会出现:

WARNING: bpftool not found for kernel ...

为避免这种情况,项目提供:

tools/resolve_bpftool.sh

默认 Makefile 会调用它寻找可用 bpftool,顺序包括:

  1. 用户显式设置的 BPFTOOL
  2. command -v bpftool
  3. /usr/lib/linux-tools-$(uname -r)/bpftool
  4. /usr/lib/linux-tools-*/bpftool
  5. /usr/local/sbin/bpftool
  6. /usr/local/bin/bpftool
  7. /usr/sbin/bpftool
  8. /usr/bin/bpftool

如果自动发现失败,可以手工指定:

BPFTOOL=/usr/lib/linux-tools-6.8.0-111/bpftool make

构建

默认 CO-RE 构建

make check-env
make

构建产物:

build/ebpf-sysdiag
build/*.skel.h
bpf/vmlinux/vmlinux.h

说明:

  • bpf/vmlinux/vmlinux.h/sys/kernel/btf/vmlinux 生成。
  • 生成过程使用临时文件原子替换,避免 bpftool 失败后留下 0 字节坏文件。
  • make clean 会删除 build/ 和生成的 bpf/vmlinux/vmlinux.h
  • bpf/vmlinux/vmlinux.h 是本机生成物,已经被 .gitignore 忽略。

无 BTF 兼容构建

如果目标机器没有 /sys/kernel/btf/vmlinux,可使用:

make clean
make NO_CORE=1

NO_CORE=1 会跳过 CO-RE vmlinux 生成,使用项目内手写 tracepoint ctx 结构。这个模式适合在已知兼容的机器上做功能验证,不建议作为生产默认路径。

需要注意:

  • NO_CORE=1 依赖 tracepoint format 布局和当前内核匹配。
  • 默认生产构建仍应优先使用 CO-RE。
  • 某些字段在不同内核上可能缺失或偏移变化,NO_CORE 模式无法像 CO-RE 一样自动重定位。

常见构建问题

找不到 /sys/kernel/btf/vmlinux

现象:

missing readable /sys/kernel/btf/vmlinux

处理:

  • 确认当前运行内核启用了 CONFIG_DEBUG_INFO_BTF
  • 确认 boot 的是带 BTF 的新内核,而不是旧内核。
  • 短期只做功能验证可用 make NO_CORE=1

bpftool 包装器失败

现象:

WARNING: bpftool not found for kernel ...

处理:

  • 当前版本默认会自动寻找 /usr/lib/linux-tools-*/bpftool
  • 如果仍失败,手工设置 BPFTOOL=/path/to/bpftool

BPF 类型冲突

现象可能包括:

typedef redefinition
unknown type name '__u16'
incomplete definition of type 'struct trace_event_raw_*'

当前版本已经处理:

  • BPF 侧不直接包含用户态 stdint.h
  • CO-RE 模式先包含 vmlinux.h 再补充项目自定义 tracepoint ctx。
  • tracepoint ctx 使用 diag_trace_event_raw_* 项目命名,避免依赖内核 BTF 中的结构名。
  • make clean 会清理坏的生成头。

快速开始

列出支持的场景

build/ebpf-sysdiag --list-scenarios

输出:

cpu
io
memory
lock
syscall

配置检查

build/ebpf-sysdiag --dry-run --config config/default.yaml

示例输出:

dry-run ok: scenarios=0x1f duration=60 output=0 sample_interval_ms=100

采集全部场景

sudo build/ebpf-sysdiag --scenario all --duration 60 --output json

采集单个场景

CPU:

sudo build/ebpf-sysdiag --scenario cpu --duration 30 --output markdown

I/O:

sudo build/ebpf-sysdiag --scenario io --duration 30 --output json

内存:

sudo build/ebpf-sysdiag --scenario memory --duration 30 --output json

锁竞争:

sudo build/ebpf-sysdiag --scenario lock --duration 30 --output yaml

慢 syscall:

sudo build/ebpf-sysdiag --scenario syscall --duration 30 --output json

组合场景

sudo build/ebpf-sysdiag --scenario cpu,syscall,lock --duration 60 --output json

按 PID 过滤

sudo build/ebpf-sysdiag --scenario syscall --pid 1234 --duration 20

按进程名过滤

sudo build/ebpf-sysdiag --scenario lock --comm nginx --duration 20

注意:comm 是 Linux task comm,长度受 TASK_COMM_LEN 限制,当前项目按 16 字节处理。

输出到文件

sudo build/ebpf-sysdiag \
  --scenario all \
  --duration 60 \
  --output json \
  --output-file report.json

使用配置文件

sudo build/ebpf-sysdiag --config config/default.yaml --output-file report.json

命令行参数会覆盖配置文件中的值。

CLI 参数

Usage: build/ebpf-sysdiag [OPTIONS]
  --scenario LIST          cpu,io,memory,lock,syscall,all
  --duration SEC           collection duration, default 60
  --config PATH            minimal key:value config file
  --output FORMAT          json,yaml,markdown
  --output-file PATH       write report to file
  --pid PID                target process id
  --comm NAME              target command name
  --sample-rate N          keep one event per N events
  --sample-interval-ms N   default 100
  --max-rss-mb N           default 200
  --max-cpu-percent N      default 5
  --dry-run                validate config only
  --list-scenarios         print supported scenarios

参数说明:

参数 说明 默认值
--scenario 启用场景,支持逗号分隔 all
--duration 采集时长,单位秒 60
--config 扁平 key:value 配置文件路径
--output 输出格式:jsonyamlmarkdown/md json
--output-file 输出文件路径,不设置则输出到 stdout
--pid 仅采集指定 pid 不限制
--comm 仅采集指定 task comm 不限制
--sample-rate 每 N 个匹配事件保留 1 个 1
--sample-interval-ms ringbuf poll 和资源检查间隔,低于 100 会被提升到 100 100
--max-rss-mb 用户态 RSS 上限 200
--max-cpu-percent CPU 预算目标 5
--dry-run 只解析配置,不加载 BPF false
--list-scenarios 打印支持的场景 false

配置文件

配置文件采用简单的扁平 key: value 格式,不是完整 YAML 解析器。支持注释和空行。

默认配置见 config/default.yaml

duration_sec: 60
scenario: all
output: json
sample_interval_ms: 100
sample_rate: 1
max_rss_mb: 200
max_cpu_percent: 5

cpu_runq_delay_us_p99: 5000
io_block_latency_us_p99: 500
memory_page_fault_rate: 1000
memory_alloc_rate: 65536
memory_alloc_bytes: 67108864
memory_rss_bytes: 536870912
memory_reclaim_events: 5
memory_available_percent: 30
lock_futex_wait_us_p99: 10000
syscall_latency_us_p99: 5000

支持的配置键:

配置键 说明
duration_sec 采集时长
scenario 启用场景
output 输出格式
pid PID 过滤
comm comm 过滤
sample_interval_ms poll 间隔
sample_rate BPF 侧采样率
max_rss_mb RSS 上限
max_cpu_percent CPU 预算
cpu_runq_delay_us_p99 CPU runqueue 延迟阈值,单位 us
io_block_latency_us_p99 块 I/O 延迟阈值,单位 us
memory_page_fault_rate 用户态缺页速率阈值,单位 events/s
memory_alloc_rate 分配字节阈值
memory_alloc_bytes 窗口累计分配字节阈值
memory_rss_bytes 目标进程 RSS 阈值
memory_reclaim_events kswapd/direct reclaim 事件数阈值
memory_available_percent 系统可用内存百分比阈值,低于该值表示风险
lock_futex_wait_us_p99 futex 等待阈值,单位 us
syscall_latency_us_p99 syscall 延迟阈值,单位 us

输出格式

支持:

  • JSON
  • YAML
  • Markdown

每条诊断结果包含:

字段 说明
type 诊断类型,例如 cpu_sched_latencyblock_io_latency
target 影响对象,例如 pid=123 comm=nginx
window.start_ns 诊断窗口开始时间,CLOCK_MONOTONIC 纳秒
window.end_ns 诊断窗口结束时间,CLOCK_MONOTONIC 纳秒
confidence 置信度
summary 人类可读摘要
root_cause 疑似根因,必须由证据链支撑,避免只输出症状
evidence 证据数组,每项包含指标名、实际值、阈值、说明
suggestions 后续排查建议

JSON 示例:

{
  "results": [
    {
      "type": "syscall_latency",
      "target": "pid=10339 comm=ebpf-sysdiag",
      "window": { "start_ns": 5631857282231, "end_ns": 5632884445209 },
      "confidence": "confirmed",
      "summary": "Slow syscalls observed for pid=10339 comm=ebpf-sysdiag, max=1001067 us, events=18",
      "root_cause": "目标进程存在高耗时系统调用,疑似被 I/O、锁等待、调度延迟或外部依赖阻塞",
      "evidence": [
        {
          "name": "syscall_latency_max_us",
          "value": 1001067,
          "threshold": 5000,
          "detail": "syscall latency exceeded threshold"
        }
      ],
      "suggestions": [
        "Group slow syscalls by id and correlate with I/O or lock waits."
      ]
    }
  ]
}

置信度规则

当前置信度由证据数量和阈值超限比例综合计算。取值:

置信度 含义
confirmed 证据较充分,且主指标明显超过阈值
highly_suspected 至少有多个证据点,异常信号清晰
possible 有异常信号,但证据不足以强断言
need_investigation 无可靠结论,需要继续排查

设计原则:

  • 单一指标异常不应被当作最终根因。
  • 输出中保留阈值和实际值,避免过度断言。
  • 时间窗口用于区分根因和表象,但当前版本仍以窗口聚合为主,尚未实现完整因果图。

BPF Map 设计

每个场景 BPF object 都包含一组独立 map,避免场景之间互相影响。

Map 类型 用途
events_rb BPF_MAP_TYPE_RINGBUF 异常事件输出,默认 8 MB
config_map BPF_MAP_TYPE_ARRAY 保存 struct diag_runtime_config
wake_ts_map BPF_MAP_TYPE_LRU_HASH CPU 场景中保存 pid -> wakeup 时间戳
request_start_map BPF_MAP_TYPE_LRU_HASH I/O 场景中保存 request key -> issue 信息
futex_wait_map BPF_MAP_TYPE_LRU_HASH lock 场景中保存 pid_tgid -> futex enter 信息
syscall_start_map BPF_MAP_TYPE_LRU_HASH syscall 场景中保存 pid_tgid -> syscall enter 信息
drop_counter_map BPF_MAP_TYPE_PERCPU_ARRAY 记录过滤、采样、ringbuf 满等 drop 计数

Map 容量默认值:

events_rb: 8 * 1024 * 1024 bytes
wake_ts_map: 65536
request_start_map: 32768
futex_wait_map: 65536
syscall_start_map: 65536
drop_counter_map: 16 per CPU slots

性能策略

项目默认从以下几个层面控制开销:

  1. 场景按需加载:只加载 --scenario 指定的 BPF object。
  2. BPF 侧过滤:PID/comm 不匹配的事件直接丢弃。
  3. BPF 侧采样:通过 sample_rate 降低高频路径输出。
  4. BPF 侧阈值判断:没有超过阈值的事件不进 ringbuf。
  5. LRU map:状态 map 有容量上限,避免无限增长。
  6. ringbuf 批处理:使用 BPF ringbuf 降低用户态拷贝和系统调用开销。
  7. 用户态资源守护:周期性检查 RSS 和 CPU 预算。

建议在压测前后对比:

scripts/perf_baseline.sh
sudo build/ebpf-sysdiag --scenario all --duration 60 --output json >/tmp/report.json
scripts/perf_baseline.sh

需要重点观察:

  • 工具自身 CPU 占用
  • 工具自身 RSS
  • 工作负载吞吐
  • 上下文切换
  • I/O 吞吐和延迟

测试与复现

环境检查

tools/check_btf.sh
tools/detect_kernel_features.sh
make check-env

编译检查

make clean
make
build/ebpf-sysdiag --dry-run --config config/default.yaml

CPU 调度压力

tests/reproduce/cpu_runqueue_delay.sh
sudo build/ebpf-sysdiag --scenario cpu --duration 20 --output markdown

块 I/O 延迟

tests/reproduce/io_latency_fio.sh
sudo build/ebpf-sysdiag --scenario io --duration 20 --output json

tests/reproduce/io_latency_fio.sh 默认使用 --ioengine=libaio --direct=1 --iodepth=64 --numjobs=4。这样可以让队列深度真实生效;如果使用 fio 默认 psync 引擎,iodepth 会被限制为 1,不适合作为赛题里的队列拥堵复现。

内存压力

tests/reproduce/memory_pressure.sh
sudo build/ebpf-sysdiag --scenario memory --duration 20 --output json

futex 竞争

cc -O2 -pthread tests/reproduce/futex_contention.c -o /tmp/futex_contention
/tmp/futex_contention &
sudo build/ebpf-sysdiag --scenario lock --duration 20 --output json
kill %1

syscall storm

tests/reproduce/syscall_storm.sh &
sudo build/ebpf-sysdiag --scenario syscall --duration 20 --output json
kill %1

集成测试脚本

tests/integration/test_cpu_sched.sh
tests/integration/test_block_io.sh
tests/integration/test_memory.sh
tests/integration/test_lock.sh
tests/integration/test_syscall.sh

测试表现分析

测试 ebpf-sysdiag 时不要只看“有没有输出”。更合理的目标是同时验证四件事:

  1. 能否稳定编译。
  2. 能否在目标内核加载并 attach。
  3. 制造异常后能否输出正确类型的诊断。
  4. 空闲或正常负载下是否少误报,并且工具自身开销可控。

推荐把测试分成基础可用性、空闲基线、单场景压力、混合压力、资源开销、结果复核六个阶段。

1. 基础可用性测试

先确认构建链路、配置解析和 BPF 加载没有问题:

cd ~/work/ebpf-sysdiag
git pull
make clean
make
build/ebpf-sysdiag --dry-run --config config/default.yaml
sudo build/ebpf-sysdiag --scenario all --duration 3 --output json

通过标准:

  • make clean && make 无编译错误。
  • --dry-run 能打印 dry-run ok
  • --scenario all 能成功运行到结束。
  • 输出是合法 JSON。
  • results 可以为空;空结果只表示短窗口内没有事件超过阈值,不代表加载失败。

如果这一步失败,先不要跑压力测试,应优先检查:

tools/check_btf.sh
tools/detect_kernel_features.sh
make check-env

常见问题包括 BTF 缺失、bpftool 包装器不可用、权限不足、目标 tracepoint 不存在。

2. 空闲基线测试

空闲基线用于评估误报率。建议在没有主动压测的情况下运行:

sudo build/ebpf-sysdiag --scenario all --duration 30 --output json

理想结果:

  • results 为空;或
  • 只有少量 possible 级别结果;或
  • 输出指向系统中真实存在的后台活动,例如容器运行时、数据库、node/java 进程。

需要警惕的情况:

  • 空闲状态下大量 confirmed
  • 结果总是指向 ebpf-sysdiag 自己。
  • 某个后台服务长期出现极高延迟,但业务没有任何对应症状。

这些情况通常说明阈值太低、观测对象太宽,或者某类阻塞等待被误当作异常。

3. 单场景压力测试

单场景压力用于验证每个 detector 是否能识别预期异常。建议一次只打开一个场景,避免多个异常互相干扰。

压力类型 压力脚本 观测命令 期望结果类型
CPU 密集/调度压力 tests/reproduce/cpu_runqueue_delay.sh sudo build/ebpf-sysdiag --scenario cpu --duration 20 --output json cpu_intensive_compute / cpu_busy_loop / cpu_thread_contention / cpu_sched_latency
块 I/O 延迟 tests/reproduce/io_latency_fio.sh sudo build/ebpf-sysdiag --scenario io --duration 20 --output json block_io_latency
内存抖动/OOM 风险 tests/reproduce/memory_pressure.sh sudo build/ebpf-sysdiag --scenario memory --duration 20 --output json memory_jitter_oom_risk
futex 竞争 /tmp/futex_contention sudo build/ebpf-sysdiag --scenario lock --duration 20 --output json lock_futex_contention
syscall storm tests/reproduce/syscall_storm.sh sudo build/ebpf-sysdiag --scenario syscall --duration 20 --output json syscall_latency

futex 测试示例:

cc -O2 -pthread tests/reproduce/futex_contention.c -o /tmp/futex_contention
/tmp/futex_contention &
sudo build/ebpf-sysdiag --scenario lock --duration 20 --output json
kill %1

syscall 测试示例:

tests/reproduce/syscall_storm.sh &
sudo build/ebpf-sysdiag --scenario syscall --duration 20 --output json
kill %1

通过标准:

  • 程序退出码为 0
  • 输出中出现对应 type
  • target 能指向压测进程或相关系统对象。
  • evidence.value 至少有一个明显超过 evidence.threshold
  • confidence 至少为 possible;强压力下通常应达到 highly_suspectedconfirmed

如果没有输出,不一定是 bug,先检查:

  • 压力是否真的发生在采集窗口内。
  • 阈值是否过高。
  • 是否被 --pid--comm 过滤掉。
  • 目标内核 tracepoint 是否覆盖该路径。
  • 压测脚本是否依赖 fiostress-ng 等未安装工具。

4. 混合压力测试

单场景通过后,再测试 all 模式:

sudo build/ebpf-sysdiag --scenario all --duration 60 --output json --output-file /tmp/ebpf-sysdiag-all.json

混合测试关注的是关联能力和噪声控制:

  • CPU、I/O、memory、lock、syscall 是否能同时工作。
  • 一个压力源是否会引出多个相关症状。
  • 输出是否被某个高频场景淹没。
  • 工具自身是否出现在 target 中。

例如 I/O 压力可能同时出现:

  • block_io_latency
  • syscall_latency
  • 少量 cpu_sched_latency

这种情况下,不能简单把所有结果都当作独立根因。通常应按时间窗口和因果链理解:

块设备慢 -> read/write/fsync syscall 变慢 -> 业务线程阻塞 -> 可能出现调度或锁等待表象

5. 资源开销测试

工具本身不能成为故障源。建议在压测前后采集基线:

scripts/perf_baseline.sh
sudo build/ebpf-sysdiag --scenario all --duration 60 --output json >/tmp/report.json
scripts/perf_baseline.sh

也可以单独观察工具进程:

sudo build/ebpf-sysdiag --scenario all --duration 120 --output json >/tmp/report.json &
pid=$!
pidstat -p $pid 1
top -p $pid
wait $pid

重点指标:

指标 目标
工具自身 CPU 默认目标低于单核 5%
工具自身 RSS 默认低于 200 MB
业务吞吐 不应因为观测明显下降
上下文切换 不应异常放大
ringbuf 丢事件 压力很高时允许少量丢弃,但不应长期占满

如果开销过高,优先做三件事:

  1. 缩小场景:从 --scenario all 改为单场景。
  2. 缩小对象:增加 --pid--comm
  3. 增大采样:使用 --sample-rate 10 或更高。

6. 结果字段解读

一条结果应按下面顺序读:

字段 解读方式
type 先确认异常类别是否符合当前压测或线上症状
target 看是否指向目标业务进程、系统服务、容器运行时或工具自身
window 确认异常是否落在压测或故障窗口内
confidence 看置信度,但不要只凭置信度下结论
summary 快速了解最大值、事件数和对象
root_cause 看疑似根因是否由 evidence 支撑,不能把它当成无需复核的最终结论
evidence 逐条比较 valuethreshold,判断超限程度
suggestions 作为下一步排查方向,不是自动修复建议

证据比结论更重要。一个高质量结论通常至少有两类互相支撑的证据:

主症状指标超阈值,例如 syscall_latency_max_us > threshold
事件数量达到一定规模,例如 slow_syscall_count 较高
影响对象明确,例如 affected_pid 指向目标进程

如果只有一个指标轻微超阈值,通常只能算 possible

7. 示例结果分析

假设输出中有:

{
  "type": "memory_jitter_oom_risk",
  "target": "pid=1221009 comm=stress-ng-vm",
  "confidence": "confirmed",
  "summary": "Memory jitter/OOM risk for pid=1221009 comm=stress-ng-vm: faults=3279717 fault_rate=204982/s alloc=0 reclaim=0 avail=38%",
  "root_cause": "同名进程组持续申请或触碰匿名内存,导致缺页速率和进程组 RSS 明显升高",
  "evidence": [
    { "name": "page_fault_events", "value": 3279717, "threshold": 0 },
    { "name": "page_fault_rate_per_sec", "value": 204982, "threshold": 1000 },
    { "name": "system_mem_available_percent", "value": 38, "threshold": 30 },
    { "name": "process_rss_bytes", "value": 4665311232, "threshold": 536870912 },
    { "name": "process_group_rss_bytes", "value": 18675007488, "threshold": 2147483648 },
    { "name": "process_group_count", "value": 8, "threshold": 2 }
  ]
}

解读:

  • stress-ng-vm 是当前 RSS 最高且与缺页风暴同窗口出现的进程。
  • 20 秒窗口内观测到 3279717 次用户态缺页,折算缺页速率约 204982/s,超过默认阈值 1000/s
  • 系统 MemAvailable 当前为 38%,没有低于 30%;这条证据表示系统余量,需要和 RSS、缺页速率一起看。
  • 单个目标进程 RSS 约 4.6 GB,同名进程组 RSS 约 18.6 GB,均超过默认阈值。
  • 缺页速率、单进程 RSS、进程组 RSS 三类证据互相支撑,因此可以判定为 confirmed 的内存抖动/OOM 风险。

建议复核:

pidstat -r -p 157603 1
cat /proc/157603/status | egrep 'VmRSS|VmSize|VmHWM|Threads'
cat /proc/pressure/memory
cat /proc/meminfo | egrep 'MemTotal|MemAvailable|Swap'

如果输出中有:

{
  "type": "lock_futex_contention",
  "target": "pid=867 comm=containerd",
  "confidence": "confirmed",
  "summary": "Futex contention observed for pid=867 comm=containerd, max=10017291 us, waits=677"
}

解读:

  • containerd 出现最长约 10 秒 的 futex wait。
  • 等待次数 677 高于默认阈值 50
  • 从“futex 等待事件”角度看证据充分,所以是 confirmed
  • 但 futex wait 不一定等价于“锁竞争故障”。很多后台服务会用 futex 做条件变量、线程池空闲等待或事件等待。

建议复核:

sudo build/ebpf-sysdiag --scenario lock --pid 867 --duration 30 --output json
pidstat -w -p 867 1
sudo strace -f -ttT -p 867 -e futex

如果 containerd 没有卡顿、CPU 正常、业务没有受影响,这可能只是正常等待被识别为锁等待热点。

如果输出中有:

{
  "type": "syscall_latency",
  "target": "pid=10856 comm=ebpf-sysdiag",
  "confidence": "confirmed",
  "summary": "Slow syscalls observed for pid=10856 comm=ebpf-sysdiag, max=19999855 us, events=2385"
}

解读:

  • 这是工具观测到了自己。
  • ebpf-sysdiag 自己会执行 pollepoll_wait、文件写入、ringbuf 等待等阻塞 syscall。
  • 这些阻塞等待可能被 raw syscall 统计为慢调用。
  • 这类结果通常不应当作为系统根因。

临时规避:

sudo build/ebpf-sysdiag --scenario syscall --pid <目标进程PID> --duration 60 --output json
sudo build/ebpf-sysdiag --scenario syscall --comm <目标进程名> --duration 60 --output json

分析时应把 target=ebpf-sysdiag 的 syscall 结果视为观测噪声,除非正在专门测试工具自身。

8. 误报和漏报分析

误报通常表现为:

  • 空闲基线中大量 confirmed
  • target 指向长期空闲的后台服务。
  • syscall_latency 总是指向 ebpf-sysdiag
  • futex 等待被直接解释成锁故障,但业务没有卡顿。

处理方法:

# 缩小到目标进程
sudo build/ebpf-sysdiag --scenario all --pid <pid> --duration 60 --output json

# 缩小到目标 comm
sudo build/ebpf-sysdiag --scenario all --comm nginx --duration 60 --output json

# 提高采样,降低高频噪声
sudo build/ebpf-sysdiag --scenario syscall --sample-rate 10 --duration 60 --output json

漏报通常表现为:

  • 压测确认存在,但 results 为空。
  • 只有低置信度结果。
  • target 没有指向压测进程。

处理方法:

# 拉长窗口
sudo build/ebpf-sysdiag --scenario all --duration 120 --output json

# 降低阈值,确认采集链路
sudo build/ebpf-sysdiag --scenario syscall --duration 30 --output json --config config/default.yaml

# 去掉过滤条件
sudo build/ebpf-sysdiag --scenario all --duration 60 --output json

如果仍然没有结果,应检查压测是否经过当前探针覆盖的内核路径。例如缓存命中的文件读取可能不会产生明显块 I/O 延迟,用户态自旋锁也不一定进入 futex。

9. 推荐测试矩阵

编号 测试项 目的 通过标准
1 make clean && make 编译链路 无错误
2 --dry-run 配置解析 输出 dry-run ok
3 空闲 --scenario all 误报基线 无大量 confirmed
4 CPU 压力 + cpu CPU detector 出现 cpu_sched_latency
5 I/O 压力 + io I/O detector 出现 block_io_latency
6 内存压力 + memory memory detector 出现 memory_jitter_oom_risk
7 futex 压力 + lock lock detector 出现 lock_futex_contention
8 syscall storm + syscall syscall detector 出现 syscall_latency
9 混合压力 + all 多场景并行 结果类型和压力源匹配
10 --pid 过滤 过滤准确性 只输出目标 pid
11 --comm 过滤 过滤准确性 只输出目标 comm
12 5 到 10 分钟长跑 稳定性 无崩溃,资源不超限

10. 测试结论模板

建议每次测试后记录一份简短结论:

测试环境:
- kernel:
- arch:
- BTF:
- clang:
- bpftool:
- libbpf:

构建结果:
- make clean && make:
- dry-run:

功能结果:
- cpu:
- io:
- memory:
- lock:
- syscall:
- all:

输出质量:
- 是否有误报:
- 是否有漏报:
- target 是否准确:
- evidence 是否可解释:

资源开销:
- CPU:
- RSS:
- 对 workload 影响:

结论:
- confirmed:
- highly_suspected:
- possible:
- need_investigation:
- 后续需要修复/优化:

交叉验证建议

ebpf-sysdiag 输出的是异常证据链,不应脱离系统背景单独定性。建议按场景做交叉验证:

场景 建议配合工具/指标
CPU 调度延迟 toppidstat -wperf sched、cgroup CPU quota、runqueue 长度
I/O 延迟 iostat -xfioblktrace、设备队列深度、cgroup I/O throttling
内存压力 vmstatsar -B/proc/pressure/memory、reclaim/swap/OOM 日志
futex/锁竞争 perf lock、pthread uprobe、业务线程栈、火焰图
慢 syscall strace -Tperf trace、I/O 和锁事件时间线

已知盲区

  • 极短存活进程可能在一个采样窗口内退出,证据不足。
  • 中断上下文内的长时间 stall 不会完整归因到用户任务。
  • futex 等待不能直接识别 mutex owner。
  • I/O 当前主要是块设备层归因,不直接提供文件路径。
  • 当前未实现容器元数据解析,只保留进程上下文和预留 cgroup 字段。
  • 当前未采集调用栈,复杂根因仍需要结合 perf、trace-cmd 或额外 uprobe/kprobe。
  • 某些 tracepoint 名称受内核配置影响,缺失时对应场景无法 attach。
  • NO_CORE=1 兼容路径依赖 tracepoint 格式,不保证跨内核稳定。

开发指南

添加新场景

推荐步骤:

  1. 新增 bpf/<scenario>.bpf.c,实现最小探针集合。
  2. include/diag_types.h 中新增事件类型和事件结构。
  3. MakefileBPF_SRCS 中加入新 BPF 源文件。
  4. src/loader.c 中新增 skeleton open/load/attach 分支。
  5. src/event_parser.c 中解析新事件。
  6. src/analysis/detectors/ 中新增 detector。
  7. src/analysis/engine.c 中接入窗口聚合。
  8. src/output/ 中确认输出字段完整。
  9. 新增 config/<scenario>.yaml
  10. 新增 tests/reproduce/tests/integration/ 测试脚本。

BPF 开发约束

  • 优先使用 tracepoint/fentry/fexit 等稳定低开销探针。
  • 避免在高频路径无条件输出事件。
  • 先做过滤,再做采样,再做阈值判断。
  • ringbuf reserve 失败时只计数,不做复杂补偿逻辑。
  • map key 必须稳定,避免 request 生命周期结束后访问无效指针。
  • CO-RE 模式中只在确有必要时读取内核结构字段。
  • 新增字段要考虑 NO_CORE=1 下的兼容结构。

用户态开发约束

  • loader 只加载被启用的场景。
  • detector 只负责诊断逻辑,不直接做输出格式化。
  • output 层只做格式化,不改变诊断含义。
  • 资源守护逻辑必须保持保守,宁可提前退出也不要让工具成为故障源。

故障定位流程建议

一次典型排查可以这样执行:

make clean && make
sudo build/ebpf-sysdiag --scenario all --duration 60 --output json --output-file report.json

如果报告为空:

  1. 确认 workload 在采集窗口内确实触发异常。
  2. 降低对应阈值,例如 syscall_latency_us_p99io_block_latency_us_p99
  3. 去掉 PID/comm 过滤。
  4. 拉长 --duration
  5. 单独启用目标场景,排除其他场景 attach 干扰。

如果加载失败:

  1. 执行 make check-env
  2. 执行 tools/check_btf.sh
  3. 确认 sudo 权限。
  4. 检查目标内核 tracepoint 是否存在,例如 /sys/kernel/tracing/events/...
  5. 使用 make clean && BPFTOOL=/path/to/bpftool make 验证 bpftool 路径。

如果输出过多:

  1. 提高阈值。
  2. 使用 --sample-rate N
  3. 使用 --pid--comm
  4. 缩短 --duration
  5. 单独启用一个场景。

验收标准

项目当前建议按以下标准验收:

  • BPF 程序可以在目标内核加载,无 verifier 错误。
  • make clean && make 在目标机器上成功。
  • --scenario all 可以运行并输出合法 JSON。
  • 五个单独场景均能独立运行。
  • --dry-run 可解析默认配置。
  • SIGINT/SIGTERM 能干净退出。
  • 正常场景下 RSS 小于 200 MB
  • 默认采样下 CPU 开销目标小于单核 5%
  • 报告中每个结论都包含指标值、阈值和建议。

相关文档

  • DESIGN.md:架构和设计原则。
  • TEST.md:测试计划和复现场景。
  • docs/architecture.md:运行路径概览。
  • docs/diagnosis_rules.md:各场景诊断规则。
  • docs/bpf_maps.md:BPF map 说明。
  • docs/compatibility.md:内核和架构兼容性说明。
  • docs/performance.md:性能基线建议。
  • docs/blind_spots.md:观测盲区。

License

项目使用 LICENSE 中声明的许可证。BPF 程序声明为 Dual BSD/GPL,以满足内核 helper 和加载要求。

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

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