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,36 +121,56 @@ 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
149- // ends execution tracer (runtime/trace) task, if started
150- taskEnd func () // +checklocks:mu
172+ // +checklocks:mu
173+ taskEnd func () // ends execution tracer (runtime/trace) task, if started
151174}
152175
153176// Context yields the SpanContext for this Span. Note that the return
@@ -540,6 +563,8 @@ func (s *Span) StartChild(operationName string, opts ...StartSpanOption) *Span {
540563
541564// setSamplingPriorityLocked updates the sampling priority.
542565// It also updates the trace's sampling priority.
566+ // s.mu must be held for writing.
567+ // +checklocks:s.mu
543568func (s * Span ) setSamplingPriorityLocked (priority int , sampler samplernames.SamplerName ) {
544569 assert .RWMutexLocked (& s .mu )
545570 // We don't lock spans when flushing, so we could have a data race when
@@ -556,6 +581,8 @@ func (s *Span) setSamplingPriorityLocked(priority int, sampler samplernames.Samp
556581// If the trace is locked, the sampling priority is forced to the given value.
557582//
558583// 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
559586func (s * Span ) forceSetSamplingPriorityLocked (priority int , sampler samplernames.SamplerName ) {
560587 assert .RWMutexLocked (& s .mu )
561588 // We don't lock spans when flushing, so we could have a data race when
@@ -569,7 +596,8 @@ func (s *Span) forceSetSamplingPriorityLocked(priority int, sampler samplernames
569596}
570597
571598// setTagErrorLocked sets the error tag. It accounts for various valid scenarios.
572- // This method assumes the span lock is already held.
599+ // s.mu must be held for writing.
600+ // +checklocks:s.mu
573601func (s * Span ) setTagErrorLocked (value interface {}, cfg errorConfig ) {
574602 assert .RWMutexLocked (& s .mu )
575603 setError := func (yes bool ) {
@@ -659,12 +687,14 @@ func (s *Span) setMeta(key, v string) {
659687}
660688
661689// setMetaLocked sets a string tag. This method assumes the span lock is already held.
690+ // +checklocks:s.mu
662691func (s * Span ) setMetaLocked (key , v string ) {
663692 assert .RWMutexLocked (& s .mu )
664693 s .setMetaInit (key , v )
665694}
666695
667696// setMetaInit sets a string tag without acquiring the lock and asserting the lock is held.
697+ // +checklocksignore
668698func (s * Span ) setMetaInit (key , v string ) {
669699 if s .meta == nil {
670700 s .meta = make (map [string ]string , 1 )
@@ -685,6 +715,7 @@ func (s *Span) setMetaInit(key, v string) {
685715}
686716
687717// setMetaStructLocked sets structured metadata. This method assumes the span lock is already held.
718+ // +checklocks:s.mu
688719func (s * Span ) setMetaStructLocked (key string , v any ) {
689720 assert .RWMutexLocked (& s .mu )
690721 if s .metaStruct == nil {
@@ -694,6 +725,7 @@ func (s *Span) setMetaStructLocked(key string, v any) {
694725}
695726
696727// setTagBoolLocked sets a boolean tag on the span. This method assumes the span lock is already held.
728+ // +checklocks:s.mu
697729func (s * Span ) setTagBoolLocked (key string , v bool ) {
698730 assert .RWMutexLocked (& s .mu )
699731 switch key {
@@ -722,6 +754,7 @@ func (s *Span) setTagBoolLocked(key string, v bool) {
722754
723755// setMetric sets a numeric tag during span initialization (before the span is published).
724756// This method should only be used during span construction in spanStart and StartSpan.
757+ // +checklocksignore
725758func (s * Span ) setMetricInit (key string , v float64 ) {
726759 if s .metrics == nil {
727760 s .metrics = make (map [string ]float64 , 1 )
@@ -740,6 +773,7 @@ func (s *Span) setMetric(key string, v float64) {
740773
741774// setMetricLocked sets a numeric tag, in our case called a metric. This method
742775// assumes the span lock is already held.
776+ // +checklocks:s.mu
743777func (s * Span ) setMetricLocked (key string , v float64 ) {
744778 assert .RWMutexLocked (& s .mu )
745779 if s .metrics == nil {
@@ -778,7 +812,9 @@ func (s *Span) AddLink(link SpanLink) {
778812}
779813
780814// serializeSpanLinksInMeta saves span links as a JSON string under `Span[meta][_dd.span_links]`.
815+ // +checklocks:s.mu
781816func (s * Span ) serializeSpanLinksInMeta () {
817+ assert .RWMutexLocked (& s .mu )
782818 if len (s .spanLinks ) == 0 {
783819 return
784820 }
@@ -795,7 +831,9 @@ func (s *Span) serializeSpanLinksInMeta() {
795831
796832// serializeSpanEvents sets the span events from the current span in the correct transport, depending on whether the
797833// agent supports the native method or not.
834+ // +checklocks:s.mu
798835func (s * Span ) serializeSpanEvents () {
836+ assert .RWMutexLocked (& s .mu )
799837 if len (s .spanEvents ) == 0 {
800838 return
801839 }
@@ -988,6 +1026,7 @@ func obfuscatedResource(o *obfuscate.Obfuscator, typ, resource string) string {
9881026
9891027// shouldKeep reports whether the trace should be kept.
9901028// a single span being kept implies the whole trace being kept.
1029+ // +checklocksignore
9911030func shouldKeep (s * Span ) bool {
9921031 if p , ok := s .context .SamplingPriority (); ok && p > 0 {
9931032 // positive sampling priorities stay
@@ -1005,6 +1044,7 @@ func shouldKeep(s *Span) bool {
10051044
10061045// shouldComputeStats mentions whether this span needs to have stats computed for.
10071046// Warning: callers must guard!
1047+ // +checklocksignore
10081048func shouldComputeStats (s * Span ) bool {
10091049 if v , ok := s .metrics [keyMeasured ]; ok && v == 1 {
10101050 return true
@@ -1047,6 +1087,7 @@ func (s *Span) String() string {
10471087}
10481088
10491089// Format implements fmt.Formatter.
1090+ // +checklocksignore
10501091func (s * Span ) Format (f fmt.State , c rune ) {
10511092 if s == nil {
10521093 fmt .Fprintf (f , "<nil>" )
0 commit comments