diff --git a/pkg/util/tracing/crdbspan.go b/pkg/util/tracing/crdbspan.go index b15fbca87726..544566bf514a 100644 --- a/pkg/util/tracing/crdbspan.go +++ b/pkg/util/tracing/crdbspan.go @@ -760,7 +760,7 @@ func (s *crdbSpan) getVerboseRecording(includeDetachedChildren bool, finishing b result.StructuredRecordsSizeBytes += result.Root.StructuredRecordsSizeBytes for i := range oldEvents { size := int64(oldEvents[i].Size()) - if result.StructuredRecordsSizeBytes+size < maxStructuredBytesPerTrace { + if result.StructuredRecordsSizeBytes+size <= maxStructuredBytesPerTrace { result.Root.AddStructuredRecord(oldEvents[i]) result.StructuredRecordsSizeBytes += size } @@ -883,14 +883,25 @@ func (s *crdbSpan) recordFinishedChildrenLocked(childRec Trace) { childRec.Root.ParentSpanID = s.spanID s.mu.recording.finishedChildren.addChildren([]Trace{childRec}, maxRecordedSpansPerTrace, maxStructuredBytesPerTrace) case tracingpb.RecordingStructured: - buf := childRec.appendStructuredEventsRecursively(nil /* buffer */) - for i := range buf { - event := &buf[i] - if s.mu.recording.finishedChildren.StructuredRecordsSizeBytes+int64(event.MemorySize()) < maxStructuredBytesPerTrace { - size := s.mu.recording.finishedChildren.Root.AddStructuredRecord(*event) - s.mu.recording.finishedChildren.StructuredRecordsSizeBytes += size + fc := &s.mu.recording.finishedChildren + num := len(fc.Root.StructuredRecords) + fc.Root.StructuredRecords = childRec.appendStructuredEventsRecursively(fc.Root.StructuredRecords) + // Account for the size of the structured records that were appended, + // breaking out of the loop if we hit the byte limit. This incorporates + // the byte size accounting logic from RecordedSpan.AddStructuredRecord. + for ; num < len(fc.Root.StructuredRecords); num++ { + size := int64(fc.Root.StructuredRecords[num].MemorySize()) + if fc.StructuredRecordsSizeBytes+size > maxStructuredBytesPerTrace { + break } + fc.Root.StructuredRecordsSizeBytes += size + fc.StructuredRecordsSizeBytes += size + } + // Trim any remaining entries if we hit the byte limit. + for i := num; i < len(fc.Root.StructuredRecords); i++ { + fc.Root.StructuredRecords[i] = tracingpb.StructuredRecord{} } + fc.Root.StructuredRecords = fc.Root.StructuredRecords[:num] case tracingpb.RecordingOff: break default: