1
0
mirror of https://github.com/open-telemetry/opentelemetry-go.git synced 2025-10-31 00:07:40 +02:00

Implement global default non-recording span (#1901)

* Remove the Tracer method from the Span API

* Update CHANGELOG with changes

* Update CHANGELOG.md

* Fix misspell

* Address feedback

* Implement global default non-recording span

* Add changes to CHANGELOG

* Update PR number in changelog
This commit is contained in:
Tyler Yahn
2021-05-12 17:11:56 +00:00
committed by GitHub
parent b6d5442ff6
commit 63e0ecfc22
3 changed files with 59 additions and 2 deletions

View File

@@ -40,6 +40,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
- The `ExportSpans` method of the`SpanExporter` interface type was updated to accept `ReadOnlySpan`s instead of the removed `SpanSnapshot`.
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)
- 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)
### Deprecated

View File

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

View File

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