forked from klaytn/klaytn
-
Notifications
You must be signed in to change notification settings - Fork 0
/
prometheusmetrics.go
96 lines (87 loc) · 2.93 KB
/
prometheusmetrics.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
// Copyright 2018 The klaytn Authors
//
// This file is derived from metrics/prometheus/prometheusmetrics.go (2018/06/04).
// See LICENSE in the top directory for the original copyright and license.
package prometheusmetrics
import (
"fmt"
"github.com/klaytn/klaytn/metrics"
"github.com/prometheus/client_golang/prometheus"
"strings"
"time"
)
// PrometheusConfig provides a container with config parameters for the Prometheus Exporter
type PrometheusConfig struct {
namespace string
Registry metrics.Registry // Registry to be exported
subsystem string
promRegistry prometheus.Registerer //Prometheus registry
FlushInterval time.Duration //interval to update prom metrics
gauges map[string]prometheus.Gauge
}
// NewPrometheusProvider returns a Provider that produces Prometheus metrics.
// Namespace and subsystem are applied to all produced metrics.
func NewPrometheusProvider(r metrics.Registry, namespace string, subsystem string, promRegistry prometheus.Registerer,
FlushInterval time.Duration) *PrometheusConfig {
return &PrometheusConfig{
namespace: namespace,
subsystem: subsystem,
Registry: r,
promRegistry: promRegistry,
FlushInterval: FlushInterval,
gauges: make(map[string]prometheus.Gauge),
}
}
func (c *PrometheusConfig) flattenKey(key string) string {
key = strings.Replace(key, " ", "_", -1)
key = strings.Replace(key, ".", "_", -1)
key = strings.Replace(key, "-", "_", -1)
key = strings.Replace(key, "=", "_", -1)
key = strings.Replace(key, "/", "_", -1)
return key
}
func (c *PrometheusConfig) gaugeFromNameAndValue(name string, val float64) {
key := fmt.Sprintf("%s_%s_%s", c.namespace, c.subsystem, name)
g, ok := c.gauges[key]
if !ok {
g = prometheus.NewGauge(prometheus.GaugeOpts{
Namespace: c.flattenKey(c.namespace),
Subsystem: c.flattenKey(c.subsystem),
Name: c.flattenKey(name),
Help: name,
})
c.promRegistry.MustRegister(g)
c.gauges[key] = g
}
g.Set(val)
}
func (c *PrometheusConfig) UpdatePrometheusMetrics() {
for range time.Tick(c.FlushInterval) {
c.UpdatePrometheusMetricsOnce()
}
}
func (c *PrometheusConfig) UpdatePrometheusMetricsOnce() error {
c.Registry.Each(func(name string, i interface{}) {
switch metric := i.(type) {
case metrics.Counter:
c.gaugeFromNameAndValue(name, float64(metric.Count()))
case metrics.Gauge:
c.gaugeFromNameAndValue(name, float64(metric.Value()))
case metrics.GaugeFloat64:
c.gaugeFromNameAndValue(name, float64(metric.Value()))
case metrics.Histogram:
samples := metric.Snapshot().Sample().Values()
if len(samples) > 0 {
lastSample := samples[len(samples)-1]
c.gaugeFromNameAndValue(name, float64(lastSample))
}
case metrics.Meter:
lastSample := metric.Snapshot().Rate1()
c.gaugeFromNameAndValue(name, float64(lastSample))
case metrics.Timer:
lastSample := metric.Snapshot().Rate1()
c.gaugeFromNameAndValue(name, float64(lastSample))
}
})
return nil
}