Source File
trace.go
Belonging Package
go.opencensus.io/trace
package trace
import (
crand
)
data *SpanData
mu sync.Mutex // protects the contents of *data (but not the pointer value.)
spanContext SpanContext
*spanStore
endOnce sync.Once
executionTracerTaskEnd func() // ends the execution tracer span
}
type TraceOptions uint32
func ( SpanContext) () bool {
return .TraceOptions.IsSampled()
}
func ( *SpanContext) ( bool) {
if {
.TraceOptions |= 1
} else {
.TraceOptions &= ^TraceOptions(1)
}
}
func ( TraceOptions) () bool {
return &1 == 1
}
type SpanContext struct {
TraceID TraceID
SpanID SpanID
TraceOptions TraceOptions
Tracestate *tracestate.Tracestate
}
type contextKey struct{}
const (
SpanKindUnspecified = iota
SpanKindServer
SpanKindClient
)
type StartOption func(*StartOptions)
func ( int) StartOption {
return func( *StartOptions) {
.SpanKind =
}
}
func ( Sampler) StartOption {
return func( *StartOptions) {
.Sampler =
}
}
func ( context.Context, string, ...StartOption) (context.Context, *Span) {
var StartOptions
var SpanContext
if := FromContext(); != nil {
.addChild()
= .spanContext
}
for , := range {
(&)
}
:= startSpanInternal(, != SpanContext{}, , false, )
, := startExecutionTracerTask(, )
.executionTracerTaskEnd =
return NewContext(, ),
}
func ( context.Context, string, SpanContext, ...StartOption) (context.Context, *Span) {
var StartOptions
for , := range {
(&)
}
:= startSpanInternal(, != SpanContext{}, , true, )
, := startExecutionTracerTask(, )
.executionTracerTaskEnd =
return NewContext(, ),
}
func ( string, bool, SpanContext, bool, StartOptions) *Span {
:= &Span{}
.spanContext =
:= config.Load().(*Config)
if ! {
.spanContext.TraceID = .IDGenerator.NewTraceID()
}
.spanContext.SpanID = .IDGenerator.NewSpanID()
:= .DefaultSampler
if .Sampler != nil {
= .Sampler
}
.spanContext.setIsSampled((SamplingParameters{
ParentContext: ,
TraceID: .spanContext.TraceID,
SpanID: .spanContext.SpanID,
Name: ,
HasRemoteParent: }).Sample)
}
if !internal.LocalSpanStoreEnabled && !.spanContext.IsSampled() {
return
}
.data = &SpanData{
SpanContext: .spanContext,
StartTime: time.Now(),
SpanKind: .SpanKind,
Name: ,
HasRemoteParent: ,
}
.lruAttributes = newLruMap(.MaxAttributesPerSpan)
.annotations = newEvictedQueue(.MaxAnnotationEventsPerSpan)
.messageEvents = newEvictedQueue(.MaxMessageEventsPerSpan)
.links = newEvictedQueue(.MaxLinksPerSpan)
if {
.data.ParentSpanID = .SpanID
}
if internal.LocalSpanStoreEnabled {
var *spanStore
= spanStoreForNameCreateIfNew()
if != nil {
.spanStore =
.add()
}
}
return
}
func ( *Span) () {
if == nil {
return
}
if .executionTracerTaskEnd != nil {
.executionTracerTaskEnd()
}
if !.IsRecordingEvents() {
return
}
.endOnce.Do(func() {
, := exporters.Load().(exportersMap)
:= .spanContext.IsSampled() && len() > 0
if .spanStore != nil || {
:= .makeSpanData()
.EndTime = internal.MonotonicEndTime(.StartTime)
if .spanStore != nil {
.spanStore.finished(, )
}
if {
for := range {
.ExportSpan()
}
}
}
})
}
func ( *Span) () *SpanData {
var SpanData
.mu.Lock()
= *.data
if .lruAttributes.len() > 0 {
.Attributes = .lruAttributesToAttributeMap()
.DroppedAttributeCount = .lruAttributes.droppedCount
}
if len(.annotations.queue) > 0 {
.Annotations = .interfaceArrayToAnnotationArray()
.DroppedAnnotationCount = .annotations.droppedCount
}
if len(.messageEvents.queue) > 0 {
.MessageEvents = .interfaceArrayToMessageEventArray()
.DroppedMessageEventCount = .messageEvents.droppedCount
}
if len(.links.queue) > 0 {
.Links = .interfaceArrayToLinksArray()
.DroppedLinkCount = .links.droppedCount
}
.mu.Unlock()
return &
}
func ( *Span) () SpanContext {
if == nil {
return SpanContext{}
}
return .spanContext
}
func ( *Span) ( Status) {
if !.IsRecordingEvents() {
return
}
.mu.Lock()
.data.Status =
.mu.Unlock()
}
func ( *Span) () []Link {
:= make([]Link, 0, len(.links.queue))
for , := range .links.queue {
= append(, .(Link))
}
return
}
func ( *Span) () []MessageEvent {
:= make([]MessageEvent, 0, len(.messageEvents.queue))
for , := range .messageEvents.queue {
= append(, .(MessageEvent))
}
return
}
func ( *Span) () []Annotation {
:= make([]Annotation, 0, len(.annotations.queue))
for , := range .annotations.queue {
= append(, .(Annotation))
}
return
}
func ( *Span) () map[string]interface{} {
:= make(map[string]interface{}, .lruAttributes.len())
for , := range .lruAttributes.keys() {
, := .lruAttributes.get()
if {
:= .(string)
[] =
}
}
return
}
func ( *Span) ( []Attribute) {
for , := range {
.lruAttributes.add(.key, .value)
}
}
func ( *Span) () {
if !.IsRecordingEvents() {
return
}
.mu.Lock()
.data.ChildSpanCount++
.mu.Unlock()
}
func ( *Span) ( ...Attribute) {
if !.IsRecordingEvents() {
return
}
.mu.Lock()
.copyToCappedAttributes()
.mu.Unlock()
}
func ( map[string]interface{}, []Attribute) {
for , := range {
[.key] = .value
}
}
func ( *Span) ( []Attribute, string, ...interface{}) {
:= time.Now()
:= fmt.Sprintf(, ...)
var map[string]interface{}
.mu.Lock()
if len() != 0 {
= make(map[string]interface{}, len())
copyAttributes(, )
}
.annotations.add(Annotation{
Time: ,
Message: ,
Attributes: ,
})
.mu.Unlock()
}
func ( *Span) ( []Attribute, string) {
:= time.Now()
var map[string]interface{}
.mu.Lock()
if len() != 0 {
= make(map[string]interface{}, len())
copyAttributes(, )
}
.annotations.add(Annotation{
Time: ,
Message: ,
Attributes: ,
})
.mu.Unlock()
}
func ( *Span) ( []Attribute, string) {
if !.IsRecordingEvents() {
return
}
.printStringInternal(, )
}
func ( *Span) ( []Attribute, string, ...interface{}) {
if !.IsRecordingEvents() {
return
}
.lazyPrintfInternal(, , ...)
}
func ( *Span) (, , int64) {
if !.IsRecordingEvents() {
return
}
:= time.Now()
.mu.Lock()
.messageEvents.add(MessageEvent{
Time: ,
EventType: MessageEventTypeSent,
MessageID: ,
UncompressedByteSize: ,
CompressedByteSize: ,
})
.mu.Unlock()
}
func ( *Span) (, , int64) {
if !.IsRecordingEvents() {
return
}
:= time.Now()
.mu.Lock()
.messageEvents.add(MessageEvent{
Time: ,
EventType: MessageEventTypeRecv,
MessageID: ,
UncompressedByteSize: ,
CompressedByteSize: ,
})
.mu.Unlock()
}
func ( *Span) ( Link) {
if !.IsRecordingEvents() {
return
}
.mu.Lock()
.links.add()
.mu.Unlock()
}
func ( *Span) () string {
if == nil {
return "<nil>"
}
if .data == nil {
return fmt.Sprintf("span %s", .spanContext.SpanID)
}
.mu.Lock()
:= fmt.Sprintf("span %s %q", .spanContext.SpanID, .data.Name)
.mu.Unlock()
return
}
var config atomic.Value // access atomically
func () {
var int64
for , := range []interface{}{
&, &.traceIDAdd, &.nextSpanID, &.spanIDInc,
} {
binary.Read(crand.Reader, binary.LittleEndian, )
}
.traceIDRand = rand.New(rand.NewSource())
.spanIDInc |= 1
config.Store(&Config{
DefaultSampler: ProbabilitySampler(defaultSamplingProbability),
IDGenerator: ,
MaxAttributesPerSpan: DefaultMaxAttributesPerSpan,
MaxAnnotationEventsPerSpan: DefaultMaxAnnotationEventsPerSpan,
MaxMessageEventsPerSpan: DefaultMaxMessageEventsPerSpan,
MaxLinksPerSpan: DefaultMaxLinksPerSpan,
})
}
type defaultIDGenerator struct {
sync.Mutex
func ( *defaultIDGenerator) () [8]byte {
var uint64
for == 0 {
= atomic.AddUint64(&.nextSpanID, .spanIDInc)
}
var [8]byte
binary.LittleEndian.PutUint64([:], )
return
}
func ( *defaultIDGenerator) () [16]byte {
.Lock()
binary.LittleEndian.PutUint64([0:8], .traceIDRand.Uint64()+.traceIDAdd[0])
binary.LittleEndian.PutUint64([8:16], .traceIDRand.Uint64()+.traceIDAdd[1])
.Unlock()
return
![]() |
The pages are generated with Golds v0.3.2-preview. (GOOS=darwin GOARCH=amd64) Golds is a Go 101 project developed by Tapir Liu. PR and bug reports are welcome and can be submitted to the issue list. Please follow @Go100and1 (reachable from the left QR code) to get the latest news of Golds. |