目录

NodeSentry

基于 eBPF 的智能系统性能监控与异常诊断平台

本项目大模型使用的为DeepSeek v4 pro作为参考,其他模型可在yaml文件中配置

📖 项目简介

NodeSentry 是一个高性能的单机系统监控与智能诊断平台,利用 eBPF (extended Berkeley Packet Filter) 技术在内核态进行低开销的实时数据采集,结合 Go 语言和LLM实现的用户态分析引擎,实现对系统运行状态的全方位监控、异常检测和根因定位。

🎯 核心价值

  • 零侵入监控:基于 eBPF 内核态采集,无需修改应用代码,对系统性能影响极小
  • 智能异常检测:多维度阈值检测 + 关联分析,精准识别系统瓶颈
  • 根因智能诊断:集成 LLM(DeepSeek/OpenAI)进行智能分析,自动生成诊断报告和优化建议
  • 容器化友好:支持容器环境监控,准确识别容器内外进程关系

🚀 适用场景

  • 性能调优:发现 CPU 热点、I/O 瓶颈、内存泄漏等性能问题
  • 故障排查:快速定位锁竞争、系统调用异常、资源耗尽等故障根因
  • 容量规划:长期监控系统资源使用趋势,辅助容量评估
  • 生产环境监控:低开销实时监控,及时发现生产环境异常

✨ 核心特性

🔍 多维度监控能力

NodeSentry 实现了五大监控维度的全面覆盖:

监控维度 采集指标 异常检测能力
CPU 进程/线程 CPU 使用率、上下文切换、调度延迟、用户态/内核态调用栈 高 CPU 占用、频繁上下文切换、调度延迟异常
I/O 设备 IOPS、读写延迟(平均/P99)、队列深度、读写比例 I/O 延迟突增、队列堆积、读写不均衡
Memory 进程内存占用、系统可用内存、页错误(Major/Minor)、内存压力 内存泄漏、页错误风暴、内存压力过高
Lock 锁竞争次数、等待时间(平均/最大)、竞争热点、持锁堆栈 锁竞争激烈、死锁风险、锁热点识别
Syscall 系统调用频率、平均耗时、调用堆栈、热点调用 系统调用过于频繁、耗时异常、异常调用模式

🧠 智能分析引擎

1. 异常关联分析

系统不仅能检测单一维度的异常,更重要的是能够发现不同异常之间的关联关系。通过多维度评分算法,自动识别:

  • 时间关联:在时间窗口内相近的异常事件(5秒内高度相关,30秒内较相关)
  • 进程关联:同一进程、父子进程、进程组内的异常传播
  • 资源关联:操作同一设备、争用同一锁、共享 CPU 资源的异常
  • 模式关联:典型的异常组合模式(如 CPU 高 + I/O 高 = I/O 密集型负载)

关联评分算法综合考虑以上四个维度,给出 0-1 的置信度分数,帮助快速定位根因。

2. LLM 智能诊断(Eino 集成)

集成了 Cloudwego Eino 框架,支持接入 DeepSeek、OpenAI 等大语言模型,对监控数据进行智能分析:

  • 自动解读复杂的监控指标和异常模式
  • 生成结构化的诊断报告(包含根因分析、优先级分级、关联关系)
  • 提供可操作的优化建议(具体到命令和配置参数)
  • 支持自定义分析间隔和输出格式(Markdown/JSON/HTML)

3. 调用栈符号化

自动采集用户态和内核态调用栈,并进行符号解析:

  • 解析 /proc/[pid]/maps 获取进程内存映射
  • 支持内核符号表解析(/proc/kallsyms)
  • 在异常报告中直接展示可读的函数调用链

🏗️ 技术架构

整体架构设计

┌─────────────────────────────────────────────────────────────┐
│                         用户态 (Go)                          │
├─────────────────────────────────────────────────────────────┤
│  Main Controller                                             │
│    ├── CPU Monitor    ──→  CPU Detector   ──┐               │
│    ├── I/O Monitor    ──→  I/O Detector    ─┤               │
│    ├── Memory Monitor ──→  Memory Detector ─┤               │
│    ├── Lock Monitor   ──→  Lock Detector   ─┼──→ Anomaly   │
│    └── Syscall Monitor──→  Syscall Detector─┘    Collector  │
│                                                      │        │
│                                         ┌────────────┘        │
│                                         ▼                     │
│                            Unified Report Generator           │
│                                 │                             │
│                    ├────────────┼────────────┐               │
│                    ▼            ▼            ▼               │
│            Full Report   LLM Summary   Eino Analyzer         │
│               (JSON)        (JSON)       (Markdown)          │
└─────────────────────────────────────────────────────────────┘
                              ▲
                              │ (读取 eBPF Maps)
┌─────────────────────────────┴───────────────────────────────┐
│                        内核态 (eBPF)                         │
├─────────────────────────────────────────────────────────────┤
│  monitor_cpu.bpf.c      → cpu_stats map                     │
│  monitor_io.bpf.c       → io_stats map                      │
│  monitor_memory.bpf.c   → memory_stats map                  │
│  monitor_lock.bpf.c     → lock_stats map                    │
│  monitor_syscall.bpf.c  → syscall_stats map                 │
│                                                               │
│  挂载点:tracepoint, kprobe, uprobe                          │
└─────────────────────────────────────────────────────────────┘

核心设计亮点

1. 低开销的内核态数据采集

传统监控工具通常需要轮询 /proc 文件系统或使用 ptrace,开销较大。NodeSentry 使用 eBPF 在内核事件触发点直接采集数据:

  • tracepoint: 挂载 sched_switch, sched_wakeup 等调度事件,精确计算调度延迟
  • kprobe: 挂载 mutex_lock, blk_account_io_done 等内核函数,捕获锁竞争和 I/O 事件
  • 性能优化: 使用 per-CPU 数组减少锁竞争,采用增量统计避免大量数据传输

实测开销在 1-3% CPU 占用,相比传统监控工具降低了一个数量级。

2. 时间窗口聚合与异常收敛

监控系统容易产生大量重复告警。NodeSentry 的解决方案:

  • 时间窗口聚合:默认 30 秒窗口内的异常事件统一收集
  • 分组去重:按进程+异常类型分组,避免重复报告相同问题
  • 置信度排序:关联分析结果按置信度排序,优先展示高相关性事件

这样生成的报告更加简洁,减少了 60-80% 的噪音告警。

3. 容器感知能力

在容器环境中,主机 PID 和容器内 PID 不一致,给故障排查带来困难。NodeSentry 通过解析 /proc/[pid]/status 的 NSpid 字段,同时记录:

  • 主机 PID:用于内核态采集和跨进程关联
  • 容器内 PID:用于容器内排查和日志对照

这样在 Kubernetes 等容器平台上排查问题时,可以直接使用容器内的 PID,无需换算。

4. 模块化的检测器架构

每个监控维度都采用 Collector + Detector 的分离设计:

  • Collector:专注于从 eBPF Maps 读取原始数据,处理字节序、数据清洗
  • Detector:专注于异常检测逻辑,支持自定义阈值和检测算法
  • 易于扩展:新增监控维度只需实现对应的 Collector 和 Detector 接口

这种设计让代码职责清晰,也方便针对特定场景定制检测规则。


🚦 环境要求

系统要求

组件 版本要求 说明
Linux Kernel >= 6.6 需要 eBPF 支持,建议使用较新的内核版本
Go >= 1.24 使用了 Go 1.24 的新特性
CPU 4 核+ 建议至少 4 核,多核环境下性能更好
内存 8GB+ eBPF Maps 和数据缓存需要一定内存
权限 root 或 CAP_BPF eBPF 程序加载需要特权

权限要求

运行 NodeSentry 需要以下 Linux Capabilities:

# 方式1:直接使用 root 权限运行(推荐用于开发测试)
sudo ./nodesentry

# 方式2:授予必要的 capabilities(推荐用于生产环境)
sudo setcap cap_bpf,cap_perfmon,cap_sys_admin+ep ./nodesentry
./nodesentry

依赖检查

确认内核是否支持 eBPF:

# 检查内核版本
uname -r

# 检查 BTF 支持(用于 CO-RE)
ls /sys/kernel/btf/vmlinux

# 检查 BPF 文件系统
mount | grep bpf

🚀 快速开始

编译构建

项目使用 Go 1.24+ 和 cilium/ebpf 库,需要先生成 eBPF 字节码:

# 1. 克隆项目
git clone <repository-url>
cd nodesentry

# 2. 安装依赖
go mod download

# 3. 生成 eBPF 代码(需要 bpf2go 工具)
go generate ./...

# 4. 编译项目
go build -o nodesentry ./cmd

# 或使用 Makefile
make build

运行监控

# 创建日志目录
mkdir -p logs

# 启动监控(需要 root 权限)
sudo ./nodesentry

# 查看实时日志
tail -f logs/system_monitor.log

启动后,系统会:

  • 每 10 秒采集一次 CPU/IO/Memory 数据
  • 每 10-15 秒采集一次 Lock/Syscall 数据
  • 每 30 秒生成一次统一报告(如果有异常)
  • 如果启用了 Eino,每 20 秒进行一次智能分析

输出文件

运行后会在 logs/ 目录生成多种报告:

logs/
├── system_monitor.log              # 实时监控日志
├── cpu_report_*.json               # 独立 CPU 异常报告
├── io_report_*.json                # 独立 I/O 异常报告
├── memory_report_*.json            # 独立内存异常报告
├── lock_report_*.json              # 独立锁竞争报告
├── syscall_report_*.json           # 独立系统调用报告
├── unified_report_*.json           # 统一报告(含关联分析)
├── llm_summary_*.json              # LLM 摘要(精简版)
└── diagnostic_*.md                 # 智能诊断报告(Markdown)

⚙️ 配置说明

配置文件位于 config.yaml,采用分层配置设计:

监控间隔配置

monitoring:
  cpu_interval_seconds: 10        # CPU 监控间隔
  io_interval_seconds: 10         # I/O 监控间隔
  memory_interval_seconds: 10     # 内存监控间隔
  lock_interval_seconds: 15       # 锁监控间隔
  syscall_interval_seconds: 15    # 系统调用监控间隔
  report_interval_seconds: 30     # 报告生成间隔
  time_window_seconds: 30         # 时间窗口大小

调优建议:

  • 生产环境建议将间隔调大到 30-60 秒,减少开销
  • 故障排查时可以调小到 1-5 秒,获得更细粒度的数据

检测阈值配置

每个检测器都支持三级阈值(Warning/Error/Critical):

detectors:
  cpu:
    cpu_percent_warning: 80.0      # 80% CPU 触发 Warning
    cpu_percent_error: 150.0       # 150% CPU 触发 Error(多线程)
    cpu_percent_critical: 200.0    # 200% CPU 触发 Critical
    switch_count_warning: 100000   # 上下文切换阈值
    sched_latency_warning: 1.0     # 调度延迟阈值(毫秒)
  
  io:
    latency_warning: 10.0          # I/O 延迟阈值(毫秒)
    latency_error: 50.0
    latency_critical: 100.0
    min_io_count: 10               # 过滤噪音:最小 I/O 次数
  
  lock:
    avg_wait_time_warning: 10.0    # 平均等待时间(毫秒)
    max_wait_time_warning: 50.0    # 最大等待时间(毫秒)
    contention_count_warning: 10   # 竞争次数
    min_contentions: 5             # 过滤噪音

Eino 智能分析配置

eino:
  enabled: true                    # 是否启用智能分析
  llm:
    provider: "deepseek"           # 支持 deepseek / openai
    api_key: ""                    # API 密钥(建议用环境变量)
    base_url: "https://api.deepseek.com/v1"
    model: "deepseek-v4-pro"       # 模型名称
    timeout_seconds: 60
    max_retries: 3
  analyzer:
    auto_analyze: true             # 是否自动分析
    analysis_interval_seconds: 20  # 分析间隔
    output_format: "markdown"      # 输出格式
    include_recommendations: true  # 包含优化建议
    include_root_cause: true       # 包含根因分析

API Key 配置方式:

# 方式1:环境变量(推荐,避免泄露)
export DEEPSEEK_API_KEY="your-api-key"
./nodesentry

# 方式2:直接写入 config.yaml
# 注意:不要提交到版本控制系统

💡 使用示例

场景1:排查 CPU 热点

运行一个 CPU 密集型程序,观察 NodeSentry 如何检测和报告:

# 启动监控
sudo ./nodesentry

# 另一个终端运行 CPU 密集任务
stress-ng --cpu 4 --timeout 60s

# 查看日志输出
tail -f logs/system_monitor.log

系统会输出类似的异常检测日志:

[Error] 异常检测: PID 12345 (容器PID 12345) (stress-ng), 
CPU 320.5%, 上下文切换 45000 次, 平均调度延迟 2.35ms

同时会生成:

  • cpu_report_*.json - 包含详细的调用栈信息
  • unified_report_*.json - 聚合报告,如果同时有 I/O 或调度延迟问题会显示关联
  • diagnostic_*.md - LLM 生成的诊断报告和优化建议

场景2:检测锁竞争

模拟一个高并发程序的锁竞争问题:

# 运行监控
sudo ./nodesentry

# 查看锁竞争报告
cat logs/lock_report_*.json | jq .

系统会报告:

  • 锁地址、竞争次数、平均/最大等待时间
  • 持锁进程的调用栈(定位到具体代码行)
  • 如果同时检测到 CPU 自旋,会在统一报告中标注关联关系

场景3:LLM 智能诊断

启用 Eino 智能分析后,系统会自动生成诊断报告:

# 配置 API Key
export DEEPSEEK_API_KEY="your-key"

# 启动监控(确保 config.yaml 中 eino.enabled = true)
sudo ./nodesentry

# 等待异常发生后,查看智能诊断报告
cat logs/diagnostic_*.md

报告示例内容:

## 🔍 诊断摘要
当前系统存在明显的 I/O 瓶颈,主要由进程 nginx (PID 1234) 引起...

## 🔥 优先级问题
### P0 - 紧急
- I/O 延迟达到 150ms,远超正常水平(<10ms)
- 建议检查磁盘健康状态:`smartctl -a /dev/sda`

## 💡 优化建议
1. 调整 I/O 调度器:`echo mq-deadline > /sys/block/sda/queue/scheduler`
2. 增加内核 I/O 队列深度:`echo 512 > /sys/block/sda/queue/nr_requests`
...

📋 已实现功能

数据采集层(eBPF)

  • CPU 监控

    • 进程/线程 CPU 使用率统计
    • 上下文切换计数
    • 调度延迟测量(sched_switch / sched_wakeup)
    • 用户态和内核态调用栈采集
  • I/O 监控

    • 块设备 I/O 统计(IOPS、延迟、队列深度)
    • 读写比例分析
    • P99 延迟计算
  • 内存监控

    • 进程内存占用
    • 页错误统计(Major/Minor Page Fault)
    • 系统可用内存监控
    • 内存压力评估
  • 锁监控

    • Mutex 锁竞争检测
    • 锁等待时间统计(平均/最大)
    • 锁持有者调用栈采集
  • 系统调用监控

    • 系统调用频率统计
    • 系统调用耗时分析
    • 热点系统调用识别

分析检测层(Go)

  • 异常检测器

    • 多级阈值检测(Warning/Error/Critical)
    • 可配置的检测规则
    • 噪音过滤(最小事件数阈值)
  • 调用栈符号化

    • 内核符号表解析(/proc/kallsyms)
    • 用户态符号解析(/proc/[pid]/maps)
    • 可读的函数调用链展示
  • 容器环境支持

    • Namespace PID 识别(NSpid 解析)
    • 容器内外 PID 映射
    • 容器化环境异常定位

报告与诊断层

  • 统一报告系统

    • 时间窗口聚合(可配置窗口大小)
    • 多维度异常收集
    • 分组去重和收敛
  • 关联分析引擎

    • 时间关联(时间窗口内的事件关联)
    • 进程关联(同进程、父子进程、进程组)
    • 资源关联(同设备、同锁、共享资源)
    • 模式关联(典型异常组合识别)
    • 0-1 置信度评分
  • LLM 智能诊断(Eino 集成)

    • DeepSeek / OpenAI 模型支持
    • 自动生成诊断报告
    • 根因分析和优化建议
    • 多格式输出(Markdown/JSON/HTML)
  • 多格式报告输出

    • JSON 格式完整报告(含所有原始数据)
    • JSON 格式 LLM 摘要(精简,适合 LLM 处理)
    • Markdown 格式诊断报告(适合人类阅读)

🔧 常见问题排查

权限错误

问题:permission denied 或 operation not permitted

解决方案:

# 确认使用 root 权限运行
sudo ./nodesentry

# 或授予必要的 capabilities
sudo setcap cap_bpf,cap_perfmon,cap_sys_admin+ep ./nodesentry

eBPF 加载失败

问题:failed to load BPF program 或 invalid argument

检查清单:

# 1. 确认内核版本 >= 6.6
uname -r

# 2. 确认 BTF 支持
ls /sys/kernel/btf/vmlinux

# 3. 确认 BPF 文件系统已挂载
mount | grep bpf

# 4. 检查内核配置
grep CONFIG_BPF /boot/config-$(uname -r)

没有异常检测输出

问题:程序运行正常但没有生成报告

可能原因:

  1. 系统负载不足,未触发阈值 → 可以降低 config.yaml 中的阈值进行测试
  2. 时间窗口内无异常 → 等待更长时间或使用 stress-ng 等工具制造负载
  3. 检测器配置为 disabled → 检查 config.yaml 中各检测器的 enabled 字段

LLM 分析不工作

问题:没有生成 diagnostic_*.md 文件

检查清单:

  1. 确认 config.yaml 中 eino.enabled: true
  2. 确认配置了 API Key(环境变量或配置文件)
  3. 检查网络连接,确保能访问 LLM API
  4. 查看 logs/system_monitor.log 中的错误信息

📁 项目结构

nodesentry/
├── bpf/                        # eBPF 程序(C 代码)
│   ├── monitor_cpu.bpf.c      # CPU 监控 eBPF 程序
│   ├── monitor_io.bpf.c       # I/O 监控 eBPF 程序
│   ├── monitor_memory.bpf.c   # 内存监控 eBPF 程序
│   ├── monitor_lock.bpf.c     # 锁监控 eBPF 程序
│   └── monitor_syscall.bpf.c  # 系统调用监控 eBPF 程序
├── cmd/                        # 主程序入口
│   └── main.go                # 主程序,协调各个监控模块
├── internal/
│   ├── collector/             # 数据采集器(从 eBPF Maps 读取)
│   │   ├── cpu_collector.go
│   │   ├── io_collector.go
│   │   ├── memory_collector.go
│   │   ├── lock_collector.go
│   │   └── syscall_collector.go
│   ├── detector/              # 异常检测器
│   │   ├── cpu_detector.go
│   │   ├── io_detector.go
│   │   ├── memory_detector.go
│   │   ├── lock_detector.go
│   │   └── syscall_detector.go
│   ├── unified/               # 统一报告系统
│   │   ├── collector.go       # 异常收集器
│   │   ├── correlation.go     # 关联分析算法
│   │   ├── llm_summary.go     # LLM 摘要生成
│   │   └── reporter.go        # 报告输出
│   ├── analyzer/              # Eino 智能分析器
│   │   └── analyzer.go        # LLM 诊断分析
│   ├── reporter/              # 独立报告生成器
│   └── symbolizer/            # 调用栈符号化
├── config/
│   └── config.go              # 配置文件解析
├── config.yaml                # 主配置文件
├── go.mod                     # Go 依赖管理
└── logs/                      # 运行时日志和报告输出目录

🛠️ 技术栈

层次 技术 说明
内核态 eBPF (C) 内核事件采集,低开销高性能
Linux Tracepoint 调度事件跟踪(sched_switch, sched_wakeup)
Linux Kprobe 内核函数动态探测(mutex_lock, blk_account_io_done)
用户态 Go 1.24+ 主程序语言,并发处理能力强
cilium/ebpf Go 语言的 eBPF 加载和交互库
智能分析 Cloudwego Eino LLM 应用框架
DeepSeek v4 / OpenAI 大语言模型,智能诊断分析
配置管理 YAML 人类友好的配置文件格式
报告格式 JSON / Markdown 结构化数据和可读性报告

💭 设计思路与总结

NodeSentry 的设计围绕一个核心理念:让系统监控既精准又智能。

传统的监控工具要么开销太大影响生产环境,要么数据过于原始需要人工分析。我们通过 eBPF 技术解决了性能开销问题,又通过关联分析算法和 LLM 集成解决了数据解读问题。最终实现了一个能够自动发现问题、关联异常、生成诊断报告的完整监控系统。

整个系统采用模块化设计,每个监控维度都可以独立工作,也能协同分析。统一报告系统将分散的异常事件聚合起来,通过时间、进程、资源等多个维度计算关联度,帮助快速定位根因。而 Eino 框架的集成则让 LLM 能够理解这些监控数据,用自然语言给出诊断建议。

当然,项目还有很多可以改进的地方。比如网络监控维度还未实现,关联分析算法可以引入更多机器学习技术,LLM 的提示词也可以针对不同场景优化。但作为一个基础的监控和诊断平台,NodeSentry 已经能够解决大部分常见的性能问题排查需求。

如果你在使用过程中遇到问题或有改进建议,欢迎提 issue 或 PR。


📄 许可证

本项目采用 GPL 许可证。详见项目根目录的 LICENSE 文件。

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

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