mirror of
https://github.com/open-telemetry/opentelemetry-go.git
synced 2025-04-13 11:30:31 +02:00
Replace meterRegistry with cache (#3255)
This commit is contained in:
parent
ff18552791
commit
4a3adaafd4
@ -16,7 +16,6 @@ package metric // import "go.opentelemetry.io/otel/sdk/metric"
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sync"
|
||||
|
||||
"go.opentelemetry.io/otel/metric"
|
||||
"go.opentelemetry.io/otel/metric/instrument"
|
||||
@ -27,49 +26,6 @@ import (
|
||||
"go.opentelemetry.io/otel/sdk/instrumentation"
|
||||
)
|
||||
|
||||
// meterRegistry keeps a record of initialized meters for instrumentation
|
||||
// scopes. A meter is unique to an instrumentation scope and if multiple
|
||||
// requests for that meter are made a meterRegistry ensure the same instance
|
||||
// is used.
|
||||
//
|
||||
// The zero meterRegistry is empty and ready for use.
|
||||
//
|
||||
// A meterRegistry must not be copied after first use.
|
||||
//
|
||||
// All methods of a meterRegistry are safe to call concurrently.
|
||||
type meterRegistry struct {
|
||||
sync.Mutex
|
||||
|
||||
meters map[instrumentation.Scope]*meter
|
||||
|
||||
pipes pipelines
|
||||
}
|
||||
|
||||
// Get returns a registered meter matching the instrumentation scope if it
|
||||
// exists in the meterRegistry. Otherwise, a new meter configured for the
|
||||
// instrumentation scope is registered and then returned.
|
||||
//
|
||||
// Get is safe to call concurrently.
|
||||
func (r *meterRegistry) Get(s instrumentation.Scope) *meter {
|
||||
r.Lock()
|
||||
defer r.Unlock()
|
||||
|
||||
if r.meters == nil {
|
||||
m := newMeter(s, r.pipes)
|
||||
r.meters = map[instrumentation.Scope]*meter{s: m}
|
||||
return m
|
||||
}
|
||||
|
||||
m, ok := r.meters[s]
|
||||
if ok {
|
||||
return m
|
||||
}
|
||||
|
||||
m = newMeter(s, r.pipes)
|
||||
r.meters[s] = m
|
||||
return m
|
||||
}
|
||||
|
||||
// meter handles the creation and coordination of all metric instruments. A
|
||||
// meter represents a single instrumentation scope; all metric telemetry
|
||||
// produced by an instrumentation scope will use metric instruments from a
|
||||
|
@ -31,28 +31,6 @@ import (
|
||||
"go.opentelemetry.io/otel/sdk/resource"
|
||||
)
|
||||
|
||||
func TestMeterRegistry(t *testing.T) {
|
||||
is0 := instrumentation.Scope{Name: "zero"}
|
||||
is1 := instrumentation.Scope{Name: "one"}
|
||||
|
||||
r := meterRegistry{}
|
||||
var m0 *meter
|
||||
t.Run("ZeroValueGetDoesNotPanic", func(t *testing.T) {
|
||||
assert.NotPanics(t, func() { m0 = r.Get(is0) })
|
||||
assert.Equal(t, is0, m0.Scope, "uninitialized meter returned")
|
||||
})
|
||||
|
||||
m01 := r.Get(is0)
|
||||
t.Run("GetSameMeter", func(t *testing.T) {
|
||||
assert.Samef(t, m0, m01, "returned different meters: %v", is0)
|
||||
})
|
||||
|
||||
m1 := r.Get(is1)
|
||||
t.Run("GetDifferentMeter", func(t *testing.T) {
|
||||
assert.NotSamef(t, m0, m1, "returned same meters: %v", is1)
|
||||
})
|
||||
}
|
||||
|
||||
// A meter should be able to make instruments concurrently.
|
||||
func TestMeterInstrumentConcurrency(t *testing.T) {
|
||||
wg := &sync.WaitGroup{}
|
||||
|
@ -26,7 +26,8 @@ import (
|
||||
// the same Views applied to them, and have their produced metric telemetry
|
||||
// passed to the configured Readers.
|
||||
type MeterProvider struct {
|
||||
meters meterRegistry
|
||||
pipes pipelines
|
||||
meters cache[instrumentation.Scope, *meter]
|
||||
|
||||
forceFlush, shutdown func(context.Context) error
|
||||
}
|
||||
@ -42,16 +43,9 @@ var _ metric.MeterProvider = (*MeterProvider)(nil)
|
||||
// Readers, will perform no operations.
|
||||
func NewMeterProvider(options ...Option) *MeterProvider {
|
||||
conf := newConfig(options)
|
||||
|
||||
flush, sdown := conf.readerSignals()
|
||||
|
||||
registry := newPipelines(conf.res, conf.readers)
|
||||
|
||||
return &MeterProvider{
|
||||
meters: meterRegistry{
|
||||
pipes: registry,
|
||||
},
|
||||
|
||||
pipes: newPipelines(conf.res, conf.readers),
|
||||
forceFlush: flush,
|
||||
shutdown: sdown,
|
||||
}
|
||||
@ -72,10 +66,13 @@ func NewMeterProvider(options ...Option) *MeterProvider {
|
||||
// This method is safe to call concurrently.
|
||||
func (mp *MeterProvider) Meter(name string, options ...metric.MeterOption) metric.Meter {
|
||||
c := metric.NewMeterConfig(options...)
|
||||
return mp.meters.Get(instrumentation.Scope{
|
||||
s := instrumentation.Scope{
|
||||
Name: name,
|
||||
Version: c.InstrumentationVersion(),
|
||||
SchemaURL: c.SchemaURL(),
|
||||
}
|
||||
return mp.meters.Lookup(s, func() *meter {
|
||||
return newMeter(s, mp.pipes)
|
||||
})
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user