mattermost/server/enterprise/metrics/histogram.go
Agniva De Sarker 59b8532a89
metrics/histogram: Fixing incorrect label_name (#29492)
We were incorrectly overwriting the same key - label_name.
```release-note
NONE
```
2024-12-06 19:34:46 +05:30

74 lines
2.1 KiB
Go

// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.enterprise for license information.
package metrics
import (
"github.com/prometheus/client_golang/prometheus"
"github.com/mattermost/mattermost/server/public/shared/mlog"
)
// HistogramVec is a wrapper of prometheus.HistogramVec that stores the buckets
// which are later passed down to WrappedObserver.
type HistogramVec struct {
*prometheus.HistogramVec
buckets []float64
fqName string
logger mlog.LoggerIFace
}
// WrappedObserver is a wrapper of prometheus.Observer which addtionally
// logs userIDs when the value exceeds or equals to the one in the highest bucket.
type WrappedObserver struct {
prometheus.Observer
labels prometheus.Labels
buckets []float64
logger mlog.LoggerIFace
metricName string
userID string
}
// NewHistogramVec returns a custom-purpose HistogramVec.
func NewHistogramVec(opts prometheus.HistogramOpts, labelNames []string, logger mlog.LoggerIFace) *HistogramVec {
if len(opts.Buckets) == 0 {
opts.Buckets = prometheus.DefBuckets
}
return &HistogramVec{
HistogramVec: prometheus.NewHistogramVec(opts, labelNames),
buckets: opts.Buckets,
fqName: prometheus.BuildFQName(opts.Namespace, opts.Subsystem, opts.Name),
logger: logger,
}
}
func (v *HistogramVec) With(labels prometheus.Labels, userID string) prometheus.Observer {
h, err := v.GetMetricWith(labels)
if err != nil {
panic(err)
}
return &WrappedObserver{
Observer: h,
labels: labels,
buckets: v.buckets,
logger: v.logger,
metricName: v.fqName,
userID: userID,
}
}
func (o *WrappedObserver) Observe(v float64) {
if v >= o.buckets[len(o.buckets)-1] {
fields := []mlog.Field{
mlog.String("metric_name", o.metricName),
mlog.String("user_id", o.userID),
mlog.Float("observed_value", v),
mlog.Float("highest_bucket_value", o.buckets[len(o.buckets)-1]),
}
for k, v := range o.labels {
fields = append(fields, mlog.String(k, v))
}
o.logger.Warn("Metric observation exceeded.", fields...)
}
o.Observer.Observe(v)
}