Golang实现自定义Prometheus导出器
Golang实现自定义Prometheus导出器 我正在尝试创建一个自定义的Prometheus导出器。虽然已经成功将指标发送到我的端口,但如何在使用新值更新指标时"覆盖"之前的指标值?我通过API GET请求获取一个数字,并将该数字传递给指标。这个数字可能在一分钟后发生变化,我该如何更新该指标?我四处查阅后得到的答案是在Update()方法中使用MustNewConstMetric,但我完全不知道具体该如何操作。有人能帮忙解释一下吗?以下是我目前的代码:
package main
import (
"fmt"
"io/ioutil"
"net/http"
"github.com/prometheus/client_golang/prometheus"
"github.com/tidwall/gjson"
)
var productionTotal = prometheus.NewGauge(prometheus.GaugeOpts{
Name: "production_total", Help: ""})
func init() {
prometheus.MustRegister(productionTotal)
productionTotal.Set(getTotal("production"))
}
func getTotal(x string) float64 {
URL := fmt.Sprintf("apigetrequest")
res, err := http.Get(URL)
if err != nil {
panic(err.Error())
}
body, err := ioutil.ReadAll(res.Body)
if err != nil {
panic(err.Error())
}
bodyString := string(body)
value := gjson.Get(bodyString, "result.total_count")
return float64(value.Num)
}
更多关于Golang实现自定义Prometheus导出器的实战教程也可以访问 https://www.itying.com/category-94-b0.html
1 回复
更多关于Golang实现自定义Prometheus导出器的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
在自定义Prometheus导出器中更新指标值,您需要使用Set()方法来覆盖之前的指标值。您的代码已经接近正确,但需要添加定期更新机制。以下是修改后的代码示例:
package main
import (
"fmt"
"io/ioutil"
"net/http"
"time"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
"github.com/tidwall/gjson"
)
var productionTotal = prometheus.NewGauge(prometheus.GaugeOpts{
Name: "production_total",
Help: "Total production count",
})
func init() {
prometheus.MustRegister(productionTotal)
// 启动定期更新指标的后台goroutine
go updateMetricsPeriodically()
}
func updateMetricsPeriodically() {
ticker := time.NewTicker(1 * time.Minute) // 每分钟更新一次
defer ticker.Stop()
for {
select {
case <-ticker.C:
updateProductionTotal()
}
}
}
func updateProductionTotal() {
newValue := getTotal("production")
productionTotal.Set(newValue) // 这会覆盖之前的指标值
fmt.Printf("Updated production_total to: %f\n", newValue)
}
func getTotal(x string) float64 {
URL := fmt.Sprintf("apigetrequest")
res, err := http.Get(URL)
if err != nil {
fmt.Printf("Error fetching data: %v\n", err)
return 0
}
defer res.Body.Close()
body, err := ioutil.ReadAll(res.Body)
if err != nil {
fmt.Printf("Error reading response: %v\n", err)
return 0
}
bodyString := string(body)
value := gjson.Get(bodyString, "result.total_count")
return float64(value.Num)
}
func main() {
// 设置HTTP处理程序用于Prometheus抓取
http.Handle("/metrics", promhttp.Handler())
// 初始更新一次指标
updateProductionTotal()
fmt.Println("Starting server on :8080")
http.ListenAndServe(":8080", nil)
}
关于MustNewConstMetric的使用,这通常用于自定义收集器(Collector)模式。如果您想使用这种方式,这里是一个示例:
type customCollector struct {
productionTotal *prometheus.Desc
}
func newCustomCollector() *customCollector {
return &customCollector{
productionTotal: prometheus.NewDesc(
"production_total",
"Total production count",
nil, nil,
),
}
}
func (c *customCollector) Describe(ch chan<- *prometheus.Desc) {
ch <- c.productionTotal
}
func (c *customCollector) Collect(ch chan<- prometheus.Metric) {
currentValue := getTotal("production")
ch <- prometheus.MustNewConstMetric(
c.productionTotal,
prometheus.GaugeValue,
currentValue,
)
}
// 在主函数中注册自定义收集器
func main() {
collector := newCustomCollector()
prometheus.MustRegister(collector)
http.Handle("/metrics", promhttp.Handler())
fmt.Println("Starting server on :8080")
http.ListenAndServe(":8080", nil)
}
第一种方法使用Gauge的Set()方法更简单直接,适合您的用例。每次调用Set()都会覆盖之前的指标值,Prometheus在抓取时会获取到最新的数值。

