mirror of
https://github.com/open-telemetry/opentelemetry-go.git
synced 2025-04-21 11:57:04 +02:00
trace: Add Span.AddLink method (#5032)
This commit is contained in:
parent
321219b2a6
commit
554282d3e4
@ -10,6 +10,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
|
|||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
|
- Add `AddLink` method to the `Span` interface in `go.opentelemetry.io/otel/trace`. (#5032)
|
||||||
- Add `WithProxy` option in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp`. (#4906)
|
- Add `WithProxy` option in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp`. (#4906)
|
||||||
- Add `WithProxy` option in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlptracehttp`. (#4906)
|
- Add `WithProxy` option in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlptracehttp`. (#4906)
|
||||||
- The `Enabled` method is added to the `Logger` interface in `go.opentelemetry.io/otel/log`.
|
- The `Enabled` method is added to the `Logger` interface in `go.opentelemetry.io/otel/log`.
|
||||||
|
@ -176,6 +176,11 @@ type MockEvent struct {
|
|||||||
Attributes []attribute.KeyValue
|
Attributes []attribute.KeyValue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type MockLink struct {
|
||||||
|
SpanContext trace.SpanContext
|
||||||
|
Attributes []attribute.KeyValue
|
||||||
|
}
|
||||||
|
|
||||||
type MockSpan struct {
|
type MockSpan struct {
|
||||||
embedded.Span
|
embedded.Span
|
||||||
|
|
||||||
@ -190,6 +195,7 @@ type MockSpan struct {
|
|||||||
EndTime time.Time
|
EndTime time.Time
|
||||||
ParentSpanID trace.SpanID
|
ParentSpanID trace.SpanID
|
||||||
Events []MockEvent
|
Events []MockEvent
|
||||||
|
Links []MockLink
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -286,6 +292,13 @@ func (s *MockSpan) AddEvent(name string, o ...trace.EventOption) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *MockSpan) AddLink(link trace.Link) {
|
||||||
|
s.Links = append(s.Links, MockLink{
|
||||||
|
SpanContext: link.SpanContext,
|
||||||
|
Attributes: link.Attributes,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func (s *MockSpan) OverrideTracer(tracer trace.Tracer) {
|
func (s *MockSpan) OverrideTracer(tracer trace.Tracer) {
|
||||||
s.officialTracer = tracer
|
s.officialTracer = tracer
|
||||||
}
|
}
|
||||||
|
@ -182,6 +182,9 @@ func (nonRecordingSpan) RecordError(error, ...trace.EventOption) {}
|
|||||||
// AddEvent does nothing.
|
// AddEvent does nothing.
|
||||||
func (nonRecordingSpan) AddEvent(string, ...trace.EventOption) {}
|
func (nonRecordingSpan) AddEvent(string, ...trace.EventOption) {}
|
||||||
|
|
||||||
|
// AddLink does nothing.
|
||||||
|
func (nonRecordingSpan) AddLink(trace.Link) {}
|
||||||
|
|
||||||
// SetName does nothing.
|
// SetName does nothing.
|
||||||
func (nonRecordingSpan) SetName(string) {}
|
func (nonRecordingSpan) SetName(string) {}
|
||||||
|
|
||||||
|
@ -629,7 +629,7 @@ func (s *recordingSpan) Resource() *resource.Resource {
|
|||||||
return s.tracer.provider.resource
|
return s.tracer.provider.resource
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *recordingSpan) addLink(link trace.Link) {
|
func (s *recordingSpan) AddLink(link trace.Link) {
|
||||||
if !s.IsRecording() || !link.SpanContext.IsValid() {
|
if !s.IsRecording() || !link.SpanContext.IsValid() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -803,6 +803,9 @@ func (nonRecordingSpan) RecordError(error, ...trace.EventOption) {}
|
|||||||
// AddEvent does nothing.
|
// AddEvent does nothing.
|
||||||
func (nonRecordingSpan) AddEvent(string, ...trace.EventOption) {}
|
func (nonRecordingSpan) AddEvent(string, ...trace.EventOption) {}
|
||||||
|
|
||||||
|
// AddLink does nothing.
|
||||||
|
func (nonRecordingSpan) AddLink(trace.Link) {}
|
||||||
|
|
||||||
// SetName does nothing.
|
// SetName does nothing.
|
||||||
func (nonRecordingSpan) SetName(string) {}
|
func (nonRecordingSpan) SetName(string) {}
|
||||||
|
|
||||||
|
@ -1976,3 +1976,81 @@ func TestEmptyRecordingSpanAttributes(t *testing.T) {
|
|||||||
func TestEmptyRecordingSpanDroppedAttributes(t *testing.T) {
|
func TestEmptyRecordingSpanDroppedAttributes(t *testing.T) {
|
||||||
assert.Equal(t, 0, (&recordingSpan{}).DroppedAttributes())
|
assert.Equal(t, 0, (&recordingSpan{}).DroppedAttributes())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestAddLinkWithInvalidSpanContext(t *testing.T) {
|
||||||
|
te := NewTestExporter()
|
||||||
|
sl := NewSpanLimits()
|
||||||
|
tp := NewTracerProvider(
|
||||||
|
WithSpanLimits(sl),
|
||||||
|
WithSyncer(te),
|
||||||
|
WithResource(resource.Empty()),
|
||||||
|
)
|
||||||
|
span := startSpan(tp, "AddSpanWithInvalidSpanContext")
|
||||||
|
inValidContext := trace.NewSpanContext(trace.SpanContextConfig{
|
||||||
|
TraceID: trace.TraceID([16]byte{}),
|
||||||
|
SpanID: [8]byte{},
|
||||||
|
})
|
||||||
|
attrs := []attribute.KeyValue{{Key: "k", Value: attribute.StringValue("v")}}
|
||||||
|
span.AddLink(trace.Link{
|
||||||
|
SpanContext: inValidContext,
|
||||||
|
Attributes: attrs,
|
||||||
|
})
|
||||||
|
|
||||||
|
want := &snapshot{
|
||||||
|
name: "span0",
|
||||||
|
spanContext: trace.NewSpanContext(trace.SpanContextConfig{
|
||||||
|
TraceID: tid,
|
||||||
|
TraceFlags: 0x1,
|
||||||
|
}),
|
||||||
|
parent: sc.WithRemote(true),
|
||||||
|
links: nil,
|
||||||
|
spanKind: trace.SpanKindInternal,
|
||||||
|
instrumentationScope: instrumentation.Scope{Name: "AddSpanWithInvalidSpanContext"},
|
||||||
|
}
|
||||||
|
got, err := endSpan(te, span)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if diff := cmpDiff(got, want); diff != "" {
|
||||||
|
t.Errorf("AddLinkWithInvalidSpanContext: -got +want %s", diff)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAddLink(t *testing.T) {
|
||||||
|
te := NewTestExporter()
|
||||||
|
sl := NewSpanLimits()
|
||||||
|
tp := NewTracerProvider(
|
||||||
|
WithSpanLimits(sl),
|
||||||
|
WithSyncer(te),
|
||||||
|
WithResource(resource.Empty()),
|
||||||
|
)
|
||||||
|
attrs := []attribute.KeyValue{{Key: "k", Value: attribute.StringValue("v")}}
|
||||||
|
span := startSpan(tp, "AddSpan")
|
||||||
|
|
||||||
|
link := trace.Link{SpanContext: sc, Attributes: attrs}
|
||||||
|
span.AddLink(link)
|
||||||
|
|
||||||
|
want := &snapshot{
|
||||||
|
name: "span0",
|
||||||
|
spanContext: trace.NewSpanContext(trace.SpanContextConfig{
|
||||||
|
TraceID: tid,
|
||||||
|
TraceFlags: 0x1,
|
||||||
|
}),
|
||||||
|
parent: sc.WithRemote(true),
|
||||||
|
links: []Link{
|
||||||
|
{
|
||||||
|
SpanContext: sc,
|
||||||
|
Attributes: attrs,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
spanKind: trace.SpanKindInternal,
|
||||||
|
instrumentationScope: instrumentation.Scope{Name: "AddSpan"},
|
||||||
|
}
|
||||||
|
got, err := endSpan(te, span)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if diff := cmpDiff(got, want); diff != "" {
|
||||||
|
t.Errorf("AddLink: -got +want %s", diff)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -138,7 +138,7 @@ func (tr *tracer) newRecordingSpan(psc, sc trace.SpanContext, name string, sr Sa
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, l := range config.Links() {
|
for _, l := range config.Links() {
|
||||||
s.addLink(l)
|
s.AddLink(l)
|
||||||
}
|
}
|
||||||
|
|
||||||
s.SetAttributes(sr.Attributes...)
|
s.SetAttributes(sr.Attributes...)
|
||||||
|
@ -75,6 +75,9 @@ func (noopSpan) RecordError(error, ...EventOption) {}
|
|||||||
// AddEvent does nothing.
|
// AddEvent does nothing.
|
||||||
func (noopSpan) AddEvent(string, ...EventOption) {}
|
func (noopSpan) AddEvent(string, ...EventOption) {}
|
||||||
|
|
||||||
|
// AddLink does nothing.
|
||||||
|
func (noopSpan) AddLink(Link) {}
|
||||||
|
|
||||||
// SetName does nothing.
|
// SetName does nothing.
|
||||||
func (noopSpan) SetName(string) {}
|
func (noopSpan) SetName(string) {}
|
||||||
|
|
||||||
|
@ -100,6 +100,9 @@ func (Span) RecordError(error, ...trace.EventOption) {}
|
|||||||
// AddEvent does nothing.
|
// AddEvent does nothing.
|
||||||
func (Span) AddEvent(string, ...trace.EventOption) {}
|
func (Span) AddEvent(string, ...trace.EventOption) {}
|
||||||
|
|
||||||
|
// AddLink does nothing.
|
||||||
|
func (Span) AddLink(trace.Link) {}
|
||||||
|
|
||||||
// SetName does nothing.
|
// SetName does nothing.
|
||||||
func (Span) SetName(string) {}
|
func (Span) SetName(string) {}
|
||||||
|
|
||||||
|
@ -350,6 +350,12 @@ type Span interface {
|
|||||||
// AddEvent adds an event with the provided name and options.
|
// AddEvent adds an event with the provided name and options.
|
||||||
AddEvent(name string, options ...EventOption)
|
AddEvent(name string, options ...EventOption)
|
||||||
|
|
||||||
|
// AddLink adds a link.
|
||||||
|
// Adding links at span creation using WithLinks is preferred to calling AddLink
|
||||||
|
// later, for contexts that are available during span creation, because head
|
||||||
|
// sampling decisions can only consider information present during span creation.
|
||||||
|
AddLink(link Link)
|
||||||
|
|
||||||
// IsRecording returns the recording state of the Span. It will return
|
// IsRecording returns the recording state of the Span. It will return
|
||||||
// true if the Span is active and events can be recorded.
|
// true if the Span is active and events can be recorded.
|
||||||
IsRecording() bool
|
IsRecording() bool
|
||||||
|
Loading…
x
Reference in New Issue
Block a user