【问题标题】:Prometheus counters: How to get current value with golang client?Prometheus 计数器:如何使用 golang 客户端获取当前值?
【发布时间】:2019-09-16 08:05:50
【问题描述】:

我正在使用计数器来计算请求数。有什么方法可以获取 prometheus 计数器的当前值?

我的目标是重用现有计数器而不分配另一个变量。

Golang prometheus 客户端版本为 1.1.0。

【问题讨论】:

    标签: go prometheus


    【解决方案1】:

    很简单,有一个获取 Prometheus 计数器值的功能

    
    import (
        "github.com/prometheus/client_golang/prometheus"
        dto "github.com/prometheus/client_model/go"
        "github.com/prometheus/common/log"
    )
    
    func GetCounterValue(metric *prometheus.CounterVec) float64 {
        var m = &dto.Metric{}
        if err := metric.WithLabelValues("label1", "label2").Write(m); err != nil {
            log.Error(err)
            return 0
        }
        return m.Counter.GetValue()
    }
    

    【讨论】:

      【解决方案2】:

      目前在Golang官方实现中没有办法获取计数器的值。

      您还可以通过增加自己的计数器并使用CounterFunc 来收集它来避免重复计算。

      注意:使用整数类型和atomic 避免并发访问问题

      // declare the counter as unsigned int
      var requestsCounter uint64 = 0
      
      // register counter in Prometheus collector
      prometheus.MustRegister(prometheus.NewCounterFunc(
          prometheus.CounterOpts{
              Name: "requests_total",
              Help: "Counts number of requests",
          },
          func() float64 {
              return float64(atomic.LoadUint64(&requestsCounter))
          }))
      
      // somewhere in your code
      atomic.AddUint64(&requestsCounter, 1)
      

      【讨论】:

      • 可以通过收集器接口“收集”一个值,这是获取指标时收集它的方式。我的回答中有例子。
      • 对。根据用例,可以应用 Deep Nirmal 解决方案或您的解决方案。
      【解决方案3】:

      可以在官方 Golang 实现中读取计数器(或任何指标)的值。我不确定它是什么时候添加的。

      这对我来说适用于没有向量的简单度量:

      func getMetricValue(col prometheus.Collector) float64 {
          c := make(chan prometheus.Metric, 1) // 1 for metric with no vector
          col.Collect(c)      // collect current metric value into the channel
          m := dto.Metric{}
          _ = (<-c).Write(&m) // read metric value from the channel
          return *m.Counter.Value
      }
      

      更新:这是一个更通用的版本,适用于向量和直方图...

      // GetMetricValue returns the sum of the Counter metrics associated with the Collector
      // e.g. the metric for a non-vector, or the sum of the metrics for vector labels.
      // If the metric is a Histogram then number of samples is used.
      func GetMetricValue(col prometheus.Collector) float64 {
          var total float64
          collect(col, func(m dto.Metric) {
              if h := m.GetHistogram(); h != nil {
                      total += float64(h.GetSampleCount())
              } else {
                      total += m.GetCounter().GetValue()
              }
          })
          return total
      }
      
      // collect calls the function for each metric associated with the Collector
      func collect(col prometheus.Collector, do func(dto.Metric)) {
          c := make(chan prometheus.Metric)
          go func(c chan prometheus.Metric) {
              col.Collect(c)
              close(c)
          }(c)
          for x := range c { // eg range across distinct label vector values
                  m := dto.Metric{}
                  _ = x.Write(&m)
                  do(m)
          }
      }
      

      【讨论】:

        猜你喜欢
        • 2020-12-14
        • 2020-06-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-05-06
        • 1970-01-01
        相关资源
        最近更新 更多