84 lines
2.0 KiB
Go
84 lines
2.0 KiB
Go
package client
|
|
|
|
import (
|
|
"math"
|
|
_ "net/http/pprof"
|
|
"sync/atomic"
|
|
"unsafe"
|
|
|
|
"github.com/prometheus/client_golang/prometheus"
|
|
"repositories.action2quare.com/ayo/gocommon/metric"
|
|
)
|
|
|
|
type metricDesc struct {
|
|
*prometheus.Desc
|
|
val *uint64
|
|
valueType prometheus.ValueType
|
|
}
|
|
|
|
type exporterForPrometheus struct {
|
|
metricPtr unsafe.Pointer // []metricDesc
|
|
}
|
|
|
|
func newExporterForPrometheus() *exporterForPrometheus {
|
|
return &exporterForPrometheus{
|
|
metricPtr: unsafe.Pointer(new([]metricDesc)),
|
|
}
|
|
}
|
|
|
|
type metricValueAccessor struct {
|
|
ptr *uint64
|
|
}
|
|
|
|
func (va metricValueAccessor) set(val float64) {
|
|
atomic.StoreUint64(va.ptr, math.Float64bits(val))
|
|
}
|
|
|
|
func convertValueType(in metric.MetricType) prometheus.ValueType {
|
|
switch in {
|
|
case metric.MetricCounter:
|
|
return prometheus.CounterValue
|
|
|
|
case metric.MetricGuage:
|
|
return prometheus.GaugeValue
|
|
}
|
|
|
|
return prometheus.UntypedValue
|
|
}
|
|
|
|
func (e *exporterForPrometheus) registMetric(namespace string, desc metric.MetricDescription) metricValueAccessor {
|
|
ptr := atomic.LoadPointer(&e.metricPtr)
|
|
container := *(*[]metricDesc)(ptr)
|
|
|
|
newcont := make([]metricDesc, len(container)+1)
|
|
copy(newcont, container)
|
|
|
|
newval := new(uint64)
|
|
newcont[len(container)] = metricDesc{
|
|
Desc: prometheus.NewDesc(prometheus.BuildFQName(namespace, "", desc.Name), desc.Help, nil, desc.ConstLabels),
|
|
val: newval,
|
|
valueType: convertValueType(desc.Type),
|
|
}
|
|
|
|
atomic.StorePointer(&e.metricPtr, unsafe.Pointer(&newcont))
|
|
return metricValueAccessor{
|
|
ptr: newval,
|
|
}
|
|
}
|
|
|
|
func (e *exporterForPrometheus) Describe(ch chan<- *prometheus.Desc) {
|
|
ptr := atomic.LoadPointer(&e.metricPtr)
|
|
container := *(*[]metricDesc)(ptr)
|
|
for _, v := range container {
|
|
ch <- v.Desc
|
|
}
|
|
}
|
|
|
|
func (e *exporterForPrometheus) Collect(ch chan<- prometheus.Metric) {
|
|
ptr := atomic.LoadPointer(&e.metricPtr)
|
|
container := *(*[]metricDesc)(ptr)
|
|
for _, v := range container {
|
|
ch <- prometheus.MustNewConstMetric(v.Desc, v.valueType, math.Float64frombits(atomic.LoadUint64(v.val)))
|
|
}
|
|
}
|