Files
unitech-golib/metric/metric.go

161 lines
4.3 KiB
Go
Raw Normal View History

2020-04-06 19:57:19 +08:00
package metric
import (
"github.com/prometheus/client_golang/prometheus"
"sync"
)
const missVal = "MissLabel"
// CounterVecDecorator Add safe decorator
type CounterVecDecorator struct {
*prometheus.CounterVec
secureLabels []string
once *sync.Once
}
func NewCounterVec(opts prometheus.CounterOpts, labelNames []string) *CounterVecDecorator {
v := &CounterVecDecorator{prometheus.NewCounterVec(opts, labelNames), labelNames, &sync.Once{}}
return v
}
// With is secure wrap for with of prometheus.CounterVec
// there is no panic, and always calculate to metrics , if miss values, will calculate to MissLabel
// It's secure
func (v *CounterVecDecorator) With(labels prometheus.Labels) prometheus.Counter {
// To avoid initialization sequence, so must delay register to with func
v.once.Do(func() {
Register(v)
})
safeLabels := labelAlignment(v.secureLabels, labels)
//
c, err := v.GetMetricWith(safeLabels)
if err != nil {
// should never happen , but should still add handler to record alert
// TODO singleton alert Gauge and return an alert counter
}
return c
}
// GaugeVecDecorator Add safe decorator
type GaugeVecDecorator struct {
*prometheus.GaugeVec
secureLabels []string
once *sync.Once
}
func NewGaugeVec(opts prometheus.GaugeOpts, labelNames []string) *GaugeVecDecorator {
v := &GaugeVecDecorator{prometheus.NewGaugeVec(opts, labelNames), labelNames, &sync.Once{}}
return v
}
// With is secure wrap for with of prometheus.GaugeVec
// there is no panic, and always calculate to metrics , if miss values, will calculate to MissLabel
// It's secure
func (v *GaugeVecDecorator) With(labels prometheus.Labels) prometheus.Gauge {
// To avoid initialization sequence, so must delay register to with func
v.once.Do(func() {
Register(v)
})
safeLabels := labelAlignment(v.secureLabels, labels)
//
c, err := v.GetMetricWith(safeLabels)
if err != nil {
// should never happen , but should still add handler to record alert
// TODO singleton alert Gauge and return
}
return c
}
// HistogramVecDecorator Add safe
type HistogramVecDecorator struct {
*prometheus.HistogramVec
secureLabels []string
once *sync.Once
}
func NewHistogramVec(opts prometheus.HistogramOpts, labelNames []string) *HistogramVecDecorator {
v := &HistogramVecDecorator{prometheus.NewHistogramVec(opts, labelNames), labelNames, &sync.Once{}}
return v
}
// With is secure wrap for with of prometheus.HistogramVec
// there is no panic, and always calculate to metrics , if miss values, will calculate to MissLabel
// It's secure
func (v *HistogramVecDecorator) With(labels prometheus.Labels) prometheus.Observer {
// To avoid initialization sequence, so must delay register to with func
v.once.Do(func() {
Register(v)
})
safeLabels := labelAlignment(v.secureLabels, labels)
//
c, err := v.GetMetricWith(safeLabels)
if err != nil {
// should never happen , but should still add handler to record alert
// TODO singleton alert Histogram and return
}
return c
}
// SummaryVecDecorator Add safe
type SummaryVecDecorator struct {
*prometheus.SummaryVec
secureLabels []string
once *sync.Once
}
func NewSummaryVec(opts prometheus.SummaryOpts, labelNames []string) *SummaryVecDecorator {
v := &SummaryVecDecorator{prometheus.NewSummaryVec(opts, labelNames), labelNames, &sync.Once{}}
//if len(autoReg) == 0 || autoReg[0] == true {
// Register(v)
//}
return v
}
// With is secure wrap for with of prometheus.SummaryVec
// there is no panic, and always calculate to metrics , if miss values, will calculate to MissLabel
// It's secure
func (v *SummaryVecDecorator) With(labels prometheus.Labels) prometheus.Observer {
// To avoid initialization sequence, so must delay register to with func
v.once.Do(func() {
Register(v)
})
safeLabels := labelAlignment(v.secureLabels, labels)
//
c, err := v.GetMetricWith(safeLabels)
if err != nil {
// should never happen , but should still add handler to record alert
// TODO singleton alert Gauge and return
}
//prometheus.NewCounter(v.SummaryVec.)
return c
}
// 标签对齐
func labelAlignment(labelNames []string, labels prometheus.Labels) prometheus.Labels {
newLabels := make(prometheus.Labels, len(labelNames))
for _, val := range labelNames {
if v, ok := labels[val]; ok {
newLabels[val] = v
} else {
newLabels[val] = missVal
}
}
return newLabels
}