1package lightstep 2 3import ( 4 "time" 5) 6 7type reportBuffer struct { 8 rawSpans []RawSpan 9 10 // droppedSpanCount is the total number of spans that have been dropped 11 // (either because the buffer was full when the span arrived or because a report 12 // failed and there wasn't sufficient room to re-enqueue the spans back into the 13 // following report). 14 // 15 // This counter increases continually until is has successfully been reported 16 // to the telemetry provider by being attached to a report that doesn't return 17 // an error. 18 droppedSpanCount int64 19 // reportedDroppedSpanCount is a counter that tracks the cumulative value of what 20 // has been reported to the service through an event status report. This should 21 // always be smaller than droppedSpanCount because droppedSpanCount is monotonically 22 // increasing and this only represents the value reported in the past. 23 // To determine what to report in the next event status report, subtract the previously 24 // reported value from the updated dropped spans count (see reportDroppedSpanCount). 25 reportedDroppedSpanCount int64 26 27 // logEncoderErrorCount is the total number of spans that have been rejected 28 // because of a log encoder error. 29 // 30 // This counter increases continually until is has successfully been reported 31 // to the telemetry provider by being attached to a report that doesn't return 32 // an error. 33 logEncoderErrorCount int64 34 // reportedLogEncoderErrorCount is a counter that tracks the cumulative value of what 35 // has been reported to the service through an event status report. This should 36 // always be smaller than logEncoderErrorCount because logEncoderErrorCount is monotonically 37 // increasing and this only represents the value reported in the past. 38 // To determine what to report in the next event status report, subtract the previously 39 // reported value from the updated dropped spans count (see reportLogEncoderErrorCount). 40 reportedLogEncoderErrorCount int64 41 42 reportStart time.Time 43 reportEnd time.Time 44} 45 46func newSpansBuffer(size int) (b reportBuffer) { 47 b.rawSpans = make([]RawSpan, 0, size) 48 b.reportStart = time.Time{} 49 b.reportEnd = time.Time{} 50 return 51} 52 53func (b *reportBuffer) isHalfFull() bool { 54 return len(b.rawSpans) > cap(b.rawSpans)/2 55} 56 57func (b *reportBuffer) setCurrent(now time.Time) { 58 b.reportStart = now 59 b.reportEnd = now 60} 61 62func (b *reportBuffer) setFlushing(now time.Time) { 63 b.reportEnd = now 64} 65 66func (b *reportBuffer) clear() { 67 b.rawSpans = b.rawSpans[:0] 68 b.reportStart = time.Time{} 69 b.reportEnd = time.Time{} 70 b.droppedSpanCount = 0 71 b.reportedDroppedSpanCount = 0 72 b.logEncoderErrorCount = 0 73 b.reportedLogEncoderErrorCount = 0 74} 75 76func (b *reportBuffer) addSpan(span RawSpan) { 77 if len(b.rawSpans) == cap(b.rawSpans) { 78 b.droppedSpanCount++ 79 return 80 } 81 b.rawSpans = append(b.rawSpans, span) 82} 83 84// mergeFrom combines the spans and metadata in `from` with `into`, 85// returning with `from` empty and `into` having a subset of the 86// combined data. 87func (b *reportBuffer) mergeFrom(from *reportBuffer) { 88 b.droppedSpanCount += from.droppedSpanCount 89 b.reportedDroppedSpanCount += from.reportedDroppedSpanCount 90 b.logEncoderErrorCount += from.logEncoderErrorCount 91 b.reportedLogEncoderErrorCount += from.reportedLogEncoderErrorCount 92 93 if from.reportStart.Before(b.reportStart) { 94 b.reportStart = from.reportStart 95 } 96 if from.reportEnd.After(b.reportEnd) { 97 b.reportEnd = from.reportEnd 98 } 99 100 // Note: Somewhat arbitrarily dropping the spans that won't 101 // fit; could be more principled here to avoid bias. 102 have := len(b.rawSpans) 103 space := cap(b.rawSpans) - have 104 unreported := len(from.rawSpans) 105 106 if space > unreported { 107 space = unreported 108 } 109 110 b.rawSpans = append(b.rawSpans, from.rawSpans[0:space]...) 111 112 if unreported > space { 113 b.droppedSpanCount += int64(unreported - space) 114 } 115 116 from.clear() 117} 118 119func (b *reportBuffer) reportDroppedSpanCount() int64 { 120 var toReport int64 121 toReport, b.reportedDroppedSpanCount = b.droppedSpanCount-b.reportedDroppedSpanCount, b.droppedSpanCount 122 return toReport 123} 124 125func (b *reportBuffer) reportLogEncoderErrorCount() int64 { 126 var toReport int64 127 toReport, b.reportedLogEncoderErrorCount = b.logEncoderErrorCount-b.reportedLogEncoderErrorCount, b.logEncoderErrorCount 128 return toReport 129} 130