- 测试
- 云原生
- 质量保障
【免费下载链接】origin
Conformance test suite for OpenShift
导读:本文以
origin(OpenShift Conformance Test Suite)仓库内 vendored 的 github.com/prometheus/procfs 文档为主线,系统讲解如何用 Go 从 Linux 伪文件系统/proc与/sys中读取系统、内核与进程指标。读完本文,你将掌握 procfs 的包组织方式、FS挂载点初始化、Stat()系统级统计与Proc进程级信息的调用方法,并了解其单元测试夹具(ttar fixtures)的构建与更新流程,为在 OpenShift 相关工具链中集成指标采集提供可复用的代码范式。
库定位:一个面向指标采集的伪文件系统读取库
procfs是一个提供函数式 API 的 Go 库,用于从 Linux 的伪文件系统/proc和/sys中检索系统(system)、内核(kernel)与进程(process)指标。在/proc与/sys下,内核以文件形式暴露运行时状态:CPU 时间片、内存用量、磁盘统计、网络连接、进程命令行等都以文本文件形式呈现,procfs将这些文本解析为类型化的 Go 结构体,是 Prometheus 生态中 node_exporter 等组件的核心依赖。
在origin仓库中,该库以间接依赖(indirect)的形式被 vendored,版本为v0.19.2(见 go.mod 第 346 行),其下包完整保留在 vendor/github.com/prometheus/procfs 目录中。这意味着 OpenShift 测试工具链中涉及系统指标读取的代码可以直接引用该库的 API,而不必自行解析/proc下的原始文本。
注意:上游 README 明确警告,该库仍在积极演进中(work in progress),其 API 可能在没有向后兼容警告的情况下发生破坏性变更(backwards-incompatible),使用前需自行评估风险。本文所有 API 描述均以当前仓库所 vendored 的 v0.19.2 源码为准。
核心用法:从挂载点初始化到指标读取
procfs的使用遵循一条固定链路:初始化文件系统挂载点 → 调用读取函数 → 得到类型化结构体。所有数据读取都从/proc(部分子包还需要/sys)出发。
系统级统计:/proc/stat
CPU 统计来自/proc/stat,由根包(root package)提供。典型用法如下(与上游 README 中的示例一致):
fs, err := procfs.NewFS("/proc") stats, err := fs.Stat()NewFS(mountPoint string)返回一个FS类型,它封装了/proc的挂载路径;如果挂载点目录无法读取或并非目录,将返回错误(见 fs.go)。fs.Stat()返回Stat结构体,其中包含系统级统计信息(见 stat.go):
| 字段 | 含义 |
|---|---|
BootTime | 自 Epoch 起的开机时间(秒) |
CPUTotal | 汇总的 CPU 统计(CPUStat) |
CPU | 按 CPU ID 索引的逐核统计(map[int64]CPUStat) |
IRQTotal/IRQ | 中断处理次数总数与各编号中断次数 |
ContextSwitches | 上下文切换次数 |
ProcessCreated | 已创建进程数 |
ProcessesRunning/ProcessesBlocked | 当前运行/阻塞(等待 IO)的进程数 |
SoftIRQTotal/SoftIRQ | softirq 调度总数与细分统计 |
CPUStat覆盖User、Nice、System、Idle、Iowait、IRQ、SoftIRQ、Steal、Guest、GuestNice共 10 个时间分量,且解析时统一除以userHZ换算为秒(见 stat.go 的归一化逻辑),调用方拿到的直接是秒级时间值,无需再关心内核时钟频率。
需要双文件系统的子包:以blockdevice为例
部分子包(如blockdevice)同时需要/proc和/sys两个文件系统的访问权:
fs, err := blockdevice.NewFS("/proc", "/sys") stats, err := fs.ProcDiskstats()以磁盘块设备为例,/proc/diskstats提供逐设备的读写统计,而设备号的语义解析需要/sys下的块设备信息,因此该子包的构造函数同时接收两个挂载点。类似的"双挂载点"模式也体现在 selinuxfs(/sys/fs/selinux)、configfs(/sys/kernel/config)等特殊文件系统的默认挂载点常量上(见 internal/fs/fs.go)。
包组织原则:按数据来源与信息类型分层
上游 README 明确了整个项目的组织规则:包按(1)数据来源是/proc还是/sys(或两者)与(2)所检索的信息类型两个维度划分:
- 根包
procfs:覆盖大多数进程信息,例如 proc.go 中的Proc类型及其方法; - 子包
blockdevice:提供磁盘等块设备信息,需要同时访问/proc与/sys。
从当前 vendor 目录的文件清单可以直观印证这一分层:根包下并存着stat.go(系统统计)、meminfo.go(内存)、loadavg.go(负载)、cpuinfo.go(CPU 信息)、mdstat.go(软件 RAID)、mountstats.go(挂载统计)等面向不同信息类型的解析文件;进程维度则对应proc_stat.go、proc_status.go、proc_io.go、proc_limits.go、proc_maps.go、proc_smaps.go、proc_environ.go、proc_cgroup.go、proc_psi.go等一批按/proc/<pid>/下文件名一一对应的模块;网络维度另有net_dev.go、net_tcp.go、net_udp.go、net_unix.go、net_route.go、net_conntrackstat.go等。这种"文件即模块"的组织方式让调用方可以按需引入,精确对应/proc中的真实文件。
深入进程维度:Proc类型与常用入口
除系统级统计外,procfs还提供面向单进程的 API。Proc结构体只保留进程 ID(PID)并持有FS引用(见 proc.go),其构造入口包括:
procfs.Self():读取当前进程自身,内部通过解析/proc/self符号链接拿到自身 PID(见 proc.go 与 proc.go);procfs.NewProc(pid):按 PID 定位任意进程(内部同样走默认挂载点/proc);procfs.AllProcs():返回当前/proc下全部可用进程的列表;fs.Proc(pid):在已初始化的FS上按 PID 取进程;fs.Self()同理。
进程信息同样通过类型化方法暴露,例如:
p, err := procfs.Self() if err != nil { log.Fatalf("could not get process: %s", err) } stat, err := p.Stat() if err != nil { log.Fatalf("could not get process stat: %s", err) } fmt.Printf("command: %s\n", stat.Comm) fmt.Printf("cpu time: %fs\n", stat.CPUTime()) fmt.Printf("vsize: %dB\n", stat.VirtualMemory()) fmt.Printf("rss: %dB\n", stat.ResidentMemory())(该示例出自 doc.go 的包文档,可直接运行验证。)其中Comm为可执行文件名,CPUTime()、VirtualMemory()、ResidentMemory()分别基于进程 CPU 时间、虚拟内存与常驻内存数据计算得到。
关于挂载点的两个实用细节
FS类型在根包中被定义为{ proc fs.FS; isReal bool }的包装结构(见 fs.go),构造时不仅校验挂载点目录可读,还会通过isRealProc判断该挂载点是否为真实的/proc(用于区分容器内非真实挂载场景)。- 常量
DefaultMountPoint = "/proc"与SectorSize = 512(Linux 块 I/O 扇区字节大小)由根包导出;NewDefaultFS()可直接使用默认挂载点快速初始化。
构建与测试:无独立二进制,靠单元测试与 ttar 夹具
procfs定位为被其他应用内嵌的库(library),不产出可分发的独立二进制文件——这一点由根包Makefile中的空build目标体现(见 Makefile)。但绝大多数 API 都带有单元测试,可通过make test运行。
测试夹具:ttar 归档与自动解包
procfs的测试依赖一组来自真实/proc与/sys的示例文件作为 fixture,它们被打包为一个 ttar 归档文件(testdata/fixtures.ttar),并在测试过程中自动解包:
make test其背后的机制是 Makefile 中的规则%/.unpacked: %.ttar:通过仓库自带的./ttar工具把fixtures.ttar解压到testdata/fixtures/目录,并生成.unpacked标记文件;test目标依赖该标记文件,确保测试前 fixture 已就绪(见 Makefile 与 Makefile)。
更新测试夹具的官方流程
当需要新增或修改测试数据(例如内核新增了某个/proc字段)时,按以下四步操作:
# 1. 移除旧目录并解包,得到最新的 fixture 目录 rm -rf testdata/fixtures make test # 2. 直接修改 testdata/fixtures/ 下的文件,模拟期望的 /proc、/sys 内容 # 3. 重新打包为新的 fixtures.ttar make update_fixtures # 4. 用 git diff 校验变更是否符合预期 git diff testdata/fixtures.ttar其中make update_fixtures内部执行./ttar -c -f testdata/fixtures.ttar -C testdata/ fixtures/,即把testdata/fixtures/目录重新归档(见 Makefile)。这一"真实样本文件驱动测试"的模式,保证了解析逻辑始终以 Linux 内核真实输出为基准进行回归验证。
在 OpenShift 测试套件中的落地意义
origin仓库将prometheus/procfs v0.19.2作为间接依赖 vendored(见 go.mod),并在测试数据中保留了相关引用(如 test/extended/util/compat_otp/testdata/bindata.go)。对 OpenShift 测试工具链而言,这意味着:
- 指标采集可复用现成解析器:无论是集群节点监控、e2e 测试中的资源观察,还是
resourcewatch、monitor等模块需要读取进程/系统状态时,都可以直接复用/proc文本解析能力,避免重复造轮子; - 解析行为有测试兜底:ttar 夹具 +
make test的回归体系确保了各字段解析在跨内核版本演进时的稳定性; - API 有明确的演进风险提示:上游"API 可能破坏性变更"的警告,提醒集成方在升级该依赖时关注解析结构体的字段变化。
综上,procfs的核心价值在于:以"挂载点初始化 + 类型化读取"的统一抽象,屏蔽了 Linux/proc、/sys文本格式的解析细节;其"按文件分模块、真实样本做夹具"的设计,也使其成为系统指标采集类 Go 库中值得借鉴的工程范式。
- 测试
- 云原生
- 质量保障
【免费下载链接】origin
Conformance test suite for OpenShift
相关推荐
procfs 库完全指南:从 /proc 与 /sys 伪文件系统读取系统指标(Prometheus 生态 Go 实现)
procfs 库完全指南:从 /proc 与 /sys 伪文件系统读取系统指标(Prometheus 生态 Go 实现) 导读 procfs 是 Prometh
云原生集群管理虚拟化多集群深入解读 prometheus/procfs:在 Grafana Tempo 中读取 /proc 与 /sys 系统指标的标准库
深入解读 prometheus/procfs:在 Grafana Tempo 中读取 /proc 与 /sys 系统指标的标准库 本文以 Grafana Tem
后端可观测性链路追踪Loop 如何管理 macOS 窗口:5 分钟从触发键到自定义主题的完整指南
Loop 如何管理 macOS 窗口:5 分钟从触发键到自定义主题的完整指南 Loop 是一款免费开源的 macOS 窗口管理工具。如果你也习惯靠鼠标拖拽窗口边
桌面应用
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考