1
0
mirror of https://github.com/open-telemetry/opentelemetry-go.git synced 2024-12-24 20:14:40 +02:00

Move trace api package into otel (#1229)

* Move trace API to otel

* Move tracetest to oteltest

* Update package documentation

* Remove old api/trace package

* Lint

* Add changes to CHANGELOG

* Add tests for rest of trace API

* Apply suggestions from code review

Co-authored-by: Anthony Mirabella <a9@aneurysm9.com>

* Documentation fixes

Includes resolutions for review issues.

* Correct CHANGELOG post release

Co-authored-by: Anthony Mirabella <a9@aneurysm9.com>
This commit is contained in:
Tyler Yahn 2020-10-08 19:58:56 -07:00 committed by GitHub
parent 9ebca887f0
commit 27c84d689d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
74 changed files with 1723 additions and 1671 deletions

View File

@ -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

View File

@ -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")

View File

@ -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 {

View File

@ -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...)
}

View File

@ -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()

View File

@ -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)
}

View File

@ -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)

View File

@ -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"
}
}

View File

@ -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()
}

View File

@ -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) {
}

View File

@ -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"

View File

@ -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) {
}

View File

@ -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
}

View File

@ -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{}
}

View File

@ -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
}

View File

@ -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)
}
}

View File

@ -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

View File

@ -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
}

View File

@ -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)
}

View File

@ -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)

View File

@ -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

View File

@ -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
}

190
config.go Normal file
View File

@ -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)
}

View File

@ -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)
}
}

59
doc.go
View File

@ -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"

View File

@ -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()

View File

@ -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"))

View File

@ -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))

View File

@ -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))

View File

@ -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

View File

@ -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{

View File

@ -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,

View File

@ -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()

View File

@ -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

View File

@ -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,

View File

@ -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

View File

@ -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,

View File

@ -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

View File

@ -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),

View File

@ -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),

View File

@ -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(), "")
}

View File

@ -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),

View File

@ -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.

View File

@ -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}
}

View File

@ -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"

View File

@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
package tracetest
package oteltest
import (
"time"

View File

@ -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
}

View File

@ -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
}

View File

@ -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) {

View File

@ -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,

View File

@ -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
}

View File

@ -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)
})
})
}

View File

@ -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
}

View File

@ -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

View File

@ -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)
}
}

View File

@ -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

View File

@ -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)
})

View File

@ -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)

View File

@ -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

View File

@ -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,

View File

@ -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)
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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()

View File

@ -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.

View File

@ -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}

View File

@ -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()

View File

@ -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}

View File

@ -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() {

View File

@ -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
}

362
trace.go Normal file
View File

@ -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
}

88
trace_noop.go Normal file
View File

@ -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) {}

76
trace_noop_test.go Normal file
View File

@ -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)
}
}

View File

@ -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)
}
}
}