trace: guard span labels
During finish, constructTrace also mutates the span
to add HTTP labels if necessary. Concurrent use of
SetLabel and Finish leads to a data race.
Fixes
@@ -561,7 +561,10 @@ func (c *Client) upload(traces []*api.Trace) error {
// Span contains information about one span of a trace.
type Span struct {
trace *trace
+
+ spanMu sync.Mutex // guards span.Labels
span api.TraceSpan
+
start time.Time
end time.Time
rootSpan bool
@@ -670,6 +673,9 @@ func (s *Span) SetLabel(key, value string) {
if !s.tracing() {
return
}
+ s.spanMu.Lock()
+ defer s.spanMu.Unlock()
+
if value == "" {
if s.span.Labels != nil {
delete(s.span.Labels, key)
