1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package metric
16
17 import (
18 "sort"
19 "sync"
20 "time"
21
22 "go.opencensus.io/metric/metricdata"
23 )
24
25
26
27
28 type Registry struct {
29 baseMetrics sync.Map
30 }
31
32 type metricOptions struct {
33 unit metricdata.Unit
34 labelkeys []metricdata.LabelKey
35 constLabels map[metricdata.LabelKey]metricdata.LabelValue
36 desc string
37 }
38
39
40 type Options func(*metricOptions)
41
42
43 func WithDescription(desc string) Options {
44 return func(mo *metricOptions) {
45 mo.desc = desc
46 }
47 }
48
49
50 func WithUnit(unit metricdata.Unit) Options {
51 return func(mo *metricOptions) {
52 mo.unit = unit
53 }
54 }
55
56
57 func WithLabelKeys(keys ...string) Options {
58 return func(mo *metricOptions) {
59 labelKeys := make([]metricdata.LabelKey, 0)
60 for _, key := range keys {
61 labelKeys = append(labelKeys, metricdata.LabelKey{Key: key})
62 }
63 mo.labelkeys = labelKeys
64 }
65 }
66
67
68 func WithLabelKeysAndDescription(labelKeys ...metricdata.LabelKey) Options {
69 return func(mo *metricOptions) {
70 mo.labelkeys = labelKeys
71 }
72 }
73
74
75 func WithConstLabel(constLabels map[metricdata.LabelKey]metricdata.LabelValue) Options {
76 return func(mo *metricOptions) {
77 mo.constLabels = constLabels
78 }
79 }
80
81
82 func NewRegistry() *Registry {
83 return &Registry{}
84 }
85
86
87 func (r *Registry) AddFloat64Gauge(name string, mos ...Options) (*Float64Gauge, error) {
88 f := &Float64Gauge{
89 bm: baseMetric{
90 bmType: gaugeFloat64,
91 },
92 }
93 _, err := r.initBaseMetric(&f.bm, name, mos...)
94 if err != nil {
95 return nil, err
96 }
97 return f, nil
98 }
99
100
101 func (r *Registry) AddInt64Gauge(name string, mos ...Options) (*Int64Gauge, error) {
102 i := &Int64Gauge{
103 bm: baseMetric{
104 bmType: gaugeInt64,
105 },
106 }
107 _, err := r.initBaseMetric(&i.bm, name, mos...)
108 if err != nil {
109 return nil, err
110 }
111 return i, nil
112 }
113
114
115
116
117 func (r *Registry) AddInt64DerivedGauge(name string, mos ...Options) (*Int64DerivedGauge, error) {
118 i := &Int64DerivedGauge{
119 bm: baseMetric{
120 bmType: derivedGaugeInt64,
121 },
122 }
123 _, err := r.initBaseMetric(&i.bm, name, mos...)
124 if err != nil {
125 return nil, err
126 }
127 return i, nil
128 }
129
130
131
132
133 func (r *Registry) AddFloat64DerivedGauge(name string, mos ...Options) (*Float64DerivedGauge, error) {
134 f := &Float64DerivedGauge{
135 bm: baseMetric{
136 bmType: derivedGaugeFloat64,
137 },
138 }
139 _, err := r.initBaseMetric(&f.bm, name, mos...)
140 if err != nil {
141 return nil, err
142 }
143 return f, nil
144 }
145
146 func bmTypeToMetricType(bm *baseMetric) metricdata.Type {
147 switch bm.bmType {
148 case derivedGaugeFloat64:
149 return metricdata.TypeGaugeFloat64
150 case derivedGaugeInt64:
151 return metricdata.TypeGaugeInt64
152 case gaugeFloat64:
153 return metricdata.TypeGaugeFloat64
154 case gaugeInt64:
155 return metricdata.TypeGaugeInt64
156 case derivedCumulativeFloat64:
157 return metricdata.TypeCumulativeFloat64
158 case derivedCumulativeInt64:
159 return metricdata.TypeCumulativeInt64
160 case cumulativeFloat64:
161 return metricdata.TypeCumulativeFloat64
162 case cumulativeInt64:
163 return metricdata.TypeCumulativeInt64
164 default:
165 panic("unsupported metric type")
166 }
167 }
168
169
170 func (r *Registry) AddFloat64Cumulative(name string, mos ...Options) (*Float64Cumulative, error) {
171 f := &Float64Cumulative{
172 bm: baseMetric{
173 bmType: cumulativeFloat64,
174 },
175 }
176 _, err := r.initBaseMetric(&f.bm, name, mos...)
177 if err != nil {
178 return nil, err
179 }
180 return f, nil
181 }
182
183
184 func (r *Registry) AddInt64Cumulative(name string, mos ...Options) (*Int64Cumulative, error) {
185 i := &Int64Cumulative{
186 bm: baseMetric{
187 bmType: cumulativeInt64,
188 },
189 }
190 _, err := r.initBaseMetric(&i.bm, name, mos...)
191 if err != nil {
192 return nil, err
193 }
194 return i, nil
195 }
196
197
198
199
200 func (r *Registry) AddInt64DerivedCumulative(name string, mos ...Options) (*Int64DerivedCumulative, error) {
201 i := &Int64DerivedCumulative{
202 bm: baseMetric{
203 bmType: derivedCumulativeInt64,
204 },
205 }
206 _, err := r.initBaseMetric(&i.bm, name, mos...)
207 if err != nil {
208 return nil, err
209 }
210 return i, nil
211 }
212
213
214
215
216 func (r *Registry) AddFloat64DerivedCumulative(name string, mos ...Options) (*Float64DerivedCumulative, error) {
217 f := &Float64DerivedCumulative{
218 bm: baseMetric{
219 bmType: derivedCumulativeFloat64,
220 },
221 }
222 _, err := r.initBaseMetric(&f.bm, name, mos...)
223 if err != nil {
224 return nil, err
225 }
226 return f, nil
227 }
228
229 func createMetricOption(mos ...Options) *metricOptions {
230 o := &metricOptions{}
231 for _, mo := range mos {
232 mo(o)
233 }
234 return o
235 }
236
237 func (r *Registry) initBaseMetric(bm *baseMetric, name string, mos ...Options) (*baseMetric, error) {
238 val, ok := r.baseMetrics.Load(name)
239 if ok {
240 existing := val.(*baseMetric)
241 if existing.bmType != bm.bmType {
242 return nil, errMetricExistsWithDiffType
243 }
244 }
245 bm.start = time.Now()
246 o := createMetricOption(mos...)
247
248 var constLabelKeys []metricdata.LabelKey
249 for k := range o.constLabels {
250 constLabelKeys = append(constLabelKeys, k)
251 }
252 sort.Slice(constLabelKeys, func(i, j int) bool {
253 return constLabelKeys[i].Key < constLabelKeys[j].Key
254 })
255
256 var constLabelValues []metricdata.LabelValue
257 for _, k := range constLabelKeys {
258 constLabelValues = append(constLabelValues, o.constLabels[k])
259 }
260
261 bm.keys = append(constLabelKeys, o.labelkeys...)
262 bm.constLabelValues = constLabelValues
263
264 bm.desc = metricdata.Descriptor{
265 Name: name,
266 Description: o.desc,
267 Unit: o.unit,
268 LabelKeys: bm.keys,
269 Type: bmTypeToMetricType(bm),
270 }
271 r.baseMetrics.Store(name, bm)
272 return bm, nil
273 }
274
275
276 func (r *Registry) Read() []*metricdata.Metric {
277 ms := []*metricdata.Metric{}
278 r.baseMetrics.Range(func(k, v interface{}) bool {
279 bm := v.(*baseMetric)
280 ms = append(ms, bm.read())
281 return true
282 })
283 return ms
284 }
285
View as plain text