@@ -174,6 +174,16 @@ func (s *recordingSpan) IsRecording() bool {
174
174
s .mu .Lock ()
175
175
defer s .mu .Unlock ()
176
176
177
+ return s .isRecording ()
178
+ }
179
+
180
+ // isRecording returns if this span is being recorded. If this span has ended
181
+ // this will return false.
182
+ // This is done without acquiring a lock.
183
+ func (s * recordingSpan ) isRecording () bool {
184
+ if s == nil {
185
+ return false
186
+ }
177
187
return s .endTime .IsZero ()
178
188
}
179
189
@@ -182,11 +192,15 @@ func (s *recordingSpan) IsRecording() bool {
182
192
// included in the set status when the code is for an error. If this span is
183
193
// not being recorded than this method does nothing.
184
194
func (s * recordingSpan ) SetStatus (code codes.Code , description string ) {
185
- if ! s . IsRecording () {
195
+ if s == nil {
186
196
return
187
197
}
198
+
188
199
s .mu .Lock ()
189
200
defer s .mu .Unlock ()
201
+ if ! s .isRecording () {
202
+ return
203
+ }
190
204
if s .status .Code > code {
191
205
return
192
206
}
@@ -210,12 +224,15 @@ func (s *recordingSpan) SetStatus(code codes.Code, description string) {
210
224
// attributes the span is configured to have, the last added attributes will
211
225
// be dropped.
212
226
func (s * recordingSpan ) SetAttributes (attributes ... attribute.KeyValue ) {
213
- if ! s . IsRecording () {
227
+ if s == nil || len ( attributes ) == 0 {
214
228
return
215
229
}
216
230
217
231
s .mu .Lock ()
218
232
defer s .mu .Unlock ()
233
+ if ! s .isRecording () {
234
+ return
235
+ }
219
236
220
237
limit := s .tracer .provider .spanLimits .AttributeCountLimit
221
238
if limit == 0 {
@@ -233,7 +250,7 @@ func (s *recordingSpan) SetAttributes(attributes ...attribute.KeyValue) {
233
250
234
251
// Otherwise, add without deduplication. When attributes are read they
235
252
// will be deduplicated, optimizing the operation.
236
- s .attributes = slices .Grow (s .attributes , len (s . attributes ) + len ( attributes ))
253
+ s .attributes = slices .Grow (s .attributes , len (attributes ))
237
254
for _ , a := range attributes {
238
255
if ! a .Valid () {
239
256
// Drop all invalid attributes.
@@ -280,13 +297,17 @@ func (s *recordingSpan) addOverCapAttrs(limit int, attrs []attribute.KeyValue) {
280
297
281
298
// Do not set a capacity when creating this map. Benchmark testing has
282
299
// showed this to only add unused memory allocations in general use.
283
- exists := make (map [attribute.Key ]int )
284
- s .dedupeAttrsFromRecord (& exists )
300
+ exists := make (map [attribute.Key ]int , len ( s . attributes ) )
301
+ s .dedupeAttrsFromRecord (exists )
285
302
286
303
// Now that s.attributes is deduplicated, adding unique attributes up to
287
304
// the capacity of s will not over allocate s.attributes.
288
- sum := len (attrs ) + len (s .attributes )
289
- s .attributes = slices .Grow (s .attributes , min (sum , limit ))
305
+
306
+ // max size = limit
307
+ maxCap := min (len (attrs )+ len (s .attributes ), limit )
308
+ if cap (s .attributes ) < maxCap {
309
+ s .attributes = slices .Grow (s .attributes , maxCap - cap (s .attributes ))
310
+ }
290
311
for _ , a := range attrs {
291
312
if ! a .Valid () {
292
313
// Drop all invalid attributes.
@@ -296,6 +317,7 @@ func (s *recordingSpan) addOverCapAttrs(limit int, attrs []attribute.KeyValue) {
296
317
297
318
if idx , ok := exists [a .Key ]; ok {
298
319
// Perform all updates before dropping, even when at capacity.
320
+ a = truncateAttr (s .tracer .provider .spanLimits .AttributeValueLengthLimit , a )
299
321
s .attributes [idx ] = a
300
322
continue
301
323
}
@@ -518,12 +540,15 @@ func (s *recordingSpan) addEvent(name string, o ...trace.EventOption) {
518
540
// SetName sets the name of this span. If this span is not being recorded than
519
541
// this method does nothing.
520
542
func (s * recordingSpan ) SetName (name string ) {
521
- if ! s . IsRecording () {
543
+ if s == nil {
522
544
return
523
545
}
524
546
525
547
s .mu .Lock ()
526
548
defer s .mu .Unlock ()
549
+ if ! s .isRecording () {
550
+ return
551
+ }
527
552
s .name = name
528
553
}
529
554
@@ -579,23 +604,23 @@ func (s *recordingSpan) Attributes() []attribute.KeyValue {
579
604
func (s * recordingSpan ) dedupeAttrs () {
580
605
// Do not set a capacity when creating this map. Benchmark testing has
581
606
// showed this to only add unused memory allocations in general use.
582
- exists := make (map [attribute.Key ]int )
583
- s .dedupeAttrsFromRecord (& exists )
607
+ exists := make (map [attribute.Key ]int , len ( s . attributes ) )
608
+ s .dedupeAttrsFromRecord (exists )
584
609
}
585
610
586
611
// dedupeAttrsFromRecord deduplicates the attributes of s to fit capacity
587
612
// using record as the record of unique attribute keys to their index.
588
613
//
589
614
// This method assumes s.mu.Lock is held by the caller.
590
- func (s * recordingSpan ) dedupeAttrsFromRecord (record * map [attribute.Key ]int ) {
615
+ func (s * recordingSpan ) dedupeAttrsFromRecord (record map [attribute.Key ]int ) {
591
616
// Use the fact that slices share the same backing array.
592
617
unique := s .attributes [:0 ]
593
618
for _ , a := range s .attributes {
594
- if idx , ok := ( * record ) [a .Key ]; ok {
619
+ if idx , ok := record [a .Key ]; ok {
595
620
unique [idx ] = a
596
621
} else {
597
622
unique = append (unique , a )
598
- ( * record ) [a .Key ] = len (unique ) - 1
623
+ record [a .Key ] = len (unique ) - 1
599
624
}
600
625
}
601
626
// s.attributes have element types of attribute.KeyValue. These types are
@@ -755,12 +780,16 @@ func (s *recordingSpan) snapshot() ReadOnlySpan {
755
780
}
756
781
757
782
func (s * recordingSpan ) addChild () {
758
- if ! s . IsRecording () {
783
+ if s == nil {
759
784
return
760
785
}
786
+
761
787
s .mu .Lock ()
788
+ defer s .mu .Unlock ()
789
+ if ! s .isRecording () {
790
+ return
791
+ }
762
792
s .childSpanCount ++
763
- s .mu .Unlock ()
764
793
}
765
794
766
795
func (* recordingSpan ) private () {}
0 commit comments