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  }