1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package global
16
17 import (
18 "container/list"
19 "sync"
20 "sync/atomic"
21
22 "go.opentelemetry.io/otel/metric"
23 "go.opentelemetry.io/otel/metric/embedded"
24 )
25
26
27
28
29
30 type meterProvider struct {
31 embedded.MeterProvider
32
33 mtx sync.Mutex
34 meters map[il]*meter
35
36 delegate metric.MeterProvider
37 }
38
39
40
41
42
43
44
45
46
47 func (p *meterProvider) setDelegate(provider metric.MeterProvider) {
48 p.mtx.Lock()
49 defer p.mtx.Unlock()
50
51 p.delegate = provider
52
53 if len(p.meters) == 0 {
54 return
55 }
56
57 for _, meter := range p.meters {
58 meter.setDelegate(provider)
59 }
60
61 p.meters = nil
62 }
63
64
65 func (p *meterProvider) Meter(name string, opts ...metric.MeterOption) metric.Meter {
66 p.mtx.Lock()
67 defer p.mtx.Unlock()
68
69 if p.delegate != nil {
70 return p.delegate.Meter(name, opts...)
71 }
72
73
74
75 c := metric.NewMeterConfig(opts...)
76 key := il{
77 name: name,
78 version: c.InstrumentationVersion(),
79 }
80
81 if p.meters == nil {
82 p.meters = make(map[il]*meter)
83 }
84
85 if val, ok := p.meters[key]; ok {
86 return val
87 }
88
89 t := &meter{name: name, opts: opts}
90 p.meters[key] = t
91 return t
92 }
93
94
95
96
97
98 type meter struct {
99 embedded.Meter
100
101 name string
102 opts []metric.MeterOption
103
104 mtx sync.Mutex
105 instruments []delegatedInstrument
106
107 registry list.List
108
109 delegate atomic.Value
110 }
111
112 type delegatedInstrument interface {
113 setDelegate(metric.Meter)
114 }
115
116
117
118
119
120
121
122 func (m *meter) setDelegate(provider metric.MeterProvider) {
123 meter := provider.Meter(m.name, m.opts...)
124 m.delegate.Store(meter)
125
126 m.mtx.Lock()
127 defer m.mtx.Unlock()
128
129 for _, inst := range m.instruments {
130 inst.setDelegate(meter)
131 }
132
133 for e := m.registry.Front(); e != nil; e = e.Next() {
134 r := e.Value.(*registration)
135 r.setDelegate(meter)
136 m.registry.Remove(e)
137 }
138
139 m.instruments = nil
140 m.registry.Init()
141 }
142
143 func (m *meter) Int64Counter(name string, options ...metric.Int64CounterOption) (metric.Int64Counter, error) {
144 if del, ok := m.delegate.Load().(metric.Meter); ok {
145 return del.Int64Counter(name, options...)
146 }
147 m.mtx.Lock()
148 defer m.mtx.Unlock()
149 i := &siCounter{name: name, opts: options}
150 m.instruments = append(m.instruments, i)
151 return i, nil
152 }
153
154 func (m *meter) Int64UpDownCounter(name string, options ...metric.Int64UpDownCounterOption) (metric.Int64UpDownCounter, error) {
155 if del, ok := m.delegate.Load().(metric.Meter); ok {
156 return del.Int64UpDownCounter(name, options...)
157 }
158 m.mtx.Lock()
159 defer m.mtx.Unlock()
160 i := &siUpDownCounter{name: name, opts: options}
161 m.instruments = append(m.instruments, i)
162 return i, nil
163 }
164
165 func (m *meter) Int64Histogram(name string, options ...metric.Int64HistogramOption) (metric.Int64Histogram, error) {
166 if del, ok := m.delegate.Load().(metric.Meter); ok {
167 return del.Int64Histogram(name, options...)
168 }
169 m.mtx.Lock()
170 defer m.mtx.Unlock()
171 i := &siHistogram{name: name, opts: options}
172 m.instruments = append(m.instruments, i)
173 return i, nil
174 }
175
176 func (m *meter) Int64ObservableCounter(name string, options ...metric.Int64ObservableCounterOption) (metric.Int64ObservableCounter, error) {
177 if del, ok := m.delegate.Load().(metric.Meter); ok {
178 return del.Int64ObservableCounter(name, options...)
179 }
180 m.mtx.Lock()
181 defer m.mtx.Unlock()
182 i := &aiCounter{name: name, opts: options}
183 m.instruments = append(m.instruments, i)
184 return i, nil
185 }
186
187 func (m *meter) Int64ObservableUpDownCounter(name string, options ...metric.Int64ObservableUpDownCounterOption) (metric.Int64ObservableUpDownCounter, error) {
188 if del, ok := m.delegate.Load().(metric.Meter); ok {
189 return del.Int64ObservableUpDownCounter(name, options...)
190 }
191 m.mtx.Lock()
192 defer m.mtx.Unlock()
193 i := &aiUpDownCounter{name: name, opts: options}
194 m.instruments = append(m.instruments, i)
195 return i, nil
196 }
197
198 func (m *meter) Int64ObservableGauge(name string, options ...metric.Int64ObservableGaugeOption) (metric.Int64ObservableGauge, error) {
199 if del, ok := m.delegate.Load().(metric.Meter); ok {
200 return del.Int64ObservableGauge(name, options...)
201 }
202 m.mtx.Lock()
203 defer m.mtx.Unlock()
204 i := &aiGauge{name: name, opts: options}
205 m.instruments = append(m.instruments, i)
206 return i, nil
207 }
208
209 func (m *meter) Float64Counter(name string, options ...metric.Float64CounterOption) (metric.Float64Counter, error) {
210 if del, ok := m.delegate.Load().(metric.Meter); ok {
211 return del.Float64Counter(name, options...)
212 }
213 m.mtx.Lock()
214 defer m.mtx.Unlock()
215 i := &sfCounter{name: name, opts: options}
216 m.instruments = append(m.instruments, i)
217 return i, nil
218 }
219
220 func (m *meter) Float64UpDownCounter(name string, options ...metric.Float64UpDownCounterOption) (metric.Float64UpDownCounter, error) {
221 if del, ok := m.delegate.Load().(metric.Meter); ok {
222 return del.Float64UpDownCounter(name, options...)
223 }
224 m.mtx.Lock()
225 defer m.mtx.Unlock()
226 i := &sfUpDownCounter{name: name, opts: options}
227 m.instruments = append(m.instruments, i)
228 return i, nil
229 }
230
231 func (m *meter) Float64Histogram(name string, options ...metric.Float64HistogramOption) (metric.Float64Histogram, error) {
232 if del, ok := m.delegate.Load().(metric.Meter); ok {
233 return del.Float64Histogram(name, options...)
234 }
235 m.mtx.Lock()
236 defer m.mtx.Unlock()
237 i := &sfHistogram{name: name, opts: options}
238 m.instruments = append(m.instruments, i)
239 return i, nil
240 }
241
242 func (m *meter) Float64ObservableCounter(name string, options ...metric.Float64ObservableCounterOption) (metric.Float64ObservableCounter, error) {
243 if del, ok := m.delegate.Load().(metric.Meter); ok {
244 return del.Float64ObservableCounter(name, options...)
245 }
246 m.mtx.Lock()
247 defer m.mtx.Unlock()
248 i := &afCounter{name: name, opts: options}
249 m.instruments = append(m.instruments, i)
250 return i, nil
251 }
252
253 func (m *meter) Float64ObservableUpDownCounter(name string, options ...metric.Float64ObservableUpDownCounterOption) (metric.Float64ObservableUpDownCounter, error) {
254 if del, ok := m.delegate.Load().(metric.Meter); ok {
255 return del.Float64ObservableUpDownCounter(name, options...)
256 }
257 m.mtx.Lock()
258 defer m.mtx.Unlock()
259 i := &afUpDownCounter{name: name, opts: options}
260 m.instruments = append(m.instruments, i)
261 return i, nil
262 }
263
264 func (m *meter) Float64ObservableGauge(name string, options ...metric.Float64ObservableGaugeOption) (metric.Float64ObservableGauge, error) {
265 if del, ok := m.delegate.Load().(metric.Meter); ok {
266 return del.Float64ObservableGauge(name, options...)
267 }
268 m.mtx.Lock()
269 defer m.mtx.Unlock()
270 i := &afGauge{name: name, opts: options}
271 m.instruments = append(m.instruments, i)
272 return i, nil
273 }
274
275
276 func (m *meter) RegisterCallback(f metric.Callback, insts ...metric.Observable) (metric.Registration, error) {
277 if del, ok := m.delegate.Load().(metric.Meter); ok {
278 insts = unwrapInstruments(insts)
279 return del.RegisterCallback(f, insts...)
280 }
281
282 m.mtx.Lock()
283 defer m.mtx.Unlock()
284
285 reg := ®istration{instruments: insts, function: f}
286 e := m.registry.PushBack(reg)
287 reg.unreg = func() error {
288 m.mtx.Lock()
289 _ = m.registry.Remove(e)
290 m.mtx.Unlock()
291 return nil
292 }
293 return reg, nil
294 }
295
296 type wrapped interface {
297 unwrap() metric.Observable
298 }
299
300 func unwrapInstruments(instruments []metric.Observable) []metric.Observable {
301 out := make([]metric.Observable, 0, len(instruments))
302
303 for _, inst := range instruments {
304 if in, ok := inst.(wrapped); ok {
305 out = append(out, in.unwrap())
306 } else {
307 out = append(out, inst)
308 }
309 }
310
311 return out
312 }
313
314 type registration struct {
315 embedded.Registration
316
317 instruments []metric.Observable
318 function metric.Callback
319
320 unreg func() error
321 unregMu sync.Mutex
322 }
323
324 func (c *registration) setDelegate(m metric.Meter) {
325 insts := unwrapInstruments(c.instruments)
326
327 c.unregMu.Lock()
328 defer c.unregMu.Unlock()
329
330 if c.unreg == nil {
331
332 return
333 }
334
335 reg, err := m.RegisterCallback(c.function, insts...)
336 if err != nil {
337 GetErrorHandler().Handle(err)
338 }
339
340 c.unreg = reg.Unregister
341 }
342
343 func (c *registration) Unregister() error {
344 c.unregMu.Lock()
345 defer c.unregMu.Unlock()
346 if c.unreg == nil {
347
348 return nil
349 }
350
351 var err error
352 err, c.unreg = c.unreg(), nil
353 return err
354 }
355
View as plain text