@@ -65,6 +65,11 @@ func durationToMilliseconds(timeDuration time.Duration) int64 {
65
65
}
66
66
67
67
type traceItem interface {
68
+ // rLock must be called before invoking time or writeItem.
69
+ rLock ()
70
+ // rUnlock must be called after processing the item is complete.
71
+ rUnlock ()
72
+
68
73
// time returns when the trace was recorded as completed.
69
74
time () time.Time
70
75
// writeItem outputs the traceItem to the buffer. If stepThreshold is non-nil, only output the
@@ -79,6 +84,10 @@ type traceStep struct {
79
84
fields []Field
80
85
}
81
86
87
+ // rLock doesn't need to do anything because traceStep instances are immutable.
88
+ func (s traceStep ) rLock () {}
89
+ func (s traceStep ) rUnlock () {}
90
+
82
91
func (s traceStep ) time () time.Time {
83
92
return s .stepTime
84
93
}
@@ -106,6 +115,14 @@ type Trace struct {
106
115
traceItems []traceItem
107
116
}
108
117
118
+ func (t * Trace ) rLock () {
119
+ t .lock .RLock ()
120
+ }
121
+
122
+ func (t * Trace ) rUnlock () {
123
+ t .lock .RUnlock ()
124
+ }
125
+
109
126
func (t * Trace ) time () time.Time {
110
127
if t .endTime != nil {
111
128
return * t .endTime
@@ -231,8 +248,10 @@ func (t *Trace) logTrace() {
231
248
func (t * Trace ) writeTraceSteps (b * bytes.Buffer , formatter string , stepThreshold * time.Duration ) {
232
249
lastStepTime := t .startTime
233
250
for _ , stepOrTrace := range t .traceItems {
251
+ stepOrTrace .rLock ()
234
252
stepOrTrace .writeItem (b , formatter , lastStepTime , stepThreshold )
235
253
lastStepTime = stepOrTrace .time ()
254
+ stepOrTrace .rUnlock ()
236
255
}
237
256
}
238
257
0 commit comments