Prometheus Collector失败,“之前收集的度量标准使用相同的名称和标签值”

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

我有一个以以下格式将温度测量结果公开为JSON的设备:

[
  {
    "dataPointId": 123456,
    "values": [
      {
        "t": 1589236277000,
        "v": 14.999993896484398
      },
      {
        "t": 1589236877000,
        "v": 14.700006103515648
      },
      {
        "t": 1589237477000,
        "v": 14.999993896484398
      },
[..]

如您所见,这些值同时包含时间戳和温度测量值。我想通过Prometheus指标公开这些度量,因此我正在使用prometheus/client_golang构建导出器。

我期望/metrics端点从上面的数据中暴露出类似的内容:

# HELP my_temperature_celsius Temperature
# TYPE my_temperature_celsius gauge
my_temperature_celsius{id="123456"} 14.999993896484398 1589236277000
my_temperature_celsius{id="123456"} 14.700006103515648 1589236877000
my_temperature_celsius{id="123456"} 14.999993896484398 1589237477000

我实现了一个简单的prometheus.Collector,正在添加我的静态指标,没有任何问题。对于上述测量,NewMetricWithTimestamp似乎是添加带有时间戳的度量的唯一方法,因此我正在使用以下类似的方法遍历这些值:

for _, measurements := range dp.Values {
  ch <- prometheus.NewMetricWithTimestamp(
    time.Unix(measurements.T, 0),
    prometheus.MustNewConstMetric(
      collector.temperature,
      prometheus.GaugeValue,
      float64(measurements.V),
      device.DatapointID))
}

但是,这导致了我不完全理解的以下错误:

An error has occurred while serving metrics:

1135 error(s) occurred:
* collected metric "my_temperature_celsius" { label:<name:"id" value:"123456" > gauge:<value:14.999993896484398 > timestamp_ms:1589236877000000 } was collected before with the same name and label values
* collected metric "my_temperature_celsius" { label:<name:"id" value:"123456" > gauge:<value:14.700006103515648 > timestamp_ms:1589237477000000 } was collected before with the same name and label values
[..]
  • 我知道metriclabel组合必须是唯一的,但是由于我还要添加一个时间戳,这不算作唯一的度量吗?我的期望甚至可能吗?

  • 我如何在Prometheus导出器中表示这些测量值?

go prometheus
1个回答
0
投票

[如果仔细观察,您会发现在度量标准收集的上下文中,JSON数据格式略有冗余,因为时间戳记在每个设备内部,而不是作为父键,并且具有作为设备ID和值数组的值。只有这样,您才可以循环访问实时序列数据,然后您的标签就不会像现在一样在循环中保持静态。标签唯一性是标签名称+标签值散列在一起。

我认为,首选的方法是制作一个Gauge Vector。使用WithLabelValues获取Gauge对象并对其调用Set来设置值

deviceTempGaugeVector := prometheus.NewGaugeVec(
    prometheus.GaugeOpts{
        Name: "my_temperature_celsius",
    },
    []string{
        "device_id" // Using single label instead of 2 labels "id" and "value"
    },
)

prometheus.MustRegister(deviceTempGaugeVector)

for _, point := range dp.TimeStamps {
  for _, measurements := range point {
    deviceId := measurements.DatapointID
    value := measurements.V
    metric := deviceTempGaugeVector.WithLabelValues(deviceId).Set(value)
    ch <- prometheus.NewMetricWithTimestamp(time.Unix(measurements.T, 0),metric)
  }
}

Ref:https://godoc.org/github.com/prometheus/client_golang/prometheus#NewGaugeVec

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