mirror of
https://github.com/open-telemetry/opentelemetry-go.git
synced 2025-04-17 11:46:27 +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 (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"sync"
|
|
||||||
|
|
||||||
"go.opentelemetry.io/otel/metric"
|
"go.opentelemetry.io/otel/metric"
|
||||||
"go.opentelemetry.io/otel/metric/instrument"
|
"go.opentelemetry.io/otel/metric/instrument"
|
||||||
@ -27,49 +26,6 @@ import (
|
|||||||
"go.opentelemetry.io/otel/sdk/instrumentation"
|
"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 handles the creation and coordination of all metric instruments. A
|
||||||
// meter represents a single instrumentation scope; all metric telemetry
|
// meter represents a single instrumentation scope; all metric telemetry
|
||||||
// produced by an instrumentation scope will use metric instruments from a
|
// produced by an instrumentation scope will use metric instruments from a
|
||||||
|
@ -31,28 +31,6 @@ import (
|
|||||||
"go.opentelemetry.io/otel/sdk/resource"
|
"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.
|
// A meter should be able to make instruments concurrently.
|
||||||
func TestMeterInstrumentConcurrency(t *testing.T) {
|
func TestMeterInstrumentConcurrency(t *testing.T) {
|
||||||
wg := &sync.WaitGroup{}
|
wg := &sync.WaitGroup{}
|
||||||
|
@ -26,7 +26,8 @@ import (
|
|||||||
// the same Views applied to them, and have their produced metric telemetry
|
// the same Views applied to them, and have their produced metric telemetry
|
||||||
// passed to the configured Readers.
|
// passed to the configured Readers.
|
||||||
type MeterProvider struct {
|
type MeterProvider struct {
|
||||||
meters meterRegistry
|
pipes pipelines
|
||||||
|
meters cache[instrumentation.Scope, *meter]
|
||||||
|
|
||||||
forceFlush, shutdown func(context.Context) error
|
forceFlush, shutdown func(context.Context) error
|
||||||
}
|
}
|
||||||
@ -42,16 +43,9 @@ var _ metric.MeterProvider = (*MeterProvider)(nil)
|
|||||||
// Readers, will perform no operations.
|
// Readers, will perform no operations.
|
||||||
func NewMeterProvider(options ...Option) *MeterProvider {
|
func NewMeterProvider(options ...Option) *MeterProvider {
|
||||||
conf := newConfig(options)
|
conf := newConfig(options)
|
||||||
|
|
||||||
flush, sdown := conf.readerSignals()
|
flush, sdown := conf.readerSignals()
|
||||||
|
|
||||||
registry := newPipelines(conf.res, conf.readers)
|
|
||||||
|
|
||||||
return &MeterProvider{
|
return &MeterProvider{
|
||||||
meters: meterRegistry{
|
pipes: newPipelines(conf.res, conf.readers),
|
||||||
pipes: registry,
|
|
||||||
},
|
|
||||||
|
|
||||||
forceFlush: flush,
|
forceFlush: flush,
|
||||||
shutdown: sdown,
|
shutdown: sdown,
|
||||||
}
|
}
|
||||||
@ -72,10 +66,13 @@ func NewMeterProvider(options ...Option) *MeterProvider {
|
|||||||
// This method is safe to call concurrently.
|
// This method is safe to call concurrently.
|
||||||
func (mp *MeterProvider) Meter(name string, options ...metric.MeterOption) metric.Meter {
|
func (mp *MeterProvider) Meter(name string, options ...metric.MeterOption) metric.Meter {
|
||||||
c := metric.NewMeterConfig(options...)
|
c := metric.NewMeterConfig(options...)
|
||||||
return mp.meters.Get(instrumentation.Scope{
|
s := instrumentation.Scope{
|
||||||
Name: name,
|
Name: name,
|
||||||
Version: c.InstrumentationVersion(),
|
Version: c.InstrumentationVersion(),
|
||||||
SchemaURL: c.SchemaURL(),
|
SchemaURL: c.SchemaURL(),
|
||||||
|
}
|
||||||
|
return mp.meters.Lookup(s, func() *meter {
|
||||||
|
return newMeter(s, mp.pipes)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user