package metrics import ( "maps" "slices" "sync" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promauto" ) const ( prometheusCounterSuffix = "_total" prometheusPrefix = "kopia_" ) //nolint:gochecknoglobals var ( promCacheMutex sync.Mutex // +checklocks:promCacheMutex promCounters = map[string]*prometheus.CounterVec{} // +checklocks:promCacheMutex promHistograms = map[string]*prometheus.HistogramVec{} ) func getPrometheusCounter(opts prometheus.CounterOpts, labels map[string]string) prometheus.Counter { promCacheMutex.Lock() defer promCacheMutex.Unlock() prom := promCounters[opts.Name] if prom == nil { prom = promauto.NewCounterVec(opts, mapKeys(labels)) promCounters[opts.Name] = prom } return prom.WithLabelValues(mapValues(labels)...) } func getPrometheusHistogram(opts prometheus.HistogramOpts, labels map[string]string) prometheus.Observer { //nolint:gocritic promCacheMutex.Lock() defer promCacheMutex.Unlock() prom := promHistograms[opts.Name] if prom == nil { prom = promauto.NewHistogramVec(opts, mapKeys(labels)) promHistograms[opts.Name] = prom } return prom.WithLabelValues(mapValues(labels)...) } func mapKeys[Map ~map[K]V, K comparable, V any](m Map) []K { return slices.AppendSeq(make([]K, 0, len(m)), maps.Keys(m)) } func mapValues[Map ~map[K]V, K comparable, V any](m Map) []V { return slices.AppendSeq(make([]V, 0, len(m)), maps.Values(m)) }