blob: 977d9d216ec4a2cee3c1af68ec297630476569f4 [file] [log] [blame]
package prometheus
import (
"bytes"
"sync"
)
import (
prom "github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
"github.com/prometheus/common/expfmt"
)
import (
"dubbo.apache.org/dubbo-go/v3/metrics"
)
func init() {
metrics.SetRegistry("prometheus", func(rc *metrics.ReporterConfig) metrics.MetricRegistry {
return &promMetricRegistry{
cvm: make(map[string]*prom.CounterVec),
gvm: make(map[string]*prom.GaugeVec),
hvm: make(map[string]*prom.HistogramVec),
svm: make(map[string]*prom.SummaryVec),
}
})
}
type promMetricRegistry struct {
mtx sync.RWMutex // Protects metrics.
cvm map[string]*prom.CounterVec // prom.CounterVec
gvm map[string]*prom.GaugeVec // prom.GaugeVec
hvm map[string]*prom.HistogramVec // prom.HistogramVec
svm map[string]*prom.SummaryVec // prom.SummaryVec
}
func (p *promMetricRegistry) Counter(m *metrics.MetricId) metrics.CounterMetric {
p.mtx.RLock()
vec, ok := p.cvm[m.Name]
p.mtx.RUnlock()
if !ok {
p.mtx.Lock()
vec = promauto.NewCounterVec(prom.CounterOpts{
Name: m.Name,
Help: m.Desc,
}, m.TagKeys())
p.cvm[m.Name] = vec
p.mtx.Unlock()
}
c := vec.With(m.Tags)
return &counter{pc: c}
}
func (p *promMetricRegistry) Gauge(m *metrics.MetricId) metrics.GaugeMetric {
p.mtx.RLock()
vec, ok := p.gvm[m.Name]
p.mtx.RUnlock()
if !ok {
p.mtx.Lock()
vec = promauto.NewGaugeVec(prom.GaugeOpts{
Name: m.Name,
Help: m.Desc,
}, m.TagKeys())
p.gvm[m.Name] = vec
p.mtx.Unlock()
}
g := vec.With(m.Tags)
return &gauge{pg: g}
}
func (p *promMetricRegistry) Histogram(m *metrics.MetricId) metrics.HistogramMetric {
p.mtx.RLock()
vec, ok := p.hvm[m.Name]
p.mtx.RUnlock()
if !ok {
p.mtx.Lock()
vec = promauto.NewHistogramVec(prom.HistogramOpts{
Name: m.Name,
Help: m.Desc,
}, m.TagKeys())
p.hvm[m.Name] = vec
p.mtx.Unlock()
}
h := vec.With(m.Tags)
return &histogram{ph: h.(prom.Histogram)}
}
func (p *promMetricRegistry) Summary(m *metrics.MetricId) metrics.SummaryMetric {
p.mtx.RLock()
vec, ok := p.svm[m.Name]
p.mtx.RUnlock()
if !ok {
p.mtx.Lock()
vec = promauto.NewSummaryVec(prom.SummaryOpts{
Name: m.Name,
Help: m.Desc,
}, m.TagKeys())
p.svm[m.Name] = vec
p.mtx.Unlock()
}
s := vec.With(m.Tags)
return &summary{ps: s.(prom.Summary)}
}
func (p *promMetricRegistry) Export() {
}
func (p *promMetricRegistry) Scrape() (string, error) {
r := prom.DefaultRegisterer.(*prom.Registry)
gathering, err := r.Gather()
if err != nil {
return "", err
}
out := &bytes.Buffer{}
for _, mf := range gathering {
if _, err := expfmt.MetricFamilyToText(out, mf); err != nil {
return "", err
}
}
return out.String(), nil
}
type counter struct {
pc prom.Counter
}
func (c *counter) Inc() {
c.pc.Inc()
}
func (c *counter) Add(v float64) {
c.pc.Add(v)
}
type gauge struct {
pg prom.Gauge
}
// func (g *gauge) Inc() {
// g.pg.Inc()
// }
//
// func (g *gauge) Dec() {
// g.pg.Dec()
// }
func (g *gauge) Set(v float64) {
g.pg.Set(v)
}
// func (g *gauge) Add(v float64) {
// g.pg.Add(v)
// }
// func (g *gauge) Sub(v float64) {
// g.pg.Sub(v)
// }
type histogram struct {
ph prom.Histogram
}
func (h *histogram) Record(v float64) {
h.ph.Observe(v)
}
type summary struct {
ps prom.Summary
}
func (s *summary) Record(v float64) {
s.ps.Observe(v)
}