72 lines
2.1 KiB
Go
72 lines
2.1 KiB
Go
package metrics
|
|||
|
|
|
||
|
|
import (
|
||
|
|
"math"
|
||
|
|
"net/http"
|
||
|
|
"strings"
|
||
|
|
"sync"
|
||
|
|
"time"
|
||
|
|
|
||
|
|
"github.com/prometheus/client_golang/prometheus"
|
||
|
|
"github.com/prometheus/client_golang/prometheus/promhttp"
|
||
|
|
)
|
||
|
|
|
||
|
|
var (
|
||
|
|
once sync.Once
|
||
|
|
registry *prometheus.Registry
|
||
|
|
processedCounter *prometheus.CounterVec
|
||
|
|
failureCounter *prometheus.CounterVec
|
||
|
|
parseLatency *prometheus.HistogramVec
|
||
|
|
)
|
||
|
|
|
||
|
|
func initCollectors() {
|
||
|
|
registry = prometheus.NewRegistry()
|
||
|
|
processedCounter = prometheus.NewCounterVec(prometheus.CounterOpts{
|
||
|
|
Name: "caatsm_processed_total",
|
||
|
|
Help: "Count of telegrams processed by status and category.",
|
||
|
|
}, []string{"status", "category"})
|
||
|
|
failureCounter = prometheus.NewCounterVec(prometheus.CounterOpts{
|
||
|
|
Name: "caatsm_failures_total",
|
||
|
|
Help: "Count of processor failures by stage (parser, repository, publisher).",
|
||
|
|
}, []string{"stage"})
|
||
|
|
parseLatency = prometheus.NewHistogramVec(prometheus.HistogramOpts{
|
||
|
|
Name: "caatsm_parse_latency_seconds",
|
||
|
|
Help: "Latency between reception and parse completion.",
|
||
|
|
Buckets: prometheus.DefBuckets,
|
||
|
|
}, []string{"status", "category"})
|
||
|
|
|
||
|
|
registry.MustRegister(processedCounter, failureCounter, parseLatency)
|
||
|
|
}
|
||
|
|
|
||
|
|
func ensureCollectors() {
|
||
|
|
once.Do(initCollectors)
|
||
|
|
}
|
||
|
|
|
||
|
|
// Handler exposes the Prometheus metrics registry.
|
||
|
|
func Handler() http.Handler {
|
||
|
|
ensureCollectors()
|
||
|
|
return promhttp.HandlerFor(registry, promhttp.HandlerOpts{})
|
||
|
|
}
|
||
|
|
|
||
|
|
// RecordProcessed tracks the final status of a telegram along with the parse latency.
|
||
|
|
func RecordProcessed(status, category string, elapsed time.Duration) {
|
||
|
|
ensureCollectors()
|
||
|
|
processedCounter.WithLabelValues(labelValue(status), labelValue(category)).Inc()
|
||
|
|
seconds := math.Max(elapsed.Seconds(), 0)
|
||
|
|
parseLatency.WithLabelValues(labelValue(status), labelValue(category)).Observe(seconds)
|
||
|
|
}
|
||
|
|
|
||
|
|
// RecordFailure increments the failure counter for the supplied stage.
|
||
|
|
func RecordFailure(stage string) {
|
||
|
|
ensureCollectors()
|
||
|
|
failureCounter.WithLabelValues(labelValue(stage)).Inc()
|
||
|
|
}
|
||
|
|
|
||
|
|
func labelValue(value string) string {
|
||
|
|
value = strings.TrimSpace(value)
|
||
|
|
if value == "" {
|
||
|
|
return "unknown"
|
||
|
|
}
|
||
|
|
return strings.ToLower(value)
|
||
|
|
}
|