diff --git a/CHANGELOG.md b/CHANGELOG.md index 1b77504b94f..9c1f0f6042f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,15 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm ## [Unreleased] +### Changed + +- Move the `go.opentelemetry.io/otel/api/trace` package into `go.opentelemetry.io/otel` with the following changes. (#1229) + - `ID` has been renamed to `TraceID`. + - `IDFromHex` has been renamed to `TraceIDFromHex`. + - `ErrorOption` has been changed to an interface to conform with project design standards which included adding a `NewErrorConfig` function. + - `EmptySpanContext` is removed. +- Move the `go.opentelemetry.io/otel/api/trace/tracetest` package into `go.opentelemetry.io/otel/oteltest`. (#1229) + ## [0.13.0] - 2020-10-08 ### Added diff --git a/api/apitest/harness.go b/api/apitest/harness.go index 94641802e60..92c43702e02 100644 --- a/api/apitest/harness.go +++ b/api/apitest/harness.go @@ -20,7 +20,7 @@ import ( "testing" "time" - "go.opentelemetry.io/otel/api/trace" + "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/codes" "go.opentelemetry.io/otel/internal/matchers" "go.opentelemetry.io/otel/label" @@ -36,7 +36,7 @@ func NewHarness(t *testing.T) *Harness { } } -func (h *Harness) TestTracer(subjectFactory func() trace.Tracer) { +func (h *Harness) TestTracer(subjectFactory func() otel.Tracer) { h.t.Run("#Start", func(t *testing.T) { t.Run("propagates the original context", func(t *testing.T) { t.Parallel() @@ -76,8 +76,8 @@ func (h *Harness) TestTracer(subjectFactory func() trace.Tracer) { ctx, span := subject.Start(context.Background(), "test") e.Expect(span).NotToBeNil() - e.Expect(span.SpanContext()).NotToEqual(trace.EmptySpanContext()) - e.Expect(trace.SpanFromContext(ctx)).ToEqual(span) + e.Expect(span.SpanContext()).NotToEqual(otel.SpanContext{}) + e.Expect(otel.SpanFromContext(ctx)).ToEqual(span) }) t.Run("starts spans with unique trace and span IDs", func(t *testing.T) { @@ -102,7 +102,7 @@ func (h *Harness) TestTracer(subjectFactory func() trace.Tracer) { e := matchers.NewExpecter(t) subject := subjectFactory() - _, span := subject.Start(context.Background(), "span", trace.WithRecord()) + _, span := subject.Start(context.Background(), "span", otel.WithRecord()) e.Expect(span.IsRecording()).ToBeTrue() }) @@ -130,7 +130,7 @@ func (h *Harness) TestTracer(subjectFactory func() trace.Tracer) { subject := subjectFactory() ctx, parent := subject.Start(context.Background(), "parent") - _, child := subject.Start(ctx, "child", trace.WithNewRoot()) + _, child := subject.Start(ctx, "child", otel.WithNewRoot()) psc := parent.SpanContext() csc := child.SpanContext() @@ -146,7 +146,7 @@ func (h *Harness) TestTracer(subjectFactory func() trace.Tracer) { subject := subjectFactory() _, remoteParent := subject.Start(context.Background(), "remote parent") - parentCtx := trace.ContextWithRemoteSpanContext(context.Background(), remoteParent.SpanContext()) + parentCtx := otel.ContextWithRemoteSpanContext(context.Background(), remoteParent.SpanContext()) _, child := subject.Start(parentCtx, "child") psc := remoteParent.SpanContext() @@ -163,8 +163,8 @@ func (h *Harness) TestTracer(subjectFactory func() trace.Tracer) { subject := subjectFactory() _, remoteParent := subject.Start(context.Background(), "remote parent") - parentCtx := trace.ContextWithRemoteSpanContext(context.Background(), remoteParent.SpanContext()) - _, child := subject.Start(parentCtx, "child", trace.WithNewRoot()) + parentCtx := otel.ContextWithRemoteSpanContext(context.Background(), remoteParent.SpanContext()) + _, child := subject.Start(parentCtx, "child", otel.WithNewRoot()) psc := remoteParent.SpanContext() csc := child.SpanContext() @@ -177,29 +177,29 @@ func (h *Harness) TestTracer(subjectFactory func() trace.Tracer) { h.testSpan(subjectFactory) } -func (h *Harness) testSpan(tracerFactory func() trace.Tracer) { - var methods = map[string]func(span trace.Span){ - "#End": func(span trace.Span) { +func (h *Harness) testSpan(tracerFactory func() otel.Tracer) { + var methods = map[string]func(span otel.Span){ + "#End": func(span otel.Span) { span.End() }, - "#AddEvent": func(span trace.Span) { + "#AddEvent": func(span otel.Span) { span.AddEvent(context.Background(), "test event") }, - "#AddEventWithTimestamp": func(span trace.Span) { + "#AddEventWithTimestamp": func(span otel.Span) { span.AddEventWithTimestamp(context.Background(), time.Now(), "test event") }, - "#SetStatus": func(span trace.Span) { + "#SetStatus": func(span otel.Span) { span.SetStatus(codes.Error, "internal") }, - "#SetName": func(span trace.Span) { + "#SetName": func(span otel.Span) { span.SetName("new name") }, - "#SetAttributes": func(span trace.Span) { + "#SetAttributes": func(span otel.Span) { span.SetAttributes(label.String("key1", "value"), label.Int("key2", 123)) }, } - var mechanisms = map[string]func() trace.Span{ - "Span created via Tracer#Start": func() trace.Span { + var mechanisms = map[string]func() otel.Span{ + "Span created via Tracer#Start": func() otel.Span { tracer := tracerFactory() _, subject := tracer.Start(context.Background(), "test") diff --git a/api/global/internal/state.go b/api/global/internal/state.go index ecdfd75ab55..e2ded6eb181 100644 --- a/api/global/internal/state.go +++ b/api/global/internal/state.go @@ -20,12 +20,11 @@ import ( "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/api/metric" - "go.opentelemetry.io/otel/api/trace" ) type ( tracerProviderHolder struct { - tp trace.TracerProvider + tp otel.TracerProvider } meterProviderHolder struct { @@ -47,12 +46,12 @@ var ( ) // TracerProvider is the internal implementation for global.TracerProvider. -func TracerProvider() trace.TracerProvider { +func TracerProvider() otel.TracerProvider { return globalTracer.Load().(tracerProviderHolder).tp } // SetTracerProvider is the internal implementation for global.SetTracerProvider. -func SetTracerProvider(tp trace.TracerProvider) { +func SetTracerProvider(tp otel.TracerProvider) { delegateTraceOnce.Do(func() { current := TracerProvider() if current == tp { diff --git a/api/global/internal/trace.go b/api/global/internal/trace.go index bcd14613052..d74966c0465 100644 --- a/api/global/internal/trace.go +++ b/api/global/internal/trace.go @@ -35,7 +35,7 @@ import ( "context" "sync" - "go.opentelemetry.io/otel/api/trace" + "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/internal/trace/noop" ) @@ -47,12 +47,12 @@ type tracerProvider struct { mtx sync.Mutex tracers []*tracer - delegate trace.TracerProvider + delegate otel.TracerProvider } // Compile-time guarantee that tracerProvider implements the TracerProvider // interface. -var _ trace.TracerProvider = &tracerProvider{} +var _ otel.TracerProvider = &tracerProvider{} // setDelegate configures p to delegate all TracerProvider functionality to // provider. @@ -62,7 +62,7 @@ var _ trace.TracerProvider = &tracerProvider{} // // Delegation only happens on the first call to this method. All subsequent // calls result in no delegation changes. -func (p *tracerProvider) setDelegate(provider trace.TracerProvider) { +func (p *tracerProvider) setDelegate(provider otel.TracerProvider) { if p.delegate != nil { return } @@ -79,7 +79,7 @@ func (p *tracerProvider) setDelegate(provider trace.TracerProvider) { } // Tracer implements TracerProvider. -func (p *tracerProvider) Tracer(name string, opts ...trace.TracerOption) trace.Tracer { +func (p *tracerProvider) Tracer(name string, opts ...otel.TracerOption) otel.Tracer { p.mtx.Lock() defer p.mtx.Unlock() @@ -92,20 +92,20 @@ func (p *tracerProvider) Tracer(name string, opts ...trace.TracerOption) trace.T return t } -// tracer is a placeholder for a trace.Tracer. +// tracer is a placeholder for a otel.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 + opts []otel.TracerOption - delegate trace.Tracer + delegate otel.Tracer } -// Compile-time guarantee that tracer implements the trace.Tracer interface. -var _ trace.Tracer = &tracer{} +// Compile-time guarantee that tracer implements the otel.Tracer interface. +var _ otel.Tracer = &tracer{} // setDelegate configures t to delegate all Tracer functionality to Tracers // created by provider. @@ -114,13 +114,13 @@ var _ trace.Tracer = &tracer{} // // Delegation only happens on the first call to this method. All subsequent // calls result in no delegation changes. -func (t *tracer) setDelegate(provider trace.TracerProvider) { +func (t *tracer) setDelegate(provider otel.TracerProvider) { t.once.Do(func() { t.delegate = provider.Tracer(t.name, t.opts...) }) } -// Start implements trace.Tracer by forwarding the call to t.delegate if +// Start implements otel.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.SpanOption) (context.Context, trace.Span) { +func (t *tracer) Start(ctx context.Context, name string, opts ...otel.SpanOption) (context.Context, otel.Span) { if t.delegate != nil { return t.delegate.Start(ctx, name, opts...) } diff --git a/api/global/internal/trace_test.go b/api/global/internal/trace_test.go index 3a466612561..8cd26747f39 100644 --- a/api/global/internal/trace_test.go +++ b/api/global/internal/trace_test.go @@ -22,7 +22,7 @@ import ( "go.opentelemetry.io/otel/api/global" "go.opentelemetry.io/otel/api/global/internal" - "go.opentelemetry.io/otel/api/trace/tracetest" + "go.opentelemetry.io/otel/oteltest" ) func TestTraceWithSDK(t *testing.T) { @@ -34,8 +34,8 @@ func TestTraceWithSDK(t *testing.T) { // This is started before an SDK was registered and should be dropped. _, span1 := tracer1.Start(ctx, "span1") - sr := new(tracetest.StandardSpanRecorder) - tp := tracetest.NewTracerProvider(tracetest.WithSpanRecorder(sr)) + sr := new(oteltest.StandardSpanRecorder) + tp := oteltest.NewTracerProvider(oteltest.WithSpanRecorder(sr)) global.SetTracerProvider(tp) // This span was started before initialization, it is expected to be dropped. @@ -50,7 +50,7 @@ func TestTraceWithSDK(t *testing.T) { _, span3 := tracer2.Start(ctx, "span3") span3.End() - filterNames := func(spans []*tracetest.Span) []string { + filterNames := func(spans []*oteltest.Span) []string { names := make([]string, len(spans)) for i := range spans { names[i] = spans[i].Name() diff --git a/api/global/trace.go b/api/global/trace.go index 49a7543897d..5c5b6f63439 100644 --- a/api/global/trace.go +++ b/api/global/trace.go @@ -15,15 +15,15 @@ package global import ( + "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/api/global/internal" - "go.opentelemetry.io/otel/api/trace" ) // Tracer creates a named tracer that implements Tracer interface. // If the name is an empty string then provider uses default name. // // This is short for TracerProvider().Tracer(name) -func Tracer(name string) trace.Tracer { +func Tracer(name string) otel.Tracer { return TracerProvider().Tracer(name) } @@ -34,11 +34,11 @@ func Tracer(name string) trace.Tracer { // tracer := global.TracerProvider().Tracer("example.com/foo") // or // tracer := global.Tracer("example.com/foo") -func TracerProvider() trace.TracerProvider { +func TracerProvider() otel.TracerProvider { return internal.TracerProvider() } // SetTracerProvider registers `tp` as the global trace provider. -func SetTracerProvider(tp trace.TracerProvider) { +func SetTracerProvider(tp otel.TracerProvider) { internal.SetTracerProvider(tp) } diff --git a/api/global/trace_test.go b/api/global/trace_test.go index c93c6d8ca44..ea68405d8db 100644 --- a/api/global/trace_test.go +++ b/api/global/trace_test.go @@ -17,22 +17,22 @@ package global_test import ( "testing" + "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/api/global" - "go.opentelemetry.io/otel/api/trace" "go.opentelemetry.io/otel/internal/trace/noop" ) type testTracerProvider struct{} -var _ trace.TracerProvider = &testTracerProvider{} +var _ otel.TracerProvider = &testTracerProvider{} -func (*testTracerProvider) Tracer(_ string, _ ...trace.TracerOption) trace.Tracer { +func (*testTracerProvider) Tracer(_ string, _ ...otel.TracerOption) otel.Tracer { return noop.Tracer } func TestMultipleGlobalTracerProvider(t *testing.T) { p1 := testTracerProvider{} - p2 := trace.NoopTracerProvider() + p2 := otel.NewNoopTracerProvider() global.SetTracerProvider(&p1) global.SetTracerProvider(p2) diff --git a/api/trace/api.go b/api/trace/api.go deleted file mode 100644 index 3f15f48e29a..00000000000 --- a/api/trace/api.go +++ /dev/null @@ -1,314 +0,0 @@ -// 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 trace - -import ( - "context" - "time" - - "go.opentelemetry.io/otel/codes" - "go.opentelemetry.io/otel/label" -) - -// TracerProvider provides access to instrumentation Tracers. -type TracerProvider interface { - // Tracer creates an implementation of the Tracer interface. - // The instrumentationName must be the name of the library providing - // instrumentation. This name may be the same as the instrumented code - // only if that code provides built-in instrumentation. If the - // instrumentationName is empty, then a implementation defined default - // name will be used instead. - Tracer(instrumentationName string, opts ...TracerOption) Tracer -} - -// TracerConfig is a group of options for a Tracer. -// -// Most users will use the tracer options instead. -type TracerConfig struct { - // InstrumentationVersion is the version of the instrumentation library. - InstrumentationVersion string -} - -// NewTracerConfig applies all the options to a returned TracerConfig. -// The default value for all the fields of the returned TracerConfig are the -// default zero value of the type. Also, this does not perform any validation -// on the returned TracerConfig (e.g. no uniqueness checking or bounding of -// data), instead it is left to the implementations of the SDK to perform this -// action. -func NewTracerConfig(opts ...TracerOption) *TracerConfig { - config := new(TracerConfig) - for _, option := range opts { - option.Apply(config) - } - return config -} - -// TracerOption applies an options to a TracerConfig. -type TracerOption interface { - Apply(*TracerConfig) -} - -type instVersionTracerOption string - -func (o instVersionTracerOption) Apply(c *TracerConfig) { c.InstrumentationVersion = string(o) } - -// WithInstrumentationVersion sets the instrumentation version for a Tracer. -func WithInstrumentationVersion(version string) TracerOption { - return instVersionTracerOption(version) -} - -type Tracer interface { - // Start a span. - Start(ctx context.Context, spanName string, opts ...SpanOption) (context.Context, Span) -} - -// ErrorConfig provides options to set properties of an error -// event at the time it is recorded. -// -// Most users will use the error options instead. -type ErrorConfig struct { - Timestamp time.Time - StatusCode codes.Code -} - -// ErrorOption applies changes to ErrorConfig that sets options when an error event is recorded. -type ErrorOption func(*ErrorConfig) - -// WithErrorTime sets the time at which the error event should be recorded. -func WithErrorTime(t time.Time) ErrorOption { - return func(c *ErrorConfig) { - c.Timestamp = t - } -} - -// WithErrorStatus indicates the span status that should be set when recording an error event. -func WithErrorStatus(s codes.Code) ErrorOption { - return func(c *ErrorConfig) { - c.StatusCode = s - } -} - -type Span interface { - // Tracer returns tracer used to create this span. Tracer cannot be nil. - Tracer() Tracer - - // End completes the span. No updates are allowed to span after it - // ends. The only exception is setting status of the span. - End(options ...SpanOption) - - // AddEvent adds an event to the span. - AddEvent(ctx context.Context, name string, attrs ...label.KeyValue) - // AddEventWithTimestamp adds an event with a custom timestamp - // to the span. - AddEventWithTimestamp(ctx context.Context, timestamp time.Time, name string, attrs ...label.KeyValue) - - // IsRecording returns true if the span is active and recording events is enabled. - IsRecording() bool - - // RecordError records an error as a span event. - RecordError(ctx context.Context, err error, opts ...ErrorOption) - - // SpanContext returns span context of the span. Returned SpanContext is usable - // even after the span ends. - SpanContext() SpanContext - - // SetStatus sets the status of the span in the form of a code - // and a message. SetStatus overrides the value of previous - // calls to SetStatus on the Span. - // - // The default span status is OK, so it is not necessary to - // explicitly set an OK status on successful Spans unless it - // is to add an OK message or to override a previous status on the Span. - SetStatus(code codes.Code, msg string) - - // SetName sets the name of the span. - SetName(name string) - - // Set span attributes - SetAttributes(kv ...label.KeyValue) -} - -// SpanConfig is a group of options for a Span. -// -// Most users will use span options instead. -type SpanConfig struct { - // Attributes describe the associated qualities of a Span. - Attributes []label.KeyValue - // Timestamp is a time in a Span life-cycle. - Timestamp time.Time - // Links are the associations a Span has with other Spans. - Links []Link - // Record is the recording state of a Span. - Record bool - // NewRoot identifies a Span as the root Span for a new trace. This is - // commonly used when an existing trace crosses trust boundaries and the - // remote parent span context should be ignored for security. - NewRoot bool - // SpanKind is the role a Span has in a trace. - SpanKind SpanKind -} - -// NewSpanConfig applies all the options to a returned SpanConfig. -// The default value for all the fields of the returned SpanConfig are the -// default zero value of the type. Also, this does not perform any validation -// on the returned SpanConfig (e.g. no uniqueness checking or bounding of -// data). Instead, it is left to the implementations of the SDK to perform this -// action. -func NewSpanConfig(opts ...SpanOption) *SpanConfig { - c := new(SpanConfig) - for _, option := range opts { - option.Apply(c) - } - return c -} - -// SpanOption applies an option to a SpanConfig. -type SpanOption interface { - Apply(*SpanConfig) -} - -type attributeSpanOption []label.KeyValue - -func (o attributeSpanOption) Apply(c *SpanConfig) { - c.Attributes = append(c.Attributes, []label.KeyValue(o)...) -} - -// WithAttributes adds the attributes to a span. These attributes are meant to -// provide additional information about the work the Span represents. The -// attributes are added to the existing Span attributes, i.e. this does not -// overwrite. -func WithAttributes(attributes ...label.KeyValue) SpanOption { - return attributeSpanOption(attributes) -} - -type timestampSpanOption time.Time - -func (o timestampSpanOption) Apply(c *SpanConfig) { c.Timestamp = time.Time(o) } - -// WithTimestamp sets the time of a Span life-cycle moment (e.g. started or -// stopped). -func WithTimestamp(t time.Time) SpanOption { - return timestampSpanOption(t) -} - -type linksSpanOption []Link - -func (o linksSpanOption) Apply(c *SpanConfig) { c.Links = append(c.Links, []Link(o)...) } - -// WithLinks adds links to a Span. The links are added to the existing Span -// links, i.e. this does not overwrite. -func WithLinks(links ...Link) SpanOption { - return linksSpanOption(links) -} - -type recordSpanOption bool - -func (o recordSpanOption) Apply(c *SpanConfig) { c.Record = bool(o) } - -// WithRecord specifies that the span should be recorded. It is important to -// note that implementations may override this option, i.e. if the span is a -// child of an un-sampled trace. -func WithRecord() SpanOption { - return recordSpanOption(true) -} - -type newRootSpanOption bool - -func (o newRootSpanOption) Apply(c *SpanConfig) { c.NewRoot = bool(o) } - -// WithNewRoot specifies that the Span should be treated as a root Span. Any -// existing parent span context will be ignored when defining the Span's trace -// identifiers. -func WithNewRoot() SpanOption { - return newRootSpanOption(true) -} - -type spanKindSpanOption SpanKind - -func (o spanKindSpanOption) Apply(c *SpanConfig) { c.SpanKind = SpanKind(o) } - -// WithSpanKind sets the SpanKind of a Span. -func WithSpanKind(kind SpanKind) SpanOption { - return spanKindSpanOption(kind) -} - -// Link is used to establish relationship between two spans within the same Trace or -// across different Traces. Few examples of Link usage. -// 1. Batch Processing: A batch of elements may contain elements associated with one -// or more traces/spans. Since there can only be one parent SpanContext, Link is -// used to keep reference to SpanContext of all elements in the batch. -// 2. Public Endpoint: A SpanContext in incoming client request on a public endpoint -// is untrusted from service provider perspective. In such case it is advisable to -// start a new trace with appropriate sampling decision. -// However, it is desirable to associate incoming SpanContext to new trace initiated -// on service provider side so two traces (from Client and from Service Provider) can -// be correlated. -type Link struct { - SpanContext - Attributes []label.KeyValue -} - -// SpanKind represents the role of a Span inside a Trace. Often, this defines how a Span -// will be processed and visualized by various backends. -type SpanKind int - -const ( - // As a convenience, these match the proto definition, see - // opentelemetry/proto/trace/v1/trace.proto - // - // The unspecified value is not a valid `SpanKind`. Use - // `ValidateSpanKind()` to coerce a span kind to a valid - // value. - SpanKindUnspecified SpanKind = 0 - SpanKindInternal SpanKind = 1 - SpanKindServer SpanKind = 2 - SpanKindClient SpanKind = 3 - SpanKindProducer SpanKind = 4 - SpanKindConsumer SpanKind = 5 -) - -// ValidateSpanKind returns a valid span kind value. This will coerce -// invalid values into the default value, SpanKindInternal. -func ValidateSpanKind(spanKind SpanKind) SpanKind { - switch spanKind { - case SpanKindInternal, - SpanKindServer, - SpanKindClient, - SpanKindProducer, - SpanKindConsumer: - // valid - return spanKind - default: - return SpanKindInternal - } -} - -// String returns the specified name of the SpanKind in lower-case. -func (sk SpanKind) String() string { - switch sk { - case SpanKindInternal: - return "internal" - case SpanKindServer: - return "server" - case SpanKindClient: - return "client" - case SpanKindProducer: - return "producer" - case SpanKindConsumer: - return "consumer" - default: - return "unspecified" - } -} diff --git a/api/trace/context.go b/api/trace/context.go deleted file mode 100644 index 0f330e3a08a..00000000000 --- a/api/trace/context.go +++ /dev/null @@ -1,55 +0,0 @@ -// 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 trace - -import ( - "context" -) - -type traceContextKeyType int - -const ( - currentSpanKey traceContextKeyType = iota - remoteContextKey -) - -// ContextWithSpan creates a new context with a current span set to -// the passed span. -func ContextWithSpan(ctx context.Context, span Span) context.Context { - return context.WithValue(ctx, currentSpanKey, span) -} - -// SpanFromContext returns the current span stored in the context. -func SpanFromContext(ctx context.Context) Span { - if span, has := ctx.Value(currentSpanKey).(Span); has { - return span - } - return noopSpan{} -} - -// ContextWithRemoteSpanContext creates a new context with a remote -// span context set to the passed span context. -func ContextWithRemoteSpanContext(ctx context.Context, sc SpanContext) context.Context { - return context.WithValue(ctx, remoteContextKey, sc) -} - -// RemoteSpanContextFromContext returns the remote span context stored -// in the context. -func RemoteSpanContextFromContext(ctx context.Context) SpanContext { - if sc, ok := ctx.Value(remoteContextKey).(SpanContext); ok { - return sc - } - return EmptySpanContext() -} diff --git a/api/trace/context_test.go b/api/trace/context_test.go deleted file mode 100644 index fd106d9d5f1..00000000000 --- a/api/trace/context_test.go +++ /dev/null @@ -1,118 +0,0 @@ -// 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 trace_test - -import ( - "context" - "testing" - "time" - - "go.opentelemetry.io/otel/api/trace" - "go.opentelemetry.io/otel/codes" - "go.opentelemetry.io/otel/internal/trace/noop" - "go.opentelemetry.io/otel/label" -) - -func TestSetCurrentSpanOverridesPreviouslySetSpan(t *testing.T) { - ctx := context.Background() - originalSpan := noop.Span - expectedSpan := mockSpan{} - - ctx = trace.ContextWithSpan(ctx, originalSpan) - ctx = trace.ContextWithSpan(ctx, expectedSpan) - - if span := trace.SpanFromContext(ctx); span != expectedSpan { - t.Errorf("Want: %v, but have: %v", expectedSpan, span) - } -} - -func TestCurrentSpan(t *testing.T) { - for _, testcase := range []struct { - name string - ctx context.Context - want trace.Span - }{ - { - name: "CurrentSpan() returns a NoopSpan{} from an empty context", - ctx: context.Background(), - want: noop.Span, - }, - { - name: "CurrentSpan() returns current span if set", - ctx: trace.ContextWithSpan(context.Background(), mockSpan{}), - want: mockSpan{}, - }, - } { - t.Run(testcase.name, func(t *testing.T) { - // proto: CurrentSpan(ctx context.Context) trace.Span - have := trace.SpanFromContext(testcase.ctx) - if have != testcase.want { - t.Errorf("Want: %v, but have: %v", testcase.want, have) - } - }) - } -} - -// a duplicate of trace.NoopSpan for testing -type mockSpan struct{} - -var _ trace.Span = mockSpan{} - -// SpanContext returns an invalid span context. -func (mockSpan) SpanContext() trace.SpanContext { - return trace.EmptySpanContext() -} - -// IsRecording always returns false for mockSpan. -func (mockSpan) IsRecording() bool { - return false -} - -// SetStatus does nothing. -func (mockSpan) SetStatus(status codes.Code, msg string) { -} - -// SetName does nothing. -func (mockSpan) SetName(name string) { -} - -// SetError does nothing. -func (mockSpan) SetError(v bool) { -} - -// SetAttributes does nothing. -func (mockSpan) SetAttributes(attributes ...label.KeyValue) { -} - -// End does nothing. -func (mockSpan) End(options ...trace.SpanOption) { -} - -// RecordError does nothing. -func (mockSpan) RecordError(ctx context.Context, err error, opts ...trace.ErrorOption) { -} - -// Tracer returns noop implementation of Tracer. -func (mockSpan) Tracer() trace.Tracer { - return noop.Tracer -} - -// Event does nothing. -func (mockSpan) AddEvent(ctx context.Context, name string, attrs ...label.KeyValue) { -} - -// AddEventWithTimestamp does nothing. -func (mockSpan) AddEventWithTimestamp(ctx context.Context, timestamp time.Time, name string, attrs ...label.KeyValue) { -} diff --git a/api/trace/doc.go b/api/trace/doc.go deleted file mode 100644 index 24f2dfb47e1..00000000000 --- a/api/trace/doc.go +++ /dev/null @@ -1,16 +0,0 @@ -// 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 trace provides tracing support. -package trace // import "go.opentelemetry.io/otel/api/trace" diff --git a/api/trace/noop_span.go b/api/trace/noop_span.go deleted file mode 100644 index f014f210697..00000000000 --- a/api/trace/noop_span.go +++ /dev/null @@ -1,75 +0,0 @@ -// 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 trace - -import ( - "context" - "time" - - "go.opentelemetry.io/otel/codes" - "go.opentelemetry.io/otel/label" -) - -type noopSpan struct { -} - -var _ Span = noopSpan{} - -// SpanContext returns an invalid span context. -func (noopSpan) SpanContext() SpanContext { - return EmptySpanContext() -} - -// IsRecording always returns false for NoopSpan. -func (noopSpan) IsRecording() bool { - return false -} - -// SetStatus does nothing. -func (noopSpan) SetStatus(status codes.Code, msg string) { -} - -// SetError does nothing. -func (noopSpan) SetError(v bool) { -} - -// SetAttributes does nothing. -func (noopSpan) SetAttributes(attributes ...label.KeyValue) { -} - -// End does nothing. -func (noopSpan) End(options ...SpanOption) { -} - -// RecordError does nothing. -func (noopSpan) RecordError(ctx context.Context, err error, opts ...ErrorOption) { -} - -// Tracer returns noop implementation of Tracer. -func (noopSpan) Tracer() Tracer { - return noopTracer{} -} - -// AddEvent does nothing. -func (noopSpan) AddEvent(ctx context.Context, name string, attrs ...label.KeyValue) { -} - -// AddEventWithTimestamp does nothing. -func (noopSpan) AddEventWithTimestamp(ctx context.Context, timestamp time.Time, name string, attrs ...label.KeyValue) { -} - -// SetName does nothing. -func (noopSpan) SetName(name string) { -} diff --git a/api/trace/noop_trace.go b/api/trace/noop_trace.go deleted file mode 100644 index 954f9e81362..00000000000 --- a/api/trace/noop_trace.go +++ /dev/null @@ -1,29 +0,0 @@ -// 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 trace - -import ( - "context" -) - -type noopTracer struct{} - -var _ Tracer = noopTracer{} - -// Start starts a noop span. -func (noopTracer) Start(ctx context.Context, name string, opts ...SpanOption) (context.Context, Span) { - span := noopSpan{} - return ContextWithSpan(ctx, span), span -} diff --git a/api/trace/noop_trace_provider.go b/api/trace/noop_trace_provider.go deleted file mode 100644 index 414c8e3ab74..00000000000 --- a/api/trace/noop_trace_provider.go +++ /dev/null @@ -1,30 +0,0 @@ -// 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 trace - -type noopTracerProvider struct{} - -var _ TracerProvider = noopTracerProvider{} - -// Tracer returns noop implementation of Tracer. -func (p noopTracerProvider) Tracer(_ string, _ ...TracerOption) Tracer { - return noopTracer{} -} - -// NoopTracerProvider returns a noop implementation of TracerProvider. The -// Tracer and Spans created from the noop provider will also be noop. -func NoopTracerProvider() TracerProvider { - return noopTracerProvider{} -} diff --git a/api/trace/span_context.go b/api/trace/span_context.go deleted file mode 100644 index 914ce5f5ac3..00000000000 --- a/api/trace/span_context.go +++ /dev/null @@ -1,197 +0,0 @@ -// 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 trace - -import ( - "bytes" - "encoding/hex" - "encoding/json" -) - -const ( - // FlagsSampled is a bitmask with the sampled bit set. A SpanContext - // with the sampling bit set means the span is sampled. - FlagsSampled = byte(0x01) - // FlagsDeferred is a bitmask with the deferred bit set. A SpanContext - // with the deferred bit set means the sampling decision has been - // defered to the receiver. - FlagsDeferred = byte(0x02) - // FlagsDebug is a bitmask with the debug bit set. - FlagsDebug = byte(0x04) - - ErrInvalidHexID errorConst = "trace-id and span-id can only contain [0-9a-f] characters, all lowercase" - - ErrInvalidTraceIDLength errorConst = "hex encoded trace-id must have length equals to 32" - ErrNilTraceID errorConst = "trace-id can't be all zero" - - ErrInvalidSpanIDLength errorConst = "hex encoded span-id must have length equals to 16" - ErrNilSpanID errorConst = "span-id can't be all zero" -) - -type errorConst string - -func (e errorConst) Error() string { - return string(e) -} - -// ID is a unique identity of a trace. -type ID [16]byte - -var nilTraceID ID -var _ json.Marshaler = nilTraceID - -// IsValid checks whether the trace ID is valid. A valid trace ID does -// not consist of zeros only. -func (t ID) IsValid() bool { - return !bytes.Equal(t[:], nilTraceID[:]) -} - -// MarshalJSON implements a custom marshal function to encode TraceID -// as a hex string. -func (t ID) MarshalJSON() ([]byte, error) { - return json.Marshal(t.String()) -} - -// String returns the hex string representation form of a TraceID -func (t ID) String() string { - return hex.EncodeToString(t[:]) -} - -// SpanID is a unique identify of a span in a trace. -type SpanID [8]byte - -var nilSpanID SpanID -var _ json.Marshaler = nilSpanID - -// IsValid checks whether the span ID is valid. A valid span ID does -// not consist of zeros only. -func (s SpanID) IsValid() bool { - return !bytes.Equal(s[:], nilSpanID[:]) -} - -// MarshalJSON implements a custom marshal function to encode SpanID -// as a hex string. -func (s SpanID) MarshalJSON() ([]byte, error) { - return json.Marshal(s.String()) -} - -// String returns the hex string representation form of a SpanID -func (s SpanID) String() string { - return hex.EncodeToString(s[:]) -} - -// IDFromHex returns a TraceID from a hex string if it is compliant -// with the w3c trace-context specification. -// See more at https://www.w3.org/TR/trace-context/#trace-id -func IDFromHex(h string) (ID, error) { - t := ID{} - if len(h) != 32 { - return t, ErrInvalidTraceIDLength - } - - if err := decodeHex(h, t[:]); err != nil { - return t, err - } - - if !t.IsValid() { - return t, ErrNilTraceID - } - return t, nil -} - -// SpanIDFromHex returns a SpanID from a hex string if it is compliant -// with the w3c trace-context specification. -// See more at https://www.w3.org/TR/trace-context/#parent-id -func SpanIDFromHex(h string) (SpanID, error) { - s := SpanID{} - if len(h) != 16 { - return s, ErrInvalidSpanIDLength - } - - if err := decodeHex(h, s[:]); err != nil { - return s, err - } - - if !s.IsValid() { - return s, ErrNilSpanID - } - return s, nil -} - -func decodeHex(h string, b []byte) error { - for _, r := range h { - switch { - case 'a' <= r && r <= 'f': - continue - case '0' <= r && r <= '9': - continue - default: - return ErrInvalidHexID - } - } - - decoded, err := hex.DecodeString(h) - if err != nil { - return err - } - - copy(b, decoded) - return nil -} - -// SpanContext contains basic information about the span - its trace -// ID, span ID and trace flags. -type SpanContext struct { - TraceID ID - SpanID SpanID - TraceFlags byte -} - -// EmptySpanContext is meant for internal use to return invalid span -// context during error conditions. -func EmptySpanContext() SpanContext { - return SpanContext{} -} - -// IsValid checks if the span context is valid. A valid span context -// has a valid trace ID and a valid span ID. -func (sc SpanContext) IsValid() bool { - return sc.HasTraceID() && sc.HasSpanID() -} - -// HasTraceID checks if the span context has a valid trace ID. -func (sc SpanContext) HasTraceID() bool { - return sc.TraceID.IsValid() -} - -// HasSpanID checks if the span context has a valid span ID. -func (sc SpanContext) HasSpanID() bool { - return sc.SpanID.IsValid() -} - -// IsDeferred returns if the deferred bit is set in the trace flags. -func (sc SpanContext) IsDeferred() bool { - return sc.TraceFlags&FlagsDeferred == FlagsDeferred -} - -// IsDebug returns if the debug bit is set in the trace flags. -func (sc SpanContext) IsDebug() bool { - return sc.TraceFlags&FlagsDebug == FlagsDebug -} - -// IsSampled returns if the sampling bit is set in the trace flags. -func (sc SpanContext) IsSampled() bool { - return sc.TraceFlags&FlagsSampled == FlagsSampled -} diff --git a/api/trace/traceprovider_test.go b/api/trace/traceprovider_test.go deleted file mode 100644 index 15572f5ed47..00000000000 --- a/api/trace/traceprovider_test.go +++ /dev/null @@ -1,58 +0,0 @@ -// 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 trace - -import ( - "testing" - - "github.com/stretchr/testify/assert" -) - -func TestTracerConfig(t *testing.T) { - v1 := "semver:0.0.1" - v2 := "semver:1.0.0" - tests := []struct { - options []TracerOption - expected *TracerConfig - }{ - { - // No non-zero-values should be set. - []TracerOption{}, - new(TracerConfig), - }, - { - []TracerOption{ - WithInstrumentationVersion(v1), - }, - &TracerConfig{ - InstrumentationVersion: v1, - }, - }, - { - []TracerOption{ - // Multiple calls should overwrite. - WithInstrumentationVersion(v1), - WithInstrumentationVersion(v2), - }, - &TracerConfig{ - InstrumentationVersion: v2, - }, - }, - } - for _, test := range tests { - config := NewTracerConfig(test.options...) - assert.Equal(t, test.expected, config) - } -} diff --git a/bridge/opentracing/bridge.go b/bridge/opentracing/bridge.go index 7edb7c2076f..d11826d95e2 100644 --- a/bridge/opentracing/bridge.go +++ b/bridge/opentracing/bridge.go @@ -27,7 +27,6 @@ import ( "go.opentelemetry.io/otel" otelglobal "go.opentelemetry.io/otel/api/global" - oteltrace "go.opentelemetry.io/otel/api/trace" "go.opentelemetry.io/otel/codes" "go.opentelemetry.io/otel/internal/baggage" "go.opentelemetry.io/otel/internal/trace/noop" @@ -39,12 +38,12 @@ import ( type bridgeSpanContext struct { baggageItems baggage.Map - otelSpanContext oteltrace.SpanContext + otelSpanContext otel.SpanContext } var _ ot.SpanContext = &bridgeSpanContext{} -func newBridgeSpanContext(otelSpanContext oteltrace.SpanContext, parentOtSpanContext ot.SpanContext) *bridgeSpanContext { +func newBridgeSpanContext(otelSpanContext otel.SpanContext, parentOtSpanContext ot.SpanContext) *bridgeSpanContext { bCtx := &bridgeSpanContext{ baggageItems: baggage.NewEmptyMap(), otelSpanContext: otelSpanContext, @@ -76,7 +75,7 @@ func (c *bridgeSpanContext) baggageItem(restrictedKey string) string { } type bridgeSpan struct { - otelSpan oteltrace.Span + otelSpan otel.Span ctx *bridgeSpanContext tracer *BridgeTracer skipDeferHook bool @@ -85,7 +84,7 @@ type bridgeSpan struct { var _ ot.Span = &bridgeSpan{} -func newBridgeSpan(otelSpan oteltrace.Span, bridgeSC *bridgeSpanContext, tracer *BridgeTracer) *bridgeSpan { +func newBridgeSpan(otelSpan otel.Span, bridgeSC *bridgeSpanContext, tracer *BridgeTracer) *bridgeSpan { return &bridgeSpan{ otelSpan: otelSpan, ctx: bridgeSC, @@ -100,10 +99,10 @@ func (s *bridgeSpan) Finish() { } func (s *bridgeSpan) FinishWithOptions(opts ot.FinishOptions) { - var otelOpts []oteltrace.SpanOption + var otelOpts []otel.SpanOption if !opts.FinishTime.IsZero() { - otelOpts = append(otelOpts, oteltrace.WithTimestamp(opts.FinishTime)) + otelOpts = append(otelOpts, otel.WithTimestamp(opts.FinishTime)) } for _, record := range opts.LogRecords { s.logRecord(record) @@ -259,13 +258,13 @@ func (s *bridgeSpan) Log(data ot.LogData) { type bridgeSetTracer struct { isSet bool - otelTracer oteltrace.Tracer + otelTracer otel.Tracer warningHandler BridgeWarningHandler warnOnce sync.Once } -func (s *bridgeSetTracer) tracer() oteltrace.Tracer { +func (s *bridgeSetTracer) tracer() otel.Tracer { if !s.isSet { s.warnOnce.Do(func() { s.warningHandler("The OpenTelemetry tracer is not set, default no-op tracer is used! Call SetOpenTelemetryTracer to set it up.\n") @@ -317,7 +316,7 @@ func (t *BridgeTracer) SetWarningHandler(handler BridgeWarningHandler) { // SetWarningHandler overrides the underlying OpenTelemetry // tracer. The passed tracer should know how to operate in the // environment that uses OpenTracing API. -func (t *BridgeTracer) SetOpenTelemetryTracer(tracer oteltrace.Tracer) { +func (t *BridgeTracer) SetOpenTelemetryTracer(tracer otel.Tracer) { t.setTracer.otelTracer = tracer t.setTracer.isSet = true } @@ -388,16 +387,16 @@ func (t *BridgeTracer) StartSpan(operationName string, opts ...ot.StartSpanOptio attributes, kind, hadTrueErrorTag := otTagsToOTelAttributesKindAndError(sso.Tags) checkCtx := migration.WithDeferredSetup(context.Background()) if parentBridgeSC != nil { - checkCtx = oteltrace.ContextWithRemoteSpanContext(checkCtx, parentBridgeSC.otelSpanContext) + checkCtx = otel.ContextWithRemoteSpanContext(checkCtx, parentBridgeSC.otelSpanContext) } checkCtx2, otelSpan := t.setTracer.tracer().Start( checkCtx, operationName, - oteltrace.WithAttributes(attributes...), - oteltrace.WithTimestamp(sso.StartTime), - oteltrace.WithLinks(links...), - oteltrace.WithRecord(), - oteltrace.WithSpanKind(kind), + otel.WithAttributes(attributes...), + otel.WithTimestamp(sso.StartTime), + otel.WithLinks(links...), + otel.WithRecord(), + otel.WithSpanKind(kind), ) if checkCtx != checkCtx2 { t.warnOnce.Do(func() { @@ -429,7 +428,7 @@ func (t *BridgeTracer) StartSpan(operationName string, opts ...ot.StartSpanOptio // This function should be used by the OpenTelemetry tracers that want // to be aware how to operate in the environment using OpenTracing // API. -func (t *BridgeTracer) ContextWithBridgeSpan(ctx context.Context, span oteltrace.Span) context.Context { +func (t *BridgeTracer) ContextWithBridgeSpan(ctx context.Context, span otel.Span) context.Context { var otSpanContext ot.SpanContext if parentSpan := ot.SpanFromContext(ctx); parentSpan != nil { otSpanContext = parentSpan.Context() @@ -459,8 +458,8 @@ func (t *BridgeTracer) ContextWithSpanHook(ctx context.Context, span ot.Span) co return ctx } -func otTagsToOTelAttributesKindAndError(tags map[string]interface{}) ([]label.KeyValue, oteltrace.SpanKind, bool) { - kind := oteltrace.SpanKindInternal +func otTagsToOTelAttributesKindAndError(tags map[string]interface{}) ([]label.KeyValue, otel.SpanKind, bool) { + kind := otel.SpanKindInternal err := false var pairs []label.KeyValue for k, v := range tags { @@ -469,13 +468,13 @@ func otTagsToOTelAttributesKindAndError(tags map[string]interface{}) ([]label.Ke if s, ok := v.(string); ok { switch strings.ToLower(s) { case "client": - kind = oteltrace.SpanKindClient + kind = otel.SpanKindClient case "server": - kind = oteltrace.SpanKindServer + kind = otel.SpanKindServer case "producer": - kind = oteltrace.SpanKindProducer + kind = otel.SpanKindProducer case "consumer": - kind = oteltrace.SpanKindConsumer + kind = otel.SpanKindConsumer } } case string(otext.Error): @@ -521,10 +520,10 @@ func otTagToOTelLabelKey(k string) label.Key { return label.Key(k) } -func otSpanReferencesToParentAndLinks(references []ot.SpanReference) (*bridgeSpanContext, []oteltrace.Link) { +func otSpanReferencesToParentAndLinks(references []ot.SpanReference) (*bridgeSpanContext, []otel.Link) { var ( parent *bridgeSpanContext - links []oteltrace.Link + links []otel.Link ) for _, reference := range references { bridgeSC, ok := reference.ReferencedContext.(*bridgeSpanContext) @@ -550,8 +549,8 @@ func otSpanReferencesToParentAndLinks(references []ot.SpanReference) (*bridgeSpa return parent, links } -func otSpanReferenceToOTelLink(bridgeSC *bridgeSpanContext, refType ot.SpanReferenceType) oteltrace.Link { - return oteltrace.Link{ +func otSpanReferenceToOTelLink(bridgeSC *bridgeSpanContext, refType ot.SpanReferenceType) otel.Link { + return otel.Link{ SpanContext: bridgeSC.otelSpanContext, Attributes: otSpanReferenceTypeToOTelLinkAttributes(refType), } @@ -580,11 +579,11 @@ func otSpanReferenceTypeToString(refType ot.SpanReferenceType) string { // fakeSpan is just a holder of span context, nothing more. It's for // propagators, so they can get the span context from Go context. type fakeSpan struct { - oteltrace.Span - sc oteltrace.SpanContext + otel.Span + sc otel.SpanContext } -func (s fakeSpan) SpanContext() oteltrace.SpanContext { +func (s fakeSpan) SpanContext() otel.SpanContext { return s.sc } @@ -612,7 +611,7 @@ func (t *BridgeTracer) Inject(sm ot.SpanContext, format interface{}, carrier int Span: noop.Span, sc: bridgeSC.otelSpanContext, } - ctx := oteltrace.ContextWithSpan(context.Background(), fs) + ctx := otel.ContextWithSpan(context.Background(), fs) ctx = baggage.ContextWithMap(ctx, bridgeSC.baggageItems) t.getPropagator().Inject(ctx, header) return nil diff --git a/bridge/opentracing/internal/mock.go b/bridge/opentracing/internal/mock.go index 265c02d8350..d7fb6ea2150 100644 --- a/bridge/opentracing/internal/mock.go +++ b/bridge/opentracing/internal/mock.go @@ -21,7 +21,7 @@ import ( "sync" "time" - oteltrace "go.opentelemetry.io/otel/api/trace" + "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/codes" "go.opentelemetry.io/otel/internal/baggage" otelparent "go.opentelemetry.io/otel/internal/trace/parent" @@ -47,15 +47,15 @@ type MockContextKeyValue struct { type MockTracer struct { Resources baggage.Map FinishedSpans []*MockSpan - SpareTraceIDs []oteltrace.ID - SpareSpanIDs []oteltrace.SpanID + SpareTraceIDs []otel.TraceID + SpareSpanIDs []otel.SpanID SpareContextKeyValues []MockContextKeyValue randLock sync.Mutex rand *rand.Rand } -var _ oteltrace.Tracer = &MockTracer{} +var _ otel.Tracer = &MockTracer{} var _ migration.DeferredContextSetupTracerExtension = &MockTracer{} func NewMockTracer() *MockTracer { @@ -70,13 +70,13 @@ func NewMockTracer() *MockTracer { } } -func (t *MockTracer) Start(ctx context.Context, name string, opts ...oteltrace.SpanOption) (context.Context, oteltrace.Span) { - config := oteltrace.NewSpanConfig(opts...) +func (t *MockTracer) Start(ctx context.Context, name string, opts ...otel.SpanOption) (context.Context, otel.Span) { + config := otel.NewSpanConfig(opts...) startTime := config.Timestamp if startTime.IsZero() { startTime = time.Now() } - spanContext := oteltrace.SpanContext{ + spanContext := otel.SpanContext{ TraceID: t.getTraceID(ctx, config), SpanID: t.getSpanID(), TraceFlags: 0, @@ -93,10 +93,10 @@ func (t *MockTracer) Start(ctx context.Context, name string, opts ...oteltrace.S EndTime: time.Time{}, ParentSpanID: t.getParentSpanID(ctx, config), Events: nil, - SpanKind: oteltrace.ValidateSpanKind(config.SpanKind), + SpanKind: otel.ValidateSpanKind(config.SpanKind), } if !migration.SkipContextSetup(ctx) { - ctx = oteltrace.ContextWithSpan(ctx, span) + ctx = otel.ContextWithSpan(ctx, span) ctx = t.addSpareContextValue(ctx) } return ctx, span @@ -115,7 +115,7 @@ func (t *MockTracer) addSpareContextValue(ctx context.Context) context.Context { return ctx } -func (t *MockTracer) getTraceID(ctx context.Context, config *oteltrace.SpanConfig) oteltrace.ID { +func (t *MockTracer) getTraceID(ctx context.Context, config *otel.SpanConfig) otel.TraceID { if parent := t.getParentSpanContext(ctx, config); parent.IsValid() { return parent.TraceID } @@ -130,19 +130,19 @@ func (t *MockTracer) getTraceID(ctx context.Context, config *oteltrace.SpanConfi return t.getRandTraceID() } -func (t *MockTracer) getParentSpanID(ctx context.Context, config *oteltrace.SpanConfig) oteltrace.SpanID { +func (t *MockTracer) getParentSpanID(ctx context.Context, config *otel.SpanConfig) otel.SpanID { if parent := t.getParentSpanContext(ctx, config); parent.IsValid() { return parent.SpanID } - return oteltrace.SpanID{} + return otel.SpanID{} } -func (t *MockTracer) getParentSpanContext(ctx context.Context, config *oteltrace.SpanConfig) oteltrace.SpanContext { +func (t *MockTracer) getParentSpanContext(ctx context.Context, config *otel.SpanConfig) otel.SpanContext { spanCtx, _, _ := otelparent.GetSpanContextAndLinks(ctx, config.NewRoot) return spanCtx } -func (t *MockTracer) getSpanID() oteltrace.SpanID { +func (t *MockTracer) getSpanID() otel.SpanID { if len(t.SpareSpanIDs) > 0 { spanID := t.SpareSpanIDs[0] t.SpareSpanIDs = t.SpareSpanIDs[1:] @@ -154,27 +154,27 @@ func (t *MockTracer) getSpanID() oteltrace.SpanID { return t.getRandSpanID() } -func (t *MockTracer) getRandSpanID() oteltrace.SpanID { +func (t *MockTracer) getRandSpanID() otel.SpanID { t.randLock.Lock() defer t.randLock.Unlock() - sid := oteltrace.SpanID{} + sid := otel.SpanID{} t.rand.Read(sid[:]) return sid } -func (t *MockTracer) getRandTraceID() oteltrace.ID { +func (t *MockTracer) getRandTraceID() otel.TraceID { t.randLock.Lock() defer t.randLock.Unlock() - tid := oteltrace.ID{} + tid := otel.TraceID{} t.rand.Read(tid[:]) return tid } -func (t *MockTracer) DeferredContextSetupHook(ctx context.Context, span oteltrace.Span) context.Context { +func (t *MockTracer) DeferredContextSetupHook(ctx context.Context, span otel.Span) context.Context { return t.addSpareContextValue(ctx) } @@ -187,22 +187,22 @@ type MockEvent struct { type MockSpan struct { mockTracer *MockTracer - officialTracer oteltrace.Tracer - spanContext oteltrace.SpanContext - SpanKind oteltrace.SpanKind + officialTracer otel.Tracer + spanContext otel.SpanContext + SpanKind otel.SpanKind recording bool Attributes baggage.Map StartTime time.Time EndTime time.Time - ParentSpanID oteltrace.SpanID + ParentSpanID otel.SpanID Events []MockEvent } -var _ oteltrace.Span = &MockSpan{} +var _ otel.Span = &MockSpan{} var _ migration.OverrideTracerSpanExtension = &MockSpan{} -func (s *MockSpan) SpanContext() oteltrace.SpanContext { +func (s *MockSpan) SpanContext() otel.SpanContext { return s.spanContext } @@ -232,11 +232,11 @@ func (s *MockSpan) applyUpdate(update baggage.MapUpdate) { s.Attributes = s.Attributes.Apply(update) } -func (s *MockSpan) End(options ...oteltrace.SpanOption) { +func (s *MockSpan) End(options ...otel.SpanOption) { if !s.EndTime.IsZero() { return // already finished } - config := oteltrace.NewSpanConfig(options...) + config := otel.NewSpanConfig(options...) endTime := config.Timestamp if endTime.IsZero() { endTime = time.Now() @@ -245,7 +245,7 @@ func (s *MockSpan) End(options ...oteltrace.SpanOption) { s.mockTracer.FinishedSpans = append(s.mockTracer.FinishedSpans, s) } -func (s *MockSpan) RecordError(ctx context.Context, err error, opts ...oteltrace.ErrorOption) { +func (s *MockSpan) RecordError(ctx context.Context, err error, opts ...otel.ErrorOption) { if err == nil { return // no-op on nil error } @@ -254,10 +254,7 @@ func (s *MockSpan) RecordError(ctx context.Context, err error, opts ...oteltrace return // already finished } - cfg := oteltrace.ErrorConfig{} - for _, o := range opts { - o(&cfg) - } + cfg := otel.NewErrorConfig(opts...) if cfg.Timestamp.IsZero() { cfg.Timestamp = time.Now() @@ -273,7 +270,7 @@ func (s *MockSpan) RecordError(ctx context.Context, err error, opts ...oteltrace ) } -func (s *MockSpan) Tracer() oteltrace.Tracer { +func (s *MockSpan) Tracer() otel.Tracer { return s.officialTracer } @@ -292,6 +289,6 @@ func (s *MockSpan) AddEventWithTimestamp(ctx context.Context, timestamp time.Tim }) } -func (s *MockSpan) OverrideTracer(tracer oteltrace.Tracer) { +func (s *MockSpan) OverrideTracer(tracer otel.Tracer) { s.officialTracer = tracer } diff --git a/bridge/opentracing/migration/api.go b/bridge/opentracing/migration/api.go index 3b866b210b2..ea6d3afaa9a 100644 --- a/bridge/opentracing/migration/api.go +++ b/bridge/opentracing/migration/api.go @@ -20,7 +20,7 @@ package migration // import "go.opentelemetry.io/otel/bridge/opentracing/migrati import ( "context" - oteltrace "go.opentelemetry.io/otel/api/trace" + "go.opentelemetry.io/otel" ) // DeferredContextSetupTracerExtension is an interface an @@ -41,7 +41,7 @@ type DeferredContextSetupTracerExtension interface { // opentracing.ContextWithSpan happens. When bridge // OpenTracing tracer calls OpenTelemetry tracer's Start() // function, it passes a context that shouldn't be modified. - DeferredContextSetupHook(ctx context.Context, span oteltrace.Span) context.Context + DeferredContextSetupHook(ctx context.Context, span otel.Span) context.Context } // OverrideTracerSpanExtension is an interface an OpenTelemetry span @@ -56,7 +56,7 @@ type DeferredContextSetupTracerExtension interface { // OpenTelemetry Span object and have WrapperTracer to alter the // current OpenTelemetry span in the context so it points to the // wrapped object, so the code in the tracer like -// `trace.SpanFromContent().(*realSpan)` would still work. Another +// `otel.SpanFromContent().(*realSpan)` would still work. Another // argument for getting rid of this interface is that is only called // by the WrapperTracer - WrapperTracer likely shouldn't require any // changes in the underlying OpenTelemetry tracer to have things @@ -72,5 +72,5 @@ type OverrideTracerSpanExtension interface { // API calls. In such case, there is no need to use the // WrapperTracer and thus no need to override the result of // the Tracer() function. - OverrideTracer(tracer oteltrace.Tracer) + OverrideTracer(tracer otel.Tracer) } diff --git a/bridge/opentracing/mix_test.go b/bridge/opentracing/mix_test.go index 9d3eacdb284..fc12819f25f 100644 --- a/bridge/opentracing/mix_test.go +++ b/bridge/opentracing/mix_test.go @@ -21,8 +21,8 @@ import ( ot "github.com/opentracing/opentracing-go" + "go.opentelemetry.io/otel" otelglobal "go.opentelemetry.io/otel/api/global" - oteltrace "go.opentelemetry.io/otel/api/trace" otelbaggage "go.opentelemetry.io/otel/internal/baggage" "go.opentelemetry.io/otel/label" @@ -142,8 +142,8 @@ func TestMixedAPIs(t *testing.T) { // simple test type simpleTest struct { - traceID oteltrace.ID - spanIDs []oteltrace.SpanID + traceID otel.TraceID + spanIDs []otel.SpanID } func newSimpleTest() *simpleTest { @@ -177,11 +177,11 @@ func (st *simpleTest) noop(t *testing.T, ctx context.Context) context.Context { // current/active span test type currentActiveSpanTest struct { - traceID oteltrace.ID - spanIDs []oteltrace.SpanID + traceID otel.TraceID + spanIDs []otel.SpanID - recordedCurrentOtelSpanIDs []oteltrace.SpanID - recordedActiveOTSpanIDs []oteltrace.SpanID + recordedCurrentOtelSpanIDs []otel.SpanID + recordedActiveOTSpanIDs []otel.SpanID } func newCurrentActiveSpanTest() *currentActiveSpanTest { @@ -229,10 +229,10 @@ func (cast *currentActiveSpanTest) runOTOtelOT(t *testing.T, ctx context.Context } func (cast *currentActiveSpanTest) recordSpans(t *testing.T, ctx context.Context) context.Context { - spanID := oteltrace.SpanFromContext(ctx).SpanContext().SpanID + spanID := otel.SpanFromContext(ctx).SpanContext().SpanID cast.recordedCurrentOtelSpanIDs = append(cast.recordedCurrentOtelSpanIDs, spanID) - spanID = oteltrace.SpanID{} + spanID = otel.SpanID{} if bridgeSpan, ok := ot.SpanFromContext(ctx).(*bridgeSpan); ok { spanID = bridgeSpan.otelSpan.SpanContext().SpanID } @@ -423,7 +423,7 @@ func (bip *baggageItemsPreservationTest) addAndRecordBaggage(t *testing.T, ctx c type tracerMessTest struct { recordedOTSpanTracers []ot.Tracer - recordedOtelSpanTracers []oteltrace.Tracer + recordedOtelSpanTracers []otel.Tracer } func newTracerMessTest() *tracerMessTest { @@ -475,7 +475,7 @@ func (tm *tracerMessTest) recordTracers(t *testing.T, ctx context.Context) conte tm.recordedOTSpanTracers = append(tm.recordedOTSpanTracers, otSpan.Tracer()) } - otelSpan := oteltrace.SpanFromContext(ctx) + otelSpan := otel.SpanFromContext(ctx) tm.recordedOtelSpanTracers = append(tm.recordedOtelSpanTracers, otelSpan.Tracer()) return ctx } @@ -613,23 +613,23 @@ func generateBaggageKeys(key string) (otKey, otelKey string) { // helpers -func checkTraceAndSpans(t *testing.T, tracer *internal.MockTracer, expectedTraceID oteltrace.ID, expectedSpanIDs []oteltrace.SpanID) { +func checkTraceAndSpans(t *testing.T, tracer *internal.MockTracer, expectedTraceID otel.TraceID, expectedSpanIDs []otel.SpanID) { expectedSpanCount := len(expectedSpanIDs) // reverse spanIDs, since first span ID belongs to root, that // finishes last - spanIDs := make([]oteltrace.SpanID, len(expectedSpanIDs)) + spanIDs := make([]otel.SpanID, len(expectedSpanIDs)) copy(spanIDs, expectedSpanIDs) reverse(len(spanIDs), func(i, j int) { spanIDs[i], spanIDs[j] = spanIDs[j], spanIDs[i] }) // the last finished span has no parent - parentSpanIDs := append(spanIDs[1:], oteltrace.SpanID{}) + parentSpanIDs := append(spanIDs[1:], otel.SpanID{}) - sks := map[oteltrace.SpanID]oteltrace.SpanKind{ - {125}: oteltrace.SpanKindProducer, - {124}: oteltrace.SpanKindInternal, - {123}: oteltrace.SpanKindClient, + sks := map[otel.SpanID]otel.SpanKind{ + {125}: otel.SpanKindProducer, + {124}: otel.SpanKindInternal, + {123}: otel.SpanKindClient, } if len(tracer.FinishedSpans) != expectedSpanCount { @@ -660,12 +660,12 @@ func reverse(length int, swap func(i, j int)) { } } -func simpleTraceID() oteltrace.ID { +func simpleTraceID() otel.TraceID { return [16]byte{123, 42} } -func simpleSpanIDs(count int) []oteltrace.SpanID { - base := []oteltrace.SpanID{ +func simpleSpanIDs(count int) []otel.SpanID { + base := []otel.SpanID{ {123}, {124}, {125}, @@ -685,7 +685,7 @@ func min(a, b int) int { func runOtelOTOtel(t *testing.T, ctx context.Context, name string, callback func(*testing.T, context.Context) context.Context) { tr := otelglobal.Tracer("") - ctx, span := tr.Start(ctx, fmt.Sprintf("%s_Otel_OTOtel", name), oteltrace.WithSpanKind(oteltrace.SpanKindClient)) + ctx, span := tr.Start(ctx, fmt.Sprintf("%s_Otel_OTOtel", name), otel.WithSpanKind(otel.SpanKindClient)) defer span.End() ctx = callback(t, ctx) func(ctx2 context.Context) { @@ -693,7 +693,7 @@ func runOtelOTOtel(t *testing.T, ctx context.Context, name string, callback func defer span.Finish() ctx2 = callback(t, ctx2) func(ctx3 context.Context) { - ctx3, span := tr.Start(ctx3, fmt.Sprintf("%sOtelOT_Otel_", name), oteltrace.WithSpanKind(oteltrace.SpanKindProducer)) + ctx3, span := tr.Start(ctx3, fmt.Sprintf("%sOtelOT_Otel_", name), otel.WithSpanKind(otel.SpanKindProducer)) defer span.End() _ = callback(t, ctx3) }(ctx2) diff --git a/bridge/opentracing/util.go b/bridge/opentracing/util.go index d2a4cd63a6c..18b80fb330d 100644 --- a/bridge/opentracing/util.go +++ b/bridge/opentracing/util.go @@ -17,7 +17,7 @@ package opentracing import ( "context" - oteltrace "go.opentelemetry.io/otel/api/trace" + "go.opentelemetry.io/otel" ) // NewTracerPair is a utility function that creates a BridgeTracer and a @@ -26,14 +26,14 @@ import ( // that wraps the passed tracer. BridgeTracer and WrapperTracerProvider are // returned to the caller and the caller is expected to register BridgeTracer // with opentracing and WrapperTracerProvider with opentelemetry. -func NewTracerPair(tracer oteltrace.Tracer) (*BridgeTracer, *WrapperTracerProvider) { +func NewTracerPair(tracer otel.Tracer) (*BridgeTracer, *WrapperTracerProvider) { bridgeTracer := NewBridgeTracer() wrapperProvider := NewWrappedTracerProvider(bridgeTracer, tracer) bridgeTracer.SetOpenTelemetryTracer(wrapperProvider.Tracer("")) return bridgeTracer, wrapperProvider } -func NewTracerPairWithContext(ctx context.Context, tracer oteltrace.Tracer) (context.Context, *BridgeTracer, *WrapperTracerProvider) { +func NewTracerPairWithContext(ctx context.Context, tracer otel.Tracer) (context.Context, *BridgeTracer, *WrapperTracerProvider) { bridgeTracer, wrapperProvider := NewTracerPair(tracer) ctx = bridgeTracer.NewHookedContext(ctx) return ctx, bridgeTracer, wrapperProvider diff --git a/bridge/opentracing/wrapper.go b/bridge/opentracing/wrapper.go index 4187a9d48b8..4625f6f544e 100644 --- a/bridge/opentracing/wrapper.go +++ b/bridge/opentracing/wrapper.go @@ -17,8 +17,7 @@ package opentracing import ( "context" - oteltrace "go.opentelemetry.io/otel/api/trace" - + "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/bridge/opentracing/migration" ) @@ -26,16 +25,16 @@ type WrapperTracerProvider struct { wTracer *WrapperTracer } -var _ oteltrace.TracerProvider = (*WrapperTracerProvider)(nil) +var _ otel.TracerProvider = (*WrapperTracerProvider)(nil) // Tracer returns the WrapperTracer associated with the WrapperTracerProvider. -func (p *WrapperTracerProvider) Tracer(_ string, _ ...oteltrace.TracerOption) oteltrace.Tracer { +func (p *WrapperTracerProvider) Tracer(_ string, _ ...otel.TracerOption) otel.Tracer { return p.wTracer } // NewWrappedTracerProvider creates a new trace provider that creates a single // instance of WrapperTracer that wraps OpenTelemetry tracer. -func NewWrappedTracerProvider(bridge *BridgeTracer, tracer oteltrace.Tracer) *WrapperTracerProvider { +func NewWrappedTracerProvider(bridge *BridgeTracer, tracer otel.Tracer) *WrapperTracerProvider { return &WrapperTracerProvider{ wTracer: NewWrapperTracer(bridge, tracer), } @@ -51,30 +50,30 @@ func NewWrappedTracerProvider(bridge *BridgeTracer, tracer oteltrace.Tracer) *Wr // used. type WrapperTracer struct { bridge *BridgeTracer - tracer oteltrace.Tracer + tracer otel.Tracer } -var _ oteltrace.Tracer = &WrapperTracer{} +var _ otel.Tracer = &WrapperTracer{} var _ migration.DeferredContextSetupTracerExtension = &WrapperTracer{} // NewWrapperTracer wraps the passed tracer and also talks to the // passed bridge tracer when setting up the context with the new // active OpenTracing span. -func NewWrapperTracer(bridge *BridgeTracer, tracer oteltrace.Tracer) *WrapperTracer { +func NewWrapperTracer(bridge *BridgeTracer, tracer otel.Tracer) *WrapperTracer { return &WrapperTracer{ bridge: bridge, tracer: tracer, } } -func (t *WrapperTracer) otelTracer() oteltrace.Tracer { +func (t *WrapperTracer) otelTracer() otel.Tracer { return t.tracer } // Start forwards the call to the wrapped tracer. It also tries to // override the tracer of the returned span if the span implements the // OverrideTracerSpanExtension interface. -func (t *WrapperTracer) Start(ctx context.Context, name string, opts ...oteltrace.SpanOption) (context.Context, oteltrace.Span) { +func (t *WrapperTracer) Start(ctx context.Context, name string, opts ...otel.SpanOption) (context.Context, otel.Span) { ctx, span := t.otelTracer().Start(ctx, name, opts...) if spanWithExtension, ok := span.(migration.OverrideTracerSpanExtension); ok { spanWithExtension.OverrideTracer(t) @@ -89,10 +88,10 @@ func (t *WrapperTracer) Start(ctx context.Context, name string, opts ...oteltrac // DeferredContextSetupTracerExtension interface. It will try to // forward the call to the wrapped tracer if it implements the // interface. -func (t *WrapperTracer) DeferredContextSetupHook(ctx context.Context, span oteltrace.Span) context.Context { +func (t *WrapperTracer) DeferredContextSetupHook(ctx context.Context, span otel.Span) context.Context { if tracerWithExtension, ok := t.otelTracer().(migration.DeferredContextSetupTracerExtension); ok { ctx = tracerWithExtension.DeferredContextSetupHook(ctx, span) } - ctx = oteltrace.ContextWithSpan(ctx, span) + ctx = otel.ContextWithSpan(ctx, span) return ctx } diff --git a/config.go b/config.go new file mode 100644 index 00000000000..70de993068b --- /dev/null +++ b/config.go @@ -0,0 +1,190 @@ +// 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 otel + +import ( + "time" + + "go.opentelemetry.io/otel/codes" + "go.opentelemetry.io/otel/label" +) + +// TracerConfig is a group of options for a Tracer. +type TracerConfig struct { + // InstrumentationVersion is the version of the library providing + // instrumentation. + InstrumentationVersion string +} + +// NewTracerConfig applies all the options to a returned TracerConfig. +func NewTracerConfig(options ...TracerOption) *TracerConfig { + config := new(TracerConfig) + for _, option := range options { + option.ApplyTracer(config) + } + return config +} + +// TracerOption applies an option to a TracerConfig. +type TracerOption interface { + ApplyTracer(*TracerConfig) +} + +type instVersionTracerOption string + +func (o instVersionTracerOption) ApplyTracer(c *TracerConfig) { c.InstrumentationVersion = string(o) } + +// WithInstrumentationVersion sets the instrumentation version for a Tracer. +func WithInstrumentationVersion(version string) TracerOption { + return instVersionTracerOption(version) +} + +// ErrorConfig is a group of options for an error event. +type ErrorConfig struct { + Timestamp time.Time + StatusCode codes.Code +} + +// NewErrorConfig applies all the options to a returned ErrorConfig. +func NewErrorConfig(options ...ErrorOption) *ErrorConfig { + c := new(ErrorConfig) + for _, option := range options { + option.ApplyError(c) + } + return c +} + +// ErrorOption applies an option to a ErrorConfig. +type ErrorOption interface { + ApplyError(*ErrorConfig) +} + +type errorTimeOption time.Time + +func (o errorTimeOption) ApplyError(c *ErrorConfig) { c.Timestamp = time.Time(o) } + +// WithErrorTime sets the time at which the error event should be recorded. +func WithErrorTime(t time.Time) ErrorOption { + return errorTimeOption(t) +} + +type errorStatusOption struct{ c codes.Code } + +func (o errorStatusOption) ApplyError(c *ErrorConfig) { c.StatusCode = o.c } + +// WithErrorStatus indicates the span status that should be set when recording an error event. +func WithErrorStatus(c codes.Code) ErrorOption { + return errorStatusOption{c} +} + +// SpanConfig is a group of options for a Span. +type SpanConfig struct { + // Attributes describe the associated qualities of a Span. + Attributes []label.KeyValue + // Timestamp is a time in a Span life-cycle. + Timestamp time.Time + // Links are the associations a Span has with other Spans. + Links []Link + // Record is the recording state of a Span. + Record bool + // NewRoot identifies a Span as the root Span for a new trace. This is + // commonly used when an existing trace crosses trust boundaries and the + // remote parent span context should be ignored for security. + NewRoot bool + // SpanKind is the role a Span has in a trace. + SpanKind SpanKind +} + +// NewSpanConfig applies all the options to a returned SpanConfig. +// No validation is performed on the returned SpanConfig (e.g. no uniqueness +// checking or bounding of data), it is left to the SDK to perform this +// action. +func NewSpanConfig(options ...SpanOption) *SpanConfig { + c := new(SpanConfig) + for _, option := range options { + option.ApplySpan(c) + } + return c +} + +// SpanOption applies an option to a SpanConfig. +type SpanOption interface { + ApplySpan(*SpanConfig) +} + +type attributeSpanOption []label.KeyValue + +func (o attributeSpanOption) ApplySpan(c *SpanConfig) { + c.Attributes = append(c.Attributes, []label.KeyValue(o)...) +} + +// WithAttributes adds the attributes to a span. These attributes are meant to +// provide additional information about the work the Span represents. The +// attributes are added to the existing Span attributes, i.e. this does not +// overwrite. +func WithAttributes(attributes ...label.KeyValue) SpanOption { + return attributeSpanOption(attributes) +} + +type timestampSpanOption time.Time + +func (o timestampSpanOption) ApplySpan(c *SpanConfig) { c.Timestamp = time.Time(o) } + +// WithTimestamp sets the time of a Span life-cycle moment (e.g. started or +// stopped). +func WithTimestamp(t time.Time) SpanOption { + return timestampSpanOption(t) +} + +type linksSpanOption []Link + +func (o linksSpanOption) ApplySpan(c *SpanConfig) { c.Links = append(c.Links, []Link(o)...) } + +// WithLinks adds links to a Span. The links are added to the existing Span +// links, i.e. this does not overwrite. +func WithLinks(links ...Link) SpanOption { + return linksSpanOption(links) +} + +type recordSpanOption bool + +func (o recordSpanOption) ApplySpan(c *SpanConfig) { c.Record = bool(o) } + +// WithRecord specifies that the span should be recorded. It is important to +// note that implementations may override this option, i.e. if the span is a +// child of an un-sampled trace. +func WithRecord() SpanOption { + return recordSpanOption(true) +} + +type newRootSpanOption bool + +func (o newRootSpanOption) ApplySpan(c *SpanConfig) { c.NewRoot = bool(o) } + +// WithNewRoot specifies that the Span should be treated as a root Span. Any +// existing parent span context will be ignored when defining the Span's trace +// identifiers. +func WithNewRoot() SpanOption { + return newRootSpanOption(true) +} + +type spanKindSpanOption SpanKind + +func (o spanKindSpanOption) ApplySpan(c *SpanConfig) { c.SpanKind = SpanKind(o) } + +// WithSpanKind sets the SpanKind of a Span. +func WithSpanKind(kind SpanKind) SpanOption { + return spanKindSpanOption(kind) +} diff --git a/api/trace/span_test.go b/config_test.go similarity index 81% rename from api/trace/span_test.go rename to config_test.go index d435d54e4de..2542806e1ef 100644 --- a/api/trace/span_test.go +++ b/config_test.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package trace +package otel import ( "testing" @@ -32,11 +32,11 @@ func TestNewSpanConfig(t *testing.T) { timestamp1 := time.Unix(0, 0) link1 := Link{ - SpanContext: SpanContext{TraceID: ID([16]byte{1, 1}), SpanID: SpanID{3}}, + SpanContext: SpanContext{TraceID: TraceID([16]byte{1, 1}), SpanID: SpanID{3}}, Attributes: []label.KeyValue{k1v1}, } link2 := Link{ - SpanContext: SpanContext{TraceID: ID([16]byte{1, 1}), SpanID: SpanID{3}}, + SpanContext: SpanContext{TraceID: TraceID([16]byte{1, 1}), SpanID: SpanID{3}}, Attributes: []label.KeyValue{k1v2, k2v2}, } @@ -193,3 +193,40 @@ func TestNewSpanConfig(t *testing.T) { assert.Equal(t, test.expected, NewSpanConfig(test.options...)) } } + +func TestTracerConfig(t *testing.T) { + v1 := "semver:0.0.1" + v2 := "semver:1.0.0" + tests := []struct { + options []TracerOption + expected *TracerConfig + }{ + { + // No non-zero-values should be set. + []TracerOption{}, + new(TracerConfig), + }, + { + []TracerOption{ + WithInstrumentationVersion(v1), + }, + &TracerConfig{ + InstrumentationVersion: v1, + }, + }, + { + []TracerOption{ + // Multiple calls should overwrite. + WithInstrumentationVersion(v1), + WithInstrumentationVersion(v2), + }, + &TracerConfig{ + InstrumentationVersion: v2, + }, + }, + } + for _, test := range tests { + config := NewTracerConfig(test.options...) + assert.Equal(t, test.expected, config) + } +} diff --git a/doc.go b/doc.go index de2f76ceeca..ae2520991d6 100644 --- a/doc.go +++ b/doc.go @@ -12,5 +12,62 @@ // See the License for the specific language governing permissions and // limitations under the License. -// Package otel contains OpenTelemetry Go packages. +/* +Package otel provides an implementation of the OpenTelemetry API. + +The provided API is used to instrument code and measure data about that code's +performance and operation. The measured data, by default, is not processed or +transmitted anywhere. An implementation of the OpenTelemetry SDK, like the +default SDK implementation (go.opentelemetry.io/otel/sdk), and associated +exporters are used to process and transport this data. + +Tracing + +To participate in distributed traces a Span needs to be created for the +operation being performed as part of a traced workflow. It its simplest form: + + var tracer otel.Tracer + + func init() { + tracer := global.Tracer("instrumentation/package/name") + } + + func operation(ctx context.Context) { + var span trace.Span + ctx, span = tracer.Start(ctx, "operation") + defer span.End() + // ... + } + +A Tracer is unique to the instrumentation and is used to create Spans. +Instrumentation should be designed to accept a TracerProvider from which it +can create its own unique Tracer. Alternatively, the registered global +TracerProvider from the go.opentelemetry.io/otel/api/global package can be +used as a default. + + const ( + name = "instrumentation/package/name" + version = "0.1.0" + ) + + type Instrumentation struct { + tracer otel.Tracer + } + + func NewInstrumentation(tp otel.TracerProvider) *Instrumentation { + if tp == nil { + tp := global.TracerProvider() + } + return &Instrumentation{ + tracer: tp.Tracer(name, otel.WithTracerVersion(version)), + } + } + + func operation(ctx context.Context, inst *Instrumentation) { + var span trace.Span + ctx, span = inst.tracer.Start(ctx, "operation") + defer span.End() + // ... + } +*/ package otel // import "go.opentelemetry.io/otel" diff --git a/example/basic/main.go b/example/basic/main.go index aa6b4544423..e7d86d5c1a9 100644 --- a/example/basic/main.go +++ b/example/basic/main.go @@ -21,7 +21,6 @@ import ( "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/api/global" "go.opentelemetry.io/otel/api/metric" - "go.opentelemetry.io/otel/api/trace" "go.opentelemetry.io/otel/exporters/stdout" "go.opentelemetry.io/otel/label" "go.opentelemetry.io/otel/propagators" @@ -85,7 +84,7 @@ func main() { defer valuerecorder.Unbind() err = func(ctx context.Context) error { - var span trace.Span + var span otel.Span ctx, span = tracer.Start(ctx, "operation") defer span.End() @@ -101,7 +100,7 @@ func main() { ) return func(ctx context.Context) error { - var span trace.Span + var span otel.Span ctx, span = tracer.Start(ctx, "Sub operation...") defer span.End() diff --git a/example/namedtracer/foo/foo.go b/example/namedtracer/foo/foo.go index 12ab8261c54..d5ddbaaea69 100644 --- a/example/namedtracer/foo/foo.go +++ b/example/namedtracer/foo/foo.go @@ -17,8 +17,8 @@ package foo import ( "context" + "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/api/global" - "go.opentelemetry.io/otel/api/trace" "go.opentelemetry.io/otel/label" ) @@ -33,7 +33,7 @@ func SubOperation(ctx context.Context) error { // for its component to get the instance of the provider. tr := global.Tracer("example/namedtracer/foo") - var span trace.Span + var span otel.Span ctx, span = tr.Start(ctx, "Sub operation...") defer span.End() span.SetAttributes(lemonsKey.String("five")) diff --git a/example/namedtracer/main.go b/example/namedtracer/main.go index ae9c284e076..f5e648f6511 100644 --- a/example/namedtracer/main.go +++ b/example/namedtracer/main.go @@ -20,7 +20,6 @@ import ( "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/api/global" - "go.opentelemetry.io/otel/api/trace" "go.opentelemetry.io/otel/example/namedtracer/foo" "go.opentelemetry.io/otel/exporters/stdout" "go.opentelemetry.io/otel/label" @@ -66,7 +65,7 @@ func main() { ctx := context.Background() ctx = otel.ContextWithBaggageValues(ctx, fooKey.String("foo1"), barKey.String("bar1")) - var span trace.Span + var span otel.Span ctx, span = tracer.Start(ctx, "operation") defer span.End() span.AddEvent(ctx, "Nice operation!", label.Int("bogons", 100)) diff --git a/example/otel-collector/main.go b/example/otel-collector/main.go index d917f5eaf19..842c4d17049 100644 --- a/example/otel-collector/main.go +++ b/example/otel-collector/main.go @@ -25,9 +25,9 @@ import ( "google.golang.org/grpc" + "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/api/global" "go.opentelemetry.io/otel/api/metric" - apitrace "go.opentelemetry.io/otel/api/trace" "go.opentelemetry.io/otel/exporters/otlp" "go.opentelemetry.io/otel/label" "go.opentelemetry.io/otel/propagators" @@ -116,7 +116,7 @@ func main() { ctx, span := tracer.Start( context.Background(), "CollectorExporter-Example", - apitrace.WithAttributes(commonLabels...)) + otel.WithAttributes(commonLabels...)) defer span.End() for i := 0; i < 10; i++ { _, iSpan := tracer.Start(ctx, fmt.Sprintf("Sample-%d", i)) diff --git a/exporters/otlp/internal/transform/span.go b/exporters/otlp/internal/transform/span.go index c037d63485b..b728a0cd9d2 100644 --- a/exporters/otlp/internal/transform/span.go +++ b/exporters/otlp/internal/transform/span.go @@ -15,10 +15,10 @@ package transform import ( + "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/codes" tracepb "go.opentelemetry.io/otel/exporters/otlp/internal/opentelemetry-proto-gen/trace/v1" - apitrace "go.opentelemetry.io/otel/api/trace" "go.opentelemetry.io/otel/label" export "go.opentelemetry.io/otel/sdk/export/trace" "go.opentelemetry.io/otel/sdk/instrumentation" @@ -140,7 +140,7 @@ func status(status codes.Code, message string) *tracepb.Status { } // links transforms span Links to OTLP span links. -func links(links []apitrace.Link) []*tracepb.Span_Link { +func links(links []otel.Link) []*tracepb.Span_Link { if len(links) == 0 { return nil } @@ -193,17 +193,17 @@ func spanEvents(es []export.Event) []*tracepb.Span_Event { } // spanKind transforms a SpanKind to an OTLP span kind. -func spanKind(kind apitrace.SpanKind) tracepb.Span_SpanKind { +func spanKind(kind otel.SpanKind) tracepb.Span_SpanKind { switch kind { - case apitrace.SpanKindInternal: + case otel.SpanKindInternal: return tracepb.Span_INTERNAL - case apitrace.SpanKindClient: + case otel.SpanKindClient: return tracepb.Span_CLIENT - case apitrace.SpanKindServer: + case otel.SpanKindServer: return tracepb.Span_SERVER - case apitrace.SpanKindProducer: + case otel.SpanKindProducer: return tracepb.Span_PRODUCER - case apitrace.SpanKindConsumer: + case otel.SpanKindConsumer: return tracepb.Span_CONSUMER default: return tracepb.Span_SPAN_KIND_UNSPECIFIED diff --git a/exporters/otlp/internal/transform/span_test.go b/exporters/otlp/internal/transform/span_test.go index 6d256679d53..d915923a9fc 100644 --- a/exporters/otlp/internal/transform/span_test.go +++ b/exporters/otlp/internal/transform/span_test.go @@ -24,10 +24,10 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "go.opentelemetry.io/otel" tracepb "go.opentelemetry.io/otel/exporters/otlp/internal/opentelemetry-proto-gen/trace/v1" "go.opentelemetry.io/otel/label" - apitrace "go.opentelemetry.io/otel/api/trace" "go.opentelemetry.io/otel/codes" export "go.opentelemetry.io/otel/sdk/export/trace" "go.opentelemetry.io/otel/sdk/instrumentation" @@ -36,31 +36,31 @@ import ( func TestSpanKind(t *testing.T) { for _, test := range []struct { - kind apitrace.SpanKind + kind otel.SpanKind expected tracepb.Span_SpanKind }{ { - apitrace.SpanKindInternal, + otel.SpanKindInternal, tracepb.Span_INTERNAL, }, { - apitrace.SpanKindClient, + otel.SpanKindClient, tracepb.Span_CLIENT, }, { - apitrace.SpanKindServer, + otel.SpanKindServer, tracepb.Span_SERVER, }, { - apitrace.SpanKindProducer, + otel.SpanKindProducer, tracepb.Span_PRODUCER, }, { - apitrace.SpanKindConsumer, + otel.SpanKindConsumer, tracepb.Span_CONSUMER, }, { - apitrace.SpanKind(-1), + otel.SpanKind(-1), tracepb.Span_SPAN_KIND_UNSPECIFIED, }, } { @@ -117,15 +117,15 @@ func TestNilLinks(t *testing.T) { } func TestEmptyLinks(t *testing.T) { - assert.Nil(t, links([]apitrace.Link{})) + assert.Nil(t, links([]otel.Link{})) } func TestLinks(t *testing.T) { attrs := []label.KeyValue{label.Int("one", 1), label.Int("two", 2)} - l := []apitrace.Link{ + l := []otel.Link{ {}, { - SpanContext: apitrace.EmptySpanContext(), + SpanContext: otel.SpanContext{}, Attributes: attrs, }, } @@ -200,12 +200,12 @@ func TestSpanData(t *testing.T) { startTime := time.Unix(1585674086, 1234) endTime := startTime.Add(10 * time.Second) spanData := &export.SpanData{ - SpanContext: apitrace.SpanContext{ - TraceID: apitrace.ID{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F}, - SpanID: apitrace.SpanID{0xFF, 0xFE, 0xFD, 0xFC, 0xFB, 0xFA, 0xF9, 0xF8}, + SpanContext: otel.SpanContext{ + TraceID: otel.TraceID{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F}, + SpanID: otel.SpanID{0xFF, 0xFE, 0xFD, 0xFC, 0xFB, 0xFA, 0xF9, 0xF8}, }, - SpanKind: apitrace.SpanKindServer, - ParentSpanID: apitrace.SpanID{0xEF, 0xEE, 0xED, 0xEC, 0xEB, 0xEA, 0xE9, 0xE8}, + SpanKind: otel.SpanKindServer, + ParentSpanID: otel.SpanID{0xEF, 0xEE, 0xED, 0xEC, 0xEB, 0xEA, 0xE9, 0xE8}, Name: "span data to span data", StartTime: startTime, EndTime: endTime, @@ -221,11 +221,11 @@ func TestSpanData(t *testing.T) { }, }, }, - Links: []apitrace.Link{ + Links: []otel.Link{ { - SpanContext: apitrace.SpanContext{ - TraceID: apitrace.ID{0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF}, - SpanID: apitrace.SpanID{0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7}, + SpanContext: otel.SpanContext{ + TraceID: otel.TraceID{0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF}, + SpanID: otel.SpanID{0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7}, TraceFlags: 0, }, Attributes: []label.KeyValue{ @@ -233,9 +233,9 @@ func TestSpanData(t *testing.T) { }, }, { - SpanContext: apitrace.SpanContext{ - TraceID: apitrace.ID{0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF}, - SpanID: apitrace.SpanID{0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7}, + SpanContext: otel.SpanContext{ + TraceID: otel.TraceID{0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF}, + SpanID: otel.SpanID{0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7}, TraceFlags: 0, }, Attributes: []label.KeyValue{ diff --git a/exporters/otlp/otlp_span_test.go b/exporters/otlp/otlp_span_test.go index 3f67427af53..41dfafdbfbe 100644 --- a/exporters/otlp/otlp_span_test.go +++ b/exporters/otlp/otlp_span_test.go @@ -22,6 +22,7 @@ import ( "github.com/stretchr/testify/assert" "google.golang.org/grpc" + "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/codes" coltracepb "go.opentelemetry.io/otel/exporters/otlp/internal/opentelemetry-proto-gen/collector/trace/v1" commonpb "go.opentelemetry.io/otel/exporters/otlp/internal/opentelemetry-proto-gen/common/v1" @@ -29,7 +30,6 @@ import ( tracepb "go.opentelemetry.io/otel/exporters/otlp/internal/opentelemetry-proto-gen/trace/v1" "go.opentelemetry.io/otel/label" - apitrace "go.opentelemetry.io/otel/api/trace" tracesdk "go.opentelemetry.io/otel/sdk/export/trace" "go.opentelemetry.io/otel/sdk/instrumentation" "go.opentelemetry.io/otel/sdk/resource" @@ -82,12 +82,12 @@ func TestExportSpans(t *testing.T) { { []*tracesdk.SpanData{ { - SpanContext: apitrace.SpanContext{ - TraceID: apitrace.ID([16]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}), - SpanID: apitrace.SpanID([8]byte{0, 0, 0, 0, 0, 0, 0, 1}), + SpanContext: otel.SpanContext{ + TraceID: otel.TraceID([16]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}), + SpanID: otel.SpanID([8]byte{0, 0, 0, 0, 0, 0, 0, 1}), TraceFlags: byte(1), }, - SpanKind: apitrace.SpanKindServer, + SpanKind: otel.SpanKindServer, Name: "parent process", StartTime: startTime, EndTime: endTime, @@ -104,12 +104,12 @@ func TestExportSpans(t *testing.T) { }, }, { - SpanContext: apitrace.SpanContext{ - TraceID: apitrace.ID([16]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2}), - SpanID: apitrace.SpanID([8]byte{0, 0, 0, 0, 0, 0, 0, 1}), + SpanContext: otel.SpanContext{ + TraceID: otel.TraceID([16]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2}), + SpanID: otel.SpanID([8]byte{0, 0, 0, 0, 0, 0, 0, 1}), TraceFlags: byte(1), }, - SpanKind: apitrace.SpanKindServer, + SpanKind: otel.SpanKindServer, Name: "secondary parent process", StartTime: startTime, EndTime: endTime, @@ -126,13 +126,13 @@ func TestExportSpans(t *testing.T) { }, }, { - SpanContext: apitrace.SpanContext{ - TraceID: apitrace.ID([16]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}), - SpanID: apitrace.SpanID([8]byte{0, 0, 0, 0, 0, 0, 0, 2}), + SpanContext: otel.SpanContext{ + TraceID: otel.TraceID([16]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}), + SpanID: otel.SpanID([8]byte{0, 0, 0, 0, 0, 0, 0, 2}), TraceFlags: byte(1), }, - ParentSpanID: apitrace.SpanID([8]byte{0, 0, 0, 0, 0, 0, 0, 1}), - SpanKind: apitrace.SpanKindInternal, + ParentSpanID: otel.SpanID([8]byte{0, 0, 0, 0, 0, 0, 0, 1}), + SpanKind: otel.SpanKindInternal, Name: "internal process", StartTime: startTime, EndTime: endTime, @@ -149,12 +149,12 @@ func TestExportSpans(t *testing.T) { }, }, { - SpanContext: apitrace.SpanContext{ - TraceID: apitrace.ID([16]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2}), - SpanID: apitrace.SpanID([8]byte{0, 0, 0, 0, 0, 0, 0, 1}), + SpanContext: otel.SpanContext{ + TraceID: otel.TraceID([16]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2}), + SpanID: otel.SpanID([8]byte{0, 0, 0, 0, 0, 0, 0, 1}), TraceFlags: byte(1), }, - SpanKind: apitrace.SpanKindServer, + SpanKind: otel.SpanKindServer, Name: "parent process", StartTime: startTime, EndTime: endTime, diff --git a/exporters/stdout/example_test.go b/exporters/stdout/example_test.go index 082dfb130f7..2704018260e 100644 --- a/exporters/stdout/example_test.go +++ b/exporters/stdout/example_test.go @@ -18,9 +18,9 @@ import ( "context" "log" + "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/api/global" "go.opentelemetry.io/otel/api/metric" - "go.opentelemetry.io/otel/api/trace" "go.opentelemetry.io/otel/exporters/stdout" "go.opentelemetry.io/otel/label" ) @@ -33,7 +33,7 @@ const ( var ( tracer = global.TracerProvider().Tracer( instrumentationName, - trace.WithInstrumentationVersion(instrumentationVersion), + otel.WithInstrumentationVersion(instrumentationVersion), ) meter = global.MeterProvider().Meter( @@ -50,7 +50,7 @@ var ( func add(ctx context.Context, x, y int64) int64 { nameKV := nameKey.String("add") - var span trace.Span + var span otel.Span ctx, span = tracer.Start(ctx, "Addition") defer span.End() @@ -64,7 +64,7 @@ func add(ctx context.Context, x, y int64) int64 { func multiply(ctx context.Context, x, y int64) int64 { nameKV := nameKey.String("multiply") - var span trace.Span + var span otel.Span ctx, span = tracer.Start(ctx, "Multiplication") defer span.End() diff --git a/exporters/stdout/exporter.go b/exporters/stdout/exporter.go index 52608a89cb2..2d850a0ad95 100644 --- a/exporters/stdout/exporter.go +++ b/exporters/stdout/exporter.go @@ -15,10 +15,10 @@ package stdout import ( + "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/api/global" - apitrace "go.opentelemetry.io/otel/api/trace" "go.opentelemetry.io/otel/sdk/export/metric" - "go.opentelemetry.io/otel/sdk/export/trace" + exporttrace "go.opentelemetry.io/otel/sdk/export/trace" "go.opentelemetry.io/otel/sdk/metric/controller/push" "go.opentelemetry.io/otel/sdk/metric/processor/basic" "go.opentelemetry.io/otel/sdk/metric/selector/simple" @@ -31,8 +31,8 @@ type Exporter struct { } var ( - _ metric.Exporter = &Exporter{} - _ trace.SpanExporter = &Exporter{} + _ metric.Exporter = &Exporter{} + _ exporttrace.SpanExporter = &Exporter{} ) // NewExporter creates an Exporter with the passed options. @@ -50,7 +50,7 @@ func NewExporter(options ...Option) (*Exporter, error) { // NewExportPipeline creates a complete export pipeline with the default // selectors, processors, and trace registration. It is the responsibility // of the caller to stop the returned push Controller. -func NewExportPipeline(exportOpts []Option, pushOpts []push.Option) (apitrace.TracerProvider, *push.Controller, error) { +func NewExportPipeline(exportOpts []Option, pushOpts []push.Option) (otel.TracerProvider, *push.Controller, error) { exporter, err := NewExporter(exportOpts...) if err != nil { return nil, nil, err diff --git a/exporters/stdout/trace_test.go b/exporters/stdout/trace_test.go index 1719160f769..7ee977b85d9 100644 --- a/exporters/stdout/trace_test.go +++ b/exporters/stdout/trace_test.go @@ -22,7 +22,7 @@ import ( "testing" "time" - "go.opentelemetry.io/otel/api/trace" + "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/codes" "go.opentelemetry.io/otel/exporters/stdout" "go.opentelemetry.io/otel/label" @@ -40,14 +40,14 @@ func TestExporter_ExportSpan(t *testing.T) { // setup test span now := time.Now() - traceID, _ := trace.IDFromHex("0102030405060708090a0b0c0d0e0f10") - spanID, _ := trace.SpanIDFromHex("0102030405060708") + traceID, _ := otel.TraceIDFromHex("0102030405060708090a0b0c0d0e0f10") + spanID, _ := otel.SpanIDFromHex("0102030405060708") keyValue := "value" doubleValue := 123.456 resource := resource.New(label.String("rk1", "rv11")) testSpan := &export.SpanData{ - SpanContext: trace.SpanContext{ + SpanContext: otel.SpanContext{ TraceID: traceID, SpanID: spanID, }, @@ -62,7 +62,7 @@ func TestExporter_ExportSpan(t *testing.T) { {Name: "foo", Attributes: []label.KeyValue{label.String("key", keyValue)}, Time: now}, {Name: "bar", Attributes: []label.KeyValue{label.Float64("double", doubleValue)}, Time: now}, }, - SpanKind: trace.SpanKindInternal, + SpanKind: otel.SpanKindInternal, StatusCode: codes.Error, StatusMessage: "interesting", Resource: resource, diff --git a/exporters/trace/jaeger/jaeger.go b/exporters/trace/jaeger/jaeger.go index d98222f35af..96e12323939 100644 --- a/exporters/trace/jaeger/jaeger.go +++ b/exporters/trace/jaeger/jaeger.go @@ -22,8 +22,8 @@ import ( "google.golang.org/api/support/bundler" + "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/api/global" - apitrace "go.opentelemetry.io/otel/api/trace" "go.opentelemetry.io/otel/codes" gen "go.opentelemetry.io/otel/exporters/trace/jaeger/internal/gen-go/jaeger" "go.opentelemetry.io/otel/label" @@ -92,8 +92,8 @@ func WithDisabled(disabled bool) Option { } } -// NewRawExporter returns a trace.Exporter implementation that exports -// the collected spans to Jaeger. +// NewRawExporter returns an OTel Exporter implementation that exports the +// collected spans to Jaeger. // // It will IGNORE Disabled option. func NewRawExporter(endpointOption EndpointOption, opts ...Option) (*Exporter, error) { @@ -151,14 +151,14 @@ func NewRawExporter(endpointOption EndpointOption, opts ...Option) (*Exporter, e // NewExportPipeline sets up a complete export pipeline // with the recommended setup for trace provider -func NewExportPipeline(endpointOption EndpointOption, opts ...Option) (apitrace.TracerProvider, func(), error) { +func NewExportPipeline(endpointOption EndpointOption, opts ...Option) (otel.TracerProvider, func(), error) { o := options{} opts = append(opts, WithDisabledFromEnv()) for _, opt := range opts { opt(&o) } if o.Disabled { - return apitrace.NoopTracerProvider(), func() {}, nil + return otel.NewNoopTracerProvider(), func() {}, nil } exporter, err := NewRawExporter(endpointOption, opts...) @@ -196,7 +196,8 @@ type Process struct { Tags []label.KeyValue } -// Exporter is an implementation of trace.SpanSyncer that uploads spans to Jaeger. +// Exporter is an implementation of an OTel SpanSyncer that uploads spans to +// Jaeger. type Exporter struct { process *gen.Process bundler *bundler.Bundler diff --git a/exporters/trace/jaeger/jaeger_test.go b/exporters/trace/jaeger/jaeger_test.go index e45496bd3de..bb7cc52b961 100644 --- a/exporters/trace/jaeger/jaeger_test.go +++ b/exporters/trace/jaeger/jaeger_test.go @@ -28,9 +28,8 @@ import ( "github.com/stretchr/testify/require" "google.golang.org/api/support/bundler" + "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/api/global" - "go.opentelemetry.io/otel/api/trace" - apitrace "go.opentelemetry.io/otel/api/trace" "go.opentelemetry.io/otel/codes" gen "go.opentelemetry.io/otel/exporters/trace/jaeger/internal/gen-go/jaeger" ottest "go.opentelemetry.io/otel/internal/testing" @@ -51,7 +50,7 @@ func TestInstallNewPipeline(t *testing.T) { name string endpoint EndpointOption options []Option - expectedProvider trace.TracerProvider + expectedProvider otel.TracerProvider }{ { name: "simple pipeline", @@ -69,7 +68,7 @@ func TestInstallNewPipeline(t *testing.T) { options: []Option{ WithDisabled(true), }, - expectedProvider: apitrace.NoopTracerProvider(), + expectedProvider: otel.NewNoopTracerProvider(), }, } @@ -94,7 +93,7 @@ func TestNewExportPipeline(t *testing.T) { name string endpoint EndpointOption options []Option - expectedProviderType trace.TracerProvider + expectedProviderType otel.TracerProvider testSpanSampling, spanShouldBeSampled bool }{ { @@ -108,7 +107,7 @@ func TestNewExportPipeline(t *testing.T) { options: []Option{ WithDisabled(true), }, - expectedProviderType: apitrace.NoopTracerProvider(), + expectedProviderType: otel.NewNoopTracerProvider(), }, { name: "always on", @@ -173,7 +172,7 @@ func TestNewExportPipelineWithDisabledFromEnv(t *testing.T) { ) defer fn() assert.NoError(t, err) - assert.IsType(t, apitrace.NoopTracerProvider(), tp) + assert.IsType(t, otel.NewNoopTracerProvider(), tp) } func TestNewRawExporter(t *testing.T) { @@ -356,11 +355,11 @@ func TestExporter_ExportSpan(t *testing.T) { func Test_spanDataToThrift(t *testing.T) { now := time.Now() - traceID, _ := apitrace.IDFromHex("0102030405060708090a0b0c0d0e0f10") - spanID, _ := apitrace.SpanIDFromHex("0102030405060708") + traceID, _ := otel.TraceIDFromHex("0102030405060708090a0b0c0d0e0f10") + spanID, _ := otel.SpanIDFromHex("0102030405060708") - linkTraceID, _ := apitrace.IDFromHex("0102030405060709090a0b0c0d0e0f11") - linkSpanID, _ := apitrace.SpanIDFromHex("0102030405060709") + linkTraceID, _ := otel.TraceIDFromHex("0102030405060709090a0b0c0d0e0f11") + linkSpanID, _ := otel.SpanIDFromHex("0102030405060709") eventNameValue := "event-test" keyValue := "value" @@ -383,16 +382,16 @@ func Test_spanDataToThrift(t *testing.T) { { name: "no parent", data: &export.SpanData{ - SpanContext: apitrace.SpanContext{ + SpanContext: otel.SpanContext{ TraceID: traceID, SpanID: spanID, }, Name: "/foo", StartTime: now, EndTime: now, - Links: []apitrace.Link{ + Links: []otel.Link{ { - SpanContext: apitrace.SpanContext{ + SpanContext: otel.SpanContext{ TraceID: linkTraceID, SpanID: linkSpanID, }, @@ -409,7 +408,7 @@ func Test_spanDataToThrift(t *testing.T) { }, StatusCode: codes.Error, StatusMessage: statusMessage, - SpanKind: apitrace.SpanKindClient, + SpanKind: otel.SpanKindClient, Resource: resource.New(label.String("rk1", rv1), label.Int64("rk2", rv2)), InstrumentationLibrary: instrumentation.Library{ Name: instrLibName, diff --git a/exporters/trace/zipkin/model.go b/exporters/trace/zipkin/model.go index 65a98959607..02400e7bb22 100644 --- a/exporters/trace/zipkin/model.go +++ b/exporters/trace/zipkin/model.go @@ -21,7 +21,7 @@ import ( zkmodel "github.com/openzipkin/zipkin-go/model" - "go.opentelemetry.io/otel/api/trace" + "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/label" export "go.opentelemetry.io/otel/sdk/export/trace" ) @@ -67,18 +67,18 @@ func toZipkinSpanContext(data *export.SpanData) zkmodel.SpanContext { } } -func toZipkinTraceID(traceID trace.ID) zkmodel.TraceID { +func toZipkinTraceID(traceID otel.TraceID) zkmodel.TraceID { return zkmodel.TraceID{ High: binary.BigEndian.Uint64(traceID[:8]), Low: binary.BigEndian.Uint64(traceID[8:]), } } -func toZipkinID(spanID trace.SpanID) zkmodel.ID { +func toZipkinID(spanID otel.SpanID) zkmodel.ID { return zkmodel.ID(binary.BigEndian.Uint64(spanID[:])) } -func toZipkinParentID(spanID trace.SpanID) *zkmodel.ID { +func toZipkinParentID(spanID otel.SpanID) *zkmodel.ID { if spanID.IsValid() { id := toZipkinID(spanID) return &id @@ -86,21 +86,21 @@ func toZipkinParentID(spanID trace.SpanID) *zkmodel.ID { return nil } -func toZipkinKind(kind trace.SpanKind) zkmodel.Kind { +func toZipkinKind(kind otel.SpanKind) zkmodel.Kind { switch kind { - case trace.SpanKindUnspecified: + case otel.SpanKindUnspecified: return zkmodel.Undetermined - case trace.SpanKindInternal: + case otel.SpanKindInternal: // The spec says we should set the kind to nil, but // the model does not allow that. return zkmodel.Undetermined - case trace.SpanKindServer: + case otel.SpanKindServer: return zkmodel.Server - case trace.SpanKindClient: + case otel.SpanKindClient: return zkmodel.Client - case trace.SpanKindProducer: + case otel.SpanKindProducer: return zkmodel.Producer - case trace.SpanKindConsumer: + case otel.SpanKindConsumer: return zkmodel.Consumer } return zkmodel.Undetermined diff --git a/exporters/trace/zipkin/model_test.go b/exporters/trace/zipkin/model_test.go index e4810b6f1f8..edb45f9b670 100644 --- a/exporters/trace/zipkin/model_test.go +++ b/exporters/trace/zipkin/model_test.go @@ -24,7 +24,7 @@ import ( zkmodel "github.com/openzipkin/zipkin-go/model" "github.com/stretchr/testify/require" - "go.opentelemetry.io/otel/api/trace" + "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/codes" "go.opentelemetry.io/otel/label" export "go.opentelemetry.io/otel/sdk/export/trace" @@ -35,12 +35,12 @@ func TestModelConversion(t *testing.T) { inputBatch := []*export.SpanData{ // typical span data { - SpanContext: trace.SpanContext{ - TraceID: trace.ID{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F}, - SpanID: trace.SpanID{0xFF, 0xFE, 0xFD, 0xFC, 0xFB, 0xFA, 0xF9, 0xF8}, + SpanContext: otel.SpanContext{ + TraceID: otel.TraceID{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F}, + SpanID: otel.SpanID{0xFF, 0xFE, 0xFD, 0xFC, 0xFB, 0xFA, 0xF9, 0xF8}, }, - ParentSpanID: trace.SpanID{0x3F, 0x3E, 0x3D, 0x3C, 0x3B, 0x3A, 0x39, 0x38}, - SpanKind: trace.SpanKindServer, + ParentSpanID: otel.SpanID{0x3F, 0x3E, 0x3D, 0x3C, 0x3B, 0x3A, 0x39, 0x38}, + SpanKind: otel.SpanKindServer, Name: "foo", StartTime: time.Date(2020, time.March, 11, 19, 24, 0, 0, time.UTC), EndTime: time.Date(2020, time.March, 11, 19, 25, 0, 0, time.UTC), @@ -68,12 +68,12 @@ func TestModelConversion(t *testing.T) { // span data with no parent (same as typical, but has // invalid parent) { - SpanContext: trace.SpanContext{ - TraceID: trace.ID{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F}, - SpanID: trace.SpanID{0xFF, 0xFE, 0xFD, 0xFC, 0xFB, 0xFA, 0xF9, 0xF8}, + SpanContext: otel.SpanContext{ + TraceID: otel.TraceID{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F}, + SpanID: otel.SpanID{0xFF, 0xFE, 0xFD, 0xFC, 0xFB, 0xFA, 0xF9, 0xF8}, }, - ParentSpanID: trace.SpanID{}, - SpanKind: trace.SpanKindServer, + ParentSpanID: otel.SpanID{}, + SpanKind: otel.SpanKindServer, Name: "foo", StartTime: time.Date(2020, time.March, 11, 19, 24, 0, 0, time.UTC), EndTime: time.Date(2020, time.March, 11, 19, 25, 0, 0, time.UTC), @@ -100,12 +100,12 @@ func TestModelConversion(t *testing.T) { }, // span data of unspecified kind { - SpanContext: trace.SpanContext{ - TraceID: trace.ID{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F}, - SpanID: trace.SpanID{0xFF, 0xFE, 0xFD, 0xFC, 0xFB, 0xFA, 0xF9, 0xF8}, + SpanContext: otel.SpanContext{ + TraceID: otel.TraceID{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F}, + SpanID: otel.SpanID{0xFF, 0xFE, 0xFD, 0xFC, 0xFB, 0xFA, 0xF9, 0xF8}, }, - ParentSpanID: trace.SpanID{0x3F, 0x3E, 0x3D, 0x3C, 0x3B, 0x3A, 0x39, 0x38}, - SpanKind: trace.SpanKindUnspecified, + ParentSpanID: otel.SpanID{0x3F, 0x3E, 0x3D, 0x3C, 0x3B, 0x3A, 0x39, 0x38}, + SpanKind: otel.SpanKindUnspecified, Name: "foo", StartTime: time.Date(2020, time.March, 11, 19, 24, 0, 0, time.UTC), EndTime: time.Date(2020, time.March, 11, 19, 25, 0, 0, time.UTC), @@ -132,12 +132,12 @@ func TestModelConversion(t *testing.T) { }, // span data of internal kind { - SpanContext: trace.SpanContext{ - TraceID: trace.ID{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F}, - SpanID: trace.SpanID{0xFF, 0xFE, 0xFD, 0xFC, 0xFB, 0xFA, 0xF9, 0xF8}, + SpanContext: otel.SpanContext{ + TraceID: otel.TraceID{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F}, + SpanID: otel.SpanID{0xFF, 0xFE, 0xFD, 0xFC, 0xFB, 0xFA, 0xF9, 0xF8}, }, - ParentSpanID: trace.SpanID{0x3F, 0x3E, 0x3D, 0x3C, 0x3B, 0x3A, 0x39, 0x38}, - SpanKind: trace.SpanKindInternal, + ParentSpanID: otel.SpanID{0x3F, 0x3E, 0x3D, 0x3C, 0x3B, 0x3A, 0x39, 0x38}, + SpanKind: otel.SpanKindInternal, Name: "foo", StartTime: time.Date(2020, time.March, 11, 19, 24, 0, 0, time.UTC), EndTime: time.Date(2020, time.March, 11, 19, 25, 0, 0, time.UTC), @@ -164,12 +164,12 @@ func TestModelConversion(t *testing.T) { }, // span data of client kind { - SpanContext: trace.SpanContext{ - TraceID: trace.ID{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F}, - SpanID: trace.SpanID{0xFF, 0xFE, 0xFD, 0xFC, 0xFB, 0xFA, 0xF9, 0xF8}, + SpanContext: otel.SpanContext{ + TraceID: otel.TraceID{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F}, + SpanID: otel.SpanID{0xFF, 0xFE, 0xFD, 0xFC, 0xFB, 0xFA, 0xF9, 0xF8}, }, - ParentSpanID: trace.SpanID{0x3F, 0x3E, 0x3D, 0x3C, 0x3B, 0x3A, 0x39, 0x38}, - SpanKind: trace.SpanKindClient, + ParentSpanID: otel.SpanID{0x3F, 0x3E, 0x3D, 0x3C, 0x3B, 0x3A, 0x39, 0x38}, + SpanKind: otel.SpanKindClient, Name: "foo", StartTime: time.Date(2020, time.March, 11, 19, 24, 0, 0, time.UTC), EndTime: time.Date(2020, time.March, 11, 19, 25, 0, 0, time.UTC), @@ -196,12 +196,12 @@ func TestModelConversion(t *testing.T) { }, // span data of producer kind { - SpanContext: trace.SpanContext{ - TraceID: trace.ID{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F}, - SpanID: trace.SpanID{0xFF, 0xFE, 0xFD, 0xFC, 0xFB, 0xFA, 0xF9, 0xF8}, + SpanContext: otel.SpanContext{ + TraceID: otel.TraceID{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F}, + SpanID: otel.SpanID{0xFF, 0xFE, 0xFD, 0xFC, 0xFB, 0xFA, 0xF9, 0xF8}, }, - ParentSpanID: trace.SpanID{0x3F, 0x3E, 0x3D, 0x3C, 0x3B, 0x3A, 0x39, 0x38}, - SpanKind: trace.SpanKindProducer, + ParentSpanID: otel.SpanID{0x3F, 0x3E, 0x3D, 0x3C, 0x3B, 0x3A, 0x39, 0x38}, + SpanKind: otel.SpanKindProducer, Name: "foo", StartTime: time.Date(2020, time.March, 11, 19, 24, 0, 0, time.UTC), EndTime: time.Date(2020, time.March, 11, 19, 25, 0, 0, time.UTC), @@ -228,12 +228,12 @@ func TestModelConversion(t *testing.T) { }, // span data of consumer kind { - SpanContext: trace.SpanContext{ - TraceID: trace.ID{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F}, - SpanID: trace.SpanID{0xFF, 0xFE, 0xFD, 0xFC, 0xFB, 0xFA, 0xF9, 0xF8}, + SpanContext: otel.SpanContext{ + TraceID: otel.TraceID{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F}, + SpanID: otel.SpanID{0xFF, 0xFE, 0xFD, 0xFC, 0xFB, 0xFA, 0xF9, 0xF8}, }, - ParentSpanID: trace.SpanID{0x3F, 0x3E, 0x3D, 0x3C, 0x3B, 0x3A, 0x39, 0x38}, - SpanKind: trace.SpanKindConsumer, + ParentSpanID: otel.SpanID{0x3F, 0x3E, 0x3D, 0x3C, 0x3B, 0x3A, 0x39, 0x38}, + SpanKind: otel.SpanKindConsumer, Name: "foo", StartTime: time.Date(2020, time.March, 11, 19, 24, 0, 0, time.UTC), EndTime: time.Date(2020, time.March, 11, 19, 25, 0, 0, time.UTC), @@ -260,12 +260,12 @@ func TestModelConversion(t *testing.T) { }, // span data with no events { - SpanContext: trace.SpanContext{ - TraceID: trace.ID{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F}, - SpanID: trace.SpanID{0xFF, 0xFE, 0xFD, 0xFC, 0xFB, 0xFA, 0xF9, 0xF8}, + SpanContext: otel.SpanContext{ + TraceID: otel.TraceID{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F}, + SpanID: otel.SpanID{0xFF, 0xFE, 0xFD, 0xFC, 0xFB, 0xFA, 0xF9, 0xF8}, }, - ParentSpanID: trace.SpanID{0x3F, 0x3E, 0x3D, 0x3C, 0x3B, 0x3A, 0x39, 0x38}, - SpanKind: trace.SpanKindServer, + ParentSpanID: otel.SpanID{0x3F, 0x3E, 0x3D, 0x3C, 0x3B, 0x3A, 0x39, 0x38}, + SpanKind: otel.SpanKindServer, Name: "foo", StartTime: time.Date(2020, time.March, 11, 19, 24, 0, 0, time.UTC), EndTime: time.Date(2020, time.March, 11, 19, 25, 0, 0, time.UTC), @@ -279,12 +279,12 @@ func TestModelConversion(t *testing.T) { }, // span data with an "error" attribute set to "false" { - SpanContext: trace.SpanContext{ - TraceID: trace.ID{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F}, - SpanID: trace.SpanID{0xFF, 0xFE, 0xFD, 0xFC, 0xFB, 0xFA, 0xF9, 0xF8}, + SpanContext: otel.SpanContext{ + TraceID: otel.TraceID{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F}, + SpanID: otel.SpanID{0xFF, 0xFE, 0xFD, 0xFC, 0xFB, 0xFA, 0xF9, 0xF8}, }, - ParentSpanID: trace.SpanID{0x3F, 0x3E, 0x3D, 0x3C, 0x3B, 0x3A, 0x39, 0x38}, - SpanKind: trace.SpanKindServer, + ParentSpanID: otel.SpanID{0x3F, 0x3E, 0x3D, 0x3C, 0x3B, 0x3A, 0x39, 0x38}, + SpanKind: otel.SpanKindServer, Name: "foo", StartTime: time.Date(2020, time.March, 11, 19, 24, 0, 0, time.UTC), EndTime: time.Date(2020, time.March, 11, 19, 25, 0, 0, time.UTC), diff --git a/exporters/trace/zipkin/zipkin_test.go b/exporters/trace/zipkin/zipkin_test.go index 7dbdd5dca7d..7725d9e5323 100644 --- a/exporters/trace/zipkin/zipkin_test.go +++ b/exporters/trace/zipkin/zipkin_test.go @@ -30,8 +30,8 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/api/global" - "go.opentelemetry.io/otel/api/trace" "go.opentelemetry.io/otel/codes" export "go.opentelemetry.io/otel/sdk/export/trace" sdktrace "go.opentelemetry.io/otel/sdk/trace" @@ -241,12 +241,12 @@ func TestExportSpans(t *testing.T) { spans := []*export.SpanData{ // parent { - SpanContext: trace.SpanContext{ - TraceID: trace.ID{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F}, - SpanID: trace.SpanID{0xFF, 0xFE, 0xFD, 0xFC, 0xFB, 0xFA, 0xF9, 0xF8}, + SpanContext: otel.SpanContext{ + TraceID: otel.TraceID{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F}, + SpanID: otel.SpanID{0xFF, 0xFE, 0xFD, 0xFC, 0xFB, 0xFA, 0xF9, 0xF8}, }, - ParentSpanID: trace.SpanID{}, - SpanKind: trace.SpanKindServer, + ParentSpanID: otel.SpanID{}, + SpanKind: otel.SpanKindServer, Name: "foo", StartTime: time.Date(2020, time.March, 11, 19, 24, 0, 0, time.UTC), EndTime: time.Date(2020, time.March, 11, 19, 25, 0, 0, time.UTC), @@ -257,12 +257,12 @@ func TestExportSpans(t *testing.T) { }, // child { - SpanContext: trace.SpanContext{ - TraceID: trace.ID{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F}, - SpanID: trace.SpanID{0xDF, 0xDE, 0xDD, 0xDC, 0xDB, 0xDA, 0xD9, 0xD8}, + SpanContext: otel.SpanContext{ + TraceID: otel.TraceID{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F}, + SpanID: otel.SpanID{0xDF, 0xDE, 0xDD, 0xDC, 0xDB, 0xDA, 0xD9, 0xD8}, }, - ParentSpanID: trace.SpanID{0xFF, 0xFE, 0xFD, 0xFC, 0xFB, 0xFA, 0xF9, 0xF8}, - SpanKind: trace.SpanKindServer, + ParentSpanID: otel.SpanID{0xFF, 0xFE, 0xFD, 0xFC, 0xFB, 0xFA, 0xF9, 0xF8}, + SpanKind: otel.SpanKindServer, Name: "bar", StartTime: time.Date(2020, time.March, 11, 19, 24, 15, 0, time.UTC), EndTime: time.Date(2020, time.March, 11, 19, 24, 45, 0, time.UTC), diff --git a/internal/trace/noop/noop.go b/internal/trace/noop/noop.go index c09a7376cbb..bfca48381a1 100644 --- a/internal/trace/noop/noop.go +++ b/internal/trace/noop/noop.go @@ -18,18 +18,18 @@ package noop import ( "context" - "go.opentelemetry.io/otel/api/trace" + "go.opentelemetry.io/otel" ) var ( // Tracer is a noop tracer that starts noop spans. - Tracer trace.Tracer + Tracer otel.Tracer // Span is a noop Span. - Span trace.Span + Span otel.Span ) func init() { - Tracer = trace.NoopTracerProvider().Tracer("") + Tracer = otel.NewNoopTracerProvider().Tracer("") _, Span = Tracer.Start(context.Background(), "") } diff --git a/internal/trace/parent/parent.go b/internal/trace/parent/parent.go index 88def335e97..991443e1a76 100644 --- a/internal/trace/parent/parent.go +++ b/internal/trace/parent/parent.go @@ -17,19 +17,19 @@ package parent import ( "context" - "go.opentelemetry.io/otel/api/trace" + "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/label" ) -func GetSpanContextAndLinks(ctx context.Context, ignoreContext bool) (trace.SpanContext, bool, []trace.Link) { - lsctx := trace.SpanFromContext(ctx).SpanContext() - rsctx := trace.RemoteSpanContextFromContext(ctx) +func GetSpanContextAndLinks(ctx context.Context, ignoreContext bool) (otel.SpanContext, bool, []otel.Link) { + lsctx := otel.SpanFromContext(ctx).SpanContext() + rsctx := otel.RemoteSpanContextFromContext(ctx) if ignoreContext { links := addLinkIfValid(nil, lsctx, "current") links = addLinkIfValid(links, rsctx, "remote") - return trace.EmptySpanContext(), false, links + return otel.SpanContext{}, false, links } if lsctx.IsValid() { return lsctx, false, nil @@ -37,14 +37,14 @@ func GetSpanContextAndLinks(ctx context.Context, ignoreContext bool) (trace.Span if rsctx.IsValid() { return rsctx, true, nil } - return trace.EmptySpanContext(), false, nil + return otel.SpanContext{}, false, nil } -func addLinkIfValid(links []trace.Link, sc trace.SpanContext, kind string) []trace.Link { +func addLinkIfValid(links []otel.Link, sc otel.SpanContext, kind string) []otel.Link { if !sc.IsValid() { return links } - return append(links, trace.Link{ + return append(links, otel.Link{ SpanContext: sc, Attributes: []label.KeyValue{ label.String("ignored-on-demand", kind), diff --git a/otel.go b/otel.go index aaabac2dc22..c38086b140b 100644 --- a/otel.go +++ b/otel.go @@ -16,11 +16,8 @@ package otel import ( "go.opentelemetry.io/otel/api/metric" - "go.opentelemetry.io/otel/api/trace" ) -type Tracer = trace.Tracer - type Meter = metric.Meter // ErrorHandler handles irremediable events. diff --git a/api/trace/tracetest/config.go b/oteltest/config.go similarity index 83% rename from api/trace/tracetest/config.go rename to oteltest/config.go index caa79e89775..3c842ea881a 100644 --- a/api/trace/tracetest/config.go +++ b/oteltest/config.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package tracetest +package oteltest import ( "context" @@ -20,17 +20,17 @@ import ( "sync" "sync/atomic" - "go.opentelemetry.io/otel/api/trace" + "go.opentelemetry.io/otel" ) // defaultSpanContextFunc returns the default SpanContextFunc. -func defaultSpanContextFunc() func(context.Context) trace.SpanContext { +func defaultSpanContextFunc() func(context.Context) otel.SpanContext { var traceID, spanID uint64 = 1, 1 - return func(ctx context.Context) trace.SpanContext { - var sc trace.SpanContext - if lsc := trace.SpanFromContext(ctx).SpanContext(); lsc.IsValid() { + return func(ctx context.Context) otel.SpanContext { + var sc otel.SpanContext + if lsc := otel.SpanFromContext(ctx).SpanContext(); lsc.IsValid() { sc = lsc - } else if rsc := trace.RemoteSpanContextFromContext(ctx); rsc.IsValid() { + } else if rsc := otel.RemoteSpanContextFromContext(ctx); rsc.IsValid() { sc = rsc } else { binary.BigEndian.PutUint64(sc.TraceID[:], atomic.AddUint64(&traceID, 1)) @@ -43,7 +43,7 @@ func defaultSpanContextFunc() func(context.Context) trace.SpanContext { type config struct { // SpanContextFunc returns a SpanContext from an parent Context for a // new span. - SpanContextFunc func(context.Context) trace.SpanContext + SpanContextFunc func(context.Context) otel.SpanContext // SpanRecorder keeps track of spans. SpanRecorder SpanRecorder @@ -65,14 +65,14 @@ type Option interface { } type spanContextFuncOption struct { - SpanContextFunc func(context.Context) trace.SpanContext + SpanContextFunc func(context.Context) otel.SpanContext } func (o spanContextFuncOption) Apply(c *config) { c.SpanContextFunc = o.SpanContextFunc } -func WithSpanContextFunc(f func(context.Context) trace.SpanContext) Option { +func WithSpanContextFunc(f func(context.Context) otel.SpanContext) Option { return spanContextFuncOption{f} } diff --git a/api/trace/tracetest/doc.go b/oteltest/doc.go similarity index 81% rename from api/trace/tracetest/doc.go rename to oteltest/doc.go index 7bc9078a0bf..ca2f1495df1 100644 --- a/api/trace/tracetest/doc.go +++ b/oteltest/doc.go @@ -12,4 +12,5 @@ // See the License for the specific language governing permissions and // limitations under the License. -package tracetest // import "go.opentelemetry.io/otel/api/trace/tracetest" +// Package oteltest provides testing utilities for the otel package. +package oteltest // import "go.opentelemetry.io/otel/oteltest" diff --git a/api/trace/tracetest/event.go b/oteltest/event.go similarity index 97% rename from api/trace/tracetest/event.go rename to oteltest/event.go index e62b8c8cbbf..175ccb510ed 100644 --- a/api/trace/tracetest/event.go +++ b/oteltest/event.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package tracetest +package oteltest import ( "time" diff --git a/api/trace/tracetest/mock_span.go b/oteltest/mock_span.go similarity index 83% rename from api/trace/tracetest/mock_span.go rename to oteltest/mock_span.go index e6de86023a3..067ced43edf 100644 --- a/api/trace/tracetest/mock_span.go +++ b/oteltest/mock_span.go @@ -12,13 +12,13 @@ // See the License for the specific language governing permissions and // limitations under the License. -package tracetest +package oteltest import ( "context" "time" - apitrace "go.opentelemetry.io/otel/api/trace" + "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/codes" "go.opentelemetry.io/otel/label" ) @@ -28,17 +28,17 @@ type MockSpan struct { StatusMsg string Name string Status codes.Code - sc apitrace.SpanContext - tracer apitrace.Tracer + sc otel.SpanContext + tracer otel.Tracer } -var _ apitrace.Span = (*MockSpan)(nil) +var _ otel.Span = (*MockSpan)(nil) // SpanContext returns associated label.SpanContext. If the receiver is nil it returns // an empty label.SpanContext -func (ms *MockSpan) SpanContext() apitrace.SpanContext { +func (ms *MockSpan) SpanContext() otel.SpanContext { if ms == nil { - return apitrace.EmptySpanContext() + return otel.SpanContext{} } return ms.sc } @@ -63,11 +63,11 @@ func (ms *MockSpan) SetAttributes(attributes ...label.KeyValue) { } // End does nothing. -func (ms *MockSpan) End(options ...apitrace.SpanOption) { +func (ms *MockSpan) End(options ...otel.SpanOption) { } // RecordError does nothing. -func (ms *MockSpan) RecordError(ctx context.Context, err error, opts ...apitrace.ErrorOption) { +func (ms *MockSpan) RecordError(ctx context.Context, err error, opts ...otel.ErrorOption) { } // SetName sets the span name. @@ -76,7 +76,7 @@ func (ms *MockSpan) SetName(name string) { } // Tracer returns MockTracer implementation of Tracer. -func (ms *MockSpan) Tracer() apitrace.Tracer { +func (ms *MockSpan) Tracer() otel.Tracer { return ms.tracer } diff --git a/api/trace/tracetest/mock_tracer.go b/oteltest/mock_tracer.go similarity index 84% rename from api/trace/tracetest/mock_tracer.go rename to oteltest/mock_tracer.go index 2d3335e1465..fa200801771 100644 --- a/api/trace/tracetest/mock_tracer.go +++ b/oteltest/mock_tracer.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package tracetest +package oteltest import ( "context" @@ -20,8 +20,7 @@ import ( "encoding/binary" "sync/atomic" - "go.opentelemetry.io/otel/api/trace" - apitrace "go.opentelemetry.io/otel/api/trace" + "go.opentelemetry.io/otel" otelparent "go.opentelemetry.io/otel/internal/trace/parent" ) @@ -42,25 +41,25 @@ type MockTracer struct { OnSpanStarted func(span *MockSpan) } -var _ apitrace.Tracer = (*MockTracer)(nil) +var _ otel.Tracer = (*MockTracer)(nil) // Start starts a MockSpan. It creates a new Span based on Parent SpanContext option. // TraceID is used from Parent Span Context and SpanID is assigned. // If Parent SpanContext option is not specified then random TraceID is used. // No other options are supported. -func (mt *MockTracer) Start(ctx context.Context, name string, o ...apitrace.SpanOption) (context.Context, apitrace.Span) { - config := trace.NewSpanConfig(o...) +func (mt *MockTracer) Start(ctx context.Context, name string, o ...otel.SpanOption) (context.Context, otel.Span) { + config := otel.NewSpanConfig(o...) var span *MockSpan - var sc apitrace.SpanContext + var sc otel.SpanContext parentSpanContext, _, _ := otelparent.GetSpanContextAndLinks(ctx, config.NewRoot) if !parentSpanContext.IsValid() { - sc = apitrace.SpanContext{} + sc = otel.SpanContext{} _, _ = rand.Read(sc.TraceID[:]) if mt.Sampled { - sc.TraceFlags = apitrace.FlagsSampled + sc.TraceFlags = otel.FlagsSampled } } else { sc = parentSpanContext @@ -76,5 +75,5 @@ func (mt *MockTracer) Start(ctx context.Context, name string, o ...apitrace.Span mt.OnSpanStarted(span) } - return apitrace.ContextWithSpan(ctx, span), span + return otel.ContextWithSpan(ctx, span), span } diff --git a/api/trace/tracetest/mock_tracer_test.go b/oteltest/mock_tracer_test.go similarity index 87% rename from api/trace/tracetest/mock_tracer_test.go rename to oteltest/mock_tracer_test.go index d061950409d..4bc7c0f08c0 100644 --- a/api/trace/tracetest/mock_tracer_test.go +++ b/oteltest/mock_tracer_test.go @@ -12,15 +12,15 @@ // See the License for the specific language governing permissions and // limitations under the License. -package tracetest_test +package oteltest_test import ( "os" "testing" "unsafe" - "go.opentelemetry.io/otel/api/trace/tracetest" ottest "go.opentelemetry.io/otel/internal/testing" + "go.opentelemetry.io/otel/oteltest" ) // Ensure struct alignment prior to running tests. @@ -28,7 +28,7 @@ func TestMain(m *testing.M) { fields := []ottest.FieldOffset{ { Name: "MockTracer.StartSpanID", - Offset: unsafe.Offsetof(tracetest.MockTracer{}.StartSpanID), + Offset: unsafe.Offsetof(oteltest.MockTracer{}.StartSpanID), }, } if !ottest.Aligned8Byte(fields, os.Stderr) { diff --git a/api/trace/tracetest/provider.go b/oteltest/provider.go similarity index 84% rename from api/trace/tracetest/provider.go rename to oteltest/provider.go index 511e80b0e7b..d30cf860b6d 100644 --- a/api/trace/tracetest/provider.go +++ b/oteltest/provider.go @@ -12,12 +12,12 @@ // See the License for the specific language governing permissions and // limitations under the License. -package tracetest +package oteltest import ( "sync" - "go.opentelemetry.io/otel/api/trace" + "go.opentelemetry.io/otel" ) type TracerProvider struct { @@ -27,7 +27,7 @@ type TracerProvider struct { tracers map[instrumentation]*Tracer } -var _ trace.TracerProvider = (*TracerProvider)(nil) +var _ otel.TracerProvider = (*TracerProvider)(nil) func NewTracerProvider(opts ...Option) *TracerProvider { return &TracerProvider{ @@ -40,8 +40,8 @@ type instrumentation struct { Name, Version string } -func (p *TracerProvider) Tracer(instName string, opts ...trace.TracerOption) trace.Tracer { - conf := trace.NewTracerConfig(opts...) +func (p *TracerProvider) Tracer(instName string, opts ...otel.TracerOption) otel.Tracer { + conf := otel.NewTracerConfig(opts...) inst := instrumentation{ Name: instName, diff --git a/api/trace/tracetest/span.go b/oteltest/span.go similarity index 88% rename from api/trace/tracetest/span.go rename to oteltest/span.go index 521695665f9..847460f43a9 100644 --- a/api/trace/tracetest/span.go +++ b/oteltest/span.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package tracetest +package oteltest import ( "context" @@ -21,7 +21,7 @@ import ( "sync" "time" - "go.opentelemetry.io/otel/api/trace" + "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/codes" "go.opentelemetry.io/otel/label" ) @@ -32,13 +32,13 @@ const ( errorEventName = "error" ) -var _ trace.Span = (*Span)(nil) +var _ otel.Span = (*Span)(nil) type Span struct { lock sync.RWMutex tracer *Tracer - spanContext trace.SpanContext - parentSpanID trace.SpanID + spanContext otel.SpanContext + parentSpanID otel.SpanID ended bool name string startTime time.Time @@ -47,15 +47,15 @@ type Span struct { statusMessage string attributes map[label.Key]label.Value events []Event - links map[trace.SpanContext][]label.KeyValue - spanKind trace.SpanKind + links map[otel.SpanContext][]label.KeyValue + spanKind otel.SpanKind } -func (s *Span) Tracer() trace.Tracer { +func (s *Span) Tracer() otel.Tracer { return s.tracer } -func (s *Span) End(opts ...trace.SpanOption) { +func (s *Span) End(opts ...otel.SpanOption) { s.lock.Lock() defer s.lock.Unlock() @@ -63,7 +63,7 @@ func (s *Span) End(opts ...trace.SpanOption) { return } - c := trace.NewSpanConfig(opts...) + c := otel.NewSpanConfig(opts...) s.endTime = time.Now() if endTime := c.Timestamp; !endTime.IsZero() { s.endTime = endTime @@ -75,15 +75,12 @@ func (s *Span) End(opts ...trace.SpanOption) { } } -func (s *Span) RecordError(ctx context.Context, err error, opts ...trace.ErrorOption) { +func (s *Span) RecordError(ctx context.Context, err error, opts ...otel.ErrorOption) { if err == nil || s.ended { return } - cfg := trace.ErrorConfig{} - for _, o := range opts { - o(&cfg) - } + cfg := otel.NewErrorConfig(opts...) if cfg.Timestamp.IsZero() { cfg.Timestamp = time.Now() @@ -134,7 +131,7 @@ func (s *Span) IsRecording() bool { return true } -func (s *Span) SpanContext() trace.SpanContext { +func (s *Span) SpanContext() otel.SpanContext { return s.spanContext } @@ -183,7 +180,7 @@ func (s *Span) Name() string { // ParentSpanID returns the SpanID of the parent Span. // If the Span is a root Span and therefore does not have a parent, the returned SpanID will be invalid // (i.e., it will contain all zeroes). -func (s *Span) ParentSpanID() trace.SpanID { +func (s *Span) ParentSpanID() otel.SpanID { return s.parentSpanID } @@ -211,8 +208,8 @@ func (s *Span) Events() []Event { // Links returns the links set on the Span at creation time. // If multiple links for the same SpanContext were set, the last link will be used. -func (s *Span) Links() map[trace.SpanContext][]label.KeyValue { - links := make(map[trace.SpanContext][]label.KeyValue) +func (s *Span) Links() map[otel.SpanContext][]label.KeyValue { + links := make(map[otel.SpanContext][]label.KeyValue) for sc, attributes := range s.links { links[sc] = append([]label.KeyValue{}, attributes...) @@ -255,6 +252,6 @@ func (s *Span) StatusMessage() string { } // SpanKind returns the span kind of this span. -func (s *Span) SpanKind() trace.SpanKind { +func (s *Span) SpanKind() otel.SpanKind { return s.spanKind } diff --git a/api/trace/tracetest/span_test.go b/oteltest/span_test.go similarity index 88% rename from api/trace/tracetest/span_test.go rename to oteltest/span_test.go index 49325850485..2b71dabbf6f 100644 --- a/api/trace/tracetest/span_test.go +++ b/oteltest/span_test.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package tracetest_test +package oteltest_test import ( "context" @@ -22,17 +22,17 @@ import ( "testing" "time" - "go.opentelemetry.io/otel/api/trace" - "go.opentelemetry.io/otel/api/trace/tracetest" + "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/codes" "go.opentelemetry.io/otel/internal/matchers" ottest "go.opentelemetry.io/otel/internal/testing" "go.opentelemetry.io/otel/label" + "go.opentelemetry.io/otel/oteltest" ) func TestSpan(t *testing.T) { t.Run("#Tracer", func(t *testing.T) { - tp := tracetest.NewTracerProvider() + tp := oteltest.NewTracerProvider() t.Run("returns the tracer used to start the span", func(t *testing.T) { t.Parallel() @@ -46,7 +46,7 @@ func TestSpan(t *testing.T) { }) t.Run("#End", func(t *testing.T) { - tp := tracetest.NewTracerProvider() + tp := oteltest.NewTracerProvider() t.Run("ends the span", func(t *testing.T) { t.Parallel() @@ -55,7 +55,7 @@ func TestSpan(t *testing.T) { tracer := tp.Tracer(t.Name()) _, span := tracer.Start(context.Background(), "test") - subject, ok := span.(*tracetest.Span) + subject, ok := span.(*oteltest.Span) e.Expect(ok).ToBeTrue() e.Expect(subject.Ended()).ToBeFalse() @@ -86,7 +86,7 @@ func TestSpan(t *testing.T) { tracer := tp.Tracer(t.Name()) _, span := tracer.Start(context.Background(), "test") - subject, ok := span.(*tracetest.Span) + subject, ok := span.(*oteltest.Span) e.Expect(ok).ToBeTrue() subject.End() @@ -109,11 +109,11 @@ func TestSpan(t *testing.T) { tracer := tp.Tracer(t.Name()) _, span := tracer.Start(context.Background(), "test") - subject, ok := span.(*tracetest.Span) + subject, ok := span.(*oteltest.Span) e.Expect(ok).ToBeTrue() expectedEndTime := time.Now().AddDate(5, 0, 0) - subject.End(trace.WithTimestamp(expectedEndTime)) + subject.End(otel.WithTimestamp(expectedEndTime)) e.Expect(subject.Ended()).ToBeTrue() @@ -125,7 +125,7 @@ func TestSpan(t *testing.T) { }) t.Run("#RecordError", func(t *testing.T) { - tp := tracetest.NewTracerProvider() + tp := oteltest.NewTracerProvider() t.Run("records an error", func(t *testing.T) { t.Parallel() @@ -152,13 +152,13 @@ func TestSpan(t *testing.T) { tracer := tp.Tracer(t.Name()) ctx, span := tracer.Start(context.Background(), "test") - subject, ok := span.(*tracetest.Span) + subject, ok := span.(*oteltest.Span) e.Expect(ok).ToBeTrue() testTime := time.Now() - subject.RecordError(ctx, s.err, trace.WithErrorTime(testTime)) + subject.RecordError(ctx, s.err, otel.WithErrorTime(testTime)) - expectedEvents := []tracetest.Event{{ + expectedEvents := []oteltest.Event{{ Timestamp: testTime, Name: "error", Attributes: map[label.Key]label.Value{ @@ -180,16 +180,16 @@ func TestSpan(t *testing.T) { tracer := tp.Tracer(t.Name()) ctx, span := tracer.Start(context.Background(), "test") - subject, ok := span.(*tracetest.Span) + subject, ok := span.(*oteltest.Span) e.Expect(ok).ToBeTrue() errMsg := "test error message" testErr := ottest.NewTestError(errMsg) testTime := time.Now() expStatusCode := codes.Error - subject.RecordError(ctx, testErr, trace.WithErrorTime(testTime), trace.WithErrorStatus(expStatusCode)) + subject.RecordError(ctx, testErr, otel.WithErrorTime(testTime), otel.WithErrorStatus(expStatusCode)) - expectedEvents := []tracetest.Event{{ + expectedEvents := []oteltest.Event{{ Timestamp: testTime, Name: "error", Attributes: map[label.Key]label.Value{ @@ -209,7 +209,7 @@ func TestSpan(t *testing.T) { tracer := tp.Tracer(t.Name()) ctx, span := tracer.Start(context.Background(), "test") - subject, ok := span.(*tracetest.Span) + subject, ok := span.(*oteltest.Span) e.Expect(ok).ToBeTrue() subject.End() @@ -226,7 +226,7 @@ func TestSpan(t *testing.T) { tracer := tp.Tracer(t.Name()) ctx, span := tracer.Start(context.Background(), "test") - subject, ok := span.(*tracetest.Span) + subject, ok := span.(*oteltest.Span) e.Expect(ok).ToBeTrue() subject.RecordError(ctx, nil) @@ -236,7 +236,7 @@ func TestSpan(t *testing.T) { }) t.Run("#IsRecording", func(t *testing.T) { - tp := tracetest.NewTracerProvider() + tp := oteltest.NewTracerProvider() t.Run("returns true", func(t *testing.T) { t.Parallel() @@ -250,7 +250,7 @@ func TestSpan(t *testing.T) { }) t.Run("#SpanContext", func(t *testing.T) { - tp := tracetest.NewTracerProvider() + tp := oteltest.NewTracerProvider() t.Run("returns a valid SpanContext", func(t *testing.T) { t.Parallel() @@ -275,7 +275,7 @@ func TestSpan(t *testing.T) { }) t.Run("#Name", func(t *testing.T) { - tp := tracetest.NewTracerProvider() + tp := oteltest.NewTracerProvider() t.Run("returns the most recently set name on the span", func(t *testing.T) { t.Parallel() @@ -285,7 +285,7 @@ func TestSpan(t *testing.T) { originalName := "test" _, span := tracer.Start(context.Background(), originalName) - subject, ok := span.(*tracetest.Span) + subject, ok := span.(*oteltest.Span) e.Expect(ok).ToBeTrue() e.Expect(subject.Name()).ToEqual(originalName) @@ -308,7 +308,7 @@ func TestSpan(t *testing.T) { originalName := "test" _, span := tracer.Start(context.Background(), originalName) - subject, ok := span.(*tracetest.Span) + subject, ok := span.(*oteltest.Span) e.Expect(ok).ToBeTrue() subject.End() @@ -319,7 +319,7 @@ func TestSpan(t *testing.T) { }) t.Run("#Attributes", func(t *testing.T) { - tp := tracetest.NewTracerProvider() + tp := oteltest.NewTracerProvider() t.Run("returns an empty map by default", func(t *testing.T) { t.Parallel() @@ -328,7 +328,7 @@ func TestSpan(t *testing.T) { tracer := tp.Tracer(t.Name()) _, span := tracer.Start(context.Background(), "test") - subject, ok := span.(*tracetest.Span) + subject, ok := span.(*oteltest.Span) e.Expect(ok).ToBeTrue() e.Expect(subject.Attributes()).ToEqual(map[label.Key]label.Value{}) @@ -342,7 +342,7 @@ func TestSpan(t *testing.T) { tracer := tp.Tracer(t.Name()) _, span := tracer.Start(context.Background(), "test") - subject, ok := span.(*tracetest.Span) + subject, ok := span.(*oteltest.Span) e.Expect(ok).ToBeTrue() attr1 := label.String("key1", "value1") @@ -368,7 +368,7 @@ func TestSpan(t *testing.T) { tracer := tp.Tracer(t.Name()) _, span := tracer.Start(context.Background(), "test") - subject, ok := span.(*tracetest.Span) + subject, ok := span.(*oteltest.Span) e.Expect(ok).ToBeTrue() expectedAttr := label.String("key", "value") @@ -391,7 +391,7 @@ func TestSpan(t *testing.T) { tracer := tp.Tracer(t.Name()) _, span := tracer.Start(context.Background(), "test") - subject, ok := span.(*tracetest.Span) + subject, ok := span.(*oteltest.Span) e.Expect(ok).ToBeTrue() var wg sync.WaitGroup @@ -415,7 +415,7 @@ func TestSpan(t *testing.T) { }) t.Run("#Links", func(t *testing.T) { - tp := tracetest.NewTracerProvider() + tp := oteltest.NewTracerProvider() t.Run("returns an empty map by default", func(t *testing.T) { t.Parallel() @@ -424,7 +424,7 @@ func TestSpan(t *testing.T) { tracer := tp.Tracer(t.Name()) _, span := tracer.Start(context.Background(), "test") - subject, ok := span.(*tracetest.Span) + subject, ok := span.(*oteltest.Span) e.Expect(ok).ToBeTrue() e.Expect(len(subject.Links())).ToEqual(0) @@ -432,7 +432,7 @@ func TestSpan(t *testing.T) { }) t.Run("#Events", func(t *testing.T) { - tp := tracetest.NewTracerProvider() + tp := oteltest.NewTracerProvider() t.Run("returns an empty slice by default", func(t *testing.T) { t.Parallel() @@ -441,7 +441,7 @@ func TestSpan(t *testing.T) { tracer := tp.Tracer(t.Name()) _, span := tracer.Start(context.Background(), "test") - subject, ok := span.(*tracetest.Span) + subject, ok := span.(*oteltest.Span) e.Expect(ok).ToBeTrue() e.Expect(len(subject.Events())).ToEqual(0) @@ -455,7 +455,7 @@ func TestSpan(t *testing.T) { tracer := tp.Tracer(t.Name()) _, span := tracer.Start(context.Background(), "test") - subject, ok := span.(*tracetest.Span) + subject, ok := span.(*oteltest.Span) e.Expect(ok).ToBeTrue() event1Name := "event1" @@ -508,7 +508,7 @@ func TestSpan(t *testing.T) { tracer := tp.Tracer(t.Name()) _, span := tracer.Start(context.Background(), "test") - subject, ok := span.(*tracetest.Span) + subject, ok := span.(*oteltest.Span) e.Expect(ok).ToBeTrue() subject.AddEvent(context.Background(), "test") @@ -526,7 +526,7 @@ func TestSpan(t *testing.T) { }) t.Run("#Status", func(t *testing.T) { - tp := tracetest.NewTracerProvider() + tp := oteltest.NewTracerProvider() t.Run("defaults to OK", func(t *testing.T) { t.Parallel() @@ -535,7 +535,7 @@ func TestSpan(t *testing.T) { tracer := tp.Tracer(t.Name()) _, span := tracer.Start(context.Background(), "test") - subject, ok := span.(*tracetest.Span) + subject, ok := span.(*oteltest.Span) e.Expect(ok).ToBeTrue() e.Expect(subject.StatusCode()).ToEqual(codes.Unset) @@ -560,7 +560,7 @@ func TestSpan(t *testing.T) { tracer := tp.Tracer(t.Name()) _, span := tracer.Start(context.Background(), "test") - subject, ok := span.(*tracetest.Span) + subject, ok := span.(*oteltest.Span) e.Expect(ok).ToBeTrue() subject.SetStatus(codes.Ok, "Ok") @@ -578,7 +578,7 @@ func TestSpan(t *testing.T) { tracer := tp.Tracer(t.Name()) _, span := tracer.Start(context.Background(), "test") - subject, ok := span.(*tracetest.Span) + subject, ok := span.(*oteltest.Span) e.Expect(ok).ToBeTrue() originalStatus := codes.Ok @@ -594,7 +594,7 @@ func TestSpan(t *testing.T) { }) t.Run("#SpanKind", func(t *testing.T) { - tp := tracetest.NewTracerProvider() + tp := oteltest.NewTracerProvider() t.Run("returns the value given at start", func(t *testing.T) { t.Parallel() @@ -602,13 +602,13 @@ func TestSpan(t *testing.T) { tracer := tp.Tracer(t.Name()) _, span := tracer.Start(context.Background(), "test", - trace.WithSpanKind(trace.SpanKindConsumer)) + otel.WithSpanKind(otel.SpanKindConsumer)) - subject, ok := span.(*tracetest.Span) + subject, ok := span.(*oteltest.Span) e.Expect(ok).ToBeTrue() subject.End() - e.Expect(subject.SpanKind()).ToEqual(trace.SpanKindConsumer) + e.Expect(subject.SpanKind()).ToEqual(otel.SpanKindConsumer) }) }) } diff --git a/api/trace/tracetest/tracer.go b/oteltest/tracer.go similarity index 72% rename from api/trace/tracetest/tracer.go rename to oteltest/tracer.go index 23ec9235a61..068b65f07fb 100644 --- a/api/trace/tracetest/tracer.go +++ b/oteltest/tracer.go @@ -12,18 +12,17 @@ // See the License for the specific language governing permissions and // limitations under the License. -// Package tracetest provides testing utilities for tracing. -package tracetest +package oteltest import ( "context" "time" - "go.opentelemetry.io/otel/api/trace" + "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/label" ) -var _ trace.Tracer = (*Tracer)(nil) +var _ otel.Tracer = (*Tracer)(nil) // Tracer is an OpenTelemetry Tracer implementation used for testing. type Tracer struct { @@ -35,8 +34,8 @@ type Tracer struct { config *config } -func (t *Tracer) Start(ctx context.Context, name string, opts ...trace.SpanOption) (context.Context, trace.Span) { - c := trace.NewSpanConfig(opts...) +func (t *Tracer) Start(ctx context.Context, name string, opts ...otel.SpanOption) (context.Context, otel.Span) { + c := otel.NewSpanConfig(opts...) startTime := time.Now() if st := c.Timestamp; !st.IsZero() { startTime = st @@ -46,26 +45,26 @@ func (t *Tracer) Start(ctx context.Context, name string, opts ...trace.SpanOptio tracer: t, startTime: startTime, attributes: make(map[label.Key]label.Value), - links: make(map[trace.SpanContext][]label.KeyValue), + links: make(map[otel.SpanContext][]label.KeyValue), spanKind: c.SpanKind, } if c.NewRoot { - span.spanContext = trace.EmptySpanContext() + span.spanContext = otel.SpanContext{} iodKey := label.Key("ignored-on-demand") - if lsc := trace.SpanFromContext(ctx).SpanContext(); lsc.IsValid() { + if lsc := otel.SpanFromContext(ctx).SpanContext(); lsc.IsValid() { span.links[lsc] = []label.KeyValue{iodKey.String("current")} } - if rsc := trace.RemoteSpanContextFromContext(ctx); rsc.IsValid() { + if rsc := otel.RemoteSpanContextFromContext(ctx); rsc.IsValid() { span.links[rsc] = []label.KeyValue{iodKey.String("remote")} } } else { span.spanContext = t.config.SpanContextFunc(ctx) - if lsc := trace.SpanFromContext(ctx).SpanContext(); lsc.IsValid() { + if lsc := otel.SpanFromContext(ctx).SpanContext(); lsc.IsValid() { span.spanContext.TraceID = lsc.TraceID span.parentSpanID = lsc.SpanID - } else if rsc := trace.RemoteSpanContextFromContext(ctx); rsc.IsValid() { + } else if rsc := otel.RemoteSpanContextFromContext(ctx); rsc.IsValid() { span.spanContext.TraceID = rsc.TraceID span.parentSpanID = rsc.SpanID } @@ -81,5 +80,5 @@ func (t *Tracer) Start(ctx context.Context, name string, opts ...trace.SpanOptio if t.config.SpanRecorder != nil { t.config.SpanRecorder.OnStart(span) } - return trace.ContextWithSpan(ctx, span), span + return otel.ContextWithSpan(ctx, span), span } diff --git a/api/trace/tracetest/tracer_test.go b/oteltest/tracer_test.go similarity index 81% rename from api/trace/tracetest/tracer_test.go rename to oteltest/tracer_test.go index fffab3bee18..713bea6537c 100644 --- a/api/trace/tracetest/tracer_test.go +++ b/oteltest/tracer_test.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package tracetest_test +package oteltest_test import ( "context" @@ -22,26 +22,26 @@ import ( "testing" "time" + "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/api/apitest" - "go.opentelemetry.io/otel/api/trace" - "go.opentelemetry.io/otel/api/trace/tracetest" "go.opentelemetry.io/otel/internal/matchers" "go.opentelemetry.io/otel/label" + "go.opentelemetry.io/otel/oteltest" ) func TestTracer(t *testing.T) { - tp := tracetest.NewTracerProvider() + tp := oteltest.NewTracerProvider() - apitest.NewHarness(t).TestTracer(func() func() trace.Tracer { - tp := tracetest.NewTracerProvider() + apitest.NewHarness(t).TestTracer(func() func() otel.Tracer { + tp := oteltest.NewTracerProvider() var i uint64 - return func() trace.Tracer { + return func() otel.Tracer { return tp.Tracer(fmt.Sprintf("tracer %d", atomic.AddUint64(&i, 1))) } }()) t.Run("#Start", func(t *testing.T) { - testTracedSpan(t, func(tracer trace.Tracer, name string) (trace.Span, error) { + testTracedSpan(t, func(tracer otel.Tracer, name string) (otel.Span, error) { _, span := tracer.Start(context.Background(), name) return span, nil @@ -55,9 +55,9 @@ func TestTracer(t *testing.T) { expectedStartTime := time.Now().AddDate(5, 0, 0) subject := tp.Tracer(t.Name()) - _, span := subject.Start(context.Background(), "test", trace.WithTimestamp(expectedStartTime)) + _, span := subject.Start(context.Background(), "test", otel.WithTimestamp(expectedStartTime)) - testSpan, ok := span.(*tracetest.Span) + testSpan, ok := span.(*oteltest.Span) e.Expect(ok).ToBeTrue() e.Expect(testSpan.StartTime()).ToEqual(expectedStartTime) @@ -72,9 +72,9 @@ func TestTracer(t *testing.T) { attr2 := label.String("b", "2") subject := tp.Tracer(t.Name()) - _, span := subject.Start(context.Background(), "test", trace.WithAttributes(attr1, attr2)) + _, span := subject.Start(context.Background(), "test", otel.WithAttributes(attr1, attr2)) - testSpan, ok := span.(*tracetest.Span) + testSpan, ok := span.(*oteltest.Span) e.Expect(ok).ToBeTrue() attributes := testSpan.Attributes() @@ -94,7 +94,7 @@ func TestTracer(t *testing.T) { _, span := subject.Start(parent, "child") - testSpan, ok := span.(*tracetest.Span) + testSpan, ok := span.(*oteltest.Span) e.Expect(ok).ToBeTrue() childSpanContext := testSpan.SpanContext() @@ -112,12 +112,12 @@ func TestTracer(t *testing.T) { parent, parentSpan := subject.Start(context.Background(), "parent") _, remoteParentSpan := subject.Start(context.Background(), "remote not-a-parent") - parent = trace.ContextWithRemoteSpanContext(parent, remoteParentSpan.SpanContext()) + parent = otel.ContextWithRemoteSpanContext(parent, remoteParentSpan.SpanContext()) parentSpanContext := parentSpan.SpanContext() _, span := subject.Start(parent, "child") - testSpan, ok := span.(*tracetest.Span) + testSpan, ok := span.(*oteltest.Span) e.Expect(ok).ToBeTrue() childSpanContext := testSpan.SpanContext() @@ -134,12 +134,12 @@ func TestTracer(t *testing.T) { subject := tp.Tracer(t.Name()) _, remoteParentSpan := subject.Start(context.Background(), "remote parent") - parent := trace.ContextWithRemoteSpanContext(context.Background(), remoteParentSpan.SpanContext()) + parent := otel.ContextWithRemoteSpanContext(context.Background(), remoteParentSpan.SpanContext()) remoteParentSpanContext := remoteParentSpan.SpanContext() _, span := subject.Start(parent, "child") - testSpan, ok := span.(*tracetest.Span) + testSpan, ok := span.(*oteltest.Span) e.Expect(ok).ToBeTrue() childSpanContext := testSpan.SpanContext() @@ -162,7 +162,7 @@ func TestTracer(t *testing.T) { _, span := subject.Start(context.Background(), "child") - testSpan, ok := span.(*tracetest.Span) + testSpan, ok := span.(*oteltest.Span) e.Expect(ok).ToBeTrue() childSpanContext := testSpan.SpanContext() @@ -184,11 +184,11 @@ func TestTracer(t *testing.T) { _, remoteParentSpan := subject.Start(context.Background(), "remote not-a-parent") parentSpanContext := parentSpan.SpanContext() remoteParentSpanContext := remoteParentSpan.SpanContext() - parentCtx = trace.ContextWithRemoteSpanContext(parentCtx, remoteParentSpanContext) + parentCtx = otel.ContextWithRemoteSpanContext(parentCtx, remoteParentSpanContext) - _, span := subject.Start(parentCtx, "child", trace.WithNewRoot()) + _, span := subject.Start(parentCtx, "child", otel.WithNewRoot()) - testSpan, ok := span.(*tracetest.Span) + testSpan, ok := span.(*oteltest.Span) e.Expect(ok).ToBeTrue() childSpanContext := testSpan.SpanContext() @@ -198,7 +198,7 @@ func TestTracer(t *testing.T) { e.Expect(childSpanContext.SpanID).NotToEqual(remoteParentSpanContext.SpanID) e.Expect(testSpan.ParentSpanID().IsValid()).ToBeFalse() - expectedLinks := []trace.Link{ + expectedLinks := []otel.Link{ { SpanContext: parentSpanContext, Attributes: []label.KeyValue{ @@ -213,9 +213,9 @@ func TestTracer(t *testing.T) { }, } tsLinks := testSpan.Links() - gotLinks := make([]trace.Link, 0, len(tsLinks)) + gotLinks := make([]otel.Link, 0, len(tsLinks)) for sc, attributes := range tsLinks { - gotLinks = append(gotLinks, trace.Link{ + gotLinks = append(gotLinks, otel.Link{ SpanContext: sc, Attributes: attributes, }) @@ -231,7 +231,7 @@ func TestTracer(t *testing.T) { subject := tp.Tracer(t.Name()) _, span := subject.Start(context.Background(), "link1") - link1 := trace.Link{ + link1 := otel.Link{ SpanContext: span.SpanContext(), Attributes: []label.KeyValue{ label.String("a", "1"), @@ -239,16 +239,16 @@ func TestTracer(t *testing.T) { } _, span = subject.Start(context.Background(), "link2") - link2 := trace.Link{ + link2 := otel.Link{ SpanContext: span.SpanContext(), Attributes: []label.KeyValue{ label.String("b", "2"), }, } - _, span = subject.Start(context.Background(), "test", trace.WithLinks(link1, link2)) + _, span = subject.Start(context.Background(), "test", otel.WithLinks(link1, link2)) - testSpan, ok := span.(*tracetest.Span) + testSpan, ok := span.(*oteltest.Span) e.Expect(ok).ToBeTrue() links := testSpan.Links() @@ -258,8 +258,8 @@ func TestTracer(t *testing.T) { }) } -func testTracedSpan(t *testing.T, fn func(tracer trace.Tracer, name string) (trace.Span, error)) { - tp := tracetest.NewTracerProvider() +func testTracedSpan(t *testing.T, fn func(tracer otel.Tracer, name string) (otel.Span, error)) { + tp := oteltest.NewTracerProvider() t.Run("starts a span with the expected name", func(t *testing.T) { t.Parallel() @@ -272,7 +272,7 @@ func testTracedSpan(t *testing.T, fn func(tracer trace.Tracer, name string) (tra e.Expect(err).ToBeNil() - testSpan, ok := span.(*tracetest.Span) + testSpan, ok := span.(*oteltest.Span) e.Expect(ok).ToBeTrue() e.Expect(testSpan.Name()).ToEqual(expectedName) @@ -291,7 +291,7 @@ func testTracedSpan(t *testing.T, fn func(tracer trace.Tracer, name string) (tra e.Expect(err).ToBeNil() - testSpan, ok := span.(*tracetest.Span) + testSpan, ok := span.(*oteltest.Span) e.Expect(ok).ToBeTrue() e.Expect(testSpan.StartTime()).ToBeTemporally(matchers.AfterOrSameTime, start) @@ -303,8 +303,8 @@ func testTracedSpan(t *testing.T, fn func(tracer trace.Tracer, name string) (tra e := matchers.NewExpecter(t) - sr := new(tracetest.StandardSpanRecorder) - subject := tracetest.NewTracerProvider(tracetest.WithSpanRecorder(sr)).Tracer(t.Name()) + sr := new(oteltest.StandardSpanRecorder) + subject := oteltest.NewTracerProvider(oteltest.WithSpanRecorder(sr)).Tracer(t.Name()) subject.Start(context.Background(), "span1") e.Expect(len(sr.Started())).ToEqual(1) @@ -323,8 +323,8 @@ func testTracedSpan(t *testing.T, fn func(tracer trace.Tracer, name string) (tra e := matchers.NewExpecter(t) - sr := new(tracetest.StandardSpanRecorder) - subject := tracetest.NewTracerProvider(tracetest.WithSpanRecorder(sr)).Tracer(t.Name()) + sr := new(oteltest.StandardSpanRecorder) + subject := oteltest.NewTracerProvider(oteltest.WithSpanRecorder(sr)).Tracer(t.Name()) numSpans := 2 diff --git a/propagators/propagators_test.go b/propagators/propagators_test.go index d362a6822c8..c5e0509e9ad 100644 --- a/propagators/propagators_test.go +++ b/propagators/propagators_test.go @@ -22,7 +22,6 @@ import ( "github.com/stretchr/testify/require" "go.opentelemetry.io/otel" - "go.opentelemetry.io/otel/api/trace" "go.opentelemetry.io/otel/propagators" ) @@ -36,18 +35,18 @@ var ( spanID = mustSpanIDFromHex(spanIDStr) ) -func mustTraceIDFromHex(s string) (t trace.ID) { +func mustTraceIDFromHex(s string) (t otel.TraceID) { var err error - t, err = trace.IDFromHex(s) + t, err = otel.TraceIDFromHex(s) if err != nil { panic(err) } return } -func mustSpanIDFromHex(s string) (t trace.SpanID) { +func mustSpanIDFromHex(s string) (t otel.SpanID) { var err error - t, err = trace.SpanIDFromHex(s) + t, err = otel.SpanIDFromHex(s) if err != nil { panic(err) } @@ -61,13 +60,13 @@ type outOfThinAirPropagator struct { var _ otel.TextMapPropagator = outOfThinAirPropagator{} func (p outOfThinAirPropagator) Extract(ctx context.Context, carrier otel.TextMapCarrier) context.Context { - sc := trace.SpanContext{ + sc := otel.SpanContext{ TraceID: traceID, SpanID: spanID, TraceFlags: 0, } require.True(p.t, sc.IsValid()) - return trace.ContextWithRemoteSpanContext(ctx, sc) + return otel.ContextWithRemoteSpanContext(ctx, sc) } func (outOfThinAirPropagator) Inject(context.Context, otel.TextMapCarrier) {} @@ -97,7 +96,7 @@ func TestMultiplePropagators(t *testing.T) { // generates the valid span context out of thin air { ctx := ootaProp.Extract(bg, ns) - sc := trace.RemoteSpanContextFromContext(ctx) + sc := otel.RemoteSpanContextFromContext(ctx) require.True(t, sc.IsValid(), "oota prop failed sanity check") } // sanity check for real propagators, ensuring that they @@ -105,13 +104,13 @@ func TestMultiplePropagators(t *testing.T) { // go context in absence of the HTTP headers. for _, prop := range testProps { ctx := prop.Extract(bg, ns) - sc := trace.RemoteSpanContextFromContext(ctx) + sc := otel.RemoteSpanContextFromContext(ctx) require.Falsef(t, sc.IsValid(), "%#v failed sanity check", prop) } for _, prop := range testProps { props := otel.NewCompositeTextMapPropagator(ootaProp, prop) ctx := props.Extract(bg, ns) - sc := trace.RemoteSpanContextFromContext(ctx) + sc := otel.RemoteSpanContextFromContext(ctx) assert.Truef(t, sc.IsValid(), "%#v clobbers span context", prop) } } diff --git a/propagators/trace_context.go b/propagators/trace_context.go index 4564c9b9e69..1d3d7769ce1 100644 --- a/propagators/trace_context.go +++ b/propagators/trace_context.go @@ -21,7 +21,6 @@ import ( "regexp" "go.opentelemetry.io/otel" - "go.opentelemetry.io/otel/api/trace" ) const ( @@ -57,7 +56,7 @@ func (tc TraceContext) Inject(ctx context.Context, carrier otel.TextMapCarrier) carrier.Set(tracestateHeader, state) } - sc := trace.SpanFromContext(ctx).SpanContext() + sc := otel.SpanFromContext(ctx).SpanContext() if !sc.IsValid() { return } @@ -65,7 +64,7 @@ func (tc TraceContext) Inject(ctx context.Context, carrier otel.TextMapCarrier) supportedVersion, sc.TraceID, sc.SpanID, - sc.TraceFlags&trace.FlagsSampled) + sc.TraceFlags&otel.FlagsSampled) carrier.Set(traceparentHeader, h) } @@ -80,72 +79,72 @@ func (tc TraceContext) Extract(ctx context.Context, carrier otel.TextMapCarrier) if !sc.IsValid() { return ctx } - return trace.ContextWithRemoteSpanContext(ctx, sc) + return otel.ContextWithRemoteSpanContext(ctx, sc) } -func (tc TraceContext) extract(carrier otel.TextMapCarrier) trace.SpanContext { +func (tc TraceContext) extract(carrier otel.TextMapCarrier) otel.SpanContext { h := carrier.Get(traceparentHeader) if h == "" { - return trace.EmptySpanContext() + return otel.SpanContext{} } matches := traceCtxRegExp.FindStringSubmatch(h) if len(matches) == 0 { - return trace.EmptySpanContext() + return otel.SpanContext{} } if len(matches) < 5 { // four subgroups plus the overall match - return trace.EmptySpanContext() + return otel.SpanContext{} } if len(matches[1]) != 2 { - return trace.EmptySpanContext() + return otel.SpanContext{} } ver, err := hex.DecodeString(matches[1]) if err != nil { - return trace.EmptySpanContext() + return otel.SpanContext{} } version := int(ver[0]) if version > maxVersion { - return trace.EmptySpanContext() + return otel.SpanContext{} } if version == 0 && len(matches) != 5 { // four subgroups plus the overall match - return trace.EmptySpanContext() + return otel.SpanContext{} } if len(matches[2]) != 32 { - return trace.EmptySpanContext() + return otel.SpanContext{} } - var sc trace.SpanContext + var sc otel.SpanContext - sc.TraceID, err = trace.IDFromHex(matches[2][:32]) + sc.TraceID, err = otel.TraceIDFromHex(matches[2][:32]) if err != nil { - return trace.EmptySpanContext() + return otel.SpanContext{} } if len(matches[3]) != 16 { - return trace.EmptySpanContext() + return otel.SpanContext{} } - sc.SpanID, err = trace.SpanIDFromHex(matches[3]) + sc.SpanID, err = otel.SpanIDFromHex(matches[3]) if err != nil { - return trace.EmptySpanContext() + return otel.SpanContext{} } if len(matches[4]) != 2 { - return trace.EmptySpanContext() + return otel.SpanContext{} } opts, err := hex.DecodeString(matches[4]) if err != nil || len(opts) < 1 || (version == 0 && opts[0] > 2) { - return trace.EmptySpanContext() + return otel.SpanContext{} } // Clear all flags other than the trace-context supported sampling bit. - sc.TraceFlags = opts[0] & trace.FlagsSampled + sc.TraceFlags = opts[0] & otel.FlagsSampled if !sc.IsValid() { - return trace.EmptySpanContext() + return otel.SpanContext{} } return sc diff --git a/propagators/trace_context_benchmark_test.go b/propagators/trace_context_benchmark_test.go index 26966610671..a3c7f1170bd 100644 --- a/propagators/trace_context_benchmark_test.go +++ b/propagators/trace_context_benchmark_test.go @@ -19,8 +19,8 @@ import ( "net/http" "testing" - "go.opentelemetry.io/otel/api/trace" - "go.opentelemetry.io/otel/api/trace/tracetest" + "go.opentelemetry.io/otel" + "go.opentelemetry.io/otel/oteltest" "go.opentelemetry.io/otel/propagators" ) @@ -39,20 +39,20 @@ func BenchmarkInject(b *testing.B) { func injectSubBenchmarks(b *testing.B, fn func(context.Context, *testing.B)) { b.Run("SampledSpanContext", func(b *testing.B) { var id uint64 - spanID, _ := trace.SpanIDFromHex("00f067aa0ba902b7") - traceID, _ := trace.IDFromHex("4bf92f3577b34da6a3ce929d0e0e4736") + spanID, _ := otel.SpanIDFromHex("00f067aa0ba902b7") + traceID, _ := otel.TraceIDFromHex("4bf92f3577b34da6a3ce929d0e0e4736") - mockTracer := &tracetest.MockTracer{ + mockTracer := &oteltest.MockTracer{ Sampled: false, StartSpanID: &id, } b.ReportAllocs() - sc := trace.SpanContext{ + sc := otel.SpanContext{ TraceID: traceID, SpanID: spanID, - TraceFlags: trace.FlagsSampled, + TraceFlags: otel.FlagsSampled, } - ctx := trace.ContextWithRemoteSpanContext(context.Background(), sc) + ctx := otel.ContextWithRemoteSpanContext(context.Background(), sc) ctx, _ = mockTracer.Start(ctx, "inject") fn(ctx, b) }) diff --git a/propagators/trace_context_test.go b/propagators/trace_context_test.go index 27d5d1c6cc9..667d19f7684 100644 --- a/propagators/trace_context_test.go +++ b/propagators/trace_context_test.go @@ -21,8 +21,8 @@ import ( "github.com/google/go-cmp/cmp" - "go.opentelemetry.io/otel/api/trace" - "go.opentelemetry.io/otel/api/trace/tracetest" + "go.opentelemetry.io/otel" + "go.opentelemetry.io/otel/oteltest" "go.opentelemetry.io/otel/propagators" ) @@ -31,12 +31,12 @@ func TestExtractValidTraceContextFromHTTPReq(t *testing.T) { tests := []struct { name string header string - wantSc trace.SpanContext + wantSc otel.SpanContext }{ { name: "valid w3cHeader", header: "00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-00", - wantSc: trace.SpanContext{ + wantSc: otel.SpanContext{ TraceID: traceID, SpanID: spanID, }, @@ -44,34 +44,34 @@ func TestExtractValidTraceContextFromHTTPReq(t *testing.T) { { name: "valid w3cHeader and sampled", header: "00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01", - wantSc: trace.SpanContext{ + wantSc: otel.SpanContext{ TraceID: traceID, SpanID: spanID, - TraceFlags: trace.FlagsSampled, + TraceFlags: otel.FlagsSampled, }, }, { name: "future version", header: "02-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01", - wantSc: trace.SpanContext{ + wantSc: otel.SpanContext{ TraceID: traceID, SpanID: spanID, - TraceFlags: trace.FlagsSampled, + TraceFlags: otel.FlagsSampled, }, }, { name: "future options with sampled bit set", header: "02-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-09", - wantSc: trace.SpanContext{ + wantSc: otel.SpanContext{ TraceID: traceID, SpanID: spanID, - TraceFlags: trace.FlagsSampled, + TraceFlags: otel.FlagsSampled, }, }, { name: "future options with sampled bit cleared", header: "02-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-08", - wantSc: trace.SpanContext{ + wantSc: otel.SpanContext{ TraceID: traceID, SpanID: spanID, }, @@ -79,28 +79,28 @@ func TestExtractValidTraceContextFromHTTPReq(t *testing.T) { { name: "future additional data", header: "02-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-09-XYZxsf09", - wantSc: trace.SpanContext{ + wantSc: otel.SpanContext{ TraceID: traceID, SpanID: spanID, - TraceFlags: trace.FlagsSampled, + TraceFlags: otel.FlagsSampled, }, }, { name: "valid b3Header ending in dash", header: "00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01-", - wantSc: trace.SpanContext{ + wantSc: otel.SpanContext{ TraceID: traceID, SpanID: spanID, - TraceFlags: trace.FlagsSampled, + TraceFlags: otel.FlagsSampled, }, }, { name: "future valid b3Header ending in dash", header: "01-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-09-", - wantSc: trace.SpanContext{ + wantSc: otel.SpanContext{ TraceID: traceID, SpanID: spanID, - TraceFlags: trace.FlagsSampled, + TraceFlags: otel.FlagsSampled, }, }, } @@ -112,7 +112,7 @@ func TestExtractValidTraceContextFromHTTPReq(t *testing.T) { ctx := context.Background() ctx = prop.Extract(ctx, req.Header) - gotSc := trace.RemoteSpanContextFromContext(ctx) + gotSc := otel.RemoteSpanContextFromContext(ctx) if diff := cmp.Diff(gotSc, tt.wantSc); diff != "" { t.Errorf("Extract Tracecontext: %s: -got +want %s", tt.name, diff) } @@ -121,7 +121,7 @@ func TestExtractValidTraceContextFromHTTPReq(t *testing.T) { } func TestExtractInvalidTraceContextFromHTTPReq(t *testing.T) { - wantSc := trace.EmptySpanContext() + wantSc := otel.SpanContext{} prop := propagators.TraceContext{} tests := []struct { name string @@ -200,7 +200,7 @@ func TestExtractInvalidTraceContextFromHTTPReq(t *testing.T) { ctx := context.Background() ctx = prop.Extract(ctx, req.Header) - gotSc := trace.RemoteSpanContextFromContext(ctx) + gotSc := otel.RemoteSpanContextFromContext(ctx) if diff := cmp.Diff(gotSc, wantSc); diff != "" { t.Errorf("Extract Tracecontext: %s: -got +want %s", tt.name, diff) } @@ -210,28 +210,28 @@ func TestExtractInvalidTraceContextFromHTTPReq(t *testing.T) { func TestInjectTraceContextToHTTPReq(t *testing.T) { var id uint64 - mockTracer := &tracetest.MockTracer{ + mockTracer := &oteltest.MockTracer{ Sampled: false, StartSpanID: &id, } prop := propagators.TraceContext{} tests := []struct { name string - sc trace.SpanContext + sc otel.SpanContext wantHeader string }{ { name: "valid spancontext, sampled", - sc: trace.SpanContext{ + sc: otel.SpanContext{ TraceID: traceID, SpanID: spanID, - TraceFlags: trace.FlagsSampled, + TraceFlags: otel.FlagsSampled, }, wantHeader: "00-4bf92f3577b34da6a3ce929d0e0e4736-0000000000000001-01", }, { name: "valid spancontext, not sampled", - sc: trace.SpanContext{ + sc: otel.SpanContext{ TraceID: traceID, SpanID: spanID, }, @@ -239,7 +239,7 @@ func TestInjectTraceContextToHTTPReq(t *testing.T) { }, { name: "valid spancontext, with unsupported bit set in traceflags", - sc: trace.SpanContext{ + sc: otel.SpanContext{ TraceID: traceID, SpanID: spanID, TraceFlags: 0xff, @@ -248,7 +248,7 @@ func TestInjectTraceContextToHTTPReq(t *testing.T) { }, { name: "invalid spancontext", - sc: trace.EmptySpanContext(), + sc: otel.SpanContext{}, wantHeader: "", }, } @@ -257,7 +257,7 @@ func TestInjectTraceContextToHTTPReq(t *testing.T) { req, _ := http.NewRequest("GET", "http://example.com", nil) ctx := context.Background() if tt.sc.IsValid() { - ctx = trace.ContextWithRemoteSpanContext(ctx, tt.sc) + ctx = otel.ContextWithRemoteSpanContext(ctx, tt.sc) ctx, _ = mockTracer.Start(ctx, "inject") } prop.Inject(ctx, req.Header) diff --git a/sdk/export/trace/trace.go b/sdk/export/trace/trace.go index 884f9487388..83a0b1c28e7 100644 --- a/sdk/export/trace/trace.go +++ b/sdk/export/trace/trace.go @@ -18,7 +18,7 @@ import ( "context" "time" - apitrace "go.opentelemetry.io/otel/api/trace" + "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/codes" "go.opentelemetry.io/otel/label" "go.opentelemetry.io/otel/sdk/instrumentation" @@ -49,9 +49,9 @@ type SpanExporter interface { // SpanData contains all the information collected by a completed span. type SpanData struct { - SpanContext apitrace.SpanContext - ParentSpanID apitrace.SpanID - SpanKind apitrace.SpanKind + SpanContext otel.SpanContext + ParentSpanID otel.SpanID + SpanKind otel.SpanKind Name string StartTime time.Time // The wall clock time of EndTime will be adjusted to always be offset @@ -59,7 +59,7 @@ type SpanData struct { EndTime time.Time Attributes []label.KeyValue MessageEvents []Event - Links []apitrace.Link + Links []otel.Link StatusCode codes.Code StatusMessage string HasRemoteParent bool diff --git a/sdk/trace/batch_span_processor_test.go b/sdk/trace/batch_span_processor_test.go index 74f81602b65..239a0af87b5 100644 --- a/sdk/trace/batch_span_processor_test.go +++ b/sdk/trace/batch_span_processor_test.go @@ -21,7 +21,7 @@ import ( "testing" "time" - apitrace "go.opentelemetry.io/otel/api/trace" + "go.opentelemetry.io/otel" export "go.opentelemetry.io/otel/sdk/export/trace" sdktrace "go.opentelemetry.io/otel/sdk/trace" ) @@ -187,15 +187,15 @@ func createAndRegisterBatchSP(option testOption, te *testBatchExporter) *sdktrac return sdktrace.NewBatchSpanProcessor(te, options...) } -func generateSpan(t *testing.T, parallel bool, tr apitrace.Tracer, option testOption) { +func generateSpan(t *testing.T, parallel bool, tr otel.Tracer, option testOption) { sc := getSpanContext() wg := &sync.WaitGroup{} for i := 0; i < option.genNumSpans; i++ { binary.BigEndian.PutUint64(sc.TraceID[0:8], uint64(i+1)) wg.Add(1) - f := func(sc apitrace.SpanContext) { - ctx := apitrace.ContextWithRemoteSpanContext(context.Background(), sc) + f := func(sc otel.SpanContext) { + ctx := otel.ContextWithRemoteSpanContext(context.Background(), sc) _, span := tr.Start(ctx, option.name) span.End() wg.Done() @@ -209,10 +209,10 @@ func generateSpan(t *testing.T, parallel bool, tr apitrace.Tracer, option testOp wg.Wait() } -func getSpanContext() apitrace.SpanContext { - tid, _ := apitrace.IDFromHex("01020304050607080102040810203040") - sid, _ := apitrace.SpanIDFromHex("0102040810203040") - return apitrace.SpanContext{ +func getSpanContext() otel.SpanContext { + tid, _ := otel.TraceIDFromHex("01020304050607080102040810203040") + sid, _ := otel.SpanIDFromHex("0102040810203040") + return otel.SpanContext{ TraceID: tid, SpanID: sid, TraceFlags: 0x1, diff --git a/sdk/trace/benchmark_test.go b/sdk/trace/benchmark_test.go index bf989fe1a35..4e6dcf1b267 100644 --- a/sdk/trace/benchmark_test.go +++ b/sdk/trace/benchmark_test.go @@ -18,13 +18,13 @@ import ( "context" "testing" - apitrace "go.opentelemetry.io/otel/api/trace" + "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/label" sdktrace "go.opentelemetry.io/otel/sdk/trace" ) func BenchmarkStartEndSpan(b *testing.B) { - traceBenchmark(b, "Benchmark StartEndSpan", func(b *testing.B, t apitrace.Tracer) { + traceBenchmark(b, "Benchmark StartEndSpan", func(b *testing.B, t otel.Tracer) { ctx := context.Background() b.ResetTimer() for i := 0; i < b.N; i++ { @@ -35,7 +35,7 @@ func BenchmarkStartEndSpan(b *testing.B) { } func BenchmarkSpanWithAttributes_4(b *testing.B) { - traceBenchmark(b, "Benchmark Start With 4 Attributes", func(b *testing.B, t apitrace.Tracer) { + traceBenchmark(b, "Benchmark Start With 4 Attributes", func(b *testing.B, t otel.Tracer) { ctx := context.Background() b.ResetTimer() @@ -53,7 +53,7 @@ func BenchmarkSpanWithAttributes_4(b *testing.B) { } func BenchmarkSpanWithAttributes_8(b *testing.B) { - traceBenchmark(b, "Benchmark Start With 8 Attributes", func(b *testing.B, t apitrace.Tracer) { + traceBenchmark(b, "Benchmark Start With 8 Attributes", func(b *testing.B, t otel.Tracer) { ctx := context.Background() b.ResetTimer() @@ -75,7 +75,7 @@ func BenchmarkSpanWithAttributes_8(b *testing.B) { } func BenchmarkSpanWithAttributes_all(b *testing.B) { - traceBenchmark(b, "Benchmark Start With all Attribute types", func(b *testing.B, t apitrace.Tracer) { + traceBenchmark(b, "Benchmark Start With all Attribute types", func(b *testing.B, t otel.Tracer) { ctx := context.Background() b.ResetTimer() @@ -99,7 +99,7 @@ func BenchmarkSpanWithAttributes_all(b *testing.B) { } func BenchmarkSpanWithAttributes_all_2x(b *testing.B) { - traceBenchmark(b, "Benchmark Start With all Attributes types twice", func(b *testing.B, t apitrace.Tracer) { + traceBenchmark(b, "Benchmark Start With all Attributes types twice", func(b *testing.B, t otel.Tracer) { ctx := context.Background() b.ResetTimer() @@ -133,8 +133,8 @@ func BenchmarkSpanWithAttributes_all_2x(b *testing.B) { } func BenchmarkTraceID_DotString(b *testing.B) { - t, _ := apitrace.IDFromHex("0000000000000001000000000000002a") - sc := apitrace.SpanContext{TraceID: t} + t, _ := otel.TraceIDFromHex("0000000000000001000000000000002a") + sc := otel.SpanContext{TraceID: t} want := "0000000000000001000000000000002a" for i := 0; i < b.N; i++ { @@ -145,7 +145,7 @@ func BenchmarkTraceID_DotString(b *testing.B) { } func BenchmarkSpanID_DotString(b *testing.B) { - sc := apitrace.SpanContext{SpanID: apitrace.SpanID{1}} + sc := otel.SpanContext{SpanID: otel.SpanID{1}} want := "0100000000000000" for i := 0; i < b.N; i++ { if got := sc.SpanID.String(); got != want { @@ -154,7 +154,7 @@ func BenchmarkSpanID_DotString(b *testing.B) { } } -func traceBenchmark(b *testing.B, name string, fn func(*testing.B, apitrace.Tracer)) { +func traceBenchmark(b *testing.B, name string, fn func(*testing.B, otel.Tracer)) { b.Run("AlwaysSample", func(b *testing.B) { b.ReportAllocs() fn(b, tracer(b, name, sdktrace.AlwaysSample())) @@ -165,7 +165,7 @@ func traceBenchmark(b *testing.B, name string, fn func(*testing.B, apitrace.Trac }) } -func tracer(b *testing.B, name string, sampler sdktrace.Sampler) apitrace.Tracer { +func tracer(b *testing.B, name string, sampler sdktrace.Sampler) otel.Tracer { tp := sdktrace.NewTracerProvider(sdktrace.WithConfig(sdktrace.Config{DefaultSampler: sampler})) return tp.Tracer(name) } diff --git a/sdk/trace/id_generator.go b/sdk/trace/id_generator.go index 18a900a6f3e..7061e2e5bea 100644 --- a/sdk/trace/id_generator.go +++ b/sdk/trace/id_generator.go @@ -18,8 +18,7 @@ import ( "math/rand" "sync" - "go.opentelemetry.io/otel/api/trace" - + "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/sdk/trace/internal" ) @@ -31,20 +30,20 @@ type defaultIDGenerator struct { var _ internal.IDGenerator = &defaultIDGenerator{} // NewSpanID returns a non-zero span ID from a randomly-chosen sequence. -func (gen *defaultIDGenerator) NewSpanID() trace.SpanID { +func (gen *defaultIDGenerator) NewSpanID() otel.SpanID { gen.Lock() defer gen.Unlock() - sid := trace.SpanID{} + sid := otel.SpanID{} gen.randSource.Read(sid[:]) return sid } // NewTraceID returns a non-zero trace ID from a randomly-chosen sequence. // mu should be held while this function is called. -func (gen *defaultIDGenerator) NewTraceID() trace.ID { +func (gen *defaultIDGenerator) NewTraceID() otel.TraceID { gen.Lock() defer gen.Unlock() - tid := trace.ID{} + tid := otel.TraceID{} gen.randSource.Read(tid[:]) return tid } diff --git a/sdk/trace/internal/internal.go b/sdk/trace/internal/internal.go index d82d778fd71..da9f13d6bd3 100644 --- a/sdk/trace/internal/internal.go +++ b/sdk/trace/internal/internal.go @@ -15,12 +15,10 @@ // Package internal provides trace internals. package internal -import ( - "go.opentelemetry.io/otel/api/trace" -) +import "go.opentelemetry.io/otel" // IDGenerator allows custom generators for TraceId and SpanId. type IDGenerator interface { - NewTraceID() trace.ID - NewSpanID() trace.SpanID + NewTraceID() otel.TraceID + NewSpanID() otel.SpanID } diff --git a/sdk/trace/provider.go b/sdk/trace/provider.go index cc4cc81b00a..afe01eb5d6d 100644 --- a/sdk/trace/provider.go +++ b/sdk/trace/provider.go @@ -18,12 +18,10 @@ import ( "sync" "sync/atomic" + "go.opentelemetry.io/otel" export "go.opentelemetry.io/otel/sdk/export/trace" "go.opentelemetry.io/otel/sdk/instrumentation" "go.opentelemetry.io/otel/sdk/resource" - - "go.opentelemetry.io/otel/api/trace" - apitrace "go.opentelemetry.io/otel/api/trace" ) const ( @@ -48,7 +46,7 @@ type TracerProvider struct { config atomic.Value // access atomically } -var _ apitrace.TracerProvider = &TracerProvider{} +var _ otel.TracerProvider = &TracerProvider{} // NewTracerProvider creates an instance of trace provider. Optional // parameter configures the provider with common options applicable @@ -82,8 +80,8 @@ func NewTracerProvider(opts ...TracerProviderOption) *TracerProvider { // Tracer with the given name. If a tracer for the given name does not exist, // it is created first. If the name is empty, DefaultTracerName is used. -func (p *TracerProvider) Tracer(name string, opts ...apitrace.TracerOption) apitrace.Tracer { - c := trace.NewTracerConfig(opts...) +func (p *TracerProvider) Tracer(name string, opts ...otel.TracerOption) otel.Tracer { + c := otel.NewTracerConfig(opts...) p.mu.Lock() defer p.mu.Unlock() diff --git a/sdk/trace/sampling.go b/sdk/trace/sampling.go index 8e4f76d1a73..49f6fa0b269 100644 --- a/sdk/trace/sampling.go +++ b/sdk/trace/sampling.go @@ -18,7 +18,7 @@ import ( "encoding/binary" "fmt" - api "go.opentelemetry.io/otel/api/trace" + "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/label" ) @@ -30,13 +30,13 @@ type Sampler interface { // SamplingParameters contains the values passed to a Sampler. type SamplingParameters struct { - ParentContext api.SpanContext - TraceID api.ID + ParentContext otel.SpanContext + TraceID otel.TraceID Name string HasRemoteParent bool - Kind api.SpanKind + Kind otel.SpanKind Attributes []label.KeyValue - Links []api.Link + Links []otel.Link } // SamplingDecision indicates whether a span is dropped, recorded and/or sampled. diff --git a/sdk/trace/sampling_test.go b/sdk/trace/sampling_test.go index f2a2be6572e..f4fb817426f 100644 --- a/sdk/trace/sampling_test.go +++ b/sdk/trace/sampling_test.go @@ -21,17 +21,17 @@ import ( "github.com/stretchr/testify/require" - api "go.opentelemetry.io/otel/api/trace" + "go.opentelemetry.io/otel" ) func TestParentBasedDefaultLocalParentSampled(t *testing.T) { sampler := ParentBased(AlwaysSample()) - traceID, _ := api.IDFromHex("4bf92f3577b34da6a3ce929d0e0e4736") - spanID, _ := api.SpanIDFromHex("00f067aa0ba902b7") - parentCtx := api.SpanContext{ + traceID, _ := otel.TraceIDFromHex("4bf92f3577b34da6a3ce929d0e0e4736") + spanID, _ := otel.SpanIDFromHex("00f067aa0ba902b7") + parentCtx := otel.SpanContext{ TraceID: traceID, SpanID: spanID, - TraceFlags: api.FlagsSampled, + TraceFlags: otel.FlagsSampled, } if sampler.ShouldSample(SamplingParameters{ParentContext: parentCtx}).Decision != RecordAndSample { t.Error("Sampling decision should be RecordAndSample") @@ -40,9 +40,9 @@ func TestParentBasedDefaultLocalParentSampled(t *testing.T) { func TestParentBasedDefaultLocalParentNotSampled(t *testing.T) { sampler := ParentBased(AlwaysSample()) - traceID, _ := api.IDFromHex("4bf92f3577b34da6a3ce929d0e0e4736") - spanID, _ := api.SpanIDFromHex("00f067aa0ba902b7") - parentCtx := api.SpanContext{ + traceID, _ := otel.TraceIDFromHex("4bf92f3577b34da6a3ce929d0e0e4736") + spanID, _ := otel.SpanIDFromHex("00f067aa0ba902b7") + parentCtx := otel.SpanContext{ TraceID: traceID, SpanID: spanID, } @@ -104,15 +104,15 @@ func TestParentBasedWithSamplerOptions(t *testing.T) { for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { - traceID, _ := api.IDFromHex("4bf92f3577b34da6a3ce929d0e0e4736") - spanID, _ := api.SpanIDFromHex("00f067aa0ba902b7") - parentCtx := api.SpanContext{ + traceID, _ := otel.TraceIDFromHex("4bf92f3577b34da6a3ce929d0e0e4736") + spanID, _ := otel.SpanIDFromHex("00f067aa0ba902b7") + parentCtx := otel.SpanContext{ TraceID: traceID, SpanID: spanID, } if tc.isParentSampled { - parentCtx.TraceFlags = api.FlagsSampled + parentCtx.TraceFlags = otel.FlagsSampled } params := SamplingParameters{ParentContext: parentCtx} diff --git a/sdk/trace/simple_span_processor_test.go b/sdk/trace/simple_span_processor_test.go index 88b6ad5df59..4014d9e59f0 100644 --- a/sdk/trace/simple_span_processor_test.go +++ b/sdk/trace/simple_span_processor_test.go @@ -18,7 +18,7 @@ import ( "context" "testing" - apitrace "go.opentelemetry.io/otel/api/trace" + "go.opentelemetry.io/otel" export "go.opentelemetry.io/otel/sdk/export/trace" sdktrace "go.opentelemetry.io/otel/sdk/trace" ) @@ -60,14 +60,14 @@ func TestSimpleSpanProcessorOnEnd(t *testing.T) { tp.RegisterSpanProcessor(ssp) tr := tp.Tracer("SimpleSpanProcessor") - tid, _ := apitrace.IDFromHex("01020304050607080102040810203040") - sid, _ := apitrace.SpanIDFromHex("0102040810203040") - sc := apitrace.SpanContext{ + tid, _ := otel.TraceIDFromHex("01020304050607080102040810203040") + sid, _ := otel.SpanIDFromHex("0102040810203040") + sc := otel.SpanContext{ TraceID: tid, SpanID: sid, TraceFlags: 0x1, } - ctx := apitrace.ContextWithRemoteSpanContext(context.Background(), sc) + ctx := otel.ContextWithRemoteSpanContext(context.Background(), sc) _, span := tr.Start(ctx, "OnEnd") span.End() diff --git a/sdk/trace/span.go b/sdk/trace/span.go index 13440d12c8c..ac8c9a413c1 100644 --- a/sdk/trace/span.go +++ b/sdk/trace/span.go @@ -22,8 +22,8 @@ import ( "sync" "time" + "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/api/global" - apitrace "go.opentelemetry.io/otel/api/trace" "go.opentelemetry.io/otel/codes" "go.opentelemetry.io/otel/label" export "go.opentelemetry.io/otel/sdk/export/trace" @@ -36,7 +36,10 @@ const ( errorEventName = "error" ) -// span implements apitrace.Span interface. +var emptySpanContext = otel.SpanContext{} + +// span is an implementation of the OpenTelemetry Span API representing the +// individual component of a trace. type span struct { // data contains information recorded about the span. // @@ -45,7 +48,7 @@ type span struct { // SpanContext, so that the trace ID is propagated. data *export.SpanData mu sync.Mutex // protects the contents of *data (but not the pointer value.) - spanContext apitrace.SpanContext + spanContext otel.SpanContext // attributes are capped at configured limit. When the capacity is reached an oldest entry // is removed to create room for a new entry. @@ -65,11 +68,11 @@ type span struct { tracer *tracer // tracer used to create span. } -var _ apitrace.Span = &span{} +var _ otel.Span = &span{} -func (s *span) SpanContext() apitrace.SpanContext { +func (s *span) SpanContext() otel.SpanContext { if s == nil { - return apitrace.EmptySpanContext() + return otel.SpanContext{} } return s.spanContext } @@ -108,7 +111,7 @@ func (s *span) SetAttributes(attributes ...label.KeyValue) { // // If this method is called while panicking an error event is added to the // Span before ending it and the panic is continued. -func (s *span) End(options ...apitrace.SpanOption) { +func (s *span) End(options ...otel.SpanOption) { if s == nil { return } @@ -130,7 +133,7 @@ func (s *span) End(options ...apitrace.SpanOption) { if !s.IsRecording() { return } - config := apitrace.NewSpanConfig(options...) + config := otel.NewSpanConfig(options...) s.endOnce.Do(func() { sps, ok := s.tracer.provider.spanProcessors.Load().(spanProcessorStates) mustExportOrProcess := ok && len(sps) > 0 @@ -148,7 +151,7 @@ func (s *span) End(options ...apitrace.SpanOption) { }) } -func (s *span) RecordError(ctx context.Context, err error, opts ...apitrace.ErrorOption) { +func (s *span) RecordError(ctx context.Context, err error, opts ...otel.ErrorOption) { if s == nil || err == nil { return } @@ -157,11 +160,7 @@ func (s *span) RecordError(ctx context.Context, err error, opts ...apitrace.Erro return } - cfg := apitrace.ErrorConfig{} - - for _, o := range opts { - o(&cfg) - } + cfg := otel.NewErrorConfig(opts...) if cfg.Timestamp.IsZero() { cfg.Timestamp = time.Now() @@ -186,7 +185,7 @@ func typeStr(i interface{}) string { return fmt.Sprintf("%s.%s", t.PkgPath(), t.Name()) } -func (s *span) Tracer() apitrace.Tracer { +func (s *span) Tracer() otel.Tracer { return s.tracer } @@ -227,9 +226,9 @@ func (s *span) SetName(name string) { s.data.Name = name // SAMPLING noParent := !s.data.ParentSpanID.IsValid() - var ctx apitrace.SpanContext + var ctx otel.SpanContext if noParent { - ctx = apitrace.EmptySpanContext() + ctx = otel.SpanContext{} } else { // FIXME: Where do we get the parent context from? // From SpanStore? @@ -255,7 +254,7 @@ func (s *span) SetName(name string) { } } -func (s *span) addLink(link apitrace.Link) { +func (s *span) addLink(link otel.Link) { if !s.IsRecording() { return } @@ -285,10 +284,10 @@ func (s *span) makeSpanData() *export.SpanData { return &sd } -func (s *span) interfaceArrayToLinksArray() []apitrace.Link { - linkArr := make([]apitrace.Link, 0) +func (s *span) interfaceArrayToLinksArray() []otel.Link { + linkArr := make([]otel.Link, 0) for _, value := range s.links.queue { - linkArr = append(linkArr, value.(apitrace.Link)) + linkArr = append(linkArr, value.(otel.Link)) } return linkArr } @@ -320,14 +319,14 @@ func (s *span) addChild() { s.mu.Unlock() } -func startSpanInternal(tr *tracer, name string, parent apitrace.SpanContext, remoteParent bool, o *apitrace.SpanConfig) *span { +func startSpanInternal(tr *tracer, name string, parent otel.SpanContext, remoteParent bool, o *otel.SpanConfig) *span { var noParent bool span := &span{} span.spanContext = parent cfg := tr.provider.config.Load().(*Config) - if parent == apitrace.EmptySpanContext() { + if parent == emptySpanContext { span.spanContext.TraceID = cfg.IDGenerator.NewTraceID() noParent = true } @@ -358,7 +357,7 @@ func startSpanInternal(tr *tracer, name string, parent apitrace.SpanContext, rem span.data = &export.SpanData{ SpanContext: span.spanContext, StartTime: startTime, - SpanKind: apitrace.ValidateSpanKind(o.SpanKind), + SpanKind: otel.ValidateSpanKind(o.SpanKind), Name: name, HasRemoteParent: remoteParent, Resource: cfg.Resource, @@ -388,13 +387,13 @@ func startSpanInternal(tr *tracer, name string, parent apitrace.SpanContext, rem type samplingData struct { noParent bool remoteParent bool - parent apitrace.SpanContext + parent otel.SpanContext name string cfg *Config span *span attributes []label.KeyValue - links []apitrace.Link - kind apitrace.SpanKind + links []otel.Link + kind otel.SpanKind } func makeSamplingDecision(data samplingData) SamplingResult { @@ -420,13 +419,13 @@ func makeSamplingDecision(data samplingData) SamplingResult { Links: data.links, }) if sampled.Decision == RecordAndSample { - spanContext.TraceFlags |= apitrace.FlagsSampled + spanContext.TraceFlags |= otel.FlagsSampled } else { - spanContext.TraceFlags &^= apitrace.FlagsSampled + spanContext.TraceFlags &^= otel.FlagsSampled } return sampled } - if data.parent.TraceFlags&apitrace.FlagsSampled != 0 { + if data.parent.TraceFlags&otel.FlagsSampled != 0 { return SamplingResult{Decision: RecordAndSample} } return SamplingResult{Decision: Drop} diff --git a/sdk/trace/trace_test.go b/sdk/trace/trace_test.go index 5b048570d7c..d4c4b09585e 100644 --- a/sdk/trace/trace_test.go +++ b/sdk/trace/trace_test.go @@ -25,6 +25,7 @@ import ( "testing" "time" + "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/api/global" "go.opentelemetry.io/otel/codes" "go.opentelemetry.io/otel/label" @@ -34,8 +35,6 @@ import ( "github.com/stretchr/testify/require" "go.opentelemetry.io/otel/api/apitest" - "go.opentelemetry.io/otel/api/trace" - apitrace "go.opentelemetry.io/otel/api/trace" ottest "go.opentelemetry.io/otel/internal/testing" export "go.opentelemetry.io/otel/sdk/export/trace" "go.opentelemetry.io/otel/sdk/instrumentation" @@ -43,8 +42,8 @@ import ( ) var ( - tid apitrace.ID - sid apitrace.SpanID + tid otel.TraceID + sid otel.SpanID ) type discardHandler struct{} @@ -52,8 +51,8 @@ type discardHandler struct{} func (*discardHandler) Handle(_ error) {} func init() { - tid, _ = apitrace.IDFromHex("01020304050607080102040810203040") - sid, _ = apitrace.SpanIDFromHex("0102040810203040") + tid, _ = otel.TraceIDFromHex("01020304050607080102040810203040") + sid, _ = otel.SpanIDFromHex("0102040810203040") global.SetErrorHandler(new(discardHandler)) } @@ -61,7 +60,7 @@ func init() { func TestTracerFollowsExpectedAPIBehaviour(t *testing.T) { tp := NewTracerProvider(WithConfig(Config{DefaultSampler: TraceIDRatioBased(0)})) harness := apitest.NewHarness(t) - subjectFactory := func() trace.Tracer { + subjectFactory := func() otel.Tracer { return tp.Tracer("") } @@ -264,14 +263,14 @@ func TestSampling(t *testing.T) { for i := 0; i < total; i++ { ctx := context.Background() if tc.parent { - psc := apitrace.SpanContext{ + psc := otel.SpanContext{ TraceID: idg.NewTraceID(), SpanID: idg.NewSpanID(), } if tc.sampledParent { - psc.TraceFlags = apitrace.FlagsSampled + psc.TraceFlags = otel.FlagsSampled } - ctx = apitrace.ContextWithRemoteSpanContext(ctx, psc) + ctx = otel.ContextWithRemoteSpanContext(ctx, psc) } _, span := tr.Start(ctx, "test") if span.SpanContext().IsSampled() { @@ -300,33 +299,33 @@ func TestStartSpanWithParent(t *testing.T) { tr := tp.Tracer("SpanWithParent") ctx := context.Background() - sc1 := apitrace.SpanContext{ + sc1 := otel.SpanContext{ TraceID: tid, SpanID: sid, TraceFlags: 0x1, } - _, s1 := tr.Start(apitrace.ContextWithRemoteSpanContext(ctx, sc1), "span1-unsampled-parent1") + _, s1 := tr.Start(otel.ContextWithRemoteSpanContext(ctx, sc1), "span1-unsampled-parent1") if err := checkChild(sc1, s1); err != nil { t.Error(err) } - _, s2 := tr.Start(apitrace.ContextWithRemoteSpanContext(ctx, sc1), "span2-unsampled-parent1") + _, s2 := tr.Start(otel.ContextWithRemoteSpanContext(ctx, sc1), "span2-unsampled-parent1") if err := checkChild(sc1, s2); err != nil { t.Error(err) } - sc2 := apitrace.SpanContext{ + sc2 := otel.SpanContext{ TraceID: tid, SpanID: sid, TraceFlags: 0x1, //Tracestate: testTracestate, } - _, s3 := tr.Start(apitrace.ContextWithRemoteSpanContext(ctx, sc2), "span3-sampled-parent2") + _, s3 := tr.Start(otel.ContextWithRemoteSpanContext(ctx, sc2), "span3-sampled-parent2") if err := checkChild(sc2, s3); err != nil { t.Error(err) } - ctx2, s4 := tr.Start(apitrace.ContextWithRemoteSpanContext(ctx, sc2), "span4-sampled-parent2") + ctx2, s4 := tr.Start(otel.ContextWithRemoteSpanContext(ctx, sc2), "span4-sampled-parent2") if err := checkChild(sc2, s4); err != nil { t.Error(err) } @@ -343,8 +342,8 @@ func TestSetSpanAttributesOnStart(t *testing.T) { tp := NewTracerProvider(WithSyncer(te)) span := startSpan(tp, "StartSpanAttribute", - apitrace.WithAttributes(label.String("key1", "value1")), - apitrace.WithAttributes(label.String("key2", "value2")), + otel.WithAttributes(label.String("key1", "value1")), + otel.WithAttributes(label.String("key2", "value2")), ) got, err := endSpan(te, span) if err != nil { @@ -352,7 +351,7 @@ func TestSetSpanAttributesOnStart(t *testing.T) { } want := &export.SpanData{ - SpanContext: apitrace.SpanContext{ + SpanContext: otel.SpanContext{ TraceID: tid, TraceFlags: 0x1, }, @@ -362,7 +361,7 @@ func TestSetSpanAttributesOnStart(t *testing.T) { label.String("key1", "value1"), label.String("key2", "value2"), }, - SpanKind: apitrace.SpanKindInternal, + SpanKind: otel.SpanKindInternal, HasRemoteParent: true, InstrumentationLibrary: instrumentation.Library{Name: "StartSpanAttribute"}, } @@ -382,7 +381,7 @@ func TestSetSpanAttributes(t *testing.T) { } want := &export.SpanData{ - SpanContext: apitrace.SpanContext{ + SpanContext: otel.SpanContext{ TraceID: tid, TraceFlags: 0x1, }, @@ -391,7 +390,7 @@ func TestSetSpanAttributes(t *testing.T) { Attributes: []label.KeyValue{ label.String("key1", "value1"), }, - SpanKind: apitrace.SpanKindInternal, + SpanKind: otel.SpanKindInternal, HasRemoteParent: true, InstrumentationLibrary: instrumentation.Library{Name: "SpanAttribute"}, } @@ -418,7 +417,7 @@ func TestSetSpanAttributesOverLimit(t *testing.T) { } want := &export.SpanData{ - SpanContext: apitrace.SpanContext{ + SpanContext: otel.SpanContext{ TraceID: tid, TraceFlags: 0x1, }, @@ -428,7 +427,7 @@ func TestSetSpanAttributesOverLimit(t *testing.T) { label.Bool("key1", false), label.Int64("key4", 4), }, - SpanKind: apitrace.SpanKindInternal, + SpanKind: otel.SpanKindInternal, HasRemoteParent: true, DroppedAttributeCount: 1, InstrumentationLibrary: instrumentation.Library{Name: "SpanAttributesOverLimit"}, @@ -464,7 +463,7 @@ func TestEvents(t *testing.T) { } want := &export.SpanData{ - SpanContext: apitrace.SpanContext{ + SpanContext: otel.SpanContext{ TraceID: tid, TraceFlags: 0x1, }, @@ -475,7 +474,7 @@ func TestEvents(t *testing.T) { {Name: "foo", Attributes: []label.KeyValue{k1v1}}, {Name: "bar", Attributes: []label.KeyValue{k2v2, k3v3}}, }, - SpanKind: apitrace.SpanKindInternal, + SpanKind: otel.SpanKindInternal, InstrumentationLibrary: instrumentation.Library{Name: "Events"}, } if diff := cmpDiff(got, want); diff != "" { @@ -515,7 +514,7 @@ func TestEventsOverLimit(t *testing.T) { } want := &export.SpanData{ - SpanContext: apitrace.SpanContext{ + SpanContext: otel.SpanContext{ TraceID: tid, TraceFlags: 0x1, }, @@ -527,7 +526,7 @@ func TestEventsOverLimit(t *testing.T) { }, DroppedMessageEventCount: 2, HasRemoteParent: true, - SpanKind: apitrace.SpanKindInternal, + SpanKind: otel.SpanKindInternal, InstrumentationLibrary: instrumentation.Library{Name: "EventsOverLimit"}, } if diff := cmpDiff(got, want); diff != "" { @@ -543,14 +542,14 @@ func TestLinks(t *testing.T) { k2v2 := label.String("key2", "value2") k3v3 := label.String("key3", "value3") - sc1 := apitrace.SpanContext{TraceID: apitrace.ID([16]byte{1, 1}), SpanID: apitrace.SpanID{3}} - sc2 := apitrace.SpanContext{TraceID: apitrace.ID([16]byte{1, 1}), SpanID: apitrace.SpanID{3}} + sc1 := otel.SpanContext{TraceID: otel.TraceID([16]byte{1, 1}), SpanID: otel.SpanID{3}} + sc2 := otel.SpanContext{TraceID: otel.TraceID([16]byte{1, 1}), SpanID: otel.SpanID{3}} - links := []apitrace.Link{ + links := []otel.Link{ {SpanContext: sc1, Attributes: []label.KeyValue{k1v1}}, {SpanContext: sc2, Attributes: []label.KeyValue{k2v2, k3v3}}, } - span := startSpan(tp, "Links", apitrace.WithLinks(links...)) + span := startSpan(tp, "Links", otel.WithLinks(links...)) got, err := endSpan(te, span) if err != nil { @@ -558,7 +557,7 @@ func TestLinks(t *testing.T) { } want := &export.SpanData{ - SpanContext: apitrace.SpanContext{ + SpanContext: otel.SpanContext{ TraceID: tid, TraceFlags: 0x1, }, @@ -566,7 +565,7 @@ func TestLinks(t *testing.T) { Name: "span0", HasRemoteParent: true, Links: links, - SpanKind: apitrace.SpanKindInternal, + SpanKind: otel.SpanKindInternal, InstrumentationLibrary: instrumentation.Library{Name: "Links"}, } if diff := cmpDiff(got, want); diff != "" { @@ -578,17 +577,17 @@ func TestLinksOverLimit(t *testing.T) { te := NewTestExporter() cfg := Config{MaxLinksPerSpan: 2} - sc1 := apitrace.SpanContext{TraceID: apitrace.ID([16]byte{1, 1}), SpanID: apitrace.SpanID{3}} - sc2 := apitrace.SpanContext{TraceID: apitrace.ID([16]byte{1, 1}), SpanID: apitrace.SpanID{3}} - sc3 := apitrace.SpanContext{TraceID: apitrace.ID([16]byte{1, 1}), SpanID: apitrace.SpanID{3}} + sc1 := otel.SpanContext{TraceID: otel.TraceID([16]byte{1, 1}), SpanID: otel.SpanID{3}} + sc2 := otel.SpanContext{TraceID: otel.TraceID([16]byte{1, 1}), SpanID: otel.SpanID{3}} + sc3 := otel.SpanContext{TraceID: otel.TraceID([16]byte{1, 1}), SpanID: otel.SpanID{3}} tp := NewTracerProvider(WithConfig(cfg), WithSyncer(te)) span := startSpan(tp, "LinksOverLimit", - apitrace.WithLinks( - apitrace.Link{SpanContext: sc1, Attributes: []label.KeyValue{label.String("key1", "value1")}}, - apitrace.Link{SpanContext: sc2, Attributes: []label.KeyValue{label.String("key2", "value2")}}, - apitrace.Link{SpanContext: sc3, Attributes: []label.KeyValue{label.String("key3", "value3")}}, + otel.WithLinks( + otel.Link{SpanContext: sc1, Attributes: []label.KeyValue{label.String("key1", "value1")}}, + otel.Link{SpanContext: sc2, Attributes: []label.KeyValue{label.String("key2", "value2")}}, + otel.Link{SpanContext: sc3, Attributes: []label.KeyValue{label.String("key3", "value3")}}, ), ) @@ -601,19 +600,19 @@ func TestLinksOverLimit(t *testing.T) { } want := &export.SpanData{ - SpanContext: apitrace.SpanContext{ + SpanContext: otel.SpanContext{ TraceID: tid, TraceFlags: 0x1, }, ParentSpanID: sid, Name: "span0", - Links: []apitrace.Link{ + Links: []otel.Link{ {SpanContext: sc2, Attributes: []label.KeyValue{k2v2}}, {SpanContext: sc3, Attributes: []label.KeyValue{k3v3}}, }, DroppedLinkCount: 1, HasRemoteParent: true, - SpanKind: apitrace.SpanKindInternal, + SpanKind: otel.SpanKindInternal, InstrumentationLibrary: instrumentation.Library{Name: "LinksOverLimit"}, } if diff := cmpDiff(got, want); diff != "" { @@ -627,7 +626,7 @@ func TestSetSpanName(t *testing.T) { ctx := context.Background() want := "SpanName-1" - ctx = apitrace.ContextWithRemoteSpanContext(ctx, apitrace.SpanContext{ + ctx = otel.ContextWithRemoteSpanContext(ctx, otel.SpanContext{ TraceID: tid, SpanID: sid, TraceFlags: 1, @@ -655,13 +654,13 @@ func TestSetSpanStatus(t *testing.T) { } want := &export.SpanData{ - SpanContext: apitrace.SpanContext{ + SpanContext: otel.SpanContext{ TraceID: tid, TraceFlags: 0x1, }, ParentSpanID: sid, Name: "span0", - SpanKind: apitrace.SpanKindInternal, + SpanKind: otel.SpanKindInternal, StatusCode: codes.Error, StatusMessage: "Error", HasRemoteParent: true, @@ -678,8 +677,8 @@ func cmpDiff(x, y interface{}) string { cmp.AllowUnexported(export.Event{})) } -func remoteSpanContext() apitrace.SpanContext { - return apitrace.SpanContext{ +func remoteSpanContext() otel.SpanContext { + return otel.SpanContext{ TraceID: tid, SpanID: sid, TraceFlags: 1, @@ -688,7 +687,7 @@ func remoteSpanContext() apitrace.SpanContext { // checkChild is test utility function that tests that c has fields set appropriately, // given that it is a child span of p. -func checkChild(p apitrace.SpanContext, apiSpan apitrace.Span) error { +func checkChild(p otel.SpanContext, apiSpan otel.Span) error { s := apiSpan.(*span) if s == nil { return fmt.Errorf("got nil child span, want non-nil") @@ -711,7 +710,7 @@ func checkChild(p apitrace.SpanContext, apiSpan apitrace.Span) error { // startSpan starts a span with a name "span0". See startNamedSpan for // details. -func startSpan(tp *TracerProvider, trName string, args ...apitrace.SpanOption) apitrace.Span { +func startSpan(tp *TracerProvider, trName string, args ...otel.SpanOption) otel.Span { return startNamedSpan(tp, trName, "span0", args...) } @@ -719,10 +718,10 @@ func startSpan(tp *TracerProvider, trName string, args ...apitrace.SpanOption) a // passed name and with remote span context as parent. The remote span // context contains TraceFlags with sampled bit set. This allows the // span to be automatically sampled. -func startNamedSpan(tp *TracerProvider, trName, name string, args ...apitrace.SpanOption) apitrace.Span { +func startNamedSpan(tp *TracerProvider, trName, name string, args ...otel.SpanOption) otel.Span { ctx := context.Background() - ctx = apitrace.ContextWithRemoteSpanContext(ctx, remoteSpanContext()) - args = append(args, apitrace.WithRecord()) + ctx = otel.ContextWithRemoteSpanContext(ctx, remoteSpanContext()) + args = append(args, otel.WithRecord()) _, span := tp.Tracer(trName).Start( ctx, name, @@ -740,7 +739,7 @@ func startNamedSpan(tp *TracerProvider, trName, name string, args ...apitrace.Sp // // It also does some basic tests on the span. // It also clears spanID in the export.SpanData to make the comparison easier. -func endSpan(te *testExporter, span apitrace.Span) (*export.SpanData, error) { +func endSpan(te *testExporter, span otel.Span) (*export.SpanData, error) { if !span.IsRecording() { return nil, fmt.Errorf("IsRecording: got false, want true") } @@ -755,7 +754,7 @@ func endSpan(te *testExporter, span apitrace.Span) (*export.SpanData, error) { if !got.SpanContext.SpanID.IsValid() { return nil, fmt.Errorf("exporting span: expected nonzero SpanID") } - got.SpanContext.SpanID = apitrace.SpanID{} + got.SpanContext.SpanID = otel.SpanID{} if !checkTime(&got.StartTime) { return nil, fmt.Errorf("exporting span: expected nonzero StartTime") } @@ -792,7 +791,7 @@ func TestStartSpanAfterEnd(t *testing.T) { ctx := context.Background() tr := tp.Tracer("SpanAfterEnd") - ctx, span0 := tr.Start(apitrace.ContextWithRemoteSpanContext(ctx, remoteSpanContext()), "parent") + ctx, span0 := tr.Start(otel.ContextWithRemoteSpanContext(ctx, remoteSpanContext()), "parent") ctx1, span1 := tr.Start(ctx, "span-1") span1.End() // Start a new span with the context containing span-1 @@ -901,12 +900,12 @@ func TestExecutionTracerTaskEnd(t *testing.T) { s.executionTracerTaskEnd = executionTracerTaskEnd spans = append(spans, s) // never sample - tID, _ := apitrace.IDFromHex("0102030405060708090a0b0c0d0e0f") - sID, _ := apitrace.SpanIDFromHex("0001020304050607") + tID, _ := otel.TraceIDFromHex("0102030405060708090a0b0c0d0e0f") + sID, _ := otel.SpanIDFromHex("0001020304050607") ctx := context.Background() - ctx = apitrace.ContextWithRemoteSpanContext(ctx, - apitrace.SpanContext{ + ctx = otel.ContextWithRemoteSpanContext(ctx, + otel.SpanContext{ TraceID: tID, SpanID: sID, TraceFlags: 0, @@ -943,9 +942,9 @@ func TestCustomStartEndTime(t *testing.T) { _, span := tp.Tracer("Custom Start and End time").Start( context.Background(), "testspan", - apitrace.WithTimestamp(startTime), + otel.WithTimestamp(startTime), ) - span.End(apitrace.WithTimestamp(endTime)) + span.End(otel.WithTimestamp(endTime)) if te.Len() != 1 { t.Fatalf("got %d exported spans, want one span", te.Len()) @@ -984,7 +983,7 @@ func TestRecordError(t *testing.T) { errTime := time.Now() span.RecordError(context.Background(), s.err, - apitrace.WithErrorTime(errTime), + otel.WithErrorTime(errTime), ) got, err := endSpan(te, span) @@ -993,13 +992,13 @@ func TestRecordError(t *testing.T) { } want := &export.SpanData{ - SpanContext: apitrace.SpanContext{ + SpanContext: otel.SpanContext{ TraceID: tid, TraceFlags: 0x1, }, ParentSpanID: sid, Name: "span0", - SpanKind: apitrace.SpanKindInternal, + SpanKind: otel.SpanKindInternal, HasRemoteParent: true, MessageEvents: []export.Event{ { @@ -1028,8 +1027,8 @@ func TestRecordErrorWithStatus(t *testing.T) { errTime := time.Now() testStatus := codes.Error span.RecordError(context.Background(), testErr, - apitrace.WithErrorTime(errTime), - apitrace.WithErrorStatus(testStatus), + otel.WithErrorTime(errTime), + otel.WithErrorStatus(testStatus), ) got, err := endSpan(te, span) @@ -1038,13 +1037,13 @@ func TestRecordErrorWithStatus(t *testing.T) { } want := &export.SpanData{ - SpanContext: apitrace.SpanContext{ + SpanContext: otel.SpanContext{ TraceID: tid, TraceFlags: 0x1, }, ParentSpanID: sid, Name: "span0", - SpanKind: apitrace.SpanKindInternal, + SpanKind: otel.SpanKindInternal, StatusCode: codes.Error, StatusMessage: "", HasRemoteParent: true, @@ -1078,13 +1077,13 @@ func TestRecordErrorNil(t *testing.T) { } want := &export.SpanData{ - SpanContext: apitrace.SpanContext{ + SpanContext: otel.SpanContext{ TraceID: tid, TraceFlags: 0x1, }, ParentSpanID: sid, Name: "span0", - SpanKind: apitrace.SpanKindInternal, + SpanKind: otel.SpanKindInternal, HasRemoteParent: true, StatusCode: codes.Unset, StatusMessage: "", @@ -1106,22 +1105,22 @@ func TestWithSpanKind(t *testing.T) { t.Error(err.Error()) } - if spanData.SpanKind != apitrace.SpanKindInternal { - t.Errorf("Default value of Spankind should be Internal: got %+v, want %+v\n", spanData.SpanKind, apitrace.SpanKindInternal) + if spanData.SpanKind != otel.SpanKindInternal { + t.Errorf("Default value of Spankind should be Internal: got %+v, want %+v\n", spanData.SpanKind, otel.SpanKindInternal) } - sks := []apitrace.SpanKind{ - apitrace.SpanKindInternal, - apitrace.SpanKindServer, - apitrace.SpanKindClient, - apitrace.SpanKindProducer, - apitrace.SpanKindConsumer, + sks := []otel.SpanKind{ + otel.SpanKindInternal, + otel.SpanKindServer, + otel.SpanKindClient, + otel.SpanKindProducer, + otel.SpanKindConsumer, } for _, sk := range sks { te.Reset() - _, span := tr.Start(context.Background(), fmt.Sprintf("SpanKind-%v", sk), apitrace.WithSpanKind(sk)) + _, span := tr.Start(context.Background(), fmt.Sprintf("SpanKind-%v", sk), otel.WithSpanKind(sk)) spanData, err := endSpan(te, span) if err != nil { t.Error(err.Error()) @@ -1146,7 +1145,7 @@ func TestWithResource(t *testing.T) { } want := &export.SpanData{ - SpanContext: apitrace.SpanContext{ + SpanContext: otel.SpanContext{ TraceID: tid, TraceFlags: 0x1, }, @@ -1155,7 +1154,7 @@ func TestWithResource(t *testing.T) { Attributes: []label.KeyValue{ label.String("key1", "value1"), }, - SpanKind: apitrace.SpanKindInternal, + SpanKind: otel.SpanKindInternal, HasRemoteParent: true, Resource: resource.New(label.String("rk1", "rv1"), label.Int64("rk2", 5)), InstrumentationLibrary: instrumentation.Library{Name: "WithResource"}, @@ -1170,24 +1169,24 @@ func TestWithInstrumentationVersion(t *testing.T) { tp := NewTracerProvider(WithSyncer(te)) ctx := context.Background() - ctx = apitrace.ContextWithRemoteSpanContext(ctx, remoteSpanContext()) + ctx = otel.ContextWithRemoteSpanContext(ctx, remoteSpanContext()) _, span := tp.Tracer( "WithInstrumentationVersion", - apitrace.WithInstrumentationVersion("v0.1.0"), - ).Start(ctx, "span0", apitrace.WithRecord()) + otel.WithInstrumentationVersion("v0.1.0"), + ).Start(ctx, "span0", otel.WithRecord()) got, err := endSpan(te, span) if err != nil { t.Error(err.Error()) } want := &export.SpanData{ - SpanContext: apitrace.SpanContext{ + SpanContext: otel.SpanContext{ TraceID: tid, TraceFlags: 0x1, }, ParentSpanID: sid, Name: "span0", - SpanKind: apitrace.SpanKindInternal, + SpanKind: otel.SpanKindInternal, HasRemoteParent: true, InstrumentationLibrary: instrumentation.Library{ Name: "WithInstrumentationVersion", @@ -1205,7 +1204,7 @@ func TestSpanCapturesPanic(t *testing.T) { _, span := tp.Tracer("CatchPanic").Start( context.Background(), "span", - apitrace.WithRecord(), + otel.WithRecord(), ) f := func() { diff --git a/sdk/trace/tracer.go b/sdk/trace/tracer.go index d826194ceaf..2eb093f4f1c 100644 --- a/sdk/trace/tracer.go +++ b/sdk/trace/tracer.go @@ -17,7 +17,7 @@ package trace import ( "context" - apitrace "go.opentelemetry.io/otel/api/trace" + "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/internal/trace/parent" "go.opentelemetry.io/otel/sdk/instrumentation" ) @@ -27,7 +27,7 @@ type tracer struct { instrumentationLibrary instrumentation.Library } -var _ apitrace.Tracer = &tracer{} +var _ otel.Tracer = &tracer{} // Start starts a Span and returns it along with a context containing it. // @@ -35,12 +35,12 @@ var _ apitrace.Tracer = &tracer{} // span context found in the passed context. The created Span will be // configured appropriately by any SpanOption passed. Any Timestamp option // passed will be used as the start time of the Span's life-cycle. -func (tr *tracer) Start(ctx context.Context, name string, options ...apitrace.SpanOption) (context.Context, apitrace.Span) { - config := apitrace.NewSpanConfig(options...) +func (tr *tracer) Start(ctx context.Context, name string, options ...otel.SpanOption) (context.Context, otel.Span) { + config := otel.NewSpanConfig(options...) parentSpanContext, remoteParent, links := parent.GetSpanContextAndLinks(ctx, config.NewRoot) - if p := apitrace.SpanFromContext(ctx); p != nil { + if p := otel.SpanFromContext(ctx); p != nil { if sdkSpan, ok := p.(*span); ok { sdkSpan.addChild() } @@ -66,5 +66,5 @@ func (tr *tracer) Start(ctx context.Context, name string, options ...apitrace.Sp ctx, end := startExecutionTracerTask(ctx, name) span.executionTracerTaskEnd = end - return apitrace.ContextWithSpan(ctx, span), span + return otel.ContextWithSpan(ctx, span), span } diff --git a/trace.go b/trace.go new file mode 100644 index 00000000000..85d4d159e7e --- /dev/null +++ b/trace.go @@ -0,0 +1,362 @@ +// 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 otel + +import ( + "bytes" + "context" + "encoding/hex" + "encoding/json" + "time" + + "go.opentelemetry.io/otel/codes" + "go.opentelemetry.io/otel/label" +) + +const ( + // FlagsSampled is a bitmask with the sampled bit set. A SpanContext + // with the sampling bit set means the span is sampled. + FlagsSampled = byte(0x01) + // FlagsDeferred is a bitmask with the deferred bit set. A SpanContext + // with the deferred bit set means the sampling decision has been + // defered to the receiver. + FlagsDeferred = byte(0x02) + // FlagsDebug is a bitmask with the debug bit set. + FlagsDebug = byte(0x04) + + ErrInvalidHexID errorConst = "trace-id and span-id can only contain [0-9a-f] characters, all lowercase" + + ErrInvalidTraceIDLength errorConst = "hex encoded trace-id must have length equals to 32" + ErrNilTraceID errorConst = "trace-id can't be all zero" + + ErrInvalidSpanIDLength errorConst = "hex encoded span-id must have length equals to 16" + ErrNilSpanID errorConst = "span-id can't be all zero" +) + +type errorConst string + +func (e errorConst) Error() string { + return string(e) +} + +// TraceID is a unique identity of a trace. +type TraceID [16]byte + +var nilTraceID TraceID +var _ json.Marshaler = nilTraceID + +// IsValid checks whether the trace TraceID is valid. A valid trace ID does +// not consist of zeros only. +func (t TraceID) IsValid() bool { + return !bytes.Equal(t[:], nilTraceID[:]) +} + +// MarshalJSON implements a custom marshal function to encode TraceID +// as a hex string. +func (t TraceID) MarshalJSON() ([]byte, error) { + return json.Marshal(t.String()) +} + +// String returns the hex string representation form of a TraceID +func (t TraceID) String() string { + return hex.EncodeToString(t[:]) +} + +// SpanID is a unique identity of a span in a trace. +type SpanID [8]byte + +var nilSpanID SpanID +var _ json.Marshaler = nilSpanID + +// IsValid checks whether the SpanID is valid. A valid SpanID does not consist +// of zeros only. +func (s SpanID) IsValid() bool { + return !bytes.Equal(s[:], nilSpanID[:]) +} + +// MarshalJSON implements a custom marshal function to encode SpanID +// as a hex string. +func (s SpanID) MarshalJSON() ([]byte, error) { + return json.Marshal(s.String()) +} + +// String returns the hex string representation form of a SpanID +func (s SpanID) String() string { + return hex.EncodeToString(s[:]) +} + +// TraceIDFromHex returns a TraceID from a hex string if it is compliant with +// the W3C trace-context specification. See more at +// https://www.w3.org/TR/trace-context/#trace-id +func TraceIDFromHex(h string) (TraceID, error) { + t := TraceID{} + if len(h) != 32 { + return t, ErrInvalidTraceIDLength + } + + if err := decodeHex(h, t[:]); err != nil { + return t, err + } + + if !t.IsValid() { + return t, ErrNilTraceID + } + return t, nil +} + +// SpanIDFromHex returns a SpanID from a hex string if it is compliant +// with the w3c trace-context specification. +// See more at https://www.w3.org/TR/trace-context/#parent-id +func SpanIDFromHex(h string) (SpanID, error) { + s := SpanID{} + if len(h) != 16 { + return s, ErrInvalidSpanIDLength + } + + if err := decodeHex(h, s[:]); err != nil { + return s, err + } + + if !s.IsValid() { + return s, ErrNilSpanID + } + return s, nil +} + +func decodeHex(h string, b []byte) error { + for _, r := range h { + switch { + case 'a' <= r && r <= 'f': + continue + case '0' <= r && r <= '9': + continue + default: + return ErrInvalidHexID + } + } + + decoded, err := hex.DecodeString(h) + if err != nil { + return err + } + + copy(b, decoded) + return nil +} + +// SpanContext contains identifying trace information about a Span. +type SpanContext struct { + TraceID TraceID + SpanID SpanID + TraceFlags byte +} + +// IsValid returns if the SpanContext is valid. A valid span context has a +// valid TraceID and SpanID. +func (sc SpanContext) IsValid() bool { + return sc.HasTraceID() && sc.HasSpanID() +} + +// HasTraceID checks if the SpanContext has a valid TraceID. +func (sc SpanContext) HasTraceID() bool { + return sc.TraceID.IsValid() +} + +// HasSpanID checks if the SpanContext has a valid SpanID. +func (sc SpanContext) HasSpanID() bool { + return sc.SpanID.IsValid() +} + +// IsDeferred returns if the deferred bit is set in the trace flags. +func (sc SpanContext) IsDeferred() bool { + return sc.TraceFlags&FlagsDeferred == FlagsDeferred +} + +// IsDebug returns if the debug bit is set in the trace flags. +func (sc SpanContext) IsDebug() bool { + return sc.TraceFlags&FlagsDebug == FlagsDebug +} + +// IsSampled returns if the sampling bit is set in the trace flags. +func (sc SpanContext) IsSampled() bool { + return sc.TraceFlags&FlagsSampled == FlagsSampled +} + +type traceContextKeyType int + +const ( + currentSpanKey traceContextKeyType = iota + remoteContextKey +) + +// ContextWithSpan returns a copy of parent with span set to current. +func ContextWithSpan(parent context.Context, span Span) context.Context { + return context.WithValue(parent, currentSpanKey, span) +} + +// SpanFromContext returns the current span from ctx, or nil if none set. +func SpanFromContext(ctx context.Context) Span { + if span, ok := ctx.Value(currentSpanKey).(Span); ok { + return span + } + return noopSpan{} +} + +// ContextWithRemoteSpanContext returns a copy of parent with a remote set as +// the remote span context. +func ContextWithRemoteSpanContext(parent context.Context, remote SpanContext) context.Context { + return context.WithValue(parent, remoteContextKey, remote) +} + +// RemoteSpanContextFromContext returns the remote span context from ctx. +func RemoteSpanContextFromContext(ctx context.Context) SpanContext { + if sc, ok := ctx.Value(remoteContextKey).(SpanContext); ok { + return sc + } + return SpanContext{} +} + +// Span is the individual component of a trace. It represents a single named +// and timed operation of a workflow that is traced. A Tracer is used to +// create a Span and it is then up to the operation the Span represents to +// properly end the Span when the operation itself ends. +type Span interface { + // Tracer returns the Tracer that created the Span. Tracer MUST NOT be + // nil. + Tracer() Tracer + + // End completes the Span. Updates are not allowed the Span after End is + // called other than setting the status. + End(options ...SpanOption) + + // AddEvent adds an event to the span. + AddEvent(ctx context.Context, name string, attrs ...label.KeyValue) + // AddEventWithTimestamp adds an event that occurred at timestamp to the + // Span. + AddEventWithTimestamp(ctx context.Context, timestamp time.Time, name string, attrs ...label.KeyValue) + + // IsRecording returns the recording state of the Span. It will return + // true if the Span is active and events can be recorded. + IsRecording() bool + + // RecordError records an error as a Span event. + RecordError(ctx context.Context, err error, opts ...ErrorOption) + + // SpanContext returns the SpanContext of the Span. The returned + // SpanContext is usable even after the End has been called for the Span. + SpanContext() SpanContext + + // SetStatus sets the status of the Span in the form of a code and a + // message. SetStatus overrides the value of previous calls to SetStatus + // on the Span. + SetStatus(code codes.Code, msg string) + + // SetName sets the Span name. + SetName(name string) + + // SetAttributes sets kv as attributes of the Span. If a key from kv + // already exists for an attribute of the Span it will be overwritten with + // the value contained in kv. + SetAttributes(kv ...label.KeyValue) +} + +// Link is the relationship between two Spans. The relationship can be within +// the same Trace or across different Traces. +// +// For example, a Link is used in the following situations: +// +// 1. Batch Processing: A batch of operations may contain operations +// associated with one or more traces/spans. Since there can only be one +// parent SpanContext, a Link is used to keep reference to the +// SpanContext of all operations in the batch. +// 2. Public Endpoint: A SpanContext for an in incoming client request on a +// public endpoint should be considered untrusted. In such a case, a new +// trace with its own identity and sampling decision needs to be created, +// but this new trace needs to be related to the original trace in some +// form. A Link is used to keep reference to the original SpanContext and +// track the relationship. +type Link struct { + SpanContext + Attributes []label.KeyValue +} + +// SpanKind is the role a Span plays in a Trace. +type SpanKind int + +const ( + // As a convenience, these match the proto definition, see + // opentelemetry/proto/trace/v1/trace.proto + // + // The unspecified value is not a valid `SpanKind`. Use + // `ValidateSpanKind()` to coerce a span kind to a valid + // value. + SpanKindUnspecified SpanKind = 0 + SpanKindInternal SpanKind = 1 + SpanKindServer SpanKind = 2 + SpanKindClient SpanKind = 3 + SpanKindProducer SpanKind = 4 + SpanKindConsumer SpanKind = 5 +) + +// ValidateSpanKind returns a valid span kind value. This will coerce +// invalid values into the default value, SpanKindInternal. +func ValidateSpanKind(spanKind SpanKind) SpanKind { + switch spanKind { + case SpanKindInternal, + SpanKindServer, + SpanKindClient, + SpanKindProducer, + SpanKindConsumer: + // valid + return spanKind + default: + return SpanKindInternal + } +} + +// String returns the specified name of the SpanKind in lower-case. +func (sk SpanKind) String() string { + switch sk { + case SpanKindInternal: + return "internal" + case SpanKindServer: + return "server" + case SpanKindClient: + return "client" + case SpanKindProducer: + return "producer" + case SpanKindConsumer: + return "consumer" + default: + return "unspecified" + } +} + +// Tracer is the creator of Spans. +type Tracer interface { + // Start creates a span. + Start(ctx context.Context, spanName string, opts ...SpanOption) (context.Context, Span) +} + +// TracerProvider provides access to instrumentation Tracers. +type TracerProvider interface { + // Tracer creates an implementation of the Tracer interface. + // The instrumentationName must be the name of the library providing + // instrumentation. This name may be the same as the instrumented code + // only if that code provides built-in instrumentation. If the + // instrumentationName is empty, then a implementation defined default + // name will be used instead. + Tracer(instrumentationName string, opts ...TracerOption) Tracer +} diff --git a/trace_noop.go b/trace_noop.go new file mode 100644 index 00000000000..b36973bcd14 --- /dev/null +++ b/trace_noop.go @@ -0,0 +1,88 @@ +// 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 otel + +import ( + "context" + "time" + + "go.opentelemetry.io/otel/codes" + "go.opentelemetry.io/otel/label" +) + +// NewNoopTracerProvider returns an implementation of TracerProvider that +// performs no operations. The Tracer and Spans created from the returned +// TracerProvider also perform no operations. +func NewNoopTracerProvider() TracerProvider { + return noopTracerProvider{} +} + +type noopTracerProvider struct{} + +var _ TracerProvider = noopTracerProvider{} + +// Tracer returns noop implementation of Tracer. +func (p noopTracerProvider) Tracer(string, ...TracerOption) Tracer { + return noopTracer{} +} + +// noopTracer is an implementation of Tracer that preforms no operations. +type noopTracer struct{} + +var _ Tracer = noopTracer{} + +// Start starts a noop span. +func (t noopTracer) Start(ctx context.Context, name string, _ ...SpanOption) (context.Context, Span) { + span := noopSpan{} + return ContextWithSpan(ctx, span), span +} + +// noopSpan is an implementation of Span that preforms no operations. +type noopSpan struct{} + +var _ noopSpan = noopSpan{} + +// SpanContext returns an empty span context. +func (noopSpan) SpanContext() SpanContext { return SpanContext{} } + +// IsRecording always returns false. +func (noopSpan) IsRecording() bool { return false } + +// SetStatus does nothing. +func (noopSpan) SetStatus(codes.Code, string) {} + +// SetError does nothing. +func (noopSpan) SetError(bool) {} + +// SetAttributes does nothing. +func (noopSpan) SetAttributes(...label.KeyValue) {} + +// End does nothing. +func (noopSpan) End(...SpanOption) {} + +// RecordError does nothing. +func (noopSpan) RecordError(context.Context, error, ...ErrorOption) {} + +// Tracer returns the Tracer that created this Span. +func (noopSpan) Tracer() Tracer { return noopTracer{} } + +// AddEvent does nothing. +func (noopSpan) AddEvent(context.Context, string, ...label.KeyValue) {} + +// AddEventWithTimestamp does nothing. +func (noopSpan) AddEventWithTimestamp(context.Context, time.Time, string, ...label.KeyValue) {} + +// SetName does nothing. +func (noopSpan) SetName(string) {} diff --git a/trace_noop_test.go b/trace_noop_test.go new file mode 100644 index 00000000000..8cae51d7692 --- /dev/null +++ b/trace_noop_test.go @@ -0,0 +1,76 @@ +// 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 otel + +import ( + "context" + "testing" +) + +func TestNewNoopTracerProvider(t *testing.T) { + got, want := NewNoopTracerProvider(), noopTracerProvider{} + if got != want { + t.Errorf("NewNoopTracerProvider() returned %#v, want %#v", got, want) + } +} + +func TestNoopTracerProviderTracer(t *testing.T) { + tp := NewNoopTracerProvider() + got, want := tp.Tracer(""), noopTracer{} + if got != want { + t.Errorf("noopTracerProvider.Tracer() returned %#v, want %#v", got, want) + } +} + +func TestNoopTracerStart(t *testing.T) { + ctx := context.Background() + tracer := NewNoopTracerProvider().Tracer("test instrumentation") + + var span Span + ctx, span = tracer.Start(ctx, "span name") + got, ok := span.(noopSpan) + if !ok { + t.Fatalf("noopTracer.Start() returned a non-noopSpan: %#v", span) + } + want := noopSpan{} + if got != want { + t.Errorf("noopTracer.Start() returned %#v, want %#v", got, want) + } + got, ok = SpanFromContext(ctx).(noopSpan) + if !ok { + t.Fatal("noopTracer.Start() did not set span as current in returned context") + } + if got != want { + t.Errorf("noopTracer.Start() current span in returned context set to %#v, want %#v", got, want) + } +} + +func TestNoopSpan(t *testing.T) { + tracer := NewNoopTracerProvider().Tracer("test instrumentation") + _, s := tracer.Start(context.Background(), "test span") + span := s.(noopSpan) + + if got, want := span.SpanContext(), (SpanContext{}); got != want { + t.Errorf("span.SpanContext() returned %#v, want %#v", got, want) + } + + if got, want := span.IsRecording(), false; got != want { + t.Errorf("span.IsRecording() returned %#v, want %#v", got, want) + } + + if got, want := span.Tracer(), tracer; got != want { + t.Errorf("span.Tracer() returned %#v, want %#v", got, want) + } +} diff --git a/api/trace/span_context_test.go b/trace_test.go similarity index 54% rename from api/trace/span_context_test.go rename to trace_test.go index 39e85439b2a..246bbd5354f 100644 --- a/api/trace/span_context_test.go +++ b/trace_test.go @@ -12,19 +12,88 @@ // See the License for the specific language governing permissions and // limitations under the License. -package trace_test +package otel import ( + "context" "testing" - - "go.opentelemetry.io/otel/api/trace" ) +type testSpan struct { + noopSpan + + ID int8 +} + +func TestContextSpan(t *testing.T) { + ctx := context.Background() + got, empty := SpanFromContext(ctx), noopSpan{} + if got != empty { + t.Errorf("SpanFromContext returned %v from an empty context, want %v", got, empty) + } + + want := testSpan{ID: 0} + ctx = ContextWithSpan(ctx, want) + if got, ok := ctx.Value(currentSpanKey).(testSpan); !ok { + t.Errorf("failed to set context with %#v", want) + } else if got != want { + t.Errorf("got %#v from context with current set, want %#v", got, want) + } + + if got := SpanFromContext(ctx); got != want { + t.Errorf("SpanFromContext returned %v from a set context, want %v", got, want) + } + + want = testSpan{ID: 1} + ctx = ContextWithSpan(ctx, want) + if got, ok := ctx.Value(currentSpanKey).(testSpan); !ok { + t.Errorf("failed to set context with %#v", want) + } else if got != want { + t.Errorf("got %#v from context with current overridden, want %#v", got, want) + } + + if got := SpanFromContext(ctx); got != want { + t.Errorf("SpanFromContext returned %v from a set context, want %v", got, want) + } +} + +func TestContextRemoteSpanContext(t *testing.T) { + ctx := context.Background() + got, empty := RemoteSpanContextFromContext(ctx), SpanContext{} + if got != empty { + t.Errorf("RemoteSpanContextFromContext returned %v from an empty context, want %v", got, empty) + } + + want := SpanContext{TraceID: [16]byte{1}, SpanID: [8]byte{42}} + ctx = ContextWithRemoteSpanContext(ctx, want) + if got, ok := ctx.Value(remoteContextKey).(SpanContext); !ok { + t.Errorf("failed to set SpanContext with %#v", want) + } else if got != want { + t.Errorf("got %#v from context with remote set, want %#v", got, want) + } + + if got := RemoteSpanContextFromContext(ctx); got != want { + t.Errorf("RemoteSpanContextFromContext returned %v from a set context, want %v", got, want) + } + + want = SpanContext{TraceID: [16]byte{1}, SpanID: [8]byte{43}} + ctx = ContextWithRemoteSpanContext(ctx, want) + if got, ok := ctx.Value(remoteContextKey).(SpanContext); !ok { + t.Errorf("failed to set SpanContext with %#v", want) + } else if got != want { + t.Errorf("got %#v from context with remote overridden, want %#v", got, want) + } + + if got := RemoteSpanContextFromContext(ctx); got != want { + t.Errorf("RemoteSpanContextFromContext returned %v from a set context, want %v", got, want) + } +} + func TestIsValid(t *testing.T) { for _, testcase := range []struct { name string - tid trace.ID - sid trace.SpanID + tid TraceID + sid SpanID want bool }{ { @@ -34,23 +103,23 @@ func TestIsValid(t *testing.T) { want: true, }, { name: "SpanContext.IsValid() returns false if sc has neither an Trace ID nor Span ID", - tid: trace.ID([16]byte{}), + tid: TraceID([16]byte{}), sid: [8]byte{}, want: false, }, { name: "SpanContext.IsValid() returns false if sc has a Span ID but not a Trace ID", - tid: trace.ID([16]byte{}), + tid: TraceID([16]byte{}), sid: [8]byte{42}, want: false, }, { name: "SpanContext.IsValid() returns false if sc has a Trace ID but not a Span ID", - tid: trace.ID([16]byte{1}), + tid: TraceID([16]byte{1}), sid: [8]byte{}, want: false, }, } { t.Run(testcase.name, func(t *testing.T) { - sc := trace.SpanContext{ + sc := SpanContext{ TraceID: testcase.tid, SpanID: testcase.sid, } @@ -66,12 +135,12 @@ func TestIsValidFromHex(t *testing.T) { for _, testcase := range []struct { name string hex string - tid trace.ID + tid TraceID valid bool }{ { name: "Valid TraceID", - tid: trace.ID([16]byte{128, 241, 152, 238, 86, 52, 59, 168, 100, 254, 139, 42, 87, 211, 239, 247}), + tid: TraceID([16]byte{128, 241, 152, 238, 86, 52, 59, 168, 100, 254, 139, 42, 87, 211, 239, 247}), hex: "80f198ee56343ba864fe8b2a57d3eff7", valid: true, }, { @@ -89,7 +158,7 @@ func TestIsValidFromHex(t *testing.T) { }, } { t.Run(testcase.name, func(t *testing.T) { - tid, err := trace.IDFromHex(testcase.hex) + tid, err := TraceIDFromHex(testcase.hex) if testcase.valid && err != nil { t.Errorf("Expected TraceID %s to be valid but end with error %s", testcase.hex, err.Error()) @@ -109,22 +178,22 @@ func TestIsValidFromHex(t *testing.T) { func TestHasTraceID(t *testing.T) { for _, testcase := range []struct { name string - tid trace.ID + tid TraceID want bool }{ { name: "SpanContext.HasTraceID() returns true if both Low and High are nonzero", - tid: trace.ID([16]byte{1}), + tid: TraceID([16]byte{1}), want: true, }, { name: "SpanContext.HasTraceID() returns false if neither Low nor High are nonzero", - tid: trace.ID{}, + tid: TraceID{}, want: false, }, } { t.Run(testcase.name, func(t *testing.T) { //proto: func (sc SpanContext) HasTraceID() bool{} - sc := trace.SpanContext{TraceID: testcase.tid} + sc := SpanContext{TraceID: testcase.tid} have := sc.HasTraceID() if have != testcase.want { t.Errorf("Want: %v, but have: %v", testcase.want, have) @@ -136,16 +205,16 @@ func TestHasTraceID(t *testing.T) { func TestHasSpanID(t *testing.T) { for _, testcase := range []struct { name string - sc trace.SpanContext + sc SpanContext want bool }{ { name: "SpanContext.HasSpanID() returns true if self.SpanID != 0", - sc: trace.SpanContext{SpanID: [8]byte{42}}, + sc: SpanContext{SpanID: [8]byte{42}}, want: true, }, { name: "SpanContext.HasSpanID() returns false if self.SpanID == 0", - sc: trace.SpanContext{}, + sc: SpanContext{}, want: false, }, } { @@ -162,33 +231,33 @@ func TestHasSpanID(t *testing.T) { func TestSpanContextIsSampled(t *testing.T) { for _, testcase := range []struct { name string - sc trace.SpanContext + sc SpanContext want bool }{ { name: "sampled", - sc: trace.SpanContext{ - TraceID: trace.ID([16]byte{1}), - TraceFlags: trace.FlagsSampled, + sc: SpanContext{ + TraceID: TraceID([16]byte{1}), + TraceFlags: FlagsSampled, }, want: true, }, { name: "unused bits are ignored, still not sampled", - sc: trace.SpanContext{ - TraceID: trace.ID([16]byte{1}), - TraceFlags: ^trace.FlagsSampled, + sc: SpanContext{ + TraceID: TraceID([16]byte{1}), + TraceFlags: ^FlagsSampled, }, want: false, }, { name: "unused bits are ignored, still sampled", - sc: trace.SpanContext{ - TraceID: trace.ID([16]byte{1}), - TraceFlags: trace.FlagsSampled | ^trace.FlagsSampled, + sc: SpanContext{ + TraceID: TraceID([16]byte{1}), + TraceFlags: FlagsSampled | ^FlagsSampled, }, want: true, }, { name: "not sampled/default", - sc: trace.SpanContext{TraceID: trace.ID{}}, + sc: SpanContext{TraceID: TraceID{}}, want: false, }, } { @@ -204,17 +273,17 @@ func TestSpanContextIsSampled(t *testing.T) { func TestStringTraceID(t *testing.T) { for _, testcase := range []struct { name string - tid trace.ID + tid TraceID want string }{ { name: "TraceID.String returns string representation of self.TraceID values > 0", - tid: trace.ID([16]byte{255}), + tid: TraceID([16]byte{255}), want: "ff000000000000000000000000000000", }, { name: "TraceID.String returns string representation of self.TraceID values == 0", - tid: trace.ID([16]byte{}), + tid: TraceID([16]byte{}), want: "00000000000000000000000000000000", }, } { @@ -231,17 +300,17 @@ func TestStringTraceID(t *testing.T) { func TestStringSpanID(t *testing.T) { for _, testcase := range []struct { name string - sid trace.SpanID + sid SpanID want string }{ { name: "SpanID.String returns string representation of self.SpanID values > 0", - sid: trace.SpanID([8]byte{255}), + sid: SpanID([8]byte{255}), want: "ff00000000000000", }, { name: "SpanID.String returns string representation of self.SpanID values == 0", - sid: trace.SpanID([8]byte{}), + sid: SpanID([8]byte{}), want: "0000000000000000", }, } { @@ -254,3 +323,83 @@ func TestStringSpanID(t *testing.T) { }) } } + +func TestValidateSpanKind(t *testing.T) { + tests := []struct { + in SpanKind + want SpanKind + }{ + { + SpanKindUnspecified, + SpanKindInternal, + }, + { + + SpanKindInternal, + SpanKindInternal, + }, + { + + SpanKindServer, + SpanKindServer, + }, + { + + SpanKindClient, + SpanKindClient, + }, + { + SpanKindProducer, + SpanKindProducer, + }, + { + SpanKindConsumer, + SpanKindConsumer, + }, + } + for _, test := range tests { + if got := ValidateSpanKind(test.in); got != test.want { + t.Errorf("ValidateSpanKind(%#v) = %#v, want %#v", test.in, got, test.want) + } + } +} + +func TestSpanKindString(t *testing.T) { + tests := []struct { + in SpanKind + want string + }{ + { + SpanKindUnspecified, + "unspecified", + }, + { + + SpanKindInternal, + "internal", + }, + { + + SpanKindServer, + "server", + }, + { + + SpanKindClient, + "client", + }, + { + SpanKindProducer, + "producer", + }, + { + SpanKindConsumer, + "consumer", + }, + } + for _, test := range tests { + if got := test.in.String(); got != test.want { + t.Errorf("%#v.String() = %#v, want %#v", test.in, got, test.want) + } + } +}