diff --git a/sdk/trace/evictedqueue.go b/sdk/trace/evictedqueue.go index 3c62c3299c2..67fe53bede0 100644 --- a/sdk/trace/evictedqueue.go +++ b/sdk/trace/evictedqueue.go @@ -29,6 +29,22 @@ func newEvictedQueue[T any](capacity int) evictedQueue[T] { } } +func newEvictedQueueEvent(capacity int) evictedQueue[Event] { + // Do not pre-allocate queue, do this lazily. + return evictedQueue[Event]{ + capacity: capacity, + logDropped: sync.OnceFunc(func() { global.Warn("limit reached: dropping trace trace.Event") }), + } +} + +func newEvictedQueueLink(capacity int) evictedQueue[Link] { + // Do not pre-allocate queue, do this lazily. + return evictedQueue[Link]{ + capacity: capacity, + logDropped: sync.OnceFunc(func() { global.Warn("limit reached: dropping trace trace.Link") }), + } +} + // add adds value to the evictedQueue eq. If eq is at capacity, the oldest // queued value will be discarded and the drop count incremented. func (eq *evictedQueue[T]) add(value T) { diff --git a/sdk/trace/evictedqueue_test.go b/sdk/trace/evictedqueue_test.go index 2a58ab345e2..7b88d63d077 100644 --- a/sdk/trace/evictedqueue_test.go +++ b/sdk/trace/evictedqueue_test.go @@ -14,47 +14,47 @@ func init() { } func TestAdd(t *testing.T) { - q := newEvictedQueue[string](3) - q.add("value1") - q.add("value2") + q := newEvictedQueueLink(3) + q.add(Link{}) + q.add(Link{}) if wantLen, gotLen := 2, len(q.queue); wantLen != gotLen { t.Errorf("got queue length %d want %d", gotLen, wantLen) } } func TestCopy(t *testing.T) { - q := newEvictedQueue[string](3) - q.add("value1") + q := newEvictedQueueEvent(3) + q.add(Event{Name: "value1"}) cp := q.copy() - q.add("value2") - assert.Equal(t, []string{"value1"}, cp, "queue update modified copy") + q.add(Event{Name: "value2"}) + assert.Equal(t, []Event{{Name: "value1"}}, cp, "queue update modified copy") - cp[0] = "value0" - assert.Equal(t, "value1", q.queue[0], "copy update modified queue") + cp[0] = Event{Name: "value0"} + assert.Equal(t, Event{Name: "value1"}, q.queue[0], "copy update modified queue") } func TestDropCount(t *testing.T) { - q := newEvictedQueue[string](3) + q := newEvictedQueueEvent(3) var called bool q.logDropped = func() { called = true } - q.add("value1") + q.add(Event{Name: "value1"}) assert.False(t, called, `"value1" logged as dropped`) - q.add("value2") + q.add(Event{Name: "value2"}) assert.False(t, called, `"value2" logged as dropped`) - q.add("value3") + q.add(Event{Name: "value3"}) assert.False(t, called, `"value3" logged as dropped`) - q.add("value1") + q.add(Event{Name: "value1"}) assert.True(t, called, `"value2" not logged as dropped`) - q.add("value4") + q.add(Event{Name: "value4"}) if wantLen, gotLen := 3, len(q.queue); wantLen != gotLen { t.Errorf("got queue length %d want %d", gotLen, wantLen) } if wantDropCount, gotDropCount := 2, q.droppedCount; wantDropCount != gotDropCount { t.Errorf("got drop count %d want %d", gotDropCount, wantDropCount) } - wantArr := []string{"value3", "value1", "value4"} + wantArr := []Event{{Name: "value3"}, {Name: "value1"}, {Name: "value4"}} gotArr := q.copy() if wantLen, gotLen := len(wantArr), len(gotArr); gotLen != wantLen { diff --git a/sdk/trace/trace_test.go b/sdk/trace/trace_test.go index 435c88849f6..bca58219a5e 100644 --- a/sdk/trace/trace_test.go +++ b/sdk/trace/trace_test.go @@ -2107,3 +2107,16 @@ func TestAddLinkToNonRecordingSpan(t *testing.T) { t.Errorf("AddLinkToNonRecordingSpan: -got +want %s", diff) } } + +func BenchmarkTraceStart(b *testing.B) { + tracer := NewTracerProvider().Tracer("") + ctx := trace.ContextWithSpanContext(context.Background(), trace.SpanContext{}) + + b.ReportAllocs() + b.ResetTimer() + + for i := 0; i < b.N; i++ { + _, span := tracer.Start(ctx, "") + span.End() + } +} diff --git a/sdk/trace/tracer.go b/sdk/trace/tracer.go index 8c4142d6f29..43419d3b541 100644 --- a/sdk/trace/tracer.go +++ b/sdk/trace/tracer.go @@ -132,8 +132,8 @@ func (tr *tracer) newRecordingSpan(psc, sc trace.SpanContext, name string, sr Sa spanKind: trace.ValidateSpanKind(config.SpanKind()), name: name, startTime: startTime, - events: newEvictedQueue[Event](tr.provider.spanLimits.EventCountLimit), - links: newEvictedQueue[Link](tr.provider.spanLimits.LinkCountLimit), + events: newEvictedQueueEvent(tr.provider.spanLimits.EventCountLimit), + links: newEvictedQueueLink(tr.provider.spanLimits.LinkCountLimit), tracer: tr, }