feat(telemetry): instrument inference duration and frame age
This commit is contained in:
		
							
								
								
									
										43
									
								
								vendor/go.opentelemetry.io/otel/internal/baggage/baggage.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								vendor/go.opentelemetry.io/otel/internal/baggage/baggage.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,43 @@
 | 
			
		||||
// Copyright The OpenTelemetry Authors
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
//     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
Package baggage provides base types and functionality to store and retrieve
 | 
			
		||||
baggage in Go context. This package exists because the OpenTracing bridge to
 | 
			
		||||
OpenTelemetry needs to synchronize state whenever baggage for a context is
 | 
			
		||||
modified and that context contains an OpenTracing span. If it were not for
 | 
			
		||||
this need this package would not need to exist and the
 | 
			
		||||
`go.opentelemetry.io/otel/baggage` package would be the singular place where
 | 
			
		||||
W3C baggage is handled.
 | 
			
		||||
*/
 | 
			
		||||
package baggage // import "go.opentelemetry.io/otel/internal/baggage"
 | 
			
		||||
 | 
			
		||||
// List is the collection of baggage members. The W3C allows for duplicates,
 | 
			
		||||
// but OpenTelemetry does not, therefore, this is represented as a map.
 | 
			
		||||
type List map[string]Item
 | 
			
		||||
 | 
			
		||||
// Item is the value and metadata properties part of a list-member.
 | 
			
		||||
type Item struct {
 | 
			
		||||
	Value      string
 | 
			
		||||
	Properties []Property
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Property is a metadata entry for a list-member.
 | 
			
		||||
type Property struct {
 | 
			
		||||
	Key, Value string
 | 
			
		||||
 | 
			
		||||
	// HasValue indicates if a zero-value value means the property does not
 | 
			
		||||
	// have a value or if it was the zero-value.
 | 
			
		||||
	HasValue bool
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										95
									
								
								vendor/go.opentelemetry.io/otel/internal/baggage/context.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										95
									
								
								vendor/go.opentelemetry.io/otel/internal/baggage/context.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,95 @@
 | 
			
		||||
// Copyright The OpenTelemetry Authors
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
//     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
package baggage // import "go.opentelemetry.io/otel/internal/baggage"
 | 
			
		||||
 | 
			
		||||
import "context"
 | 
			
		||||
 | 
			
		||||
type baggageContextKeyType int
 | 
			
		||||
 | 
			
		||||
const baggageKey baggageContextKeyType = iota
 | 
			
		||||
 | 
			
		||||
// SetHookFunc is a callback called when storing baggage in the context.
 | 
			
		||||
type SetHookFunc func(context.Context, List) context.Context
 | 
			
		||||
 | 
			
		||||
// GetHookFunc is a callback called when getting baggage from the context.
 | 
			
		||||
type GetHookFunc func(context.Context, List) List
 | 
			
		||||
 | 
			
		||||
type baggageState struct {
 | 
			
		||||
	list List
 | 
			
		||||
 | 
			
		||||
	setHook SetHookFunc
 | 
			
		||||
	getHook GetHookFunc
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ContextWithSetHook returns a copy of parent with hook configured to be
 | 
			
		||||
// invoked every time ContextWithBaggage is called.
 | 
			
		||||
//
 | 
			
		||||
// Passing nil SetHookFunc creates a context with no set hook to call.
 | 
			
		||||
func ContextWithSetHook(parent context.Context, hook SetHookFunc) context.Context {
 | 
			
		||||
	var s baggageState
 | 
			
		||||
	switch v := parent.Value(baggageKey).(type) {
 | 
			
		||||
	case baggageState:
 | 
			
		||||
		s = v
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	s.setHook = hook
 | 
			
		||||
	return context.WithValue(parent, baggageKey, s)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ContextWithGetHook returns a copy of parent with hook configured to be
 | 
			
		||||
// invoked every time FromContext is called.
 | 
			
		||||
//
 | 
			
		||||
// Passing nil GetHookFunc creates a context with no get hook to call.
 | 
			
		||||
func ContextWithGetHook(parent context.Context, hook GetHookFunc) context.Context {
 | 
			
		||||
	var s baggageState
 | 
			
		||||
	switch v := parent.Value(baggageKey).(type) {
 | 
			
		||||
	case baggageState:
 | 
			
		||||
		s = v
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	s.getHook = hook
 | 
			
		||||
	return context.WithValue(parent, baggageKey, s)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ContextWithList returns a copy of parent with baggage. Passing nil list
 | 
			
		||||
// returns a context without any baggage.
 | 
			
		||||
func ContextWithList(parent context.Context, list List) context.Context {
 | 
			
		||||
	var s baggageState
 | 
			
		||||
	switch v := parent.Value(baggageKey).(type) {
 | 
			
		||||
	case baggageState:
 | 
			
		||||
		s = v
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	s.list = list
 | 
			
		||||
	ctx := context.WithValue(parent, baggageKey, s)
 | 
			
		||||
	if s.setHook != nil {
 | 
			
		||||
		ctx = s.setHook(ctx, list)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return ctx
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ListFromContext returns the baggage contained in ctx.
 | 
			
		||||
func ListFromContext(ctx context.Context) List {
 | 
			
		||||
	switch v := ctx.Value(baggageKey).(type) {
 | 
			
		||||
	case baggageState:
 | 
			
		||||
		if v.getHook != nil {
 | 
			
		||||
			return v.getHook(ctx, v.list)
 | 
			
		||||
		}
 | 
			
		||||
		return v.list
 | 
			
		||||
	default:
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										82
									
								
								vendor/go.opentelemetry.io/otel/internal/global/propagator.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										82
									
								
								vendor/go.opentelemetry.io/otel/internal/global/propagator.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,82 @@
 | 
			
		||||
// Copyright The OpenTelemetry Authors
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
//     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
package global // import "go.opentelemetry.io/otel/internal/global"
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"context"
 | 
			
		||||
	"sync"
 | 
			
		||||
 | 
			
		||||
	"go.opentelemetry.io/otel/propagation"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// textMapPropagator is a default TextMapPropagator that delegates calls to a
 | 
			
		||||
// registered delegate if one is set, otherwise it defaults to delegating the
 | 
			
		||||
// calls to a the default no-op propagation.TextMapPropagator.
 | 
			
		||||
type textMapPropagator struct {
 | 
			
		||||
	mtx      sync.Mutex
 | 
			
		||||
	once     sync.Once
 | 
			
		||||
	delegate propagation.TextMapPropagator
 | 
			
		||||
	noop     propagation.TextMapPropagator
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Compile-time guarantee that textMapPropagator implements the
 | 
			
		||||
// propagation.TextMapPropagator interface.
 | 
			
		||||
var _ propagation.TextMapPropagator = (*textMapPropagator)(nil)
 | 
			
		||||
 | 
			
		||||
func newTextMapPropagator() *textMapPropagator {
 | 
			
		||||
	return &textMapPropagator{
 | 
			
		||||
		noop: propagation.NewCompositeTextMapPropagator(),
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SetDelegate sets a delegate propagation.TextMapPropagator that all calls are
 | 
			
		||||
// forwarded to. Delegation can only be performed once, all subsequent calls
 | 
			
		||||
// perform no delegation.
 | 
			
		||||
func (p *textMapPropagator) SetDelegate(delegate propagation.TextMapPropagator) {
 | 
			
		||||
	if delegate == nil {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	p.mtx.Lock()
 | 
			
		||||
	p.once.Do(func() { p.delegate = delegate })
 | 
			
		||||
	p.mtx.Unlock()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// effectiveDelegate returns the current delegate of p if one is set,
 | 
			
		||||
// otherwise the default noop TextMapPropagator is returned. This method
 | 
			
		||||
// can be called concurrently.
 | 
			
		||||
func (p *textMapPropagator) effectiveDelegate() propagation.TextMapPropagator {
 | 
			
		||||
	p.mtx.Lock()
 | 
			
		||||
	defer p.mtx.Unlock()
 | 
			
		||||
	if p.delegate != nil {
 | 
			
		||||
		return p.delegate
 | 
			
		||||
	}
 | 
			
		||||
	return p.noop
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Inject set cross-cutting concerns from the Context into the carrier.
 | 
			
		||||
func (p *textMapPropagator) Inject(ctx context.Context, carrier propagation.TextMapCarrier) {
 | 
			
		||||
	p.effectiveDelegate().Inject(ctx, carrier)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Extract reads cross-cutting concerns from the carrier into a Context.
 | 
			
		||||
func (p *textMapPropagator) Extract(ctx context.Context, carrier propagation.TextMapCarrier) context.Context {
 | 
			
		||||
	return p.effectiveDelegate().Extract(ctx, carrier)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Fields returns the keys whose values are set with Inject.
 | 
			
		||||
func (p *textMapPropagator) Fields() []string {
 | 
			
		||||
	return p.effectiveDelegate().Fields()
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										106
									
								
								vendor/go.opentelemetry.io/otel/internal/global/state.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										106
									
								
								vendor/go.opentelemetry.io/otel/internal/global/state.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,106 @@
 | 
			
		||||
// Copyright The OpenTelemetry Authors
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
//     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
package global // import "go.opentelemetry.io/otel/internal/global"
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"sync"
 | 
			
		||||
	"sync/atomic"
 | 
			
		||||
 | 
			
		||||
	"go.opentelemetry.io/otel/propagation"
 | 
			
		||||
	"go.opentelemetry.io/otel/trace"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type (
 | 
			
		||||
	tracerProviderHolder struct {
 | 
			
		||||
		tp trace.TracerProvider
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	propagatorsHolder struct {
 | 
			
		||||
		tm propagation.TextMapPropagator
 | 
			
		||||
	}
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	globalTracer      = defaultTracerValue()
 | 
			
		||||
	globalPropagators = defaultPropagatorsValue()
 | 
			
		||||
 | 
			
		||||
	delegateTraceOnce             sync.Once
 | 
			
		||||
	delegateTextMapPropagatorOnce sync.Once
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// TracerProvider is the internal implementation for global.TracerProvider.
 | 
			
		||||
func TracerProvider() trace.TracerProvider {
 | 
			
		||||
	return globalTracer.Load().(tracerProviderHolder).tp
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SetTracerProvider is the internal implementation for global.SetTracerProvider.
 | 
			
		||||
func SetTracerProvider(tp trace.TracerProvider) {
 | 
			
		||||
	delegateTraceOnce.Do(func() {
 | 
			
		||||
		current := TracerProvider()
 | 
			
		||||
		if current == tp {
 | 
			
		||||
			// Setting the provider to the prior default is nonsense, panic.
 | 
			
		||||
			// Panic is acceptable because we are likely still early in the
 | 
			
		||||
			// process lifetime.
 | 
			
		||||
			panic("invalid TracerProvider, the global instance cannot be reinstalled")
 | 
			
		||||
		} else if def, ok := current.(*tracerProvider); ok {
 | 
			
		||||
			def.setDelegate(tp)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	})
 | 
			
		||||
	globalTracer.Store(tracerProviderHolder{tp: tp})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// TextMapPropagator is the internal implementation for global.TextMapPropagator.
 | 
			
		||||
func TextMapPropagator() propagation.TextMapPropagator {
 | 
			
		||||
	return globalPropagators.Load().(propagatorsHolder).tm
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SetTextMapPropagator is the internal implementation for global.SetTextMapPropagator.
 | 
			
		||||
func SetTextMapPropagator(p propagation.TextMapPropagator) {
 | 
			
		||||
	// For the textMapPropagator already returned by TextMapPropagator
 | 
			
		||||
	// delegate to p.
 | 
			
		||||
	delegateTextMapPropagatorOnce.Do(func() {
 | 
			
		||||
		if current := TextMapPropagator(); current == p {
 | 
			
		||||
			// Setting the provider to the prior default is nonsense, panic.
 | 
			
		||||
			// Panic is acceptable because we are likely still early in the
 | 
			
		||||
			// process lifetime.
 | 
			
		||||
			panic("invalid TextMapPropagator, the global instance cannot be reinstalled")
 | 
			
		||||
		} else if def, ok := current.(*textMapPropagator); ok {
 | 
			
		||||
			def.SetDelegate(p)
 | 
			
		||||
		}
 | 
			
		||||
	})
 | 
			
		||||
	// Return p when subsequent calls to TextMapPropagator are made.
 | 
			
		||||
	globalPropagators.Store(propagatorsHolder{tm: p})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func defaultTracerValue() *atomic.Value {
 | 
			
		||||
	v := &atomic.Value{}
 | 
			
		||||
	v.Store(tracerProviderHolder{tp: &tracerProvider{}})
 | 
			
		||||
	return v
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func defaultPropagatorsValue() *atomic.Value {
 | 
			
		||||
	v := &atomic.Value{}
 | 
			
		||||
	v.Store(propagatorsHolder{tm: newTextMapPropagator()})
 | 
			
		||||
	return v
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ResetForTest restores the initial global state, for testing purposes.
 | 
			
		||||
func ResetForTest() {
 | 
			
		||||
	globalTracer = defaultTracerValue()
 | 
			
		||||
	globalPropagators = defaultPropagatorsValue()
 | 
			
		||||
	delegateTraceOnce = sync.Once{}
 | 
			
		||||
	delegateTextMapPropagatorOnce = sync.Once{}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										192
									
								
								vendor/go.opentelemetry.io/otel/internal/global/trace.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										192
									
								
								vendor/go.opentelemetry.io/otel/internal/global/trace.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,192 @@
 | 
			
		||||
// Copyright The OpenTelemetry Authors
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
//     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
package global // import "go.opentelemetry.io/otel/internal/global"
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
This file contains the forwarding implementation of the TracerProvider used as
 | 
			
		||||
the default global instance. Prior to initialization of an SDK, Tracers
 | 
			
		||||
returned by the global TracerProvider will provide no-op functionality. This
 | 
			
		||||
means that all Span created prior to initialization are no-op Spans.
 | 
			
		||||
 | 
			
		||||
Once an SDK has been initialized, all provided no-op Tracers are swapped for
 | 
			
		||||
Tracers provided by the SDK defined TracerProvider. However, any Span started
 | 
			
		||||
prior to this initialization does not change its behavior. Meaning, the Span
 | 
			
		||||
remains a no-op Span.
 | 
			
		||||
 | 
			
		||||
The implementation to track and swap Tracers locks all new Tracer creation
 | 
			
		||||
until the swap is complete. This assumes that this operation is not
 | 
			
		||||
performance-critical. If that assumption is incorrect, be sure to configure an
 | 
			
		||||
SDK prior to any Tracer creation.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"context"
 | 
			
		||||
	"sync"
 | 
			
		||||
	"sync/atomic"
 | 
			
		||||
 | 
			
		||||
	"go.opentelemetry.io/otel/attribute"
 | 
			
		||||
	"go.opentelemetry.io/otel/codes"
 | 
			
		||||
	"go.opentelemetry.io/otel/trace"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// tracerProvider is a placeholder for a configured SDK TracerProvider.
 | 
			
		||||
//
 | 
			
		||||
// All TracerProvider functionality is forwarded to a delegate once
 | 
			
		||||
// configured.
 | 
			
		||||
type tracerProvider struct {
 | 
			
		||||
	mtx      sync.Mutex
 | 
			
		||||
	tracers  map[il]*tracer
 | 
			
		||||
	delegate trace.TracerProvider
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Compile-time guarantee that tracerProvider implements the TracerProvider
 | 
			
		||||
// interface.
 | 
			
		||||
var _ trace.TracerProvider = &tracerProvider{}
 | 
			
		||||
 | 
			
		||||
// setDelegate configures p to delegate all TracerProvider functionality to
 | 
			
		||||
// provider.
 | 
			
		||||
//
 | 
			
		||||
// All Tracers provided prior to this function call are switched out to be
 | 
			
		||||
// Tracers provided by provider.
 | 
			
		||||
//
 | 
			
		||||
// It is guaranteed by the caller that this happens only once.
 | 
			
		||||
func (p *tracerProvider) setDelegate(provider trace.TracerProvider) {
 | 
			
		||||
	p.mtx.Lock()
 | 
			
		||||
	defer p.mtx.Unlock()
 | 
			
		||||
 | 
			
		||||
	p.delegate = provider
 | 
			
		||||
 | 
			
		||||
	if len(p.tracers) == 0 {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for _, t := range p.tracers {
 | 
			
		||||
		t.setDelegate(provider)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	p.tracers = nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Tracer implements TracerProvider.
 | 
			
		||||
func (p *tracerProvider) Tracer(name string, opts ...trace.TracerOption) trace.Tracer {
 | 
			
		||||
	p.mtx.Lock()
 | 
			
		||||
	defer p.mtx.Unlock()
 | 
			
		||||
 | 
			
		||||
	if p.delegate != nil {
 | 
			
		||||
		return p.delegate.Tracer(name, opts...)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// At this moment it is guaranteed that no sdk is installed, save the tracer in the tracers map.
 | 
			
		||||
 | 
			
		||||
	c := trace.NewTracerConfig(opts...)
 | 
			
		||||
	key := il{
 | 
			
		||||
		name:    name,
 | 
			
		||||
		version: c.InstrumentationVersion(),
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if p.tracers == nil {
 | 
			
		||||
		p.tracers = make(map[il]*tracer)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if val, ok := p.tracers[key]; ok {
 | 
			
		||||
		return val
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	t := &tracer{name: name, opts: opts, provider: p}
 | 
			
		||||
	p.tracers[key] = t
 | 
			
		||||
	return t
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type il struct {
 | 
			
		||||
	name    string
 | 
			
		||||
	version string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// tracer is a placeholder for a trace.Tracer.
 | 
			
		||||
//
 | 
			
		||||
// All Tracer functionality is forwarded to a delegate once configured.
 | 
			
		||||
// Otherwise, all functionality is forwarded to a NoopTracer.
 | 
			
		||||
type tracer struct {
 | 
			
		||||
	name     string
 | 
			
		||||
	opts     []trace.TracerOption
 | 
			
		||||
	provider *tracerProvider
 | 
			
		||||
 | 
			
		||||
	delegate atomic.Value
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Compile-time guarantee that tracer implements the trace.Tracer interface.
 | 
			
		||||
var _ trace.Tracer = &tracer{}
 | 
			
		||||
 | 
			
		||||
// setDelegate configures t to delegate all Tracer functionality to Tracers
 | 
			
		||||
// created by provider.
 | 
			
		||||
//
 | 
			
		||||
// All subsequent calls to the Tracer methods will be passed to the delegate.
 | 
			
		||||
//
 | 
			
		||||
// It is guaranteed by the caller that this happens only once.
 | 
			
		||||
func (t *tracer) setDelegate(provider trace.TracerProvider) {
 | 
			
		||||
	t.delegate.Store(provider.Tracer(t.name, t.opts...))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Start implements trace.Tracer by forwarding the call to t.delegate if
 | 
			
		||||
// set, otherwise it forwards the call to a NoopTracer.
 | 
			
		||||
func (t *tracer) Start(ctx context.Context, name string, opts ...trace.SpanStartOption) (context.Context, trace.Span) {
 | 
			
		||||
	delegate := t.delegate.Load()
 | 
			
		||||
	if delegate != nil {
 | 
			
		||||
		return delegate.(trace.Tracer).Start(ctx, name, opts...)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	s := nonRecordingSpan{sc: trace.SpanContextFromContext(ctx), tracer: t}
 | 
			
		||||
	ctx = trace.ContextWithSpan(ctx, s)
 | 
			
		||||
	return ctx, s
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// nonRecordingSpan is a minimal implementation of a Span that wraps a
 | 
			
		||||
// SpanContext. It performs no operations other than to return the wrapped
 | 
			
		||||
// SpanContext.
 | 
			
		||||
type nonRecordingSpan struct {
 | 
			
		||||
	sc     trace.SpanContext
 | 
			
		||||
	tracer *tracer
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var _ trace.Span = nonRecordingSpan{}
 | 
			
		||||
 | 
			
		||||
// SpanContext returns the wrapped SpanContext.
 | 
			
		||||
func (s nonRecordingSpan) SpanContext() trace.SpanContext { return s.sc }
 | 
			
		||||
 | 
			
		||||
// IsRecording always returns false.
 | 
			
		||||
func (nonRecordingSpan) IsRecording() bool { return false }
 | 
			
		||||
 | 
			
		||||
// SetStatus does nothing.
 | 
			
		||||
func (nonRecordingSpan) SetStatus(codes.Code, string) {}
 | 
			
		||||
 | 
			
		||||
// SetError does nothing.
 | 
			
		||||
func (nonRecordingSpan) SetError(bool) {}
 | 
			
		||||
 | 
			
		||||
// SetAttributes does nothing.
 | 
			
		||||
func (nonRecordingSpan) SetAttributes(...attribute.KeyValue) {}
 | 
			
		||||
 | 
			
		||||
// End does nothing.
 | 
			
		||||
func (nonRecordingSpan) End(...trace.SpanEndOption) {}
 | 
			
		||||
 | 
			
		||||
// RecordError does nothing.
 | 
			
		||||
func (nonRecordingSpan) RecordError(error, ...trace.EventOption) {}
 | 
			
		||||
 | 
			
		||||
// AddEvent does nothing.
 | 
			
		||||
func (nonRecordingSpan) AddEvent(string, ...trace.EventOption) {}
 | 
			
		||||
 | 
			
		||||
// SetName does nothing.
 | 
			
		||||
func (nonRecordingSpan) SetName(string) {}
 | 
			
		||||
 | 
			
		||||
func (s nonRecordingSpan) TracerProvider() trace.TracerProvider { return s.tracer.provider }
 | 
			
		||||
							
								
								
									
										201
									
								
								vendor/go.opentelemetry.io/otel/internal/metric/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										201
									
								
								vendor/go.opentelemetry.io/otel/internal/metric/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,201 @@
 | 
			
		||||
                                 Apache License
 | 
			
		||||
                           Version 2.0, January 2004
 | 
			
		||||
                        http://www.apache.org/licenses/
 | 
			
		||||
 | 
			
		||||
   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
 | 
			
		||||
 | 
			
		||||
   1. Definitions.
 | 
			
		||||
 | 
			
		||||
      "License" shall mean the terms and conditions for use, reproduction,
 | 
			
		||||
      and distribution as defined by Sections 1 through 9 of this document.
 | 
			
		||||
 | 
			
		||||
      "Licensor" shall mean the copyright owner or entity authorized by
 | 
			
		||||
      the copyright owner that is granting the License.
 | 
			
		||||
 | 
			
		||||
      "Legal Entity" shall mean the union of the acting entity and all
 | 
			
		||||
      other entities that control, are controlled by, or are under common
 | 
			
		||||
      control with that entity. For the purposes of this definition,
 | 
			
		||||
      "control" means (i) the power, direct or indirect, to cause the
 | 
			
		||||
      direction or management of such entity, whether by contract or
 | 
			
		||||
      otherwise, or (ii) ownership of fifty percent (50%) or more of the
 | 
			
		||||
      outstanding shares, or (iii) beneficial ownership of such entity.
 | 
			
		||||
 | 
			
		||||
      "You" (or "Your") shall mean an individual or Legal Entity
 | 
			
		||||
      exercising permissions granted by this License.
 | 
			
		||||
 | 
			
		||||
      "Source" form shall mean the preferred form for making modifications,
 | 
			
		||||
      including but not limited to software source code, documentation
 | 
			
		||||
      source, and configuration files.
 | 
			
		||||
 | 
			
		||||
      "Object" form shall mean any form resulting from mechanical
 | 
			
		||||
      transformation or translation of a Source form, including but
 | 
			
		||||
      not limited to compiled object code, generated documentation,
 | 
			
		||||
      and conversions to other media types.
 | 
			
		||||
 | 
			
		||||
      "Work" shall mean the work of authorship, whether in Source or
 | 
			
		||||
      Object form, made available under the License, as indicated by a
 | 
			
		||||
      copyright notice that is included in or attached to the work
 | 
			
		||||
      (an example is provided in the Appendix below).
 | 
			
		||||
 | 
			
		||||
      "Derivative Works" shall mean any work, whether in Source or Object
 | 
			
		||||
      form, that is based on (or derived from) the Work and for which the
 | 
			
		||||
      editorial revisions, annotations, elaborations, or other modifications
 | 
			
		||||
      represent, as a whole, an original work of authorship. For the purposes
 | 
			
		||||
      of this License, Derivative Works shall not include works that remain
 | 
			
		||||
      separable from, or merely link (or bind by name) to the interfaces of,
 | 
			
		||||
      the Work and Derivative Works thereof.
 | 
			
		||||
 | 
			
		||||
      "Contribution" shall mean any work of authorship, including
 | 
			
		||||
      the original version of the Work and any modifications or additions
 | 
			
		||||
      to that Work or Derivative Works thereof, that is intentionally
 | 
			
		||||
      submitted to Licensor for inclusion in the Work by the copyright owner
 | 
			
		||||
      or by an individual or Legal Entity authorized to submit on behalf of
 | 
			
		||||
      the copyright owner. For the purposes of this definition, "submitted"
 | 
			
		||||
      means any form of electronic, verbal, or written communication sent
 | 
			
		||||
      to the Licensor or its representatives, including but not limited to
 | 
			
		||||
      communication on electronic mailing lists, source code control systems,
 | 
			
		||||
      and issue tracking systems that are managed by, or on behalf of, the
 | 
			
		||||
      Licensor for the purpose of discussing and improving the Work, but
 | 
			
		||||
      excluding communication that is conspicuously marked or otherwise
 | 
			
		||||
      designated in writing by the copyright owner as "Not a Contribution."
 | 
			
		||||
 | 
			
		||||
      "Contributor" shall mean Licensor and any individual or Legal Entity
 | 
			
		||||
      on behalf of whom a Contribution has been received by Licensor and
 | 
			
		||||
      subsequently incorporated within the Work.
 | 
			
		||||
 | 
			
		||||
   2. Grant of Copyright License. Subject to the terms and conditions of
 | 
			
		||||
      this License, each Contributor hereby grants to You a perpetual,
 | 
			
		||||
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
 | 
			
		||||
      copyright license to reproduce, prepare Derivative Works of,
 | 
			
		||||
      publicly display, publicly perform, sublicense, and distribute the
 | 
			
		||||
      Work and such Derivative Works in Source or Object form.
 | 
			
		||||
 | 
			
		||||
   3. Grant of Patent License. Subject to the terms and conditions of
 | 
			
		||||
      this License, each Contributor hereby grants to You a perpetual,
 | 
			
		||||
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
 | 
			
		||||
      (except as stated in this section) patent license to make, have made,
 | 
			
		||||
      use, offer to sell, sell, import, and otherwise transfer the Work,
 | 
			
		||||
      where such license applies only to those patent claims licensable
 | 
			
		||||
      by such Contributor that are necessarily infringed by their
 | 
			
		||||
      Contribution(s) alone or by combination of their Contribution(s)
 | 
			
		||||
      with the Work to which such Contribution(s) was submitted. If You
 | 
			
		||||
      institute patent litigation against any entity (including a
 | 
			
		||||
      cross-claim or counterclaim in a lawsuit) alleging that the Work
 | 
			
		||||
      or a Contribution incorporated within the Work constitutes direct
 | 
			
		||||
      or contributory patent infringement, then any patent licenses
 | 
			
		||||
      granted to You under this License for that Work shall terminate
 | 
			
		||||
      as of the date such litigation is filed.
 | 
			
		||||
 | 
			
		||||
   4. Redistribution. You may reproduce and distribute copies of the
 | 
			
		||||
      Work or Derivative Works thereof in any medium, with or without
 | 
			
		||||
      modifications, and in Source or Object form, provided that You
 | 
			
		||||
      meet the following conditions:
 | 
			
		||||
 | 
			
		||||
      (a) You must give any other recipients of the Work or
 | 
			
		||||
          Derivative Works a copy of this License; and
 | 
			
		||||
 | 
			
		||||
      (b) You must cause any modified files to carry prominent notices
 | 
			
		||||
          stating that You changed the files; and
 | 
			
		||||
 | 
			
		||||
      (c) You must retain, in the Source form of any Derivative Works
 | 
			
		||||
          that You distribute, all copyright, patent, trademark, and
 | 
			
		||||
          attribution notices from the Source form of the Work,
 | 
			
		||||
          excluding those notices that do not pertain to any part of
 | 
			
		||||
          the Derivative Works; and
 | 
			
		||||
 | 
			
		||||
      (d) If the Work includes a "NOTICE" text file as part of its
 | 
			
		||||
          distribution, then any Derivative Works that You distribute must
 | 
			
		||||
          include a readable copy of the attribution notices contained
 | 
			
		||||
          within such NOTICE file, excluding those notices that do not
 | 
			
		||||
          pertain to any part of the Derivative Works, in at least one
 | 
			
		||||
          of the following places: within a NOTICE text file distributed
 | 
			
		||||
          as part of the Derivative Works; within the Source form or
 | 
			
		||||
          documentation, if provided along with the Derivative Works; or,
 | 
			
		||||
          within a display generated by the Derivative Works, if and
 | 
			
		||||
          wherever such third-party notices normally appear. The contents
 | 
			
		||||
          of the NOTICE file are for informational purposes only and
 | 
			
		||||
          do not modify the License. You may add Your own attribution
 | 
			
		||||
          notices within Derivative Works that You distribute, alongside
 | 
			
		||||
          or as an addendum to the NOTICE text from the Work, provided
 | 
			
		||||
          that such additional attribution notices cannot be construed
 | 
			
		||||
          as modifying the License.
 | 
			
		||||
 | 
			
		||||
      You may add Your own copyright statement to Your modifications and
 | 
			
		||||
      may provide additional or different license terms and conditions
 | 
			
		||||
      for use, reproduction, or distribution of Your modifications, or
 | 
			
		||||
      for any such Derivative Works as a whole, provided Your use,
 | 
			
		||||
      reproduction, and distribution of the Work otherwise complies with
 | 
			
		||||
      the conditions stated in this License.
 | 
			
		||||
 | 
			
		||||
   5. Submission of Contributions. Unless You explicitly state otherwise,
 | 
			
		||||
      any Contribution intentionally submitted for inclusion in the Work
 | 
			
		||||
      by You to the Licensor shall be under the terms and conditions of
 | 
			
		||||
      this License, without any additional terms or conditions.
 | 
			
		||||
      Notwithstanding the above, nothing herein shall supersede or modify
 | 
			
		||||
      the terms of any separate license agreement you may have executed
 | 
			
		||||
      with Licensor regarding such Contributions.
 | 
			
		||||
 | 
			
		||||
   6. Trademarks. This License does not grant permission to use the trade
 | 
			
		||||
      names, trademarks, service marks, or product names of the Licensor,
 | 
			
		||||
      except as required for reasonable and customary use in describing the
 | 
			
		||||
      origin of the Work and reproducing the content of the NOTICE file.
 | 
			
		||||
 | 
			
		||||
   7. Disclaimer of Warranty. Unless required by applicable law or
 | 
			
		||||
      agreed to in writing, Licensor provides the Work (and each
 | 
			
		||||
      Contributor provides its Contributions) on an "AS IS" BASIS,
 | 
			
		||||
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
 | 
			
		||||
      implied, including, without limitation, any warranties or conditions
 | 
			
		||||
      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
 | 
			
		||||
      PARTICULAR PURPOSE. You are solely responsible for determining the
 | 
			
		||||
      appropriateness of using or redistributing the Work and assume any
 | 
			
		||||
      risks associated with Your exercise of permissions under this License.
 | 
			
		||||
 | 
			
		||||
   8. Limitation of Liability. In no event and under no legal theory,
 | 
			
		||||
      whether in tort (including negligence), contract, or otherwise,
 | 
			
		||||
      unless required by applicable law (such as deliberate and grossly
 | 
			
		||||
      negligent acts) or agreed to in writing, shall any Contributor be
 | 
			
		||||
      liable to You for damages, including any direct, indirect, special,
 | 
			
		||||
      incidental, or consequential damages of any character arising as a
 | 
			
		||||
      result of this License or out of the use or inability to use the
 | 
			
		||||
      Work (including but not limited to damages for loss of goodwill,
 | 
			
		||||
      work stoppage, computer failure or malfunction, or any and all
 | 
			
		||||
      other commercial damages or losses), even if such Contributor
 | 
			
		||||
      has been advised of the possibility of such damages.
 | 
			
		||||
 | 
			
		||||
   9. Accepting Warranty or Additional Liability. While redistributing
 | 
			
		||||
      the Work or Derivative Works thereof, You may choose to offer,
 | 
			
		||||
      and charge a fee for, acceptance of support, warranty, indemnity,
 | 
			
		||||
      or other liability obligations and/or rights consistent with this
 | 
			
		||||
      License. However, in accepting such obligations, You may act only
 | 
			
		||||
      on Your own behalf and on Your sole responsibility, not on behalf
 | 
			
		||||
      of any other Contributor, and only if You agree to indemnify,
 | 
			
		||||
      defend, and hold each Contributor harmless for any liability
 | 
			
		||||
      incurred by, or claims asserted against, such Contributor by reason
 | 
			
		||||
      of your accepting any such warranty or additional liability.
 | 
			
		||||
 | 
			
		||||
   END OF TERMS AND CONDITIONS
 | 
			
		||||
 | 
			
		||||
   APPENDIX: How to apply the Apache License to your work.
 | 
			
		||||
 | 
			
		||||
      To apply the Apache License to your work, attach the following
 | 
			
		||||
      boilerplate notice, with the fields enclosed by brackets "[]"
 | 
			
		||||
      replaced with your own identifying information. (Don't include
 | 
			
		||||
      the brackets!)  The text should be enclosed in the appropriate
 | 
			
		||||
      comment syntax for the file format. We also recommend that a
 | 
			
		||||
      file or class name and description of purpose be included on the
 | 
			
		||||
      same "printed page" as the copyright notice for easier
 | 
			
		||||
      identification within third-party archives.
 | 
			
		||||
 | 
			
		||||
   Copyright [yyyy] [name of copyright owner]
 | 
			
		||||
 | 
			
		||||
   Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
   you may not use this file except in compliance with the License.
 | 
			
		||||
   You may obtain a copy of the License at
 | 
			
		||||
 | 
			
		||||
       http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 | 
			
		||||
   Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
   distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
   See the License for the specific language governing permissions and
 | 
			
		||||
   limitations under the License.
 | 
			
		||||
							
								
								
									
										149
									
								
								vendor/go.opentelemetry.io/otel/internal/metric/async.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										149
									
								
								vendor/go.opentelemetry.io/otel/internal/metric/async.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,149 @@
 | 
			
		||||
// Copyright The OpenTelemetry Authors
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
//     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
package metric // import "go.opentelemetry.io/otel/internal/metric"
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"context"
 | 
			
		||||
	"errors"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"sync"
 | 
			
		||||
 | 
			
		||||
	"go.opentelemetry.io/otel"
 | 
			
		||||
	"go.opentelemetry.io/otel/attribute"
 | 
			
		||||
	"go.opentelemetry.io/otel/metric/sdkapi"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
//nolint:revive // ignoring missing comments for exported error in an internal package
 | 
			
		||||
var ErrInvalidAsyncRunner = errors.New("unknown async runner type")
 | 
			
		||||
 | 
			
		||||
// AsyncCollector is an interface used between the MeterImpl and the
 | 
			
		||||
// AsyncInstrumentState helper below.  This interface is implemented by
 | 
			
		||||
// the SDK to provide support for running observer callbacks.
 | 
			
		||||
type AsyncCollector interface {
 | 
			
		||||
	// CollectAsync passes a batch of observations to the MeterImpl.
 | 
			
		||||
	CollectAsync(labels []attribute.KeyValue, observation ...sdkapi.Observation)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// AsyncInstrumentState manages an ordered set of asynchronous
 | 
			
		||||
// instruments and the distinct runners, taking into account batch
 | 
			
		||||
// observer callbacks.
 | 
			
		||||
type AsyncInstrumentState struct {
 | 
			
		||||
	lock sync.Mutex
 | 
			
		||||
 | 
			
		||||
	// errorOnce will use the otel.Handler to report an error
 | 
			
		||||
	// once in case of an invalid runner attempting to run.
 | 
			
		||||
	errorOnce sync.Once
 | 
			
		||||
 | 
			
		||||
	// runnerMap keeps the set of runners that will run each
 | 
			
		||||
	// collection interval.  Singletons are entered with a real
 | 
			
		||||
	// instrument each, batch observers are entered with a nil
 | 
			
		||||
	// instrument, ensuring that when a singleton callback is used
 | 
			
		||||
	// repeatedly, it is executed repeatedly in the interval, while
 | 
			
		||||
	// when a batch callback is used repeatedly, it only executes
 | 
			
		||||
	// once per interval.
 | 
			
		||||
	runnerMap map[asyncRunnerPair]struct{}
 | 
			
		||||
 | 
			
		||||
	// runners maintains the set of runners in the order they were
 | 
			
		||||
	// registered.
 | 
			
		||||
	runners []asyncRunnerPair
 | 
			
		||||
 | 
			
		||||
	// instruments maintains the set of instruments in the order
 | 
			
		||||
	// they were registered.
 | 
			
		||||
	instruments []sdkapi.AsyncImpl
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// asyncRunnerPair is a map entry for Observer callback runners.
 | 
			
		||||
type asyncRunnerPair struct {
 | 
			
		||||
	// runner is used as a map key here.  The API ensures
 | 
			
		||||
	// that all callbacks are pointers for this reason.
 | 
			
		||||
	runner sdkapi.AsyncRunner
 | 
			
		||||
 | 
			
		||||
	// inst refers to a non-nil instrument when `runner` is a
 | 
			
		||||
	// AsyncSingleRunner.
 | 
			
		||||
	inst sdkapi.AsyncImpl
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewAsyncInstrumentState returns a new *AsyncInstrumentState, for
 | 
			
		||||
// use by MeterImpl to manage running the set of observer callbacks in
 | 
			
		||||
// the correct order.
 | 
			
		||||
func NewAsyncInstrumentState() *AsyncInstrumentState {
 | 
			
		||||
	return &AsyncInstrumentState{
 | 
			
		||||
		runnerMap: map[asyncRunnerPair]struct{}{},
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Instruments returns the asynchronous instruments managed by this
 | 
			
		||||
// object, the set that should be checkpointed after observers are
 | 
			
		||||
// run.
 | 
			
		||||
func (a *AsyncInstrumentState) Instruments() []sdkapi.AsyncImpl {
 | 
			
		||||
	a.lock.Lock()
 | 
			
		||||
	defer a.lock.Unlock()
 | 
			
		||||
	return a.instruments
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Register adds a new asynchronous instrument to by managed by this
 | 
			
		||||
// object.  This should be called during NewAsyncInstrument() and
 | 
			
		||||
// assumes that errors (e.g., duplicate registration) have already
 | 
			
		||||
// been checked.
 | 
			
		||||
func (a *AsyncInstrumentState) Register(inst sdkapi.AsyncImpl, runner sdkapi.AsyncRunner) {
 | 
			
		||||
	a.lock.Lock()
 | 
			
		||||
	defer a.lock.Unlock()
 | 
			
		||||
 | 
			
		||||
	a.instruments = append(a.instruments, inst)
 | 
			
		||||
 | 
			
		||||
	// asyncRunnerPair reflects this callback in the asyncRunners
 | 
			
		||||
	// list.  If this is a batch runner, the instrument is nil.
 | 
			
		||||
	// If this is a single-Observer runner, the instrument is
 | 
			
		||||
	// included.  This ensures that batch callbacks are called
 | 
			
		||||
	// once and single callbacks are called once per instrument.
 | 
			
		||||
	rp := asyncRunnerPair{
 | 
			
		||||
		runner: runner,
 | 
			
		||||
	}
 | 
			
		||||
	if _, ok := runner.(sdkapi.AsyncSingleRunner); ok {
 | 
			
		||||
		rp.inst = inst
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if _, ok := a.runnerMap[rp]; !ok {
 | 
			
		||||
		a.runnerMap[rp] = struct{}{}
 | 
			
		||||
		a.runners = append(a.runners, rp)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Run executes the complete set of observer callbacks.
 | 
			
		||||
func (a *AsyncInstrumentState) Run(ctx context.Context, collector AsyncCollector) {
 | 
			
		||||
	a.lock.Lock()
 | 
			
		||||
	runners := a.runners
 | 
			
		||||
	a.lock.Unlock()
 | 
			
		||||
 | 
			
		||||
	for _, rp := range runners {
 | 
			
		||||
		// The runner must be a single or batch runner, no
 | 
			
		||||
		// other implementations are possible because the
 | 
			
		||||
		// interface has un-exported methods.
 | 
			
		||||
 | 
			
		||||
		if singleRunner, ok := rp.runner.(sdkapi.AsyncSingleRunner); ok {
 | 
			
		||||
			singleRunner.Run(ctx, rp.inst, collector.CollectAsync)
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if multiRunner, ok := rp.runner.(sdkapi.AsyncBatchRunner); ok {
 | 
			
		||||
			multiRunner.Run(ctx, collector.CollectAsync)
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		a.errorOnce.Do(func() {
 | 
			
		||||
			otel.Handle(fmt.Errorf("%w: type %T (reported once)", ErrInvalidAsyncRunner, rp))
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										361
									
								
								vendor/go.opentelemetry.io/otel/internal/metric/global/meter.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										361
									
								
								vendor/go.opentelemetry.io/otel/internal/metric/global/meter.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,361 @@
 | 
			
		||||
// Copyright The OpenTelemetry Authors
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
//     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
package global // import "go.opentelemetry.io/otel/internal/metric/global"
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"context"
 | 
			
		||||
	"sync"
 | 
			
		||||
	"sync/atomic"
 | 
			
		||||
	"unsafe"
 | 
			
		||||
 | 
			
		||||
	"go.opentelemetry.io/otel/attribute"
 | 
			
		||||
	"go.opentelemetry.io/otel/internal/metric/registry"
 | 
			
		||||
	"go.opentelemetry.io/otel/metric"
 | 
			
		||||
	"go.opentelemetry.io/otel/metric/number"
 | 
			
		||||
	"go.opentelemetry.io/otel/metric/sdkapi"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// This file contains the forwarding implementation of MeterProvider used as
 | 
			
		||||
// the default global instance.  Metric events using instruments provided by
 | 
			
		||||
// this implementation are no-ops until the first Meter implementation is set
 | 
			
		||||
// as the global provider.
 | 
			
		||||
//
 | 
			
		||||
// The implementation here uses Mutexes to maintain a list of active Meters in
 | 
			
		||||
// the MeterProvider and Instruments in each Meter, under the assumption that
 | 
			
		||||
// these interfaces are not performance-critical.
 | 
			
		||||
//
 | 
			
		||||
// We have the invariant that setDelegate() will be called before a new
 | 
			
		||||
// MeterProvider implementation is registered as the global provider.  Mutexes
 | 
			
		||||
// in the MeterProvider and Meters ensure that each instrument has a delegate
 | 
			
		||||
// before the global provider is set.
 | 
			
		||||
//
 | 
			
		||||
// Bound instrument operations are implemented by delegating to the
 | 
			
		||||
// instrument after it is registered, with a sync.Once initializer to
 | 
			
		||||
// protect against races with Release().
 | 
			
		||||
//
 | 
			
		||||
// Metric uniqueness checking is implemented by calling the exported
 | 
			
		||||
// methods of the api/metric/registry package.
 | 
			
		||||
 | 
			
		||||
type meterKey struct {
 | 
			
		||||
	InstrumentationName    string
 | 
			
		||||
	InstrumentationVersion string
 | 
			
		||||
	SchemaURL              string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type meterProvider struct {
 | 
			
		||||
	delegate metric.MeterProvider
 | 
			
		||||
 | 
			
		||||
	// lock protects `delegate` and `meters`.
 | 
			
		||||
	lock sync.Mutex
 | 
			
		||||
 | 
			
		||||
	// meters maintains a unique entry for every named Meter
 | 
			
		||||
	// that has been registered through the global instance.
 | 
			
		||||
	meters map[meterKey]*meterEntry
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type meterImpl struct {
 | 
			
		||||
	delegate unsafe.Pointer // (*metric.MeterImpl)
 | 
			
		||||
 | 
			
		||||
	lock       sync.Mutex
 | 
			
		||||
	syncInsts  []*syncImpl
 | 
			
		||||
	asyncInsts []*asyncImpl
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type meterEntry struct {
 | 
			
		||||
	unique sdkapi.MeterImpl
 | 
			
		||||
	impl   meterImpl
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type instrument struct {
 | 
			
		||||
	descriptor sdkapi.Descriptor
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type syncImpl struct {
 | 
			
		||||
	delegate unsafe.Pointer // (*sdkapi.SyncImpl)
 | 
			
		||||
 | 
			
		||||
	instrument
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type asyncImpl struct {
 | 
			
		||||
	delegate unsafe.Pointer // (*sdkapi.AsyncImpl)
 | 
			
		||||
 | 
			
		||||
	instrument
 | 
			
		||||
 | 
			
		||||
	runner sdkapi.AsyncRunner
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SyncImpler is implemented by all of the sync metric
 | 
			
		||||
// instruments.
 | 
			
		||||
type SyncImpler interface {
 | 
			
		||||
	SyncImpl() sdkapi.SyncImpl
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// AsyncImpler is implemented by all of the async
 | 
			
		||||
// metric instruments.
 | 
			
		||||
type AsyncImpler interface {
 | 
			
		||||
	AsyncImpl() sdkapi.AsyncImpl
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type syncHandle struct {
 | 
			
		||||
	delegate unsafe.Pointer // (*sdkapi.BoundInstrumentImpl)
 | 
			
		||||
 | 
			
		||||
	inst   *syncImpl
 | 
			
		||||
	labels []attribute.KeyValue
 | 
			
		||||
 | 
			
		||||
	initialize sync.Once
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var _ metric.MeterProvider = &meterProvider{}
 | 
			
		||||
var _ sdkapi.MeterImpl = &meterImpl{}
 | 
			
		||||
var _ sdkapi.InstrumentImpl = &syncImpl{}
 | 
			
		||||
var _ sdkapi.BoundSyncImpl = &syncHandle{}
 | 
			
		||||
var _ sdkapi.AsyncImpl = &asyncImpl{}
 | 
			
		||||
 | 
			
		||||
func (inst *instrument) Descriptor() sdkapi.Descriptor {
 | 
			
		||||
	return inst.descriptor
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// MeterProvider interface and delegation
 | 
			
		||||
 | 
			
		||||
func newMeterProvider() *meterProvider {
 | 
			
		||||
	return &meterProvider{
 | 
			
		||||
		meters: map[meterKey]*meterEntry{},
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (p *meterProvider) setDelegate(provider metric.MeterProvider) {
 | 
			
		||||
	p.lock.Lock()
 | 
			
		||||
	defer p.lock.Unlock()
 | 
			
		||||
 | 
			
		||||
	p.delegate = provider
 | 
			
		||||
	for key, entry := range p.meters {
 | 
			
		||||
		entry.impl.setDelegate(key, provider)
 | 
			
		||||
	}
 | 
			
		||||
	p.meters = nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (p *meterProvider) Meter(instrumentationName string, opts ...metric.MeterOption) metric.Meter {
 | 
			
		||||
	p.lock.Lock()
 | 
			
		||||
	defer p.lock.Unlock()
 | 
			
		||||
 | 
			
		||||
	if p.delegate != nil {
 | 
			
		||||
		return p.delegate.Meter(instrumentationName, opts...)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	cfg := metric.NewMeterConfig(opts...)
 | 
			
		||||
	key := meterKey{
 | 
			
		||||
		InstrumentationName:    instrumentationName,
 | 
			
		||||
		InstrumentationVersion: cfg.InstrumentationVersion(),
 | 
			
		||||
		SchemaURL:              cfg.SchemaURL(),
 | 
			
		||||
	}
 | 
			
		||||
	entry, ok := p.meters[key]
 | 
			
		||||
	if !ok {
 | 
			
		||||
		entry = &meterEntry{}
 | 
			
		||||
		// Note: This code implements its own MeterProvider
 | 
			
		||||
		// name-uniqueness logic because there is
 | 
			
		||||
		// synchronization required at the moment of
 | 
			
		||||
		// delegation.  We use the same instrument-uniqueness
 | 
			
		||||
		// checking the real SDK uses here:
 | 
			
		||||
		entry.unique = registry.NewUniqueInstrumentMeterImpl(&entry.impl)
 | 
			
		||||
		p.meters[key] = entry
 | 
			
		||||
	}
 | 
			
		||||
	return metric.WrapMeterImpl(entry.unique)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Meter interface and delegation
 | 
			
		||||
 | 
			
		||||
func (m *meterImpl) setDelegate(key meterKey, provider metric.MeterProvider) {
 | 
			
		||||
	m.lock.Lock()
 | 
			
		||||
	defer m.lock.Unlock()
 | 
			
		||||
 | 
			
		||||
	d := new(sdkapi.MeterImpl)
 | 
			
		||||
	*d = provider.Meter(
 | 
			
		||||
		key.InstrumentationName,
 | 
			
		||||
		metric.WithInstrumentationVersion(key.InstrumentationVersion),
 | 
			
		||||
		metric.WithSchemaURL(key.SchemaURL),
 | 
			
		||||
	).MeterImpl()
 | 
			
		||||
	m.delegate = unsafe.Pointer(d)
 | 
			
		||||
 | 
			
		||||
	for _, inst := range m.syncInsts {
 | 
			
		||||
		inst.setDelegate(*d)
 | 
			
		||||
	}
 | 
			
		||||
	m.syncInsts = nil
 | 
			
		||||
	for _, obs := range m.asyncInsts {
 | 
			
		||||
		obs.setDelegate(*d)
 | 
			
		||||
	}
 | 
			
		||||
	m.asyncInsts = nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (m *meterImpl) NewSyncInstrument(desc sdkapi.Descriptor) (sdkapi.SyncImpl, error) {
 | 
			
		||||
	m.lock.Lock()
 | 
			
		||||
	defer m.lock.Unlock()
 | 
			
		||||
 | 
			
		||||
	if meterPtr := (*sdkapi.MeterImpl)(atomic.LoadPointer(&m.delegate)); meterPtr != nil {
 | 
			
		||||
		return (*meterPtr).NewSyncInstrument(desc)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	inst := &syncImpl{
 | 
			
		||||
		instrument: instrument{
 | 
			
		||||
			descriptor: desc,
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
	m.syncInsts = append(m.syncInsts, inst)
 | 
			
		||||
	return inst, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Synchronous delegation
 | 
			
		||||
 | 
			
		||||
func (inst *syncImpl) setDelegate(d sdkapi.MeterImpl) {
 | 
			
		||||
	implPtr := new(sdkapi.SyncImpl)
 | 
			
		||||
 | 
			
		||||
	var err error
 | 
			
		||||
	*implPtr, err = d.NewSyncInstrument(inst.descriptor)
 | 
			
		||||
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		// TODO: There is no standard way to deliver this error to the user.
 | 
			
		||||
		// See https://github.com/open-telemetry/opentelemetry-go/issues/514
 | 
			
		||||
		// Note that the default SDK will not generate any errors yet, this is
 | 
			
		||||
		// only for added safety.
 | 
			
		||||
		panic(err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	atomic.StorePointer(&inst.delegate, unsafe.Pointer(implPtr))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (inst *syncImpl) Implementation() interface{} {
 | 
			
		||||
	if implPtr := (*sdkapi.SyncImpl)(atomic.LoadPointer(&inst.delegate)); implPtr != nil {
 | 
			
		||||
		return (*implPtr).Implementation()
 | 
			
		||||
	}
 | 
			
		||||
	return inst
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (inst *syncImpl) Bind(labels []attribute.KeyValue) sdkapi.BoundSyncImpl {
 | 
			
		||||
	if implPtr := (*sdkapi.SyncImpl)(atomic.LoadPointer(&inst.delegate)); implPtr != nil {
 | 
			
		||||
		return (*implPtr).Bind(labels)
 | 
			
		||||
	}
 | 
			
		||||
	return &syncHandle{
 | 
			
		||||
		inst:   inst,
 | 
			
		||||
		labels: labels,
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (bound *syncHandle) Unbind() {
 | 
			
		||||
	bound.initialize.Do(func() {})
 | 
			
		||||
 | 
			
		||||
	implPtr := (*sdkapi.BoundSyncImpl)(atomic.LoadPointer(&bound.delegate))
 | 
			
		||||
 | 
			
		||||
	if implPtr == nil {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	(*implPtr).Unbind()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Async delegation
 | 
			
		||||
 | 
			
		||||
func (m *meterImpl) NewAsyncInstrument(
 | 
			
		||||
	desc sdkapi.Descriptor,
 | 
			
		||||
	runner sdkapi.AsyncRunner,
 | 
			
		||||
) (sdkapi.AsyncImpl, error) {
 | 
			
		||||
 | 
			
		||||
	m.lock.Lock()
 | 
			
		||||
	defer m.lock.Unlock()
 | 
			
		||||
 | 
			
		||||
	if meterPtr := (*sdkapi.MeterImpl)(atomic.LoadPointer(&m.delegate)); meterPtr != nil {
 | 
			
		||||
		return (*meterPtr).NewAsyncInstrument(desc, runner)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	inst := &asyncImpl{
 | 
			
		||||
		instrument: instrument{
 | 
			
		||||
			descriptor: desc,
 | 
			
		||||
		},
 | 
			
		||||
		runner: runner,
 | 
			
		||||
	}
 | 
			
		||||
	m.asyncInsts = append(m.asyncInsts, inst)
 | 
			
		||||
	return inst, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (obs *asyncImpl) Implementation() interface{} {
 | 
			
		||||
	if implPtr := (*sdkapi.AsyncImpl)(atomic.LoadPointer(&obs.delegate)); implPtr != nil {
 | 
			
		||||
		return (*implPtr).Implementation()
 | 
			
		||||
	}
 | 
			
		||||
	return obs
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (obs *asyncImpl) setDelegate(d sdkapi.MeterImpl) {
 | 
			
		||||
	implPtr := new(sdkapi.AsyncImpl)
 | 
			
		||||
 | 
			
		||||
	var err error
 | 
			
		||||
	*implPtr, err = d.NewAsyncInstrument(obs.descriptor, obs.runner)
 | 
			
		||||
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		// TODO: There is no standard way to deliver this error to the user.
 | 
			
		||||
		// See https://github.com/open-telemetry/opentelemetry-go/issues/514
 | 
			
		||||
		// Note that the default SDK will not generate any errors yet, this is
 | 
			
		||||
		// only for added safety.
 | 
			
		||||
		panic(err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	atomic.StorePointer(&obs.delegate, unsafe.Pointer(implPtr))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Metric updates
 | 
			
		||||
 | 
			
		||||
func (m *meterImpl) RecordBatch(ctx context.Context, labels []attribute.KeyValue, measurements ...sdkapi.Measurement) {
 | 
			
		||||
	if delegatePtr := (*sdkapi.MeterImpl)(atomic.LoadPointer(&m.delegate)); delegatePtr != nil {
 | 
			
		||||
		(*delegatePtr).RecordBatch(ctx, labels, measurements...)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (inst *syncImpl) RecordOne(ctx context.Context, number number.Number, labels []attribute.KeyValue) {
 | 
			
		||||
	if instPtr := (*sdkapi.SyncImpl)(atomic.LoadPointer(&inst.delegate)); instPtr != nil {
 | 
			
		||||
		(*instPtr).RecordOne(ctx, number, labels)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Bound instrument initialization
 | 
			
		||||
 | 
			
		||||
func (bound *syncHandle) RecordOne(ctx context.Context, number number.Number) {
 | 
			
		||||
	instPtr := (*sdkapi.SyncImpl)(atomic.LoadPointer(&bound.inst.delegate))
 | 
			
		||||
	if instPtr == nil {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	var implPtr *sdkapi.BoundSyncImpl
 | 
			
		||||
	bound.initialize.Do(func() {
 | 
			
		||||
		implPtr = new(sdkapi.BoundSyncImpl)
 | 
			
		||||
		*implPtr = (*instPtr).Bind(bound.labels)
 | 
			
		||||
		atomic.StorePointer(&bound.delegate, unsafe.Pointer(implPtr))
 | 
			
		||||
	})
 | 
			
		||||
	if implPtr == nil {
 | 
			
		||||
		implPtr = (*sdkapi.BoundSyncImpl)(atomic.LoadPointer(&bound.delegate))
 | 
			
		||||
	}
 | 
			
		||||
	// This may still be nil if instrument was created and bound
 | 
			
		||||
	// without a delegate, then the instrument was set to have a
 | 
			
		||||
	// delegate and unbound.
 | 
			
		||||
	if implPtr == nil {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	(*implPtr).RecordOne(ctx, number)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func AtomicFieldOffsets() map[string]uintptr {
 | 
			
		||||
	return map[string]uintptr{
 | 
			
		||||
		"meterProvider.delegate": unsafe.Offsetof(meterProvider{}.delegate),
 | 
			
		||||
		"meterImpl.delegate":     unsafe.Offsetof(meterImpl{}.delegate),
 | 
			
		||||
		"syncImpl.delegate":      unsafe.Offsetof(syncImpl{}.delegate),
 | 
			
		||||
		"asyncImpl.delegate":     unsafe.Offsetof(asyncImpl{}.delegate),
 | 
			
		||||
		"syncHandle.delegate":    unsafe.Offsetof(syncHandle{}.delegate),
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										66
									
								
								vendor/go.opentelemetry.io/otel/internal/metric/global/metric.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								vendor/go.opentelemetry.io/otel/internal/metric/global/metric.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,66 @@
 | 
			
		||||
// Copyright The OpenTelemetry Authors
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
//     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
package global // import "go.opentelemetry.io/otel/internal/metric/global"
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"sync"
 | 
			
		||||
	"sync/atomic"
 | 
			
		||||
 | 
			
		||||
	"go.opentelemetry.io/otel/metric"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type meterProviderHolder struct {
 | 
			
		||||
	mp metric.MeterProvider
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	globalMeter = defaultMeterValue()
 | 
			
		||||
 | 
			
		||||
	delegateMeterOnce sync.Once
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// MeterProvider is the internal implementation for global.MeterProvider.
 | 
			
		||||
func MeterProvider() metric.MeterProvider {
 | 
			
		||||
	return globalMeter.Load().(meterProviderHolder).mp
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SetMeterProvider is the internal implementation for global.SetMeterProvider.
 | 
			
		||||
func SetMeterProvider(mp metric.MeterProvider) {
 | 
			
		||||
	delegateMeterOnce.Do(func() {
 | 
			
		||||
		current := MeterProvider()
 | 
			
		||||
 | 
			
		||||
		if current == mp {
 | 
			
		||||
			// Setting the provider to the prior default is nonsense, panic.
 | 
			
		||||
			// Panic is acceptable because we are likely still early in the
 | 
			
		||||
			// process lifetime.
 | 
			
		||||
			panic("invalid MeterProvider, the global instance cannot be reinstalled")
 | 
			
		||||
		} else if def, ok := current.(*meterProvider); ok {
 | 
			
		||||
			def.setDelegate(mp)
 | 
			
		||||
		}
 | 
			
		||||
	})
 | 
			
		||||
	globalMeter.Store(meterProviderHolder{mp: mp})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func defaultMeterValue() *atomic.Value {
 | 
			
		||||
	v := &atomic.Value{}
 | 
			
		||||
	v.Store(meterProviderHolder{mp: newMeterProvider()})
 | 
			
		||||
	return v
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ResetForTest restores the initial global state, for testing purposes.
 | 
			
		||||
func ResetForTest() {
 | 
			
		||||
	globalMeter = defaultMeterValue()
 | 
			
		||||
	delegateMeterOnce = sync.Once{}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										24
									
								
								vendor/go.opentelemetry.io/otel/internal/metric/registry/doc.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								vendor/go.opentelemetry.io/otel/internal/metric/registry/doc.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,24 @@
 | 
			
		||||
// Copyright The OpenTelemetry Authors
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
//     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
Package registry provides a non-standalone implementation of
 | 
			
		||||
MeterProvider that adds uniqueness checking for instrument descriptors
 | 
			
		||||
on top of other MeterProvider it wraps.
 | 
			
		||||
 | 
			
		||||
This package is currently in a pre-GA phase. Backwards incompatible changes
 | 
			
		||||
may be introduced in subsequent minor version releases as we work to track the
 | 
			
		||||
evolving OpenTelemetry specification and user feedback.
 | 
			
		||||
*/
 | 
			
		||||
package registry // import "go.opentelemetry.io/otel/internal/metric/registry"
 | 
			
		||||
							
								
								
									
										139
									
								
								vendor/go.opentelemetry.io/otel/internal/metric/registry/registry.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										139
									
								
								vendor/go.opentelemetry.io/otel/internal/metric/registry/registry.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,139 @@
 | 
			
		||||
// Copyright The OpenTelemetry Authors
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
//     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
package registry // import "go.opentelemetry.io/otel/internal/metric/registry"
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"context"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"sync"
 | 
			
		||||
 | 
			
		||||
	"go.opentelemetry.io/otel/attribute"
 | 
			
		||||
	"go.opentelemetry.io/otel/metric/sdkapi"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// UniqueInstrumentMeterImpl implements the metric.MeterImpl interface, adding
 | 
			
		||||
// uniqueness checking for instrument descriptors.
 | 
			
		||||
type UniqueInstrumentMeterImpl struct {
 | 
			
		||||
	lock  sync.Mutex
 | 
			
		||||
	impl  sdkapi.MeterImpl
 | 
			
		||||
	state map[string]sdkapi.InstrumentImpl
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var _ sdkapi.MeterImpl = (*UniqueInstrumentMeterImpl)(nil)
 | 
			
		||||
 | 
			
		||||
// ErrMetricKindMismatch is the standard error for mismatched metric
 | 
			
		||||
// instrument definitions.
 | 
			
		||||
var ErrMetricKindMismatch = fmt.Errorf(
 | 
			
		||||
	"a metric was already registered by this name with another kind or number type")
 | 
			
		||||
 | 
			
		||||
// NewUniqueInstrumentMeterImpl returns a wrapped metric.MeterImpl
 | 
			
		||||
// with the addition of instrument name uniqueness checking.
 | 
			
		||||
func NewUniqueInstrumentMeterImpl(impl sdkapi.MeterImpl) *UniqueInstrumentMeterImpl {
 | 
			
		||||
	return &UniqueInstrumentMeterImpl{
 | 
			
		||||
		impl:  impl,
 | 
			
		||||
		state: map[string]sdkapi.InstrumentImpl{},
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// MeterImpl gives the caller access to the underlying MeterImpl
 | 
			
		||||
// used by this UniqueInstrumentMeterImpl.
 | 
			
		||||
func (u *UniqueInstrumentMeterImpl) MeterImpl() sdkapi.MeterImpl {
 | 
			
		||||
	return u.impl
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// RecordBatch implements sdkapi.MeterImpl.
 | 
			
		||||
func (u *UniqueInstrumentMeterImpl) RecordBatch(ctx context.Context, labels []attribute.KeyValue, ms ...sdkapi.Measurement) {
 | 
			
		||||
	u.impl.RecordBatch(ctx, labels, ms...)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewMetricKindMismatchError formats an error that describes a
 | 
			
		||||
// mismatched metric instrument definition.
 | 
			
		||||
func NewMetricKindMismatchError(desc sdkapi.Descriptor) error {
 | 
			
		||||
	return fmt.Errorf("metric %s registered as %s %s: %w",
 | 
			
		||||
		desc.Name(),
 | 
			
		||||
		desc.NumberKind(),
 | 
			
		||||
		desc.InstrumentKind(),
 | 
			
		||||
		ErrMetricKindMismatch)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Compatible determines whether two sdkapi.Descriptors are considered
 | 
			
		||||
// the same for the purpose of uniqueness checking.
 | 
			
		||||
func Compatible(candidate, existing sdkapi.Descriptor) bool {
 | 
			
		||||
	return candidate.InstrumentKind() == existing.InstrumentKind() &&
 | 
			
		||||
		candidate.NumberKind() == existing.NumberKind()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// checkUniqueness returns an ErrMetricKindMismatch error if there is
 | 
			
		||||
// a conflict between a descriptor that was already registered and the
 | 
			
		||||
// `descriptor` argument.  If there is an existing compatible
 | 
			
		||||
// registration, this returns the already-registered instrument.  If
 | 
			
		||||
// there is no conflict and no prior registration, returns (nil, nil).
 | 
			
		||||
func (u *UniqueInstrumentMeterImpl) checkUniqueness(descriptor sdkapi.Descriptor) (sdkapi.InstrumentImpl, error) {
 | 
			
		||||
	impl, ok := u.state[descriptor.Name()]
 | 
			
		||||
	if !ok {
 | 
			
		||||
		return nil, nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if !Compatible(descriptor, impl.Descriptor()) {
 | 
			
		||||
		return nil, NewMetricKindMismatchError(impl.Descriptor())
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return impl, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewSyncInstrument implements sdkapi.MeterImpl.
 | 
			
		||||
func (u *UniqueInstrumentMeterImpl) NewSyncInstrument(descriptor sdkapi.Descriptor) (sdkapi.SyncImpl, error) {
 | 
			
		||||
	u.lock.Lock()
 | 
			
		||||
	defer u.lock.Unlock()
 | 
			
		||||
 | 
			
		||||
	impl, err := u.checkUniqueness(descriptor)
 | 
			
		||||
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	} else if impl != nil {
 | 
			
		||||
		return impl.(sdkapi.SyncImpl), nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	syncInst, err := u.impl.NewSyncInstrument(descriptor)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	u.state[descriptor.Name()] = syncInst
 | 
			
		||||
	return syncInst, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewAsyncInstrument implements sdkapi.MeterImpl.
 | 
			
		||||
func (u *UniqueInstrumentMeterImpl) NewAsyncInstrument(
 | 
			
		||||
	descriptor sdkapi.Descriptor,
 | 
			
		||||
	runner sdkapi.AsyncRunner,
 | 
			
		||||
) (sdkapi.AsyncImpl, error) {
 | 
			
		||||
	u.lock.Lock()
 | 
			
		||||
	defer u.lock.Unlock()
 | 
			
		||||
 | 
			
		||||
	impl, err := u.checkUniqueness(descriptor)
 | 
			
		||||
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	} else if impl != nil {
 | 
			
		||||
		return impl.(sdkapi.AsyncImpl), nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	asyncInst, err := u.impl.NewAsyncInstrument(descriptor, runner)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	u.state[descriptor.Name()] = asyncInst
 | 
			
		||||
	return asyncInst, nil
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										55
									
								
								vendor/go.opentelemetry.io/otel/internal/rawhelpers.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								vendor/go.opentelemetry.io/otel/internal/rawhelpers.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,55 @@
 | 
			
		||||
// Copyright The OpenTelemetry Authors
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
//     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
package internal // import "go.opentelemetry.io/otel/internal"
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"math"
 | 
			
		||||
	"unsafe"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func BoolToRaw(b bool) uint64 {
 | 
			
		||||
	if b {
 | 
			
		||||
		return 1
 | 
			
		||||
	}
 | 
			
		||||
	return 0
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func RawToBool(r uint64) bool {
 | 
			
		||||
	return r != 0
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func Int64ToRaw(i int64) uint64 {
 | 
			
		||||
	return uint64(i)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func RawToInt64(r uint64) int64 {
 | 
			
		||||
	return int64(r)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func Float64ToRaw(f float64) uint64 {
 | 
			
		||||
	return math.Float64bits(f)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func RawToFloat64(r uint64) float64 {
 | 
			
		||||
	return math.Float64frombits(r)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func RawPtrToFloat64Ptr(r *uint64) *float64 {
 | 
			
		||||
	return (*float64)(unsafe.Pointer(r))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func RawPtrToInt64Ptr(r *uint64) *int64 {
 | 
			
		||||
	return (*int64)(unsafe.Pointer(r))
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user