@@ -151,13 +151,23 @@ type recordingSpan struct {
151151
152152 // tracer is the SDK tracer that created this span.
153153 tracer * tracer
154+
155+ // origCtx is the context used when starting this span that has the
156+ // recordingSpan instance set as the active span. If not nil, it is used
157+ // when ending the span to ensure any metrics are recorded with a context
158+ // containing this span without requiring an additional allocation.
159+ origCtx context.Context
154160}
155161
156162var (
157163 _ ReadWriteSpan = (* recordingSpan )(nil )
158164 _ runtimeTracer = (* recordingSpan )(nil )
159165)
160166
167+ func (s * recordingSpan ) setOrigCtx (ctx context.Context ) {
168+ s .origCtx = ctx
169+ }
170+
161171// SpanContext returns the SpanContext of this span.
162172func (s * recordingSpan ) SpanContext () trace.SpanContext {
163173 if s == nil {
@@ -497,13 +507,17 @@ func (s *recordingSpan) End(options ...trace.SpanEndOption) {
497507 s .mu .Unlock ()
498508
499509 if s .tracer .observabilityEnabled {
500- defer func () {
501- // Add the span to the context to ensure the metric is recorded
502- // with the correct span context.
503- ctx := trace .ContextWithSpan (context .Background (), s )
510+ ctx := s .origCtx
511+ if ctx == nil {
512+ // This should not happen as the origCtx should be set, but
513+ // ensure trace information is propagated in the case of an
514+ // error.
515+ ctx = trace .ContextWithSpan (context .Background (), s )
516+ }
517+ defer func (ctx context.Context ) {
504518 set := spanLiveSet (s .spanContext .IsSampled ())
505519 s .tracer .spanLiveMetric .AddSet (ctx , - 1 , set )
506- }()
520+ }(ctx )
507521 }
508522
509523 sps := s .tracer .provider .getSpanProcessors ()
0 commit comments