Skip to content

Commit 1333b2f

Browse files
Jesse-Bonfirepellareddashpoledmathieu
authored
Fix delegation for global MeterProviders (#5828)
Fixes #5827 Fixes #5852 --------- Co-authored-by: Robert Pająk <[email protected]> Co-authored-by: David Ashpole <[email protected]> Co-authored-by: Damien Mathieu <[email protected]>
1 parent 19877b1 commit 1333b2f

File tree

4 files changed

+128
-28
lines changed

4 files changed

+128
-28
lines changed

CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
2828
- The race condition for multiple `FixedSize` exemplar reservoirs identified in #5814 is resolved. (#5819)
2929
- Fix log records duplication in case of heterogeneous resource attributes by correctly mapping each log record to it's resource and scope. (#5803)
3030
- Fix timer channel drain to avoid hanging on Go 1.23. (#5868)
31+
- Fix delegation for global meter providers. (#5827)
32+
Change the `reflect.TypeOf` to use a nil pointer to not allocate on the heap unless necessary.
3133

3234
<!-- Released section -->
3335
<!-- Don't change this section unless doing release -->

internal/global/meter.go

+71-28
Original file line numberDiff line numberDiff line change
@@ -152,14 +152,17 @@ func (m *meter) Int64Counter(name string, options ...metric.Int64CounterOption)
152152
return m.delegate.Int64Counter(name, options...)
153153
}
154154

155-
i := &siCounter{name: name, opts: options}
156155
cfg := metric.NewInt64CounterConfig(options...)
157156
id := instID{
158157
name: name,
159-
kind: reflect.TypeOf(i),
158+
kind: reflect.TypeOf((*siCounter)(nil)),
160159
description: cfg.Description(),
161160
unit: cfg.Unit(),
162161
}
162+
if f, ok := m.instruments[id]; ok {
163+
return f.(metric.Int64Counter), nil
164+
}
165+
i := &siCounter{name: name, opts: options}
163166
m.instruments[id] = i
164167
return i, nil
165168
}
@@ -172,14 +175,17 @@ func (m *meter) Int64UpDownCounter(name string, options ...metric.Int64UpDownCou
172175
return m.delegate.Int64UpDownCounter(name, options...)
173176
}
174177

175-
i := &siUpDownCounter{name: name, opts: options}
176178
cfg := metric.NewInt64UpDownCounterConfig(options...)
177179
id := instID{
178180
name: name,
179-
kind: reflect.TypeOf(i),
181+
kind: reflect.TypeOf((*siUpDownCounter)(nil)),
180182
description: cfg.Description(),
181183
unit: cfg.Unit(),
182184
}
185+
if f, ok := m.instruments[id]; ok {
186+
return f.(metric.Int64UpDownCounter), nil
187+
}
188+
i := &siUpDownCounter{name: name, opts: options}
183189
m.instruments[id] = i
184190
return i, nil
185191
}
@@ -192,14 +198,17 @@ func (m *meter) Int64Histogram(name string, options ...metric.Int64HistogramOpti
192198
return m.delegate.Int64Histogram(name, options...)
193199
}
194200

195-
i := &siHistogram{name: name, opts: options}
196201
cfg := metric.NewInt64HistogramConfig(options...)
197202
id := instID{
198203
name: name,
199-
kind: reflect.TypeOf(i),
204+
kind: reflect.TypeOf((*siHistogram)(nil)),
200205
description: cfg.Description(),
201206
unit: cfg.Unit(),
202207
}
208+
if f, ok := m.instruments[id]; ok {
209+
return f.(metric.Int64Histogram), nil
210+
}
211+
i := &siHistogram{name: name, opts: options}
203212
m.instruments[id] = i
204213
return i, nil
205214
}
@@ -212,14 +221,17 @@ func (m *meter) Int64Gauge(name string, options ...metric.Int64GaugeOption) (met
212221
return m.delegate.Int64Gauge(name, options...)
213222
}
214223

215-
i := &siGauge{name: name, opts: options}
216224
cfg := metric.NewInt64GaugeConfig(options...)
217225
id := instID{
218226
name: name,
219-
kind: reflect.TypeOf(i),
227+
kind: reflect.TypeOf((*siGauge)(nil)),
220228
description: cfg.Description(),
221229
unit: cfg.Unit(),
222230
}
231+
if f, ok := m.instruments[id]; ok {
232+
return f.(metric.Int64Gauge), nil
233+
}
234+
i := &siGauge{name: name, opts: options}
223235
m.instruments[id] = i
224236
return i, nil
225237
}
@@ -232,14 +244,17 @@ func (m *meter) Int64ObservableCounter(name string, options ...metric.Int64Obser
232244
return m.delegate.Int64ObservableCounter(name, options...)
233245
}
234246

235-
i := &aiCounter{name: name, opts: options}
236247
cfg := metric.NewInt64ObservableCounterConfig(options...)
237248
id := instID{
238249
name: name,
239-
kind: reflect.TypeOf(i),
250+
kind: reflect.TypeOf((*aiCounter)(nil)),
240251
description: cfg.Description(),
241252
unit: cfg.Unit(),
242253
}
254+
if f, ok := m.instruments[id]; ok {
255+
return f.(metric.Int64ObservableCounter), nil
256+
}
257+
i := &aiCounter{name: name, opts: options}
243258
m.instruments[id] = i
244259
return i, nil
245260
}
@@ -252,14 +267,17 @@ func (m *meter) Int64ObservableUpDownCounter(name string, options ...metric.Int6
252267
return m.delegate.Int64ObservableUpDownCounter(name, options...)
253268
}
254269

255-
i := &aiUpDownCounter{name: name, opts: options}
256270
cfg := metric.NewInt64ObservableUpDownCounterConfig(options...)
257271
id := instID{
258272
name: name,
259-
kind: reflect.TypeOf(i),
273+
kind: reflect.TypeOf((*aiUpDownCounter)(nil)),
260274
description: cfg.Description(),
261275
unit: cfg.Unit(),
262276
}
277+
if f, ok := m.instruments[id]; ok {
278+
return f.(metric.Int64ObservableUpDownCounter), nil
279+
}
280+
i := &aiUpDownCounter{name: name, opts: options}
263281
m.instruments[id] = i
264282
return i, nil
265283
}
@@ -272,14 +290,17 @@ func (m *meter) Int64ObservableGauge(name string, options ...metric.Int64Observa
272290
return m.delegate.Int64ObservableGauge(name, options...)
273291
}
274292

275-
i := &aiGauge{name: name, opts: options}
276293
cfg := metric.NewInt64ObservableGaugeConfig(options...)
277294
id := instID{
278295
name: name,
279-
kind: reflect.TypeOf(i),
296+
kind: reflect.TypeOf((*aiGauge)(nil)),
280297
description: cfg.Description(),
281298
unit: cfg.Unit(),
282299
}
300+
if f, ok := m.instruments[id]; ok {
301+
return f.(metric.Int64ObservableGauge), nil
302+
}
303+
i := &aiGauge{name: name, opts: options}
283304
m.instruments[id] = i
284305
return i, nil
285306
}
@@ -292,14 +313,17 @@ func (m *meter) Float64Counter(name string, options ...metric.Float64CounterOpti
292313
return m.delegate.Float64Counter(name, options...)
293314
}
294315

295-
i := &sfCounter{name: name, opts: options}
296316
cfg := metric.NewFloat64CounterConfig(options...)
297317
id := instID{
298318
name: name,
299-
kind: reflect.TypeOf(i),
319+
kind: reflect.TypeOf((*sfCounter)(nil)),
300320
description: cfg.Description(),
301321
unit: cfg.Unit(),
302322
}
323+
if f, ok := m.instruments[id]; ok {
324+
return f.(metric.Float64Counter), nil
325+
}
326+
i := &sfCounter{name: name, opts: options}
303327
m.instruments[id] = i
304328
return i, nil
305329
}
@@ -312,14 +336,17 @@ func (m *meter) Float64UpDownCounter(name string, options ...metric.Float64UpDow
312336
return m.delegate.Float64UpDownCounter(name, options...)
313337
}
314338

315-
i := &sfUpDownCounter{name: name, opts: options}
316339
cfg := metric.NewFloat64UpDownCounterConfig(options...)
317340
id := instID{
318341
name: name,
319-
kind: reflect.TypeOf(i),
342+
kind: reflect.TypeOf((*sfUpDownCounter)(nil)),
320343
description: cfg.Description(),
321344
unit: cfg.Unit(),
322345
}
346+
if f, ok := m.instruments[id]; ok {
347+
return f.(metric.Float64UpDownCounter), nil
348+
}
349+
i := &sfUpDownCounter{name: name, opts: options}
323350
m.instruments[id] = i
324351
return i, nil
325352
}
@@ -332,14 +359,17 @@ func (m *meter) Float64Histogram(name string, options ...metric.Float64Histogram
332359
return m.delegate.Float64Histogram(name, options...)
333360
}
334361

335-
i := &sfHistogram{name: name, opts: options}
336362
cfg := metric.NewFloat64HistogramConfig(options...)
337363
id := instID{
338364
name: name,
339-
kind: reflect.TypeOf(i),
365+
kind: reflect.TypeOf((*sfHistogram)(nil)),
340366
description: cfg.Description(),
341367
unit: cfg.Unit(),
342368
}
369+
if f, ok := m.instruments[id]; ok {
370+
return f.(metric.Float64Histogram), nil
371+
}
372+
i := &sfHistogram{name: name, opts: options}
343373
m.instruments[id] = i
344374
return i, nil
345375
}
@@ -352,14 +382,17 @@ func (m *meter) Float64Gauge(name string, options ...metric.Float64GaugeOption)
352382
return m.delegate.Float64Gauge(name, options...)
353383
}
354384

355-
i := &sfGauge{name: name, opts: options}
356385
cfg := metric.NewFloat64GaugeConfig(options...)
357386
id := instID{
358387
name: name,
359-
kind: reflect.TypeOf(i),
388+
kind: reflect.TypeOf((*sfGauge)(nil)),
360389
description: cfg.Description(),
361390
unit: cfg.Unit(),
362391
}
392+
if f, ok := m.instruments[id]; ok {
393+
return f.(metric.Float64Gauge), nil
394+
}
395+
i := &sfGauge{name: name, opts: options}
363396
m.instruments[id] = i
364397
return i, nil
365398
}
@@ -372,14 +405,17 @@ func (m *meter) Float64ObservableCounter(name string, options ...metric.Float64O
372405
return m.delegate.Float64ObservableCounter(name, options...)
373406
}
374407

375-
i := &afCounter{name: name, opts: options}
376408
cfg := metric.NewFloat64ObservableCounterConfig(options...)
377409
id := instID{
378410
name: name,
379-
kind: reflect.TypeOf(i),
411+
kind: reflect.TypeOf((*afCounter)(nil)),
380412
description: cfg.Description(),
381413
unit: cfg.Unit(),
382414
}
415+
if f, ok := m.instruments[id]; ok {
416+
return f.(metric.Float64ObservableCounter), nil
417+
}
418+
i := &afCounter{name: name, opts: options}
383419
m.instruments[id] = i
384420
return i, nil
385421
}
@@ -392,14 +428,17 @@ func (m *meter) Float64ObservableUpDownCounter(name string, options ...metric.Fl
392428
return m.delegate.Float64ObservableUpDownCounter(name, options...)
393429
}
394430

395-
i := &afUpDownCounter{name: name, opts: options}
396431
cfg := metric.NewFloat64ObservableUpDownCounterConfig(options...)
397432
id := instID{
398433
name: name,
399-
kind: reflect.TypeOf(i),
434+
kind: reflect.TypeOf((*afUpDownCounter)(nil)),
400435
description: cfg.Description(),
401436
unit: cfg.Unit(),
402437
}
438+
if f, ok := m.instruments[id]; ok {
439+
return f.(metric.Float64ObservableUpDownCounter), nil
440+
}
441+
i := &afUpDownCounter{name: name, opts: options}
403442
m.instruments[id] = i
404443
return i, nil
405444
}
@@ -412,14 +451,17 @@ func (m *meter) Float64ObservableGauge(name string, options ...metric.Float64Obs
412451
return m.delegate.Float64ObservableGauge(name, options...)
413452
}
414453

415-
i := &afGauge{name: name, opts: options}
416454
cfg := metric.NewFloat64ObservableGaugeConfig(options...)
417455
id := instID{
418456
name: name,
419-
kind: reflect.TypeOf(i),
457+
kind: reflect.TypeOf((*afGauge)(nil)),
420458
description: cfg.Description(),
421459
unit: cfg.Unit(),
422460
}
461+
if f, ok := m.instruments[id]; ok {
462+
return f.(metric.Float64ObservableGauge), nil
463+
}
464+
i := &afGauge{name: name, opts: options}
423465
m.instruments[id] = i
424466
return i, nil
425467
}
@@ -487,6 +529,7 @@ func (c *registration) setDelegate(m metric.Meter) {
487529
reg, err := m.RegisterCallback(c.function, insts...)
488530
if err != nil {
489531
GetErrorHandler().Handle(err)
532+
return
490533
}
491534

492535
c.unreg = reg.Unregister

internal/global/meter_test.go

+20
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ package global // import "go.opentelemetry.io/otel/internal/global"
55

66
import (
77
"context"
8+
"errors"
89
"fmt"
910
"sync"
1011
"testing"
@@ -430,3 +431,22 @@ func TestMeterIdentity(t *testing.T) {
430431
}
431432
}
432433
}
434+
435+
type failingRegisterCallbackMeter struct {
436+
noop.Meter
437+
}
438+
439+
func (m *failingRegisterCallbackMeter) RegisterCallback(metric.Callback, ...metric.Observable) (metric.Registration, error) {
440+
return nil, errors.New("an error occurred")
441+
}
442+
443+
func TestRegistrationDelegateFailingCallback(t *testing.T) {
444+
r := &registration{
445+
unreg: func() error { return nil },
446+
}
447+
m := &failingRegisterCallbackMeter{}
448+
449+
assert.NotPanics(t, func() {
450+
r.setDelegate(m)
451+
})
452+
}

sdk/metric/meter_test.go

+35
Original file line numberDiff line numberDiff line change
@@ -2427,3 +2427,38 @@ func TestDuplicateInstrumentCreation(t *testing.T) {
24272427
})
24282428
}
24292429
}
2430+
2431+
func TestMeterProviderDelegation(t *testing.T) {
2432+
meter := otel.Meter("go.opentelemetry.io/otel/metric/internal/global/meter_test")
2433+
otel.SetErrorHandler(otel.ErrorHandlerFunc(func(err error) { require.NoError(t, err) }))
2434+
for i := 0; i < 5; i++ {
2435+
int64Counter, err := meter.Int64ObservableCounter("observable.int64.counter")
2436+
require.NoError(t, err)
2437+
int64UpDownCounter, err := meter.Int64ObservableUpDownCounter("observable.int64.up.down.counter")
2438+
require.NoError(t, err)
2439+
int64Gauge, err := meter.Int64ObservableGauge("observable.int64.gauge")
2440+
require.NoError(t, err)
2441+
floatCounter, err := meter.Float64ObservableCounter("observable.float.counter")
2442+
require.NoError(t, err)
2443+
floatUpDownCounter, err := meter.Float64ObservableUpDownCounter("observable.float.up.down.counter")
2444+
require.NoError(t, err)
2445+
floatGauge, err := meter.Float64ObservableGauge("observable.float.gauge")
2446+
require.NoError(t, err)
2447+
_, err = meter.RegisterCallback(func(ctx context.Context, o metric.Observer) error {
2448+
o.ObserveInt64(int64Counter, int64(10))
2449+
o.ObserveInt64(int64UpDownCounter, int64(10))
2450+
o.ObserveInt64(int64Gauge, int64(10))
2451+
2452+
o.ObserveFloat64(floatCounter, float64(10))
2453+
o.ObserveFloat64(floatUpDownCounter, float64(10))
2454+
o.ObserveFloat64(floatGauge, float64(10))
2455+
return nil
2456+
}, int64Counter, int64UpDownCounter, int64Gauge, floatCounter, floatUpDownCounter, floatGauge)
2457+
require.NoError(t, err)
2458+
}
2459+
provider := NewMeterProvider()
2460+
2461+
assert.NotPanics(t, func() {
2462+
otel.SetMeterProvider(provider)
2463+
})
2464+
}

0 commit comments

Comments
 (0)