mirror of
https://github.com/open-telemetry/opentelemetry-go.git
synced 2024-12-14 10:13:10 +02:00
a98bb979df
* Update Tracer API with instrumentation version Add option to the `Provider.Tracer` method to specify the instrumentation version. Update the global, noop, opentracing bridge, and default SDK implementations. This does not propagate the instrumentation library version to the exported span. That is left for a follow-on PR. * Revert trace_test.go This is for the next PR. * Update SDK to include version for default instrumentation If the instrumentation library name is empty and the default instrumentation is uses, include the SDK version. * Update comments and documentation * Remove default instrumentation version
134 lines
4.2 KiB
Go
134 lines
4.2 KiB
Go
// 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
|
|
|
|
/*
|
|
This file contains the forwarding implementation of the trace.Provider used as
|
|
the default global instance. Prior to initialization of an SDK, Tracers
|
|
returned by the global Provider 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 Provider. 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"
|
|
|
|
"go.opentelemetry.io/otel/api/trace"
|
|
)
|
|
|
|
// traceProvider is a placeholder for a configured SDK Provider.
|
|
//
|
|
// All Provider functionality is forwarded to a delegate once configured.
|
|
type traceProvider struct {
|
|
mtx sync.Mutex
|
|
tracers []*tracer
|
|
|
|
delegate trace.Provider
|
|
}
|
|
|
|
// Compile-time guarantee that traceProvider implements the trace.Provider interface.
|
|
var _ trace.Provider = &traceProvider{}
|
|
|
|
// setDelegate configures p to delegate all Provider functionality to provider.
|
|
//
|
|
// All Tracers provided prior to this function call are switched out to be
|
|
// Tracers provided by provider.
|
|
//
|
|
// Delegation only happens on the first call to this method. All subsequent
|
|
// calls result in no delegation changes.
|
|
func (p *traceProvider) setDelegate(provider trace.Provider) {
|
|
if p.delegate != nil {
|
|
return
|
|
}
|
|
|
|
p.mtx.Lock()
|
|
defer p.mtx.Unlock()
|
|
|
|
p.delegate = provider
|
|
for _, t := range p.tracers {
|
|
t.setDelegate(provider)
|
|
}
|
|
|
|
p.tracers = nil
|
|
}
|
|
|
|
// Tracer implements trace.Provider.
|
|
func (p *traceProvider) Tracer(name string, opts ...trace.TracerOption) trace.Tracer {
|
|
p.mtx.Lock()
|
|
defer p.mtx.Unlock()
|
|
|
|
if p.delegate != nil {
|
|
return p.delegate.Tracer(name)
|
|
}
|
|
|
|
t := &tracer{name: name, opts: opts}
|
|
p.tracers = append(p.tracers, t)
|
|
return t
|
|
}
|
|
|
|
// 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 {
|
|
once sync.Once
|
|
name string
|
|
opts []trace.TracerOption
|
|
|
|
delegate trace.Tracer
|
|
}
|
|
|
|
// 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.
|
|
//
|
|
// Delegation only happens on the first call to this method. All subsequent
|
|
// calls result in no delegation changes.
|
|
func (t *tracer) setDelegate(provider trace.Provider) {
|
|
t.once.Do(func() { t.delegate = provider.Tracer(t.name, t.opts...) })
|
|
}
|
|
|
|
// WithSpan implements trace.Tracer by forwarding the call to t.delegate if
|
|
// set, otherwise it forwards the call to a NoopTracer.
|
|
func (t *tracer) WithSpan(ctx context.Context, name string, body func(context.Context) error, opts ...trace.StartOption) error {
|
|
if t.delegate != nil {
|
|
return t.delegate.WithSpan(ctx, name, body, opts...)
|
|
}
|
|
return trace.NoopTracer{}.WithSpan(ctx, name, body, 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.StartOption) (context.Context, trace.Span) {
|
|
if t.delegate != nil {
|
|
return t.delegate.Start(ctx, name, opts...)
|
|
}
|
|
return trace.NoopTracer{}.Start(ctx, name, opts...)
|
|
}
|