85 lines
2.6 KiB
Go
85 lines
2.6 KiB
Go
package ingestor
|
|
|
|
import (
|
|
"sync"
|
|
"time"
|
|
|
|
"github.com/tech/sendico/fx/ingestor/internal/config"
|
|
"github.com/prometheus/client_golang/prometheus"
|
|
"github.com/prometheus/client_golang/prometheus/promauto"
|
|
)
|
|
|
|
type serviceMetrics struct {
|
|
pollDuration *prometheus.HistogramVec
|
|
pollTotal *prometheus.CounterVec
|
|
pairDuration *prometheus.HistogramVec
|
|
pairTotal *prometheus.CounterVec
|
|
pairLastUpdate *prometheus.GaugeVec
|
|
}
|
|
|
|
var (
|
|
metricsOnce sync.Once
|
|
globalMetricsRef *serviceMetrics
|
|
)
|
|
|
|
func getServiceMetrics() *serviceMetrics {
|
|
metricsOnce.Do(func() {
|
|
reg := prometheus.DefaultRegisterer
|
|
globalMetricsRef = &serviceMetrics{
|
|
pollDuration: promauto.With(reg).NewHistogramVec(prometheus.HistogramOpts{
|
|
Name: "fx_ingestor_poll_duration_seconds",
|
|
Help: "Duration of a polling cycle.",
|
|
Buckets: prometheus.DefBuckets,
|
|
}, []string{"result"}),
|
|
pollTotal: promauto.With(reg).NewCounterVec(prometheus.CounterOpts{
|
|
Name: "fx_ingestor_poll_total",
|
|
Help: "Total polling cycles executed.",
|
|
}, []string{"result"}),
|
|
pairDuration: promauto.With(reg).NewHistogramVec(prometheus.HistogramOpts{
|
|
Name: "fx_ingestor_pair_duration_seconds",
|
|
Help: "Duration of individual pair ingestion.",
|
|
Buckets: prometheus.DefBuckets,
|
|
}, []string{"source", "provider", "symbol", "result"}),
|
|
pairTotal: promauto.With(reg).NewCounterVec(prometheus.CounterOpts{
|
|
Name: "fx_ingestor_pair_total",
|
|
Help: "Total ingestion attempts per pair.",
|
|
}, []string{"source", "provider", "symbol", "result"}),
|
|
pairLastUpdate: promauto.With(reg).NewGaugeVec(prometheus.GaugeOpts{
|
|
Name: "fx_ingestor_pair_last_success_unix",
|
|
Help: "Unix timestamp of the last successful ingestion per pair.",
|
|
}, []string{"source", "provider", "symbol"}),
|
|
}
|
|
})
|
|
return globalMetricsRef
|
|
}
|
|
|
|
func (m *serviceMetrics) observePoll(duration time.Duration, err error) {
|
|
if m == nil {
|
|
return
|
|
}
|
|
result := labelForError(err)
|
|
m.pollDuration.WithLabelValues(result).Observe(duration.Seconds())
|
|
m.pollTotal.WithLabelValues(result).Inc()
|
|
}
|
|
|
|
func (m *serviceMetrics) observePair(pair config.Pair, duration time.Duration, err error) {
|
|
if m == nil {
|
|
return
|
|
}
|
|
result := labelForError(err)
|
|
labels := []string{pair.Source.String(), pair.Provider, pair.Symbol, result}
|
|
m.pairDuration.WithLabelValues(labels...).Observe(duration.Seconds())
|
|
m.pairTotal.WithLabelValues(labels...).Inc()
|
|
if err == nil {
|
|
m.pairLastUpdate.WithLabelValues(pair.Source.String(), pair.Provider, pair.Symbol).
|
|
Set(float64(time.Now().Unix()))
|
|
}
|
|
}
|
|
|
|
func labelForError(err error) string {
|
|
if err != nil {
|
|
return "error"
|
|
}
|
|
return "success"
|
|
}
|