
Telegraf slab 输入插件详解解析 /proc/slabinfo 监控内核 Slab 缓存内存占用【免费下载链接】telegrafAgent for collecting, processing, aggregating, and writing metrics, logs, and other arbitrary data.项目地址: https://gitcode.com/GitHub_Trending/te/telegrafTelegraf 的slab输入插件专为 Linux 系统设计它通过解析/proc/slabinfo文件收集内核 Slab 缓存kmalloc、文件系统缓存、驱动对象等的内存占用情况并以带_size后缀的字段形式输出每个 slab 类型的内存消耗字节数。本文基于 plugins/inputs/slab/README.md 与对应源码完整讲解该插件的配置方式、sudo 权限打通方法、指标命名规则以及其底层解析实现与测试验证逻辑帮助你把它可靠地纳入服务器内存监控体系。插件定位与适用前提slab插件用于收集 Slab 缓存 条目的内存消耗详情。Slab 是 Linux 内核的小对象内存分配器内核为每类频繁分配的对象如kmalloc_1024这类通用分配器以及xfs_inode、ext4_inode_cache等内核子系统和驱动对象维护独立的 slab 缓存。监控这些数据可以回答“哪些内核对象在持续吃掉内存”这类问题对排查内存缓慢增长、slab 泄漏尤为有用。该插件自 Telegraf v1.23.0 引入可参见 CHANGELOG.md 中 “Add slab metrics input plugin” 条目关键适用前提如下仅支持 Linux。插件通过构建标签隔离平台行为slab.go 头部带有//go:build linux仅在 Linux 上编译真实采集逻辑而非 Linux 平台编译的是 slab_notlinux.go其Init()只会打出一条Current platform is not supported的警告日志Gather()直接空实现。因此在非 Linux 系统上启用该插件不会报错但也不会有任何指标产出。需要/proc/slabinfo可读。由于该文件默认只有 root 可读运行 Telegraf 的用户必须具备读取权限通常借助 sudo 实现见下文。支持HOST_PROC环境变量。插件读取的文件路径为path.Join(internal.GetProcPath(), slabinfo)见 slab.go 的init()。GetProcPath()定义在 internal/env.go 中若设置了HOST_PROC环境变量则返回其值否则回退到/proc。这一机制便于在容器内监控宿主机把宿主机的/proc挂载进容器后指定HOST_PROC即可。配置方式slab插件没有可配置项官方样例配置 sample.conf 全部内容如下# Get slab statistics from procfs # This plugin ONLY supports Linux [[inputs.slab]] # no configuration - please see the plugins README for steps to configure # sudo properly也就是说在telegraf.conf中加入一个空的[[inputs.slab]]段即可启用采集真正的工作量在于配置 sudo 权限。与 Telegraf 其他插件一样它同样支持全局配置选项例如修改 measurement/field/tag、创建插件别名、显式指定插件顺序等这些通用能力说明见 docs/CONFIGURATION.md 的 Plugins 章节。Sudo 权限配置核心步骤/proc/slabinfo只对 root 开放因此插件采用“以 root 身份执行cat”的方式读取文件。从源码 slab.go 的runCmd()可以看到实际行为execCmd : exec.Command(cmd, args...) if os.Geteuid() ! 0 ss.useSudo { execCmd exec.Command(sudo, append([]string{-n, cmd}, args...)...) }即当 Telegraf 不是以 rooteuid ! 0运行且useSudo为 trueinit()中默认置为 true时插件执行的是sudo -n /bin/cat slabinfo 路径。-n参数意味着非交互模式如果 sudoers 要求输入密码命令会直接失败因此必须配置免密规则。假设 Telegraf 以用户telegraf运行且未使用HOST_PROC在 sudoers 文件中添加telegraf ALL (root) NOPASSWD: /bin/cat /proc/slabinfo这条规则把权限收敛到“只允许执行/bin/cat读取/proc/slabinfo这一个动作”避免给 Telegraf 用户开放更宽的 root 能力。如果使用HOST_PROC指向了其他挂载点例如容器内的/host/procsudoers 规则中的路径也应相应改为/bin/cat /host/proc/slabinfo并且挂载点需要对 root 可读。指标输出与字段命名规则插件的Gather()将整个解析结果作为一个 measurement 写入func (ss *Slab) Gather(acc telegraf.Accumulator) error { fields, err : ss.getSlabStats() ... acc.AddGauge(slab, fields, nil) return nil }见 slab.go指标特性measurement 名固定为slab不带 tag字段覆盖通用分配器与各内核子系统/驱动例如kmalloc_8_size到kmalloc_512_size等kmalloc_*系列以及系统实际加载的子系统和驱动对应的缓存如xfs_ili_size、xfs_inode_size。具体出现哪些字段取决于目标机器内核加载了哪些 slab 类型每个带_size后缀的字段表示该类 slab 的内存消耗单位为字节。字段名由normalizeName()统一生成见 slab.gofunc normalizeName(name string) string { return strings.ReplaceAll(strings.ToLower(name), -, _) _size }即slab 原始名称转小写、把连字符-替换为下划线_再追加_size后缀。例如/proc/slabinfo中的kmalloc-1024会输出为字段kmalloc_1024_size。官方文档给出的示例输出为slab kmalloc_1024_size239927296i,kmalloc_512_size5582848i 1651049129000000000底层解析逻辑字段值是怎么算出来的理解字段数值来源对使用指标很关键。getSlabStats()的解析流程如下见 slab.go通过runCmd(/bin/cat, ...)读取文件内容必要时经sudo -n执行命令执行带有5 秒超时——源码使用 internal/exec.go 中的StdOutputTimeout(execCmd, 5*time.Second)超时或失败会返回包含命令参数和输出的错误方便排查跳过前两行第一行是slabinfo - version: 2.1版本行第二行是以#开头的列说明行逐行按空白符切分列结构为name active_objs num_objs objsize objperslab pagesperslab : tunables ... : slabdata ...。若某行有效列数不足 4直接报错the content of /proc/slabinfo is invalid取第 3 列num_objs对象总数含空闲对象与第 4 列objsize单个对象字节数字段值 num_objs * objsize即该类 slab 当前占用的总内存字节数。可以结合测试数据 testdata/slabinfo实际为 plugins/inputs/slab/testdata/slabinfo验证这一计算slab 原始行num_objsobjsize输出字段值字节kmalloc-1024 ... 234304 ... 10242343041024kmalloc_1024_size239927296ext4_inode_cache ... 480 ... 10244801024ext4_inode_cache_size491520kmalloc-8 ... 28672 ... 8286728kmalloc_8_size229376ext4_free_data ... 0 ... 64064ext4_free_data_size0注意字段值为num_objs × objsize而不是active_objs × objsize——也就是说空闲但未释放的 slab 对象也计入内存消耗这符合 slab 实际占用物理内存的语义。测试用例与验证方式插件的单元测试 slab_test.go 展示了不依赖真实内核环境的验证思路slabStats : Slab{ statFile: path.Join(testdata, slabinfo), useSudo: false, } var acc testutil.Accumulator require.NoError(t, slabStats.Gather(acc))测试直接把statFile指向随仓库提供的样例文件 plugins/inputs/slab/testdata/slabinfo并关闭 sudo随后用acc.AssertContainsFields(t, slab, fields)断言ext4_inode_cache_size、kmalloc_16_size等 20 个字段的精确取值与上表计算一致例如kmalloc_1024_size: 239927296。该测试文件同样带有//go:build linux构建标签仅在 Linux 上运行。实践要点小结在telegraf.conf中加入空的[[inputs.slab]]段即可启用插件无可调参数非 root 运行时必须配置 sudoers 免密规则NOPASSWD: /bin/cat /proc/slabinfo路径需与HOST_PROC设置一致否则sudo -n会静默失败并产生错误日志容器场景下通过挂载宿主机/proc并设置HOST_PROC环境变量实现跨边界监控输出的slabmeasurement 中每个name_size字段单位为字节值为num_objs × objsize可用于按 slab 类型做内存占比分析与趋势告警在非 Linux 平台启用该插件只会收到一条“当前平台不受支持”的警告不会产生指标部署时应按目标系统过滤该插件。【免费下载链接】telegrafAgent for collecting, processing, aggregating, and writing metrics, logs, and other arbitrary data.项目地址: https://gitcode.com/GitHub_Trending/te/telegraf创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考