Golang - 如何从 Prometheus 删除孤立指标

问题描述 投票:0回答:1

我有一个 Go 程序,它获取 Prometheus 时间序列以在其上动态注入标签,然后将它们暴露回“/metrics”以供 Prometheus 再次抓取。

我现在遇到的问题是,每当指标停止报告值时,该指标不会被删除,而是会继续使用与它具有的相同的最后一个值。

示例: 我有 10:00 的时间序列

new_billing_raw:memory_allocated:sum{billed_namespace="monitoring",exported_job="prometheus",task="prometheus",task_group="monitoring",uuaa="CD34"} 300

如果在 10:01 我停止 Prometheus 从中接收这些标签和值的导出器,则该指标的值将为空。 我的程序将无限期地报告最后一个值(本例中为 300),而不是 null,直到我重新启动程序为止。

知道如何解决这个问题吗?

go prometheus metrics
1个回答
0
投票

在这种情况下,您不应使用内置指标实现(prometheus.NewGauge 等)。它们永远不会忘记标签值,并且无法取消注册。相反,编写一个实现 prometheus.Collector 的新类型并注册该类型的实例。将查询 prometheus 的代码移至该新类型的 Collect 方法中。

来自文档

在为导出器实现收集器时,您不应该使用通常的直接检测方法,然后更新每次抓取的指标。

而是每次都创建新的指标。在 Go 中,这是通过 Collect() 方法中的 MustNewConstMetric 完成的。 [...]

造成这种情况的原因有两个。首先,两次刮擦可能同时发生,并且直接检测使用有效的文件级全局变量,因此您将获得竞争条件。其次,如果标签值消失,它仍然会被导出。

这是一个草稿:

package main

import (
    "github.com/prometheus/client_golang/prometheus"
)

func main() {
    prometheus.MustRegister(&MyCollector{})
}

var memAllocatedDesc = prometheus.NewDesc(
    "new_billing_raw:memory_allocated:sum",
    "TODO: help",
    []string{"billed_namespace", "exported_job", "task", "task_group", "uuaa"},
    nil, // constant labels
)

// add descriptions for more metrics as necessary


type MyCollector struct{}

// Describe implements prometheus.Collector. It sends to ch descriptions of
// all metrics that Collect could ever possibly produce over c's entire
// lifetime.
//
// See also prometheus.DescribeByCollect for a possible shortcut
// implementation.
func (c *MyCollector) Describe(ch chan<- *prometheus.Desc) {
    ch <- memAllocatedDesc
}

func (c *MyCollector) Collect(ch chan<- prometheus.Metric) {
    // TODO: query upstream prometheus

    ch <- prometheus.MustNewConstMetric(
        memAllocatedDesc,
        prometheus.GaugeValue,
        300,           // value
        "default",     // billed_namespace
        "code-server", // exported_job
        "code-serer",  // task
        "code-serer",  // task_group
        "GBT5",        // uuaa
    )

    // Repeat as necessary, for each metric and label set.
}

Describe 在收集器注册时被调用一次。对 /metrics 的每个请求都会调用 Collect。

在 Collect 中查询上游 Prometheus 可确保每次抓取都看到最新值。如果在每次抓取时查询上游 Prometheus 实例的成本太高(不太可能),请异步执行查询并将它们存储在某种并发安全的数据结构中,然后在 Collect 中使用此数据结构。这里的关键是只有发送到

chan prometheus.Metric
的指标才会出现在抓取响应中。

© www.soinside.com 2019 - 2024. All rights reserved.