gitee.com/sasukebo/go-micro/v4@v4.7.1/debug/trace/default.go (about)

     1  package trace
     2  
     3  import (
     4  	"context"
     5  	"time"
     6  
     7  	"gitee.com/sasukebo/go-micro/v4/util/ring"
     8  	"github.com/google/uuid"
     9  )
    10  
    11  type memTracer struct {
    12  	opts Options
    13  
    14  	// ring buffer of traces
    15  	buffer *ring.Buffer
    16  }
    17  
    18  func (t *memTracer) Read(opts ...ReadOption) ([]*Span, error) {
    19  	var options ReadOptions
    20  	for _, o := range opts {
    21  		o(&options)
    22  	}
    23  
    24  	sp := t.buffer.Get(t.buffer.Size())
    25  
    26  	spans := make([]*Span, 0, len(sp))
    27  
    28  	for _, span := range sp {
    29  		val := span.Value.(*Span)
    30  		// skip if trace id is specified and doesn't match
    31  		if len(options.Trace) > 0 && val.Trace != options.Trace {
    32  			continue
    33  		}
    34  		spans = append(spans, val)
    35  	}
    36  
    37  	return spans, nil
    38  }
    39  
    40  func (t *memTracer) Start(ctx context.Context, name string) (context.Context, *Span) {
    41  	span := &Span{
    42  		Name:     name,
    43  		Trace:    uuid.New().String(),
    44  		Id:       uuid.New().String(),
    45  		Started:  time.Now(),
    46  		Metadata: make(map[string]string),
    47  	}
    48  
    49  	// return span if no context
    50  	if ctx == nil {
    51  		return ToContext(context.Background(), span.Trace, span.Id), span
    52  	}
    53  	traceID, parentSpanID, ok := FromContext(ctx)
    54  	// If the trace can not be found in the header,
    55  	// that means this is where the trace is created.
    56  	if !ok {
    57  		return ToContext(ctx, span.Trace, span.Id), span
    58  	}
    59  
    60  	// set trace id
    61  	span.Trace = traceID
    62  	// set parent
    63  	span.Parent = parentSpanID
    64  
    65  	// return the span
    66  	return ToContext(ctx, span.Trace, span.Id), span
    67  }
    68  
    69  func (t *memTracer) Finish(s *Span) error {
    70  	// set finished time
    71  	s.Duration = time.Since(s.Started)
    72  	// save the span
    73  	t.buffer.Put(s)
    74  
    75  	return nil
    76  }
    77  
    78  func NewTracer(opts ...Option) Tracer {
    79  	var options Options
    80  	for _, o := range opts {
    81  		o(&options)
    82  	}
    83  
    84  	return &memTracer{
    85  		opts: options,
    86  		// the last 256 requests
    87  		buffer: ring.New(256),
    88  	}
    89  }