fix: Update go.opentelemetry.io/otel/sdk/trace to satisfy traceProvider interface

Signed-off-by: Bryant Biggs <bryantbiggs@gmail.com>
This commit is contained in:
Bryant Biggs 2023-12-28 09:56:35 -05:00
parent 78421616e0
commit a1e0601e03
14 changed files with 177 additions and 42 deletions

2
go.mod
View File

@ -62,7 +62,7 @@ require (
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.19.0 go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.19.0
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.19.0 go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.19.0
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.19.0 go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.19.0
go.opentelemetry.io/otel/sdk v1.19.0 go.opentelemetry.io/otel/sdk v1.21.0
go.opentelemetry.io/otel/trace v1.21.0 go.opentelemetry.io/otel/trace v1.21.0
golang.org/x/mod v0.14.0 golang.org/x/mod v0.14.0
golang.org/x/sync v0.5.0 golang.org/x/sync v0.5.0

4
go.sum
View File

@ -345,8 +345,8 @@ go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.19.0 h1:IeMey
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.19.0/go.mod h1:oVdCUtjq9MK9BlS7TtucsQwUcXcymNiEDjgDD2jMtZU= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.19.0/go.mod h1:oVdCUtjq9MK9BlS7TtucsQwUcXcymNiEDjgDD2jMtZU=
go.opentelemetry.io/otel/metric v1.21.0 h1:tlYWfeo+Bocx5kLEloTjbcDwBuELRrIFxwdQ36PlJu4= go.opentelemetry.io/otel/metric v1.21.0 h1:tlYWfeo+Bocx5kLEloTjbcDwBuELRrIFxwdQ36PlJu4=
go.opentelemetry.io/otel/metric v1.21.0/go.mod h1:o1p3CA8nNHW8j5yuQLdc1eeqEaPfzug24uvsyIEJRWM= go.opentelemetry.io/otel/metric v1.21.0/go.mod h1:o1p3CA8nNHW8j5yuQLdc1eeqEaPfzug24uvsyIEJRWM=
go.opentelemetry.io/otel/sdk v1.19.0 h1:6USY6zH+L8uMH8L3t1enZPR3WFEmSTADlqldyHtJi3o= go.opentelemetry.io/otel/sdk v1.21.0 h1:FTt8qirL1EysG6sTQRZ5TokkU8d0ugCj8htOgThZXQ8=
go.opentelemetry.io/otel/sdk v1.19.0/go.mod h1:NedEbbS4w3C6zElbLdPJKOpJQOrGUJ+GfzpjUvI0v1A= go.opentelemetry.io/otel/sdk v1.21.0/go.mod h1:Nna6Yv7PWTdgJHVRD9hIYywQBRx7pbox6nwBnZIxl/E=
go.opentelemetry.io/otel/trace v1.21.0 h1:WD9i5gzvoUPuXIXH24ZNBudiarZDKuekPqi/E8fpfLc= go.opentelemetry.io/otel/trace v1.21.0 h1:WD9i5gzvoUPuXIXH24ZNBudiarZDKuekPqi/E8fpfLc=
go.opentelemetry.io/otel/trace v1.21.0/go.mod h1:LGbsEB0f9LGjN+OZaQQ26sohbOmiMR+BaslueVtS/qQ= go.opentelemetry.io/otel/trace v1.21.0/go.mod h1:LGbsEB0f9LGjN+OZaQQ26sohbOmiMR+BaslueVtS/qQ=
go.opentelemetry.io/proto/otlp v1.0.0 h1:T0TX0tmXU8a3CbNXzEKGeU5mIVOdf0oykP+u2lIVU/I= go.opentelemetry.io/proto/otlp v1.0.0 h1:T0TX0tmXU8a3CbNXzEKGeU5mIVOdf0oykP+u2lIVU/I=

View File

@ -21,12 +21,10 @@ import (
"strings" "strings"
) )
var ( // ErrPartialResource is returned by a detector when complete source
// ErrPartialResource is returned by a detector when complete source // information for a Resource is unavailable or the source information
// information for a Resource is unavailable or the source information // contains invalid values that are omitted from the returned Resource.
// contains invalid values that are omitted from the returned Resource. var ErrPartialResource = errors.New("partial resource")
ErrPartialResource = errors.New("partial resource")
)
// Detector detects OpenTelemetry resource information. // Detector detects OpenTelemetry resource information.
type Detector interface { type Detector interface {

View File

@ -28,16 +28,14 @@ import (
const ( const (
// resourceAttrKey is the environment variable name OpenTelemetry Resource information will be read from. // resourceAttrKey is the environment variable name OpenTelemetry Resource information will be read from.
resourceAttrKey = "OTEL_RESOURCE_ATTRIBUTES" resourceAttrKey = "OTEL_RESOURCE_ATTRIBUTES" //nolint:gosec // False positive G101: Potential hardcoded credentials
// svcNameKey is the environment variable name that Service Name information will be read from. // svcNameKey is the environment variable name that Service Name information will be read from.
svcNameKey = "OTEL_SERVICE_NAME" svcNameKey = "OTEL_SERVICE_NAME"
) )
var ( // errMissingValue is returned when a resource value is missing.
// errMissingValue is returned when a resource value is missing. var errMissingValue = fmt.Errorf("%w: missing value", ErrPartialResource)
errMissingValue = fmt.Errorf("%w: missing value", ErrPartialResource)
)
// fromEnv is a Detector that implements the Detector and collects // fromEnv is a Detector that implements the Detector and collects
// resources from environment. This Detector is included as a // resources from environment. This Detector is included as a
@ -91,7 +89,7 @@ func constructOTResources(s string) (*Resource, error) {
continue continue
} }
key := strings.TrimSpace(k) key := strings.TrimSpace(k)
val, err := url.QueryUnescape(strings.TrimSpace(v)) val, err := url.PathUnescape(strings.TrimSpace(v))
if err != nil { if err != nil {
// Retain original value if decoding fails, otherwise it will be // Retain original value if decoding fails, otherwise it will be
// an empty string. // an empty string.

View File

@ -36,8 +36,10 @@ func setOSDescriptionProvider(osDescriptionProvider osDescriptionProvider) {
osDescription = osDescriptionProvider osDescription = osDescriptionProvider
} }
type osTypeDetector struct{} type (
type osDescriptionDetector struct{} osTypeDetector struct{}
osDescriptionDetector struct{}
)
// Detect returns a *Resource that describes the operating system type the // Detect returns a *Resource that describes the operating system type the
// service is running on. // service is running on.
@ -56,7 +58,6 @@ func (osTypeDetector) Detect(ctx context.Context) (*Resource, error) {
// service is running on. // service is running on.
func (osDescriptionDetector) Detect(ctx context.Context) (*Resource, error) { func (osDescriptionDetector) Detect(ctx context.Context) (*Resource, error) {
description, err := osDescription() description, err := osDescription()
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -25,14 +25,16 @@ import (
semconv "go.opentelemetry.io/otel/semconv/v1.21.0" semconv "go.opentelemetry.io/otel/semconv/v1.21.0"
) )
type pidProvider func() int type (
type executablePathProvider func() (string, error) pidProvider func() int
type commandArgsProvider func() []string executablePathProvider func() (string, error)
type ownerProvider func() (*user.User, error) commandArgsProvider func() []string
type runtimeNameProvider func() string ownerProvider func() (*user.User, error)
type runtimeVersionProvider func() string runtimeNameProvider func() string
type runtimeOSProvider func() string runtimeVersionProvider func() string
type runtimeArchProvider func() string runtimeOSProvider func() string
runtimeArchProvider func() string
)
var ( var (
defaultPidProvider pidProvider = os.Getpid defaultPidProvider pidProvider = os.Getpid
@ -108,14 +110,16 @@ func setUserProviders(ownerProvider ownerProvider) {
owner = ownerProvider owner = ownerProvider
} }
type processPIDDetector struct{} type (
type processExecutableNameDetector struct{} processPIDDetector struct{}
type processExecutablePathDetector struct{} processExecutableNameDetector struct{}
type processCommandArgsDetector struct{} processExecutablePathDetector struct{}
type processOwnerDetector struct{} processCommandArgsDetector struct{}
type processRuntimeNameDetector struct{} processOwnerDetector struct{}
type processRuntimeVersionDetector struct{} processRuntimeNameDetector struct{}
type processRuntimeDescriptionDetector struct{} processRuntimeVersionDetector struct{}
processRuntimeDescriptionDetector struct{}
)
// Detect returns a *Resource that describes the process identifier (PID) of the // Detect returns a *Resource that describes the process identifier (PID) of the
// executing process. // executing process.

View File

@ -25,6 +25,8 @@ import (
"go.opentelemetry.io/otel/sdk/instrumentation" "go.opentelemetry.io/otel/sdk/instrumentation"
"go.opentelemetry.io/otel/sdk/resource" "go.opentelemetry.io/otel/sdk/resource"
"go.opentelemetry.io/otel/trace" "go.opentelemetry.io/otel/trace"
"go.opentelemetry.io/otel/trace/embedded"
"go.opentelemetry.io/otel/trace/noop"
) )
const ( const (
@ -73,6 +75,8 @@ func (cfg tracerProviderConfig) MarshalLog() interface{} {
// TracerProvider is an OpenTelemetry TracerProvider. It provides Tracers to // TracerProvider is an OpenTelemetry TracerProvider. It provides Tracers to
// instrumentation so it can trace operational flow through a system. // instrumentation so it can trace operational flow through a system.
type TracerProvider struct { type TracerProvider struct {
embedded.TracerProvider
mu sync.Mutex mu sync.Mutex
namedTracer map[instrumentation.Scope]*tracer namedTracer map[instrumentation.Scope]*tracer
spanProcessors atomic.Pointer[spanProcessorStates] spanProcessors atomic.Pointer[spanProcessorStates]
@ -139,7 +143,7 @@ func NewTracerProvider(opts ...TracerProviderOption) *TracerProvider {
func (p *TracerProvider) Tracer(name string, opts ...trace.TracerOption) trace.Tracer { func (p *TracerProvider) Tracer(name string, opts ...trace.TracerOption) trace.Tracer {
// This check happens before the mutex is acquired to avoid deadlocking if Tracer() is called from within Shutdown(). // This check happens before the mutex is acquired to avoid deadlocking if Tracer() is called from within Shutdown().
if p.isShutdown.Load() { if p.isShutdown.Load() {
return trace.NewNoopTracerProvider().Tracer(name, opts...) return noop.NewTracerProvider().Tracer(name, opts...)
} }
c := trace.NewTracerConfig(opts...) c := trace.NewTracerConfig(opts...)
if name == "" { if name == "" {
@ -157,7 +161,7 @@ func (p *TracerProvider) Tracer(name string, opts ...trace.TracerOption) trace.T
// Must check the flag after acquiring the mutex to avoid returning a valid tracer if Shutdown() ran // Must check the flag after acquiring the mutex to avoid returning a valid tracer if Shutdown() ran
// after the first check above but before we acquired the mutex. // after the first check above but before we acquired the mutex.
if p.isShutdown.Load() { if p.isShutdown.Load() {
return trace.NewNoopTracerProvider().Tracer(name, opts...), true return noop.NewTracerProvider().Tracer(name, opts...), true
} }
t, ok := p.namedTracer[is] t, ok := p.namedTracer[is]
if !ok { if !ok {

View File

@ -158,9 +158,9 @@ func NeverSample() Sampler {
return alwaysOffSampler{} return alwaysOffSampler{}
} }
// ParentBased returns a composite sampler which behaves differently, // ParentBased returns a sampler decorator which behaves differently,
// based on the parent of the span. If the span has no parent, // based on the parent of the span. If the span has no parent,
// the root(Sampler) is used to make sampling decision. If the span has // the decorated sampler is used to make sampling decision. If the span has
// a parent, depending on whether the parent is remote and whether it // a parent, depending on whether the parent is remote and whether it
// is sampled, one of the following samplers will apply: // is sampled, one of the following samplers will apply:
// - remoteParentSampled(Sampler) (default: AlwaysOn) // - remoteParentSampled(Sampler) (default: AlwaysOn)

View File

@ -32,6 +32,7 @@ import (
"go.opentelemetry.io/otel/sdk/resource" "go.opentelemetry.io/otel/sdk/resource"
semconv "go.opentelemetry.io/otel/semconv/v1.21.0" semconv "go.opentelemetry.io/otel/semconv/v1.21.0"
"go.opentelemetry.io/otel/trace" "go.opentelemetry.io/otel/trace"
"go.opentelemetry.io/otel/trace/embedded"
) )
// ReadOnlySpan allows reading information from the data structure underlying a // ReadOnlySpan allows reading information from the data structure underlying a
@ -108,6 +109,8 @@ type ReadWriteSpan interface {
// recordingSpan is an implementation of the OpenTelemetry Span API // recordingSpan is an implementation of the OpenTelemetry Span API
// representing the individual component of a trace that is sampled. // representing the individual component of a trace that is sampled.
type recordingSpan struct { type recordingSpan struct {
embedded.Span
// mu protects the contents of this span. // mu protects the contents of this span.
mu sync.Mutex mu sync.Mutex
@ -158,8 +161,10 @@ type recordingSpan struct {
tracer *tracer tracer *tracer
} }
var _ ReadWriteSpan = (*recordingSpan)(nil) var (
var _ runtimeTracer = (*recordingSpan)(nil) _ ReadWriteSpan = (*recordingSpan)(nil)
_ runtimeTracer = (*recordingSpan)(nil)
)
// SpanContext returns the SpanContext of this span. // SpanContext returns the SpanContext of this span.
func (s *recordingSpan) SpanContext() trace.SpanContext { func (s *recordingSpan) SpanContext() trace.SpanContext {
@ -772,6 +777,8 @@ func (s *recordingSpan) runtimeTrace(ctx context.Context) context.Context {
// that wraps a SpanContext. It performs no operations other than to return // that wraps a SpanContext. It performs no operations other than to return
// the wrapped SpanContext or TracerProvider that created it. // the wrapped SpanContext or TracerProvider that created it.
type nonRecordingSpan struct { type nonRecordingSpan struct {
embedded.Span
// tracer is the SDK tracer that created this span. // tracer is the SDK tracer that created this span.
tracer *tracer tracer *tracer
sc trace.SpanContext sc trace.SpanContext

View File

@ -20,9 +20,12 @@ import (
"go.opentelemetry.io/otel/sdk/instrumentation" "go.opentelemetry.io/otel/sdk/instrumentation"
"go.opentelemetry.io/otel/trace" "go.opentelemetry.io/otel/trace"
"go.opentelemetry.io/otel/trace/embedded"
) )
type tracer struct { type tracer struct {
embedded.Tracer
provider *TracerProvider provider *TracerProvider
instrumentationScope instrumentation.Scope instrumentationScope instrumentation.Scope
} }

View File

@ -162,6 +162,7 @@ func (s spanSnapshot) Resource() *resource.Resource { return s.resource }
func (s spanSnapshot) InstrumentationScope() instrumentation.Scope { func (s spanSnapshot) InstrumentationScope() instrumentation.Scope {
return s.instrumentationScope return s.instrumentationScope
} }
func (s spanSnapshot) InstrumentationLibrary() instrumentation.Library { func (s spanSnapshot) InstrumentationLibrary() instrumentation.Library {
return s.instrumentationScope return s.instrumentationScope
} }

View File

@ -16,5 +16,5 @@ package sdk // import "go.opentelemetry.io/otel/sdk"
// Version is the current release version of the OpenTelemetry SDK in use. // Version is the current release version of the OpenTelemetry SDK in use.
func Version() string { func Version() string {
return "1.19.0" return "1.21.0"
} }

118
vendor/go.opentelemetry.io/otel/trace/noop/noop.go generated vendored Normal file
View File

@ -0,0 +1,118 @@
// 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 noop provides an implementation of the OpenTelemetry trace API that
// produces no telemetry and minimizes used computation resources.
//
// Using this package to implement the OpenTelemetry trace API will effectively
// disable OpenTelemetry.
//
// This implementation can be embedded in other implementations of the
// OpenTelemetry trace API. Doing so will mean the implementation defaults to
// no operation for methods it does not implement.
package noop // import "go.opentelemetry.io/otel/trace/noop"
import (
"context"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/codes"
"go.opentelemetry.io/otel/trace"
"go.opentelemetry.io/otel/trace/embedded"
)
var (
// Compile-time check this implements the OpenTelemetry API.
_ trace.TracerProvider = TracerProvider{}
_ trace.Tracer = Tracer{}
_ trace.Span = Span{}
)
// TracerProvider is an OpenTelemetry No-Op TracerProvider.
type TracerProvider struct{ embedded.TracerProvider }
// NewTracerProvider returns a TracerProvider that does not record any telemetry.
func NewTracerProvider() TracerProvider {
return TracerProvider{}
}
// Tracer returns an OpenTelemetry Tracer that does not record any telemetry.
func (TracerProvider) Tracer(string, ...trace.TracerOption) trace.Tracer {
return Tracer{}
}
// Tracer is an OpenTelemetry No-Op Tracer.
type Tracer struct{ embedded.Tracer }
// Start creates a span. The created span will be set in a child context of ctx
// and returned with the span.
//
// If ctx contains a span context, the returned span will also contain that
// span context. If the span context in ctx is for a non-recording span, that
// span instance will be returned directly.
func (t Tracer) Start(ctx context.Context, _ string, _ ...trace.SpanStartOption) (context.Context, trace.Span) {
span := trace.SpanFromContext(ctx)
// If the parent context contains a non-zero span context, that span
// context needs to be returned as a non-recording span
// (https://github.com/open-telemetry/opentelemetry-specification/blob/3a1dde966a4ce87cce5adf464359fe369741bbea/specification/trace/api.md#behavior-of-the-api-in-the-absence-of-an-installed-sdk).
var zeroSC trace.SpanContext
if sc := span.SpanContext(); !sc.Equal(zeroSC) {
if !span.IsRecording() {
// If the span is not recording return it directly.
return ctx, span
}
// Otherwise, return the span context needs in a non-recording span.
span = Span{sc: sc}
} else {
// No parent, return a No-Op span with an empty span context.
span = Span{}
}
return trace.ContextWithSpan(ctx, span), span
}
// Span is an OpenTelemetry No-Op Span.
type Span struct {
embedded.Span
sc trace.SpanContext
}
// SpanContext returns an empty span context.
func (s Span) SpanContext() trace.SpanContext { return s.sc }
// IsRecording always returns false.
func (Span) IsRecording() bool { return false }
// SetStatus does nothing.
func (Span) SetStatus(codes.Code, string) {}
// SetAttributes does nothing.
func (Span) SetAttributes(...attribute.KeyValue) {}
// End does nothing.
func (Span) End(...trace.SpanEndOption) {}
// RecordError does nothing.
func (Span) RecordError(error, ...trace.EventOption) {}
// AddEvent does nothing.
func (Span) AddEvent(string, ...trace.EventOption) {}
// SetName does nothing.
func (Span) SetName(string) {}
// TracerProvider returns a No-Op TracerProvider.
func (Span) TracerProvider() trace.TracerProvider { return TracerProvider{} }

3
vendor/modules.txt vendored
View File

@ -446,7 +446,7 @@ go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp/internal/retry
## explicit; go 1.20 ## explicit; go 1.20
go.opentelemetry.io/otel/metric go.opentelemetry.io/otel/metric
go.opentelemetry.io/otel/metric/embedded go.opentelemetry.io/otel/metric/embedded
# go.opentelemetry.io/otel/sdk v1.19.0 # go.opentelemetry.io/otel/sdk v1.21.0
## explicit; go 1.20 ## explicit; go 1.20
go.opentelemetry.io/otel/sdk go.opentelemetry.io/otel/sdk
go.opentelemetry.io/otel/sdk/instrumentation go.opentelemetry.io/otel/sdk/instrumentation
@ -459,6 +459,7 @@ go.opentelemetry.io/otel/sdk/trace/tracetest
## explicit; go 1.20 ## explicit; go 1.20
go.opentelemetry.io/otel/trace go.opentelemetry.io/otel/trace
go.opentelemetry.io/otel/trace/embedded go.opentelemetry.io/otel/trace/embedded
go.opentelemetry.io/otel/trace/noop
# go.opentelemetry.io/proto/otlp v1.0.0 # go.opentelemetry.io/proto/otlp v1.0.0
## explicit; go 1.17 ## explicit; go 1.17
go.opentelemetry.io/proto/otlp/collector/trace/v1 go.opentelemetry.io/proto/otlp/collector/trace/v1