【问题标题】:Prometheus client cleaning up counter prematurely?Prometheus 客户端过早清理计数器?
【发布时间】:2020-06-18 12:46:16
【问题描述】:

我正在尝试编写一个公开普罗米修斯指标的程序。 这是一个简单的程序,每次在我的结构上调用我的“运行”方法时,我都想增加一个计数器。


import (
    "log"
    "net/http"
    "time"

    "github.com/prometheus/client_golang/prometheus"
    "github.com/prometheus/client_golang/prometheus/promhttp"
)

type myStruct struct {
    errorCount prometheus.Counter
}

func (s myStruct) initialize() {
    s.errorCount = prometheus.NewCounter(prometheus.CounterOpts{
        Name: "my_counter",
        Help: "sample prometheus counter",
    })
}

func (s myStruct) run() {
    s.errorCount.Add(1)
}

func main() {
    s := new(myStruct)
    s.initialize()

    http.Handle("/metrics", promhttp.Handler())

    go func() {
        for {
            s.run()
            time.Sleep(time.Second)
        }
    }()

    log.Fatal(http.ListenAndServe(":8080", nil))
}

每次我尝试增加计数器时,上述代码都会失败并显示“无法继续 - 访问错误”错误。即在这一行

s.errorCount.Inc()

我无法确定为什么计数器突然从内存中消失(如果我正确理解错误消息的话)。 我确定我是否遗漏了一些基本的东西。去吧,还是我用错了prometheus客户端库。

【问题讨论】:

  • 您是否使用调试器运行程序?有an issuedelve,这可能会导致您的错误。在没有调试器的情况下运行它时行为是否有所不同?
  • @xarantolus - 我在 VSCode 中使用 delve 运行它。我尝试了您的建议并使用“运行”从命令行运行它,但我仍然收到运行时错误$go run sample.go panic: runtime error: invalid memory address or nil pointer dereference [signal SIGSEGV: segmentation violation code=0x1 addr=0x38 pc=0x13d3859] ....

标签: go prometheus


【解决方案1】:

initialise() s 是按值传递的,这意味着 main() s.errorCountnil

只需更改initialise(和run)的声明以获取指针。

func (s *myStruct) initialize() {
...

还有一些您可能想尝试的建议:

func init() {
    go func() {
        http.Handle("/metrics", promhttp.Handler())
        log.Fatal(http.ListenAndServe(":8080", nil))
    }()
}

type myStruct struct {
    errorCount prometheus.Counter
}

func NewMyStruct() *myStruct {
    return &myStruct {
        errorCount: prometheus.NewCounter(prometheus.CounterOpts {
            Name: "my_counter",
            Help: "sample prometheus counter",
        }),
    }
}

func (s *myStruct) run() {
    s.errorCount.Add(1)
}

func main() {
    s := NewMyStruct()

    go func() {
     for {
         s.run()
         time.Sleep(time.Second)
     }
    }()

    // ... OR select{}
}

【讨论】:

  • 谢谢@AJR。我知道这一定是我缺少的一些小东西:)
猜你喜欢
  • 2020-12-10
  • 1970-01-01
  • 2014-02-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-10
  • 2010-09-22
相关资源
最近更新 更多