uniugm/admin/lib/prom/promethus.go
2025-04-18 17:17:23 +08:00

212 lines
6.9 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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_nameapp_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_nameapp_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_nameapp_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()))
}