/
counter.go
132 lines (108 loc) · 3.08 KB
/
counter.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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
package publisher
import (
"github.com/prometheus/client_golang/prometheus"
"github.com/the-anna-project/instrumentor/spec"
)
// CounterConfig represents the configuration used to create a new prometheus
// publisher counter object.
type CounterConfig struct {
// Settings.
// help represents some sort of informative description of the registered
// metric.
help string
// labels represents labels as being used by prometheus. They partition
// metrics.
labels []string
// name represents the metric's key as it is supposed to be registered. In the
// scope of prometheus publisher this is expected to be an underscored
// string.
name string
}
func (cc *CounterConfig) Help() string {
return cc.help
}
func (cc *CounterConfig) Labels() []string {
return cc.labels
}
func (cc *CounterConfig) Name() string {
return cc.name
}
func (cc *CounterConfig) SetHelp(help string) {
cc.help = help
}
func (cc *CounterConfig) SetLabels(labels []string) {
cc.labels = labels
}
func (cc *CounterConfig) SetName(name string) {
cc.name = name
}
// DefaultCounterConfig provides a default configuration to create a new
// prometheus publisher counter object by best effort.
func DefaultCounterConfig() *CounterConfig {
newConfig := &CounterConfig{
// Settings.
help: "",
labels: nil,
name: "",
}
return newConfig
}
// NewCounter creates a new configured prometheus publisher counter object.
func NewCounter(config spec.CounterConfig) (*Counter, error) {
// Settings.
if config.Help() == "" {
return nil, maskAnyf(invalidConfigError, "help must not be empty")
}
if config.Name() == "" {
return nil, maskAnyf(invalidConfigError, "name must not be empty")
}
var clientCounter prometheus.Counter
var clientCounterVec *prometheus.CounterVec
if len(config.Labels()) == 0 {
clientCounter = prometheus.NewCounter(
prometheus.CounterOpts{
Help: config.Help(),
Name: config.Name(),
},
)
} else {
clientCounterVec = prometheus.NewCounterVec(
prometheus.CounterOpts{
Help: config.Help(),
Name: config.Name(),
},
config.Labels(),
)
}
newCounter := &Counter{
ClientCounter: clientCounter,
ClientCounterVec: clientCounterVec,
}
return newCounter, nil
}
type Counter struct {
// Public.
ClientCounter prometheus.Counter
ClientCounterVec *prometheus.CounterVec
}
func (c *Counter) Increment(delta float64) error {
if c.ClientCounter == nil {
// This error indicates that the counter has been configured with labels.
// Therefore Counter.ObserveWithLabels must be used.
return maskAnyf(invalidConfigError, "counter must be configured")
}
c.ClientCounter.Add(delta)
return nil
}
func (c *Counter) IncrementWithLabels(delta float64, values ...string) error {
if c.ClientCounterVec == nil {
// This error indicates that the counter has not been configured with
// labels. Therefore Counter.Observe must be used.
return maskAnyf(invalidConfigError, "counter must be configured")
}
if len(values) == 0 {
return maskAnyf(invalidConfigError, "labels must not be empty")
}
c.ClientCounterVec.WithLabelValues(values...).Add(delta)
return nil
}