mirror of
https://github.com/ceph/ceph-csi.git
synced 2025-03-09 17:09:29 +00:00
Several packages are only used while running the e2e suite. These packages are less important to update, as the they can not influence the final executable that is part of the Ceph-CSI container-image. By moving these dependencies out of the main Ceph-CSI go.mod, it is easier to identify if a reported CVE affects Ceph-CSI, or only the testing (like most of the Kubernetes CVEs). Signed-off-by: Niels de Vos <ndevos@ibm.com>
599 lines
15 KiB
Go
599 lines
15 KiB
Go
// Copyright The OpenTelemetry Authors
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
package global // import "go.opentelemetry.io/otel/internal/global"
|
|
|
|
import (
|
|
"container/list"
|
|
"context"
|
|
"reflect"
|
|
"sync"
|
|
|
|
"go.opentelemetry.io/otel/metric"
|
|
"go.opentelemetry.io/otel/metric/embedded"
|
|
)
|
|
|
|
// meterProvider is a placeholder for a configured SDK MeterProvider.
|
|
//
|
|
// All MeterProvider functionality is forwarded to a delegate once
|
|
// configured.
|
|
type meterProvider struct {
|
|
embedded.MeterProvider
|
|
|
|
mtx sync.Mutex
|
|
meters map[il]*meter
|
|
|
|
delegate metric.MeterProvider
|
|
}
|
|
|
|
// setDelegate configures p to delegate all MeterProvider functionality to
|
|
// provider.
|
|
//
|
|
// All Meters provided prior to this function call are switched out to be
|
|
// Meters provided by provider. All instruments and callbacks are recreated and
|
|
// delegated.
|
|
//
|
|
// It is guaranteed by the caller that this happens only once.
|
|
func (p *meterProvider) setDelegate(provider metric.MeterProvider) {
|
|
p.mtx.Lock()
|
|
defer p.mtx.Unlock()
|
|
|
|
p.delegate = provider
|
|
|
|
if len(p.meters) == 0 {
|
|
return
|
|
}
|
|
|
|
for _, meter := range p.meters {
|
|
meter.setDelegate(provider)
|
|
}
|
|
|
|
p.meters = nil
|
|
}
|
|
|
|
// Meter implements MeterProvider.
|
|
func (p *meterProvider) Meter(name string, opts ...metric.MeterOption) metric.Meter {
|
|
p.mtx.Lock()
|
|
defer p.mtx.Unlock()
|
|
|
|
if p.delegate != nil {
|
|
return p.delegate.Meter(name, opts...)
|
|
}
|
|
|
|
// At this moment it is guaranteed that no sdk is installed, save the meter in the meters map.
|
|
|
|
c := metric.NewMeterConfig(opts...)
|
|
key := il{
|
|
name: name,
|
|
version: c.InstrumentationVersion(),
|
|
schema: c.SchemaURL(),
|
|
attrs: c.InstrumentationAttributes(),
|
|
}
|
|
|
|
if p.meters == nil {
|
|
p.meters = make(map[il]*meter)
|
|
}
|
|
|
|
if val, ok := p.meters[key]; ok {
|
|
return val
|
|
}
|
|
|
|
t := &meter{name: name, opts: opts, instruments: make(map[instID]delegatedInstrument)}
|
|
p.meters[key] = t
|
|
return t
|
|
}
|
|
|
|
// meter is a placeholder for a metric.Meter.
|
|
//
|
|
// All Meter functionality is forwarded to a delegate once configured.
|
|
// Otherwise, all functionality is forwarded to a NoopMeter.
|
|
type meter struct {
|
|
embedded.Meter
|
|
|
|
name string
|
|
opts []metric.MeterOption
|
|
|
|
mtx sync.Mutex
|
|
instruments map[instID]delegatedInstrument
|
|
|
|
registry list.List
|
|
|
|
delegate metric.Meter
|
|
}
|
|
|
|
type delegatedInstrument interface {
|
|
setDelegate(metric.Meter)
|
|
}
|
|
|
|
// instID are the identifying properties of a instrument.
|
|
type instID struct {
|
|
// name is the name of the stream.
|
|
name string
|
|
// description is the description of the stream.
|
|
description string
|
|
// kind defines the functional group of the instrument.
|
|
kind reflect.Type
|
|
// unit is the unit of the stream.
|
|
unit string
|
|
}
|
|
|
|
// setDelegate configures m to delegate all Meter functionality to Meters
|
|
// created by provider.
|
|
//
|
|
// All subsequent calls to the Meter methods will be passed to the delegate.
|
|
//
|
|
// It is guaranteed by the caller that this happens only once.
|
|
func (m *meter) setDelegate(provider metric.MeterProvider) {
|
|
m.mtx.Lock()
|
|
defer m.mtx.Unlock()
|
|
|
|
meter := provider.Meter(m.name, m.opts...)
|
|
m.delegate = meter
|
|
|
|
for _, inst := range m.instruments {
|
|
inst.setDelegate(meter)
|
|
}
|
|
|
|
var n *list.Element
|
|
for e := m.registry.Front(); e != nil; e = n {
|
|
r := e.Value.(*registration)
|
|
r.setDelegate(meter)
|
|
n = e.Next()
|
|
m.registry.Remove(e)
|
|
}
|
|
|
|
m.instruments = nil
|
|
m.registry.Init()
|
|
}
|
|
|
|
func (m *meter) Int64Counter(name string, options ...metric.Int64CounterOption) (metric.Int64Counter, error) {
|
|
m.mtx.Lock()
|
|
defer m.mtx.Unlock()
|
|
|
|
if m.delegate != nil {
|
|
return m.delegate.Int64Counter(name, options...)
|
|
}
|
|
|
|
cfg := metric.NewInt64CounterConfig(options...)
|
|
id := instID{
|
|
name: name,
|
|
kind: reflect.TypeOf((*siCounter)(nil)),
|
|
description: cfg.Description(),
|
|
unit: cfg.Unit(),
|
|
}
|
|
if f, ok := m.instruments[id]; ok {
|
|
return f.(metric.Int64Counter), nil
|
|
}
|
|
i := &siCounter{name: name, opts: options}
|
|
m.instruments[id] = i
|
|
return i, nil
|
|
}
|
|
|
|
func (m *meter) Int64UpDownCounter(name string, options ...metric.Int64UpDownCounterOption) (metric.Int64UpDownCounter, error) {
|
|
m.mtx.Lock()
|
|
defer m.mtx.Unlock()
|
|
|
|
if m.delegate != nil {
|
|
return m.delegate.Int64UpDownCounter(name, options...)
|
|
}
|
|
|
|
cfg := metric.NewInt64UpDownCounterConfig(options...)
|
|
id := instID{
|
|
name: name,
|
|
kind: reflect.TypeOf((*siUpDownCounter)(nil)),
|
|
description: cfg.Description(),
|
|
unit: cfg.Unit(),
|
|
}
|
|
if f, ok := m.instruments[id]; ok {
|
|
return f.(metric.Int64UpDownCounter), nil
|
|
}
|
|
i := &siUpDownCounter{name: name, opts: options}
|
|
m.instruments[id] = i
|
|
return i, nil
|
|
}
|
|
|
|
func (m *meter) Int64Histogram(name string, options ...metric.Int64HistogramOption) (metric.Int64Histogram, error) {
|
|
m.mtx.Lock()
|
|
defer m.mtx.Unlock()
|
|
|
|
if m.delegate != nil {
|
|
return m.delegate.Int64Histogram(name, options...)
|
|
}
|
|
|
|
cfg := metric.NewInt64HistogramConfig(options...)
|
|
id := instID{
|
|
name: name,
|
|
kind: reflect.TypeOf((*siHistogram)(nil)),
|
|
description: cfg.Description(),
|
|
unit: cfg.Unit(),
|
|
}
|
|
if f, ok := m.instruments[id]; ok {
|
|
return f.(metric.Int64Histogram), nil
|
|
}
|
|
i := &siHistogram{name: name, opts: options}
|
|
m.instruments[id] = i
|
|
return i, nil
|
|
}
|
|
|
|
func (m *meter) Int64Gauge(name string, options ...metric.Int64GaugeOption) (metric.Int64Gauge, error) {
|
|
m.mtx.Lock()
|
|
defer m.mtx.Unlock()
|
|
|
|
if m.delegate != nil {
|
|
return m.delegate.Int64Gauge(name, options...)
|
|
}
|
|
|
|
cfg := metric.NewInt64GaugeConfig(options...)
|
|
id := instID{
|
|
name: name,
|
|
kind: reflect.TypeOf((*siGauge)(nil)),
|
|
description: cfg.Description(),
|
|
unit: cfg.Unit(),
|
|
}
|
|
if f, ok := m.instruments[id]; ok {
|
|
return f.(metric.Int64Gauge), nil
|
|
}
|
|
i := &siGauge{name: name, opts: options}
|
|
m.instruments[id] = i
|
|
return i, nil
|
|
}
|
|
|
|
func (m *meter) Int64ObservableCounter(name string, options ...metric.Int64ObservableCounterOption) (metric.Int64ObservableCounter, error) {
|
|
m.mtx.Lock()
|
|
defer m.mtx.Unlock()
|
|
|
|
if m.delegate != nil {
|
|
return m.delegate.Int64ObservableCounter(name, options...)
|
|
}
|
|
|
|
cfg := metric.NewInt64ObservableCounterConfig(options...)
|
|
id := instID{
|
|
name: name,
|
|
kind: reflect.TypeOf((*aiCounter)(nil)),
|
|
description: cfg.Description(),
|
|
unit: cfg.Unit(),
|
|
}
|
|
if f, ok := m.instruments[id]; ok {
|
|
return f.(metric.Int64ObservableCounter), nil
|
|
}
|
|
i := &aiCounter{name: name, opts: options}
|
|
m.instruments[id] = i
|
|
return i, nil
|
|
}
|
|
|
|
func (m *meter) Int64ObservableUpDownCounter(name string, options ...metric.Int64ObservableUpDownCounterOption) (metric.Int64ObservableUpDownCounter, error) {
|
|
m.mtx.Lock()
|
|
defer m.mtx.Unlock()
|
|
|
|
if m.delegate != nil {
|
|
return m.delegate.Int64ObservableUpDownCounter(name, options...)
|
|
}
|
|
|
|
cfg := metric.NewInt64ObservableUpDownCounterConfig(options...)
|
|
id := instID{
|
|
name: name,
|
|
kind: reflect.TypeOf((*aiUpDownCounter)(nil)),
|
|
description: cfg.Description(),
|
|
unit: cfg.Unit(),
|
|
}
|
|
if f, ok := m.instruments[id]; ok {
|
|
return f.(metric.Int64ObservableUpDownCounter), nil
|
|
}
|
|
i := &aiUpDownCounter{name: name, opts: options}
|
|
m.instruments[id] = i
|
|
return i, nil
|
|
}
|
|
|
|
func (m *meter) Int64ObservableGauge(name string, options ...metric.Int64ObservableGaugeOption) (metric.Int64ObservableGauge, error) {
|
|
m.mtx.Lock()
|
|
defer m.mtx.Unlock()
|
|
|
|
if m.delegate != nil {
|
|
return m.delegate.Int64ObservableGauge(name, options...)
|
|
}
|
|
|
|
cfg := metric.NewInt64ObservableGaugeConfig(options...)
|
|
id := instID{
|
|
name: name,
|
|
kind: reflect.TypeOf((*aiGauge)(nil)),
|
|
description: cfg.Description(),
|
|
unit: cfg.Unit(),
|
|
}
|
|
if f, ok := m.instruments[id]; ok {
|
|
return f.(metric.Int64ObservableGauge), nil
|
|
}
|
|
i := &aiGauge{name: name, opts: options}
|
|
m.instruments[id] = i
|
|
return i, nil
|
|
}
|
|
|
|
func (m *meter) Float64Counter(name string, options ...metric.Float64CounterOption) (metric.Float64Counter, error) {
|
|
m.mtx.Lock()
|
|
defer m.mtx.Unlock()
|
|
|
|
if m.delegate != nil {
|
|
return m.delegate.Float64Counter(name, options...)
|
|
}
|
|
|
|
cfg := metric.NewFloat64CounterConfig(options...)
|
|
id := instID{
|
|
name: name,
|
|
kind: reflect.TypeOf((*sfCounter)(nil)),
|
|
description: cfg.Description(),
|
|
unit: cfg.Unit(),
|
|
}
|
|
if f, ok := m.instruments[id]; ok {
|
|
return f.(metric.Float64Counter), nil
|
|
}
|
|
i := &sfCounter{name: name, opts: options}
|
|
m.instruments[id] = i
|
|
return i, nil
|
|
}
|
|
|
|
func (m *meter) Float64UpDownCounter(name string, options ...metric.Float64UpDownCounterOption) (metric.Float64UpDownCounter, error) {
|
|
m.mtx.Lock()
|
|
defer m.mtx.Unlock()
|
|
|
|
if m.delegate != nil {
|
|
return m.delegate.Float64UpDownCounter(name, options...)
|
|
}
|
|
|
|
cfg := metric.NewFloat64UpDownCounterConfig(options...)
|
|
id := instID{
|
|
name: name,
|
|
kind: reflect.TypeOf((*sfUpDownCounter)(nil)),
|
|
description: cfg.Description(),
|
|
unit: cfg.Unit(),
|
|
}
|
|
if f, ok := m.instruments[id]; ok {
|
|
return f.(metric.Float64UpDownCounter), nil
|
|
}
|
|
i := &sfUpDownCounter{name: name, opts: options}
|
|
m.instruments[id] = i
|
|
return i, nil
|
|
}
|
|
|
|
func (m *meter) Float64Histogram(name string, options ...metric.Float64HistogramOption) (metric.Float64Histogram, error) {
|
|
m.mtx.Lock()
|
|
defer m.mtx.Unlock()
|
|
|
|
if m.delegate != nil {
|
|
return m.delegate.Float64Histogram(name, options...)
|
|
}
|
|
|
|
cfg := metric.NewFloat64HistogramConfig(options...)
|
|
id := instID{
|
|
name: name,
|
|
kind: reflect.TypeOf((*sfHistogram)(nil)),
|
|
description: cfg.Description(),
|
|
unit: cfg.Unit(),
|
|
}
|
|
if f, ok := m.instruments[id]; ok {
|
|
return f.(metric.Float64Histogram), nil
|
|
}
|
|
i := &sfHistogram{name: name, opts: options}
|
|
m.instruments[id] = i
|
|
return i, nil
|
|
}
|
|
|
|
func (m *meter) Float64Gauge(name string, options ...metric.Float64GaugeOption) (metric.Float64Gauge, error) {
|
|
m.mtx.Lock()
|
|
defer m.mtx.Unlock()
|
|
|
|
if m.delegate != nil {
|
|
return m.delegate.Float64Gauge(name, options...)
|
|
}
|
|
|
|
cfg := metric.NewFloat64GaugeConfig(options...)
|
|
id := instID{
|
|
name: name,
|
|
kind: reflect.TypeOf((*sfGauge)(nil)),
|
|
description: cfg.Description(),
|
|
unit: cfg.Unit(),
|
|
}
|
|
if f, ok := m.instruments[id]; ok {
|
|
return f.(metric.Float64Gauge), nil
|
|
}
|
|
i := &sfGauge{name: name, opts: options}
|
|
m.instruments[id] = i
|
|
return i, nil
|
|
}
|
|
|
|
func (m *meter) Float64ObservableCounter(name string, options ...metric.Float64ObservableCounterOption) (metric.Float64ObservableCounter, error) {
|
|
m.mtx.Lock()
|
|
defer m.mtx.Unlock()
|
|
|
|
if m.delegate != nil {
|
|
return m.delegate.Float64ObservableCounter(name, options...)
|
|
}
|
|
|
|
cfg := metric.NewFloat64ObservableCounterConfig(options...)
|
|
id := instID{
|
|
name: name,
|
|
kind: reflect.TypeOf((*afCounter)(nil)),
|
|
description: cfg.Description(),
|
|
unit: cfg.Unit(),
|
|
}
|
|
if f, ok := m.instruments[id]; ok {
|
|
return f.(metric.Float64ObservableCounter), nil
|
|
}
|
|
i := &afCounter{name: name, opts: options}
|
|
m.instruments[id] = i
|
|
return i, nil
|
|
}
|
|
|
|
func (m *meter) Float64ObservableUpDownCounter(name string, options ...metric.Float64ObservableUpDownCounterOption) (metric.Float64ObservableUpDownCounter, error) {
|
|
m.mtx.Lock()
|
|
defer m.mtx.Unlock()
|
|
|
|
if m.delegate != nil {
|
|
return m.delegate.Float64ObservableUpDownCounter(name, options...)
|
|
}
|
|
|
|
cfg := metric.NewFloat64ObservableUpDownCounterConfig(options...)
|
|
id := instID{
|
|
name: name,
|
|
kind: reflect.TypeOf((*afUpDownCounter)(nil)),
|
|
description: cfg.Description(),
|
|
unit: cfg.Unit(),
|
|
}
|
|
if f, ok := m.instruments[id]; ok {
|
|
return f.(metric.Float64ObservableUpDownCounter), nil
|
|
}
|
|
i := &afUpDownCounter{name: name, opts: options}
|
|
m.instruments[id] = i
|
|
return i, nil
|
|
}
|
|
|
|
func (m *meter) Float64ObservableGauge(name string, options ...metric.Float64ObservableGaugeOption) (metric.Float64ObservableGauge, error) {
|
|
m.mtx.Lock()
|
|
defer m.mtx.Unlock()
|
|
|
|
if m.delegate != nil {
|
|
return m.delegate.Float64ObservableGauge(name, options...)
|
|
}
|
|
|
|
cfg := metric.NewFloat64ObservableGaugeConfig(options...)
|
|
id := instID{
|
|
name: name,
|
|
kind: reflect.TypeOf((*afGauge)(nil)),
|
|
description: cfg.Description(),
|
|
unit: cfg.Unit(),
|
|
}
|
|
if f, ok := m.instruments[id]; ok {
|
|
return f.(metric.Float64ObservableGauge), nil
|
|
}
|
|
i := &afGauge{name: name, opts: options}
|
|
m.instruments[id] = i
|
|
return i, nil
|
|
}
|
|
|
|
// RegisterCallback captures the function that will be called during Collect.
|
|
func (m *meter) RegisterCallback(f metric.Callback, insts ...metric.Observable) (metric.Registration, error) {
|
|
m.mtx.Lock()
|
|
defer m.mtx.Unlock()
|
|
|
|
if m.delegate != nil {
|
|
return m.delegate.RegisterCallback(unwrapCallback(f), unwrapInstruments(insts)...)
|
|
}
|
|
|
|
reg := ®istration{instruments: insts, function: f}
|
|
e := m.registry.PushBack(reg)
|
|
reg.unreg = func() error {
|
|
m.mtx.Lock()
|
|
_ = m.registry.Remove(e)
|
|
m.mtx.Unlock()
|
|
return nil
|
|
}
|
|
return reg, nil
|
|
}
|
|
|
|
func unwrapInstruments(instruments []metric.Observable) []metric.Observable {
|
|
out := make([]metric.Observable, 0, len(instruments))
|
|
|
|
for _, inst := range instruments {
|
|
if in, ok := inst.(unwrapper); ok {
|
|
out = append(out, in.unwrap())
|
|
} else {
|
|
out = append(out, inst)
|
|
}
|
|
}
|
|
|
|
return out
|
|
}
|
|
|
|
type registration struct {
|
|
embedded.Registration
|
|
|
|
instruments []metric.Observable
|
|
function metric.Callback
|
|
|
|
unreg func() error
|
|
unregMu sync.Mutex
|
|
}
|
|
|
|
type unwrapObs struct {
|
|
embedded.Observer
|
|
obs metric.Observer
|
|
}
|
|
|
|
// unwrapFloat64Observable returns an expected metric.Float64Observable after
|
|
// unwrapping the global object.
|
|
func unwrapFloat64Observable(inst metric.Float64Observable) metric.Float64Observable {
|
|
if unwrapped, ok := inst.(unwrapper); ok {
|
|
if floatObs, ok := unwrapped.unwrap().(metric.Float64Observable); ok {
|
|
// Note: if the unwrapped object does not
|
|
// unwrap as an observable for either of the
|
|
// predicates here, it means an internal bug in
|
|
// this package. We avoid logging an error in
|
|
// this case, because the SDK has to try its
|
|
// own type conversion on the object. The SDK
|
|
// will see this and be forced to respond with
|
|
// its own error.
|
|
//
|
|
// This code uses a double-nested if statement
|
|
// to avoid creating a branch that is
|
|
// impossible to cover.
|
|
inst = floatObs
|
|
}
|
|
}
|
|
return inst
|
|
}
|
|
|
|
// unwrapInt64Observable returns an expected metric.Int64Observable after
|
|
// unwrapping the global object.
|
|
func unwrapInt64Observable(inst metric.Int64Observable) metric.Int64Observable {
|
|
if unwrapped, ok := inst.(unwrapper); ok {
|
|
if unint, ok := unwrapped.unwrap().(metric.Int64Observable); ok {
|
|
// See the comment in unwrapFloat64Observable().
|
|
inst = unint
|
|
}
|
|
}
|
|
return inst
|
|
}
|
|
|
|
func (uo *unwrapObs) ObserveFloat64(inst metric.Float64Observable, value float64, opts ...metric.ObserveOption) {
|
|
uo.obs.ObserveFloat64(unwrapFloat64Observable(inst), value, opts...)
|
|
}
|
|
|
|
func (uo *unwrapObs) ObserveInt64(inst metric.Int64Observable, value int64, opts ...metric.ObserveOption) {
|
|
uo.obs.ObserveInt64(unwrapInt64Observable(inst), value, opts...)
|
|
}
|
|
|
|
func unwrapCallback(f metric.Callback) metric.Callback {
|
|
return func(ctx context.Context, obs metric.Observer) error {
|
|
return f(ctx, &unwrapObs{obs: obs})
|
|
}
|
|
}
|
|
|
|
func (c *registration) setDelegate(m metric.Meter) {
|
|
c.unregMu.Lock()
|
|
defer c.unregMu.Unlock()
|
|
|
|
if c.unreg == nil {
|
|
// Unregister already called.
|
|
return
|
|
}
|
|
|
|
reg, err := m.RegisterCallback(unwrapCallback(c.function), unwrapInstruments(c.instruments)...)
|
|
if err != nil {
|
|
GetErrorHandler().Handle(err)
|
|
return
|
|
}
|
|
|
|
c.unreg = reg.Unregister
|
|
}
|
|
|
|
func (c *registration) Unregister() error {
|
|
c.unregMu.Lock()
|
|
defer c.unregMu.Unlock()
|
|
if c.unreg == nil {
|
|
// Unregister already called.
|
|
return nil
|
|
}
|
|
|
|
var err error
|
|
err, c.unreg = c.unreg(), nil
|
|
return err
|
|
}
|