
node_exporter 源码拆解52 个默认采集器如何把 /proc 变成可告警的曲线【免费下载链接】node_exporterExporter for machine metrics项目地址: https://gitcode.com/GitHub_Trending/no/node_exporter磁盘悄悄写满、内存缓慢上涨而监控一条告警没响——问题通常不在告警规则而在谁把内核状态读成指标这一步。node_exporter 就是负责这件事的 Prometheus 导出器一个 Go 编写的二进制采集 *NIX 内核暴露的硬件与 OS 指标默认在 9100 端口暴露供 Prometheus 拉取。本文拆解它的并行采集框架、两个代表性采集器的工程细节以及部署与调优的关键参数。全貌速览52 个默认采集器与 pull 模型这节回答它是什么、不是什么。node_exporter 是一个 HTTP 服务不是带配置文件的守护进程更不是推送客户端。node_exporter.go的启动代码只做三件事注册/metricshandler、监听 9100 端口、挂一个落地页。指标来源几乎全部是内核提供的伪文件系统与系统调用——/proc/stat、/sys/class/hwmon、adjtimex等。当前版本为 1.12.1README 里的采集器清单分三档52 个默认启用覆盖 cpu、meminfo、filesystem、netdev、diskstats、loadavg 等核心资源支持 Linux、FreeBSD、macOS、Solaris 等多系统28 个默认禁用如 ethtool、systemd、perf、interrupts禁用的常见理由是基数高、采集耗时可能超过抓取间隔、或对主机资源消耗大3 个已弃用ntp、runit、supervisord将在下一个大版本移除。pull 模型由 Prometheus 定时来拉而不是 exporter 主动上报决定了它的定位自身不存储任何时间序列、不做推送只在被抓取时把内核状态重新表达一遍。这也解释了为什么二进制能读到什么决定了你能监控什么。一次 /metrics 请求的生命周期并行采集框架走一遍这节走核心机制一次抓取就是一轮扇出、收集、汇总、自检。每个采集器都实现同一个两行接口并通过工厂函数注册// collector/collector.go type Collector interface { // Get new metrics and expose them via prometheus registry. Update(ch chan- prometheus.Metric) error } func registerCollector(name string, isDefaultEnabled bool, factory func(logger *slog.Logger) (Collector, error))抓取到达时NodeCollector.Collect为每个启用的采集器起一个 goroutine各自把结果推进同一个 channel由sync.WaitGroup等全部完成再返回。三个细节值得注意并行采集器之间互不阻塞一个慢采集器如要遍历所有网卡的 ethtool不会拖垮整次抓取自检 每个采集器结束后execute()都会补写两条指标——node_scrape_collector_duration_seconds该采集器耗时与node_scrape_collector_success是否成功哪个采集器超时本身成了可查询的曲线README 启用新采集器时的建议也正是盯这两条按需过滤抓取 URL 支持collect[]与exclude[]参数handler 会在运行时现建一个过滤版 handler两者同时给出则直接返回 400。多个 Prometheus 实例可以从同一个二进制各取所需无需改启动参数重启。采集器实例惰性创建并缓存所有文件读取都经过collector/paths.go里定义的可注入路径前缀——path.procfs、path.sysfs、path.rootfs、path.udev.data这是容器化部署的全部基础。cpu 采集器如何消化计数器回跳rate() 曲线的保命细节这节看单个采集器如何应对并不总是干净的内核状态。/proc/stat里的 CPU 时间是单调递增计数器Prometheus 的rate()基于计数器计算每秒变化率依赖这一点。但真实环境里计数器会回跳热插拔让 CPU 离线/上线、部分虚拟化环境重置计数。直接相减会出现负增量曲线当场撕裂。collector/cpu_linux.go的做法是三道防线缓存合并为每颗 CPU 维护上一轮数值缓存本轮逐字段取max(旧值, 新值)一次回跳不会产生负增量热插拔重置idle 计数器单次回跳超过具名常量jumpBackSeconds 3.0秒判定为热插拔事件清空该 CPU 缓存重新基线离线清理在线 CPU 数量变化时把离线 CPU 从缓存中删除避免残留僵尸标签。这三行逻辑不显眼却是曲线可用和曲线偶尔撕的分界线判断阈值还是具名常量方便按场景调整。textfile 采集器把批任务指标接进同一个 /metrics这节回答脚本、定时任务的指标如何不进新 exporter 也能进同一个端口。textfile 采集器监视指定目录把其中每个*.prom文件按 Prometheus 文本格式解析并入主端口输出。两个工程约束要记牢不支持时间戳文件里一旦带客户端时间戳整文件拒绝并记警告新鲜度统一用文件 mtime 表达node_textfile_mtime_seconds你可以据此判断这份文件的数据有多新原子写入官方姿势是先写xxx.prom.$$再mv成xxx.prom避免采集器读到半截文件错误指标node_textfile_scrape_error让你能区分文件有问题和没有指标。README 里的例子很实用cron 任务把完成时间写成指标机器静态角色写成role{roleapplication_server} 1。它与 Pushgateway 的分工也写得很清楚——textfile 管绑定这台机器的指标Pushgateway 管服务级指标。node_exporter 部署三路径裸机、容器与 EPEL 怎么跑通这节给最小可跑通方案以及三组最影响生产行为的参数。 容器里监控宿主机的关键参数把 node_exporter 放进容器监控宿主机是常见但容易翻车的场景直接读/proc监控到的是容器自己。正确姿势是绑定挂载宿主根目录并用--path.rootfs注入docker run -d \ --nethost --pidhost \ -v /:/host:ro,rslave \ quay.io/prometheus/node-exporter:latest \ --path.rootfs/host想监控的非根挂载点需要额外 bind mounttimex 采集器还要加--cap-addSYS_TIME才能调用adjtimex系统调用。裸机更简单RHEL 系可直接装 EPEL 7/8/9 里的golang-github-prometheus-node-exporter包源码构建就是make build。程序会在日志里明确警告以 root 运行——它本就设计为无特权用户运行。三个启动参数决定采集行为runtime.gomaxprocs默认 1采集是 I/O 密集型单核默认够用web.max-requests默认 40并发抓取请求上限防止抓取堆积拖垮主机--collector.disable-defaults默认全关再用--collector.name只开需要的配合各采集器的 include/exclude 正则参数如 filesystem 的挂载点过滤在源头控制基数。⚠️ 对默认禁用的采集器README 的建议很具体一次最多启用一个、先在非生产环境测试、启用后盯scrape_duration_seconds确认不超时并用scrape_samples_post_metric_relabeling观察基数变化。perf 采集器还需先放宽 sysctl 的kernel.perf_event_paranoid。边界与替代何时该选 windows_exporter 或 dcgm-exporter这节给选型结论它不做什么以及该去哪里找替代。场景node_exporter 的做法常见替代差异Windows 主机不支持windows_exporter官方 README 明确推荐后者NVIDIA GPU 指标不支持dcgm-exporter同为 pull 模型数据源不同时间同步监控timex 采集器细节见 docs 里的 TIME 文档ntp 采集器已弃用新方案读内核标志无需 SNTP 查询大盘与告警模板docs 里的 node-mixin 提供 libsonnet 模板手写 PromQL开箱即可复用还有两条注意级结论tcpstat 在 README 中被明确标注高负载下有潜在性能问题这也是它默认禁用的原因之一3 个弃用采集器将在下一个大版本移除存量监控方案要预留迁移时间。下一步建议先读框架唯一入口 collector/collector.go不到 200 行再按需求挑一个实现看自定义指标看 textfile 采集器。然后起一个默认实例curl 127.0.0.1:9100/metrics对照node_scrape_collector_success的输出与 README 的 52 个采集器清单确认你的机器上实际生效的是哪些——这一步比任何配置文档都更接近真实环境。【免费下载链接】node_exporterExporter for machine metrics项目地址: https://gitcode.com/GitHub_Trending/no/node_exporter创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考