-
Notifications
You must be signed in to change notification settings - Fork 1
/
gauge.go
104 lines (82 loc) · 2.12 KB
/
gauge.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
97
98
99
100
101
102
103
104
package openmetrics
import (
"math"
"sync/atomic"
)
// GaugeFamily is a metric family of Gauges.
type GaugeFamily interface {
MetricFamily
// With returns a Gauge for the given label values.
With(labelValues ...string) Gauge
}
type gaugeFamily struct {
metricFamily
}
func (f *gaugeFamily) With(labelValues ...string) Gauge {
met, err := f.with(labelValues...)
if err != nil {
f.onError(err)
return nullGauge{}
}
return met.(Gauge)
}
// ----------------------------------------------------------------------------
const float64BitsNaN = 0x7FF9000000000001
// GaugeOptions configure Gauge instances.
type GaugeOptions struct{}
// Gauge is a Metric.
type Gauge interface {
Metric
// Set sets the value.
Set(val float64)
// Add increments the value.
Add(val float64)
// Value returns the current value.
Value() float64
// Reset resets the gauge to its original state.
Reset(GaugeOptions)
}
type gauge uint64
// NewGauge inits a new Gauge.
func NewGauge(_ GaugeOptions) Gauge {
var v gauge = float64BitsNaN
return &v
}
func (m *gauge) AppendPoints(dst []MetricPoint, _ *Desc) ([]MetricPoint, error) {
if *m == float64BitsNaN {
return dst, nil
}
return append(dst,
MetricPoint{Value: m.Value()},
), nil
}
func (m *gauge) Set(val float64) {
atomic.StoreUint64((*uint64)(m), math.Float64bits(val))
}
func (m *gauge) Add(val float64) {
for {
cur := atomic.LoadUint64((*uint64)(m))
sum := math.Float64bits(normalizeFloat(math.Float64frombits(cur)) + val)
if atomic.CompareAndSwapUint64((*uint64)(m), cur, sum) {
return
}
}
}
func (m *gauge) Reset(_ GaugeOptions) {
atomic.StoreUint64((*uint64)(m), float64BitsNaN)
}
func (m *gauge) Value() float64 {
return math.Float64frombits(atomic.LoadUint64((*uint64)(m)))
}
type nullGauge struct{}
func (nullGauge) AppendPoints(dst []MetricPoint, _ *Desc) ([]MetricPoint, error) { return dst, nil }
func (nullGauge) Set(_ float64) {}
func (nullGauge) Add(_ float64) {}
func (nullGauge) Value() float64 { return 0.0 }
func (nullGauge) Reset(_ GaugeOptions) {}
func normalizeFloat(x float64) float64 {
if math.IsNaN(x) {
return 0
}
return x
}