Прометей клиент очищает счетчик преждевременно? - PullRequest
0 голосов
/ 05 марта 2020

Я пытаюсь написать программу, которая выставляет метрики Прометея. Это простая программа, в которой я хочу увеличивать счетчик каждый раз, когда мой метод «run» вызывается в моей структуре.


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))
}

Вышеприведенный код завершается с ошибкой «Failed to continue - bad access» , каждый раз, когда я пытаюсь увеличить счетчик. то есть в этой строке

s.errorCount.Inc()

Я не могу определить, почему счетчик внезапно исчезает из памяти (если я правильно понимаю сообщение об ошибке). Я определяю, упускаю ли я что-то фундаментальное из Go или неправильно использую клиентскую библиотеку Prometheus.

1 Ответ

2 голосов
/ 06 марта 2020

В initialise() s передается по значению, что означает, что в main() s.errorCount есть nil.

Просто измените объявление initialiserun) взять указатель.

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{}
}
...