diff --git a/CHANGELOG.md b/CHANGELOG.md index 9590cedc03f..b2cda4b4fd1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -41,6 +41,8 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm This brings the export interface into compliance with the specification in that it now accepts an explicitly immutable type instead of just an implied one. (#1873) - Unembed `SpanContext` in `Link`. (#1877) - Semantic conventions are now generated from the specification YAML. (#1891) +- Spans created by the global `Tracer` obtained from `go.opentelemetry.io/otel`, prior to a functioning `TracerProvider` being set, now propagate the span context from their parent if one exists. (#1901) +- Move the `go.opentelemetry.io/otel/unit` package to `go.opentelemetry.io/otel/metric/unit`. (#1903) ### Deprecated diff --git a/bridge/opencensus/exporter.go b/bridge/opencensus/exporter.go index c73ea891c68..ca12f283a60 100644 --- a/bridge/opencensus/exporter.go +++ b/bridge/opencensus/exporter.go @@ -28,10 +28,10 @@ import ( "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/metric" "go.opentelemetry.io/otel/metric/number" + "go.opentelemetry.io/otel/metric/unit" export "go.opentelemetry.io/otel/sdk/export/metric" "go.opentelemetry.io/otel/sdk/export/metric/aggregation" "go.opentelemetry.io/otel/sdk/resource" - "go.opentelemetry.io/otel/unit" ) var errConversion = errors.New("Unable to convert from OpenCensus to OpenTelemetry") diff --git a/bridge/opencensus/exporter_test.go b/bridge/opencensus/exporter_test.go index c15ba4b6812..766f8a10140 100644 --- a/bridge/opencensus/exporter_test.go +++ b/bridge/opencensus/exporter_test.go @@ -29,11 +29,11 @@ import ( "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/metric" "go.opentelemetry.io/otel/metric/number" + "go.opentelemetry.io/otel/metric/unit" export "go.opentelemetry.io/otel/sdk/export/metric" exportmetric "go.opentelemetry.io/otel/sdk/export/metric" "go.opentelemetry.io/otel/sdk/export/metric/aggregation" "go.opentelemetry.io/otel/sdk/resource" - "go.opentelemetry.io/otel/unit" ) type fakeExporter struct { diff --git a/internal/global/trace.go b/internal/global/trace.go index d7f71dc06c6..aedf1168804 100644 --- a/internal/global/trace.go +++ b/internal/global/trace.go @@ -36,7 +36,8 @@ import ( "sync" "sync/atomic" - "go.opentelemetry.io/otel/internal/trace/noop" + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/codes" "go.opentelemetry.io/otel/trace" ) @@ -143,5 +144,44 @@ func (t *tracer) Start(ctx context.Context, name string, opts ...trace.SpanOptio if delegate != nil { return delegate.(trace.Tracer).Start(ctx, name, opts...) } - return noop.Tracer.Start(ctx, name, opts...) + + s := nonRecordingSpan{sc: trace.SpanContextFromContext(ctx)} + ctx = trace.ContextWithSpan(ctx, s) + return ctx, s +} + +// nonRecordingSpan is a minimal implementation of a Span that wraps a +// SpanContext. It performs no operations other than to return the wrapped +// SpanContext. +type nonRecordingSpan struct { + sc trace.SpanContext } + +var _ trace.Span = nonRecordingSpan{} + +// SpanContext returns the wrapped SpanContext. +func (s nonRecordingSpan) SpanContext() trace.SpanContext { return s.sc } + +// IsRecording always returns false. +func (nonRecordingSpan) IsRecording() bool { return false } + +// SetStatus does nothing. +func (nonRecordingSpan) SetStatus(codes.Code, string) {} + +// SetError does nothing. +func (nonRecordingSpan) SetError(bool) {} + +// SetAttributes does nothing. +func (nonRecordingSpan) SetAttributes(...attribute.KeyValue) {} + +// End does nothing. +func (nonRecordingSpan) End(...trace.SpanOption) {} + +// RecordError does nothing. +func (nonRecordingSpan) RecordError(error, ...trace.EventOption) {} + +// AddEvent does nothing. +func (nonRecordingSpan) AddEvent(string, ...trace.EventOption) {} + +// SetName does nothing. +func (nonRecordingSpan) SetName(string) {} diff --git a/internal/global/trace_test.go b/internal/global/trace_test.go index a8fdfb44d9d..4ca53c35984 100644 --- a/internal/global/trace_test.go +++ b/internal/global/trace_test.go @@ -213,3 +213,19 @@ func TestTraceProviderDelegatesSameInstance(t *testing.T) { assert.NotSame(t, tracer, gtp.Tracer("abc", trace.WithInstrumentationVersion("xyz"))) } + +func TestSpanContextPropagatedWithNonRecordingSpan(t *testing.T) { + global.ResetForTest() + + sc := trace.NewSpanContext(trace.SpanContextConfig{ + TraceID: [16]byte{0x01}, + SpanID: [8]byte{0x01}, + TraceFlags: trace.FlagsSampled, + Remote: true, + }) + ctx := trace.ContextWithSpanContext(context.Background(), sc) + _, span := otel.Tracer("test").Start(ctx, "test") + + assert.Equal(t, sc, span.SpanContext()) + assert.False(t, span.IsRecording()) +} diff --git a/metric/config.go b/metric/config.go index 02f0ff8e0cb..8877ae78021 100644 --- a/metric/config.go +++ b/metric/config.go @@ -15,7 +15,7 @@ package metric // import "go.opentelemetry.io/otel/metric" import ( - "go.opentelemetry.io/otel/unit" + "go.opentelemetry.io/otel/metric/unit" ) // InstrumentConfig contains options for metric instrument descriptors. diff --git a/metric/metric.go b/metric/metric.go index b591985df68..a5d0dcd04f2 100644 --- a/metric/metric.go +++ b/metric/metric.go @@ -19,7 +19,7 @@ import ( "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/metric/number" - "go.opentelemetry.io/otel/unit" + "go.opentelemetry.io/otel/metric/unit" ) // MeterProvider supports named Meter instances. diff --git a/metric/metric_test.go b/metric/metric_test.go index a50bf68cd74..f01d7a1ebd2 100644 --- a/metric/metric_test.go +++ b/metric/metric_test.go @@ -22,8 +22,8 @@ import ( "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/metric" "go.opentelemetry.io/otel/metric/number" + "go.opentelemetry.io/otel/metric/unit" "go.opentelemetry.io/otel/oteltest" - "go.opentelemetry.io/otel/unit" "github.com/google/go-cmp/cmp" "github.com/stretchr/testify/assert" diff --git a/unit/doc.go b/metric/unit/doc.go similarity index 93% rename from unit/doc.go rename to metric/unit/doc.go index 0d77a750cc3..f8e723593e6 100644 --- a/unit/doc.go +++ b/metric/unit/doc.go @@ -17,4 +17,4 @@ // This package is currently in a pre-GA phase. Backwards incompatible changes // may be introduced in subsequent minor version releases as we work to track // the evolving OpenTelemetry specification and user feedback. -package unit // import "go.opentelemetry.io/otel/unit" +package unit // import "go.opentelemetry.io/otel/metric/unit" diff --git a/unit/unit.go b/metric/unit/unit.go similarity index 91% rename from unit/unit.go rename to metric/unit/unit.go index 523bfe1d0a1..08a3b21f004 100644 --- a/unit/unit.go +++ b/metric/unit/unit.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package unit // import "go.opentelemetry.io/otel/unit" +package unit // import "go.opentelemetry.io/otel/metric/unit" type Unit string