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 }