55
66//msgp:ignore inheritedData
77//go:generate go run github.com/tinylib/msgp -unexported -marshal=false -o=span_msgp.go -tests=false
8+ //go:generate go run ../../scripts/msgp_checklocks_ignore.go -type Span -file span_msgp.go
89
910package tracer
1011
@@ -70,6 +71,7 @@ type errorConfig struct {
7071// properties set at any time during normal operation! This is used for testing only,
7172// and should not be used in non-test code, or you may run into performance or other
7273// issues.
74+ // +checklocksignore
7375func (s * Span ) AsMap () map [string ]interface {} {
7476 m := make (map [string ]interface {})
7577 if s == nil {
@@ -100,6 +102,7 @@ func (s *Span) AsMap() map[string]interface{} {
100102 return m
101103}
102104
105+ // +checklocksignore
103106func (s * Span ) spanEventsAsJSONString () string {
104107 if ! s .supportsEvents {
105108 return s .meta ["events" ]
@@ -118,34 +121,55 @@ func (s *Span) spanEventsAsJSONString() string {
118121// Span represents a computation. Callers must call Finish when a Span is
119122// complete to ensure it's submitted.
120123type Span struct {
121- mu locking.RWMutex `msg:"-"` // all fields are protected by this RWMutex
122-
123- name string `msg:"name"` // operation name
124- service string `msg:"service"` // service name (i.e. "grpc.server", "http.request")
125- resource string `msg:"resource"` // resource name (i.e. "/user?id=123", "SELECT * FROM users")
126- spanType string `msg:"type"` // protocol associated with the span (i.e. "web", "db", "cache")
127- start int64 `msg:"start"` // span start time expressed in nanoseconds since epoch
128- duration int64 `msg:"duration"` // duration of the span expressed in nanoseconds
129- meta map [string ]string `msg:"meta,omitempty"` // arbitrary map of metadata
130- metaStruct metaStructMap `msg:"meta_struct,omitempty"` // arbitrary map of metadata with structured values
131- metrics map [string ]float64 `msg:"metrics,omitempty"` // arbitrary map of numeric metrics
132- spanID uint64 `msg:"span_id"` // identifier of this span
133- traceID uint64 `msg:"trace_id"` // lower 64-bits of the root span identifier
134- parentID uint64 `msg:"parent_id"` // identifier of the span's direct parent
135- error int32 `msg:"error"` // error status of the span; 0 means no errors
136- spanLinks []SpanLink `msg:"span_links,omitempty"` // links to other spans
137- spanEvents []spanEvent `msg:"span_events,omitempty"` // events produced related to this span
124+ // guards below fields
125+ mu locking.RWMutex `msg:"-"`
126+
127+ // +checklocks:mu
128+ name string `msg:"name"` // operation name
129+ // +checklocks:mu
130+ service string `msg:"service"` // service name (i.e. "grpc.server", "http.request")
131+ // +checklocks:mu
132+ resource string `msg:"resource"` // resource name (i.e. "/user?id=123", "SELECT * FROM users")
133+ // +checklocks:mu
134+ spanType string `msg:"type"` // protocol associated with the span (i.e. "web", "db", "cache")
135+ // +checklocks:mu
136+ start int64 `msg:"start"` // span start time expressed in nanoseconds since epoch
137+ // +checklocks:mu
138+ duration int64 `msg:"duration"` // duration of the span expressed in nanoseconds
139+ // +checklocks:mu
140+ meta map [string ]string `msg:"meta,omitempty"` // arbitrary map of metadata
141+ // +checklocks:mu
142+ metaStruct metaStructMap `msg:"meta_struct,omitempty"` // arbitrary map of metadata with structured values
143+ // +checklocks:mu
144+ metrics map [string ]float64 `msg:"metrics,omitempty"` // arbitrary map of numeric metrics
145+ // +checklocks:mu
146+ spanID uint64 `msg:"span_id"` // identifier of this span
147+ // +checklocks:mu
148+ traceID uint64 `msg:"trace_id"` // lower 64-bits of the root span identifier
149+ // +checklocks:mu
150+ parentID uint64 `msg:"parent_id"` // identifier of the span's direct parent
151+ // +checklocks:mu
152+ error int32 `msg:"error"` // error status of the span; 0 means no errors
153+ // +checklocks:mu
154+ spanLinks []SpanLink `msg:"span_links,omitempty"` // links to other spans
155+ // +checklocks:mu
156+ spanEvents []spanEvent `msg:"span_events,omitempty"` // events produced related to this span
138157
139158 goExecTraced bool `msg:"-"`
140159 noDebugStack bool `msg:"-"` // disables debug stack traces
141- finished bool `msg:"-"` // true if the span has been submitted to a tracer. Can only be read/modified if the trace is locked.
142160 context * SpanContext `msg:"-"` // span propagation context
143- integration string `msg:"-"` // where the span was started from, such as a specific contrib or "manual"
144161 supportsEvents bool `msg:"-"` // whether the span supports native span events or not
145162
146- pprofCtxActive context.Context `msg:"-"` // contains pprof.WithLabel labels to tell the profiler more about this span
163+ // +checklocks:mu
164+ finished bool `msg:"-"` // true if the span has been submitted to a tracer. Can only be read/modified if the trace is locked.
165+ // +checklocks:mu
166+ integration string `msg:"-"` // where the span was started from, such as a specific contrib or "manual"
167+ // +checklocks:mu
168+ pprofCtxActive context.Context `msg:"-"` // contains pprof.WithLabel labels to tell the profiler more about this span
169+
147170 pprofCtxRestore context.Context `msg:"-"` // contains pprof.WithLabel labels of the parent span (if any) that need to be restored when this span finishes
148171
172+ // +checklocks:mu
149173 taskEnd func () // ends execution tracer (runtime/trace) task, if started
150174}
151175
@@ -539,6 +563,8 @@ func (s *Span) StartChild(operationName string, opts ...StartSpanOption) *Span {
539563
540564// setSamplingPriorityLocked updates the sampling priority.
541565// It also updates the trace's sampling priority.
566+ // s.mu must be held for writing.
567+ // +checklocks:s.mu
542568func (s * Span ) setSamplingPriorityLocked (priority int , sampler samplernames.SamplerName ) {
543569 assert .RWMutexLocked (& s .mu )
544570 // We don't lock spans when flushing, so we could have a data race when
@@ -555,6 +581,8 @@ func (s *Span) setSamplingPriorityLocked(priority int, sampler samplernames.Samp
555581// If the trace is locked, the sampling priority is forced to the given value.
556582//
557583// This function is should only be used when applying a manual keep or drop decision.
584+ // s.mu must be held for writing.
585+ // +checklocks:s.mu
558586func (s * Span ) forceSetSamplingPriorityLocked (priority int , sampler samplernames.SamplerName ) {
559587 assert .RWMutexLocked (& s .mu )
560588 // We don't lock spans when flushing, so we could have a data race when
@@ -568,7 +596,8 @@ func (s *Span) forceSetSamplingPriorityLocked(priority int, sampler samplernames
568596}
569597
570598// setTagErrorLocked sets the error tag. It accounts for various valid scenarios.
571- // This method assumes the span lock is already held.
599+ // s.mu must be held for writing.
600+ // +checklocks:s.mu
572601func (s * Span ) setTagErrorLocked (value interface {}, cfg errorConfig ) {
573602 assert .RWMutexLocked (& s .mu )
574603 setError := func (yes bool ) {
@@ -658,12 +687,14 @@ func (s *Span) setMeta(key, v string) {
658687}
659688
660689// setMetaLocked sets a string tag. This method assumes the span lock is already held.
690+ // +checklocks:s.mu
661691func (s * Span ) setMetaLocked (key , v string ) {
662692 assert .RWMutexLocked (& s .mu )
663693 s .setMetaInit (key , v )
664694}
665695
666696// setMetaInit sets a string tag without acquiring the lock and asserting the lock is held.
697+ // +checklocksignore
667698func (s * Span ) setMetaInit (key , v string ) {
668699 if s .meta == nil {
669700 s .meta = make (map [string ]string , 1 )
@@ -684,6 +715,7 @@ func (s *Span) setMetaInit(key, v string) {
684715}
685716
686717// setMetaStructLocked sets structured metadata. This method assumes the span lock is already held.
718+ // +checklocks:s.mu
687719func (s * Span ) setMetaStructLocked (key string , v any ) {
688720 assert .RWMutexLocked (& s .mu )
689721 if s .metaStruct == nil {
@@ -693,6 +725,7 @@ func (s *Span) setMetaStructLocked(key string, v any) {
693725}
694726
695727// setTagBoolLocked sets a boolean tag on the span. This method assumes the span lock is already held.
728+ // +checklocks:s.mu
696729func (s * Span ) setTagBoolLocked (key string , v bool ) {
697730 assert .RWMutexLocked (& s .mu )
698731 switch key {
@@ -721,6 +754,7 @@ func (s *Span) setTagBoolLocked(key string, v bool) {
721754
722755// setMetric sets a numeric tag during span initialization (before the span is published).
723756// This method should only be used during span construction in spanStart and StartSpan.
757+ // +checklocksignore
724758func (s * Span ) setMetricInit (key string , v float64 ) {
725759 if s .metrics == nil {
726760 s .metrics = make (map [string ]float64 , 1 )
@@ -739,6 +773,7 @@ func (s *Span) setMetric(key string, v float64) {
739773
740774// setMetricLocked sets a numeric tag, in our case called a metric. This method
741775// assumes the span lock is already held.
776+ // +checklocks:s.mu
742777func (s * Span ) setMetricLocked (key string , v float64 ) {
743778 assert .RWMutexLocked (& s .mu )
744779 if s .metrics == nil {
@@ -777,7 +812,9 @@ func (s *Span) AddLink(link SpanLink) {
777812}
778813
779814// serializeSpanLinksInMeta saves span links as a JSON string under `Span[meta][_dd.span_links]`.
815+ // +checklocks:s.mu
780816func (s * Span ) serializeSpanLinksInMeta () {
817+ assert .RWMutexLocked (& s .mu )
781818 if len (s .spanLinks ) == 0 {
782819 return
783820 }
@@ -794,7 +831,9 @@ func (s *Span) serializeSpanLinksInMeta() {
794831
795832// serializeSpanEvents sets the span events from the current span in the correct transport, depending on whether the
796833// agent supports the native method or not.
834+ // +checklocks:s.mu
797835func (s * Span ) serializeSpanEvents () {
836+ assert .RWMutexLocked (& s .mu )
798837 if len (s .spanEvents ) == 0 {
799838 return
800839 }
@@ -987,6 +1026,7 @@ func obfuscatedResource(o *obfuscate.Obfuscator, typ, resource string) string {
9871026
9881027// shouldKeep reports whether the trace should be kept.
9891028// a single span being kept implies the whole trace being kept.
1029+ // +checklocksignore
9901030func shouldKeep (s * Span ) bool {
9911031 if p , ok := s .context .SamplingPriority (); ok && p > 0 {
9921032 // positive sampling priorities stay
@@ -1004,6 +1044,7 @@ func shouldKeep(s *Span) bool {
10041044
10051045// shouldComputeStats mentions whether this span needs to have stats computed for.
10061046// Warning: callers must guard!
1047+ // +checklocksignore
10071048func shouldComputeStats (s * Span ) bool {
10081049 if v , ok := s .metrics [keyMeasured ]; ok && v == 1 {
10091050 return true
@@ -1046,6 +1087,7 @@ func (s *Span) String() string {
10461087}
10471088
10481089// Format implements fmt.Formatter.
1090+ // +checklocksignore
10491091func (s * Span ) Format (f fmt.State , c rune ) {
10501092 if s == nil {
10511093 fmt .Fprintf (f , "<nil>" )
0 commit comments