之前在搞 PVE 的时候分享过怎么采集 PVE 的温度并把温度显示到 PVE 的摘要中,但是温度都是实时的,无法记录历史数据。这次借着 Prometheus 指标采集插件的学习的机会,我用 Go 写了一个指标采集插件,把 PVE 的温度和功率采集并显示到 Grafana 看板中。
Grafana 显示效果
先直接看 Grafana 显示效果:
这里是自定义的一个看板,只显示两个采集指标,分别是 PVE 的 CPU 温度和功率。
自定义采集插件
1. 指标采集的方式
我这里主要是采集两个指标,其他系统相关的指标就不需要自己采集了,官方的 node_exporter
插件采集的指标已经非常丰富。这两个指标分别为:
cpu_temperature_celsius
:CPU 温度power_usage_watts
:功率
采集的方式之前写过的文章 PVE系统在概要中显示CPU温度的方法 中已经提到过,就是通过安装和执行 sensors
命令,然后使用正则表达式采集。
sensors
命令的返回数据如下:
iwlwifi_1-virtual-0
Adapter: Virtual device
temp1: N/A
nvme-pci-0300
Adapter: PCI adapter
Composite: +58.9°C (low = -273.1°C, high = +81.8°C)
(crit = +84.8°C)
Sensor 1: +58.9°C (low = -273.1°C, high = +65261.8°C)
Sensor 2: +62.9°C (low = -273.1°C, high = +65261.8°C)
amdgpu-pci-0400
Adapter: PCI adapter
vddgfx: 1.39 V
vddnb: 743.00 mV
edge: +58.0°C
PPT: 16.00 W
k10temp-pci-00c3
Adapter: PCI adapter
Tctl: +68.2°C
温度指标为 Tctl: +68.2°C
,需要使用正则提取 68.2;功率指标数据为 PPT: 16.00 W
,需要使用正则提取 16.00。
2. 开发采集插件
采集插件可以使用多种语言,Prometheus 官方提供了好几种语言的 SDK,比如 Python 和 Go,为了保持跟官方插件的运行方式一致,我这里采用 Go 来编写采集插件。
开发文档查看:INSTRUMENTING A GO APPLICATION FOR PROMETHEUS
直接查看代码 main.go
:
package main
import (
"bytes"
"fmt"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
"net/http"
"os/exec"
"regexp"
"strconv"
"time"
)
// 将要注册的指标定义为全局变量
var (
cpuTemperature = prometheus.NewGauge(prometheus.GaugeOpts{
Name: "cpu_temperature_celsius",
Help: "Current temperature of the CPU in degrees Celsius",
})
powerUsage = prometheus.NewGauge(prometheus.GaugeOpts{
Name: "power_usage_watts",
Help: "Current power usage in watts",
})
)
func initCustomRegistry() *prometheus.Registry {
// 创建一个新的注册表
reg := prometheus.NewRegistry()
// 注册自定义指标
reg.MustRegister(cpuTemperature)
reg.MustRegister(powerUsage)
return reg
}
// executeCommand 执行给定的 shell 命令并返回执行结果
func executeCommand(cmd string) (string, error) {
// 创建一个新的命令
command := exec.Command("bash", "-c", cmd)
// 捕获命令的标准输出和错误输出
var out bytes.Buffer
var stderr bytes.Buffer
command.Stdout = &out
command.Stderr = &stderr
// 运行命令
err := command.Run()
if err != nil {
return "", err
}
return out.String(), nil
}
// getInfoByRegexp 使用正则提取信息
func getInfoByRegexp(input, pattern string) (string, error) {
// 定义匹配
re := regexp.MustCompile(pattern)
// 查找匹配项
match := re.FindStringSubmatch(input)
// 如果找到匹配项,返回第一个捕获组的内容
if len(match) > 1 {
str := match[1]
return str, nil
}
// 如果没有找到匹配项,返回错误
return "", fmt.Errorf("no info found")
}
// recordMetrics 可以每个指标一个单独的 Goroutine 来采集
func recordMetrics() {
go func() {
for {
var temperature, power float64
output, err := executeCommand("sensors")
if err != nil {
fmt.Println(err)
}
temperatureStr, err := getInfoByRegexp(output, `Tctl:\s*\+([0-9.]+)°C`)
powerStr, err := getInfoByRegexp(output, `PPT:\s*([0-9.]+)\s*W`)
temperature, err = strconv.ParseFloat(temperatureStr, 64)
power, err = strconv.ParseFloat(powerStr, 64)
cpuTemperature.Set(temperature)
powerUsage.Set(power)
// 休眠 10 秒
time.Sleep(10 * time.Second)
}
}()
}
func main() {
// 创建自定义注册表并注册指标
reg := initCustomRegistry()
// 开始记录指标
recordMetrics()
// 使用自定义注册表创建 HTTP 处理器
http.Handle("/metrics", promhttp.HandlerFor(reg, promhttp.HandlerOpts{}))
_ = http.ListenAndServe(":9010", nil)
}
关于指标数据的采集逻辑就不做过多的说明了,这里主要是说一下指标的定义、注册和值的更新:
- 指标定义:指标的定义可以统一放到全局变量中,定义指标的
key
和说明,这样可以保持跟官方的指标一致 - 指标注册:为了只显示自己定义的指标,这里使用自定义的指标注册器,而不是内置的指标注册器
- 指标采集:每个指标可以单独定义一个函数启动一个
goruntine
去执行,这样可以让每个指标的采集异步执行,也可以把同类指标放到一起采集,比如我上面的温度和功率,由于都是使用正则从命令行返回中提取,所以直接放到一起反而比分开好
3. 运行和配置插件
3.1 下载安装包
插件已经被我上传到 github 上面,可以自动编译,可以下载最新版本:https://github.com/Hopetree/pve_exporter/releases
下载命令:
wget https://github.com/Hopetree/pve_exporter/releases/download/v0.0.4/pve_exporter_0.0.4_linux_x86_64.tar.gz
3.2 解压并运行插件
解压包:
tar -zxvf pve_exporter_0.0.4_linux_x86_64.tar.gz
mv pve_exporter_0.0.4_linux_x86_64 pve_exporter
运行插件:
nohup ./pve_exporter &
3.3 验证指标
插件启动后,访问本地 http://localhost:9010/metrics 即可查看到指标数据,指标数据如下:
4. Prometheus 对接插件
首先去 Prometheus 配置文件 prometheus/prometheus.yml
中添加指标采集任务 pve_exporter
,添加后完整配置大概如下:
global:
scrape_interval: 15s
scrape_configs:
- job_name: 'prometheus'
static_configs:
- targets: ['localhost:9090']
- job_name: 'node'
static_configs:
- targets: ['192.168.0.202:9100']
- job_name: 'pve_exporter'
static_configs:
- targets: ['192.168.0.254:9010']
然后重启 Prometheus 服务即可。
此时在Prometheus 的 Targets 中可以查看到新增的节点信息:
然后可以查询指标信息:
Grafana 配置可视化图表
添加可视化:
选择数据源为 prometheus:
选择指标,并命令一个图表,然后 Apply 保存图表:
添加两个指标图表后,保存看板:
版权声明:如无特殊说明,文章均为本站原创,转载请注明出处
本文链接:https://tendcode.com/subject/article/prometheus-exporter-plugin-for-PVE/
许可协议:署名-非商业性使用 4.0 国际许可协议