212 lines
6.9 KiB
Go
212 lines
6.9 KiB
Go
package prom
|
||
|
||
import (
|
||
"fmt"
|
||
"sync/atomic"
|
||
|
||
ginPprof "github.com/gin-contrib/pprof"
|
||
"github.com/gin-gonic/gin"
|
||
"github.com/prometheus/client_golang/prometheus"
|
||
"github.com/prometheus/client_golang/prometheus/promhttp"
|
||
)
|
||
|
||
func NewCounter(name string) *PromeCounterStatMgr {
|
||
mgr := new(PromeCounterStatMgr)
|
||
mgr.promeStatMgr = newPromeStatMgr(name, func(defaultLabels, labels []string) prometheus.Collector {
|
||
return newCounterVec(name, defaultLabels, labels)
|
||
})
|
||
return mgr
|
||
}
|
||
|
||
func NewGauge(name string) *PromeGaugeStatMgr {
|
||
mgr := new(PromeGaugeStatMgr)
|
||
mgr.promeStatMgr = newPromeStatMgr(name, func(defaultLabels, labels []string) prometheus.Collector {
|
||
return newGagueVec(name, defaultLabels, labels)
|
||
})
|
||
return mgr
|
||
}
|
||
|
||
func NewHistogram(name string, buckets []float64) *PromeHistogramStatMgr {
|
||
mgr := new(PromeHistogramStatMgr)
|
||
mgr.promeStatMgr = newPromeStatMgr(name, func(defaultLabels, labels []string) prometheus.Collector {
|
||
return newHistogramVec(name, defaultLabels, labels, buckets)
|
||
})
|
||
return mgr
|
||
}
|
||
|
||
type PromeCounterStatMgr struct {
|
||
*promeStatMgr
|
||
}
|
||
|
||
// InitLabels 初始化指标的标签说明,以后每次收集指标都给上标签值
|
||
func (c *PromeCounterStatMgr) InitLabels(labels []string) *PromeCounterStatMgr {
|
||
return c.InitDefaultLabels(nil, labels)
|
||
}
|
||
|
||
// InitDefaultLabels 带上默认标签,例如某些服务启动就能知道标签值,比如app_name,app_id等,
|
||
// 又不想每次收集指标都传递标签值,可以用此方法一开始就设置好
|
||
func (c *PromeCounterStatMgr) InitDefaultLabels(defaultLabels map[string]string, labels []string) *PromeCounterStatMgr {
|
||
c.promeStatMgr.withDefaultLabels(defaultLabels, labels)
|
||
return c
|
||
}
|
||
|
||
// LabelValues 准备收集指标,调用这个传递标签值,后续再给上指标值
|
||
// 即:c.LabelValues("xxx").Add(234)
|
||
func (c *PromeCounterStatMgr) LabelValues(labels ...string) prometheus.Counter {
|
||
return c.promeStatMgr.getCounterWithLabels(labels...)
|
||
}
|
||
|
||
type PromeGaugeStatMgr struct {
|
||
*promeStatMgr
|
||
}
|
||
|
||
// InitLabels 初始化指标的标签说明,以后每次收集指标都给上标签值
|
||
func (c *PromeGaugeStatMgr) InitLabels(labels []string) *PromeGaugeStatMgr {
|
||
return c.InitDefaultLabels(nil, labels)
|
||
}
|
||
|
||
// InitDefaultLabels 带上默认标签,例如某些服务启动就能知道标签值,比如app_name,app_id等,
|
||
// 又不想每次收集指标都传递标签值,可以用此方法一开始就设置好
|
||
func (c *PromeGaugeStatMgr) InitDefaultLabels(defaultLabels map[string]string, labels []string) *PromeGaugeStatMgr {
|
||
c.promeStatMgr.withDefaultLabels(defaultLabels, labels)
|
||
return c
|
||
}
|
||
|
||
// LabelValues 准备收集指标,调用这个传递标签值,后续再给上指标值
|
||
// 即:c.LabelValues("xxx").Add(234)
|
||
func (c *PromeGaugeStatMgr) LabelValues(labels ...string) prometheus.Gauge {
|
||
return c.promeStatMgr.getGaugeWithLabels(labels...)
|
||
}
|
||
|
||
type PromeHistogramStatMgr struct {
|
||
*promeStatMgr
|
||
}
|
||
|
||
// InitLabels 初始化指标的标签说明,以后每次收集指标都给上标签值
|
||
func (c *PromeHistogramStatMgr) InitLabels(labels []string) *PromeHistogramStatMgr {
|
||
return c.InitDefaultLabels(nil, labels)
|
||
}
|
||
|
||
// InitDefaultLabels 带上默认标签,例如某些服务启动就能知道标签值,比如app_name,app_id等,
|
||
// 又不想每次收集指标都传递标签值,可以用此方法一开始就设置好
|
||
func (c *PromeHistogramStatMgr) InitDefaultLabels(defaultLabels map[string]string, labels []string) *PromeHistogramStatMgr {
|
||
c.promeStatMgr.withDefaultLabels(defaultLabels, labels)
|
||
return c
|
||
}
|
||
|
||
// LabelValues 准备收集指标,调用这个传递标签值,后续再给上指标值
|
||
// 即:c.LabelValues("xxx").Add(234)
|
||
func (c *PromeHistogramStatMgr) LabelValues(labels ...string) prometheus.Observer {
|
||
return c.promeStatMgr.getHistogramWithLabels(labels...)
|
||
}
|
||
|
||
type promeStatMgr struct {
|
||
collector prometheus.Collector
|
||
name string
|
||
newCollectorFun func(defaultLabels, labels []string) prometheus.Collector
|
||
defaultLabelsValue []string
|
||
initCounter int32
|
||
}
|
||
|
||
func (mgr *promeStatMgr) withDefaultLabels(defaultLabels map[string]string, labels []string) {
|
||
if atomic.AddInt32(&mgr.initCounter, 1) > 1 {
|
||
panic(fmt.Errorf("promethus vec labels must init once"))
|
||
}
|
||
|
||
defaultLabelKeys := make([]string, 0)
|
||
defaultLabelValues := make([]string, 0)
|
||
for k, v := range defaultLabels {
|
||
defaultLabelKeys = append(defaultLabelKeys, k)
|
||
defaultLabelValues = append(defaultLabelValues, v)
|
||
}
|
||
|
||
mgr.defaultLabelsValue = defaultLabelValues
|
||
mgr.collector = mgr.newCollectorFun(defaultLabelKeys, labels)
|
||
return
|
||
}
|
||
|
||
func (mgr *promeStatMgr) joinLabels(labels ...string) []string {
|
||
newLabels := make([]string, 0, len(mgr.defaultLabelsValue)+len(labels))
|
||
newLabels = append(newLabels, mgr.defaultLabelsValue...)
|
||
newLabels = append(newLabels, labels...)
|
||
return newLabels
|
||
}
|
||
|
||
func (mgr *promeStatMgr) getCounterWithLabels(labels ...string) prometheus.Counter {
|
||
newLabels := mgr.joinLabels(labels...)
|
||
return mgr.collector.(*prometheus.CounterVec).WithLabelValues(newLabels...)
|
||
}
|
||
|
||
func (mgr *promeStatMgr) getGaugeWithLabels(labels ...string) prometheus.Gauge {
|
||
newLabels := mgr.joinLabels(labels...)
|
||
return mgr.collector.(*prometheus.GaugeVec).WithLabelValues(newLabels...)
|
||
}
|
||
|
||
func (mgr *promeStatMgr) getHistogramWithLabels(labels ...string) prometheus.Observer {
|
||
newLabels := mgr.joinLabels(labels...)
|
||
return mgr.collector.(*prometheus.HistogramVec).WithLabelValues(newLabels...)
|
||
}
|
||
|
||
func newPromeStatMgr(name string,
|
||
newCollectorFun func(defaultLabelsKey []string, labels []string) prometheus.Collector) *promeStatMgr {
|
||
mgr := new(promeStatMgr)
|
||
mgr.name = name
|
||
mgr.newCollectorFun = newCollectorFun
|
||
return mgr
|
||
}
|
||
|
||
func newCounterVec(name string, defaultLabels []string, dynamicLabels []string) prometheus.Collector {
|
||
vec := prometheus.NewCounterVec(
|
||
prometheus.CounterOpts{
|
||
Name: name,
|
||
Help: name,
|
||
},
|
||
append(defaultLabels, dynamicLabels...),
|
||
)
|
||
prometheus.MustRegister(vec)
|
||
return vec
|
||
}
|
||
|
||
func newGagueVec(name string, defaultLabels []string, dynamicLabels []string) prometheus.Collector {
|
||
vec := prometheus.NewGaugeVec(
|
||
prometheus.GaugeOpts{
|
||
Name: name,
|
||
Help: name,
|
||
},
|
||
append(defaultLabels, dynamicLabels...),
|
||
)
|
||
prometheus.MustRegister(vec)
|
||
return vec
|
||
}
|
||
|
||
func newHistogramVec(name string, defaultLabels []string, dynamicLabels []string, buckets []float64) prometheus.Collector {
|
||
vec := prometheus.NewHistogramVec(
|
||
prometheus.HistogramOpts{
|
||
Name: name,
|
||
Help: name,
|
||
Buckets: buckets,
|
||
},
|
||
append(defaultLabels, dynamicLabels...),
|
||
)
|
||
prometheus.MustRegister(vec)
|
||
return vec
|
||
}
|
||
|
||
func NewEngine(enablePprof bool) *gin.Engine {
|
||
//gin.SetMode(gin.ReleaseMode)
|
||
engine := gin.New()
|
||
engine.Use(gin.Recovery())
|
||
RouteEngine(engine, enablePprof)
|
||
return engine
|
||
}
|
||
|
||
func RouteEngine(engine *gin.Engine, enablePprof bool) {
|
||
if enablePprof {
|
||
ginPprof.Register(engine)
|
||
}
|
||
engine.Use(gin.LoggerWithConfig(gin.LoggerConfig{
|
||
SkipPaths: []string{"/metrics"},
|
||
}))
|
||
engine.GET("/metrics", gin.WrapH(promhttp.Handler()))
|
||
}
|