109 lines
2.4 KiB
Go
109 lines
2.4 KiB
Go
package metric
|
|
|
|
import (
|
|
"maps"
|
|
"math"
|
|
"sync/atomic"
|
|
|
|
"github.com/prometheus/client_golang/prometheus"
|
|
"repositories.action2quare.com/ayo/gocommon/logger"
|
|
)
|
|
|
|
const (
|
|
METRIC_HEAD_INLINE = byte(14)
|
|
METRIC_TAIL_INLINE = byte(15)
|
|
)
|
|
|
|
type MetricType int
|
|
|
|
const (
|
|
MetricCounter = MetricType(1)
|
|
MetricGuage = MetricType(2)
|
|
metric_key_size = 8
|
|
)
|
|
|
|
func convertValueType(in MetricType) prometheus.ValueType {
|
|
switch in {
|
|
case MetricCounter:
|
|
return prometheus.CounterValue
|
|
|
|
case MetricGuage:
|
|
return prometheus.GaugeValue
|
|
}
|
|
|
|
return prometheus.UntypedValue
|
|
}
|
|
|
|
type prometheusMetricDesc struct {
|
|
*prometheus.Desc
|
|
valueType prometheus.ValueType
|
|
valptr *uint64
|
|
key string
|
|
}
|
|
|
|
type PrometheusCollector struct {
|
|
namespace string
|
|
metrics map[string]*prometheusMetricDesc
|
|
registry *prometheus.Registry
|
|
}
|
|
|
|
func (pc *PrometheusCollector) Describe(ch chan<- *prometheus.Desc) {
|
|
for _, v := range pc.metrics {
|
|
logger.Println("collector describe :", v.Desc.String())
|
|
ch <- v.Desc
|
|
}
|
|
}
|
|
|
|
func (pc *PrometheusCollector) Collect(ch chan<- prometheus.Metric) {
|
|
for _, v := range pc.metrics {
|
|
value := atomic.LoadUint64(v.valptr)
|
|
cm, err := prometheus.NewConstMetric(v.Desc, v.valueType, math.Float64frombits(value))
|
|
if err == nil {
|
|
ch <- cm
|
|
}
|
|
}
|
|
}
|
|
|
|
func (pc *PrometheusCollector) RegisterMetric(md *MetricDescription) *PrometheusCollector {
|
|
nm := &prometheusMetricDesc{
|
|
Desc: prometheus.NewDesc(prometheus.BuildFQName("ou", "", md.Name), md.Help, nil, md.ConstLabels),
|
|
valueType: convertValueType(md.Type),
|
|
valptr: new(uint64),
|
|
key: md.Key,
|
|
}
|
|
|
|
next := NewPrometheusCollector(pc.namespace, pc.registry)
|
|
maps.Copy(next.metrics, pc.metrics)
|
|
next.metrics[nm.key] = nm
|
|
|
|
pc.registry.Unregister(pc)
|
|
pc.registry.Register(next)
|
|
|
|
return next
|
|
}
|
|
|
|
func (pc *PrometheusCollector) UpdateMetric(key string, val float64) {
|
|
if m := pc.metrics[key]; m != nil {
|
|
atomic.StoreUint64(m.valptr, math.Float64bits(val))
|
|
}
|
|
}
|
|
|
|
func (pc *PrometheusCollector) UnregisterMetric(key string) *PrometheusCollector {
|
|
next := NewPrometheusCollector(pc.namespace, pc.registry)
|
|
maps.Copy(next.metrics, pc.metrics)
|
|
delete(next.metrics, key)
|
|
|
|
pc.registry.Unregister(pc)
|
|
pc.registry.Register(next)
|
|
|
|
return next
|
|
}
|
|
|
|
func NewPrometheusCollector(namespace string, registry *prometheus.Registry) *PrometheusCollector {
|
|
return &PrometheusCollector{
|
|
namespace: namespace,
|
|
metrics: make(map[string]*prometheusMetricDesc),
|
|
registry: registry,
|
|
}
|
|
}
|