Initial commit
This commit is contained in:
160
metric/metric.go
Normal file
160
metric/metric.go
Normal file
@@ -0,0 +1,160 @@
|
||||
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
|
||||
}
|
||||
Reference in New Issue
Block a user