github.com/tickoalcantara12/micro/v3@v3.0.0-20221007104245-9d75b9bcbab9/service/debug/trace/memory/memory.go (about) 1 // Licensed under the Apache License, Version 2.0 (the "License"); 2 // you may not use this file except in compliance with the License. 3 // You may obtain a copy of the License at 4 // 5 // https://www.apache.org/licenses/LICENSE-2.0 6 // 7 // Unless required by applicable law or agreed to in writing, software 8 // distributed under the License is distributed on an "AS IS" BASIS, 9 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 // See the License for the specific language governing permissions and 11 // limitations under the License. 12 // 13 // Original source: github.com/micro/go-micro/v3/debug/trace/memory/memory.go 14 15 package memory 16 17 import ( 18 "context" 19 "time" 20 21 "github.com/google/uuid" 22 "github.com/tickoalcantara12/micro/v3/service/debug/trace" 23 "github.com/tickoalcantara12/micro/v3/util/ring" 24 ) 25 26 type Tracer struct { 27 opts trace.Options 28 29 // ring buffer of traces 30 buffer *ring.Buffer 31 } 32 33 func (t *Tracer) Read(opts ...trace.ReadOption) ([]*trace.Span, error) { 34 var options trace.ReadOptions 35 for _, o := range opts { 36 o(&options) 37 } 38 39 sp := t.buffer.Get(t.buffer.Size()) 40 41 spans := make([]*trace.Span, 0, len(sp)) 42 43 for _, span := range sp { 44 val := span.Value.(*trace.Span) 45 // skip if trace id is specified and doesn't match 46 if len(options.Trace) > 0 && val.Trace != options.Trace { 47 continue 48 } 49 spans = append(spans, val) 50 } 51 52 return spans, nil 53 } 54 55 func (t *Tracer) Start(ctx context.Context, name string) (context.Context, *trace.Span) { 56 span := &trace.Span{ 57 Name: name, 58 Trace: uuid.New().String(), 59 Id: uuid.New().String(), 60 Started: time.Now(), 61 Metadata: make(map[string]string), 62 } 63 64 // return span if no context 65 if ctx == nil { 66 return trace.ToContext(context.Background(), span.Trace, span.Id), span 67 } 68 traceID, parentSpanID, ok := trace.FromContext(ctx) 69 // If the trace can not be found in the header, 70 // that means this is where the trace is created. 71 if !ok { 72 return trace.ToContext(ctx, span.Trace, span.Id), span 73 } 74 75 // set trace id 76 span.Trace = traceID 77 // set parent 78 span.Parent = parentSpanID 79 80 // return the span 81 return trace.ToContext(ctx, span.Trace, span.Id), span 82 } 83 84 func (t *Tracer) Finish(s *trace.Span) error { 85 // set finished time 86 s.Duration = time.Since(s.Started) 87 // save the span 88 t.buffer.Put(s) 89 90 return nil 91 } 92 93 func NewTracer(opts ...trace.Option) trace.Tracer { 94 var options trace.Options 95 for _, o := range opts { 96 o(&options) 97 } 98 99 return &Tracer{ 100 opts: options, 101 // the last 256 requests 102 buffer: ring.New(256), 103 } 104 }