github.com/annwntech/go-micro/v2@v2.9.5/debug/trace/trace.go (about)

     1  // Package trace provides an interface for distributed tracing
     2  package trace
     3  
     4  import (
     5  	"context"
     6  	"time"
     7  
     8  	"github.com/annwntech/go-micro/v2/metadata"
     9  )
    10  
    11  // Tracer is an interface for distributed tracing
    12  type Tracer interface {
    13  	// Start a trace
    14  	Start(ctx context.Context, name string) (context.Context, *Span)
    15  	// Finish the trace
    16  	Finish(*Span) error
    17  	// Read the traces
    18  	Read(...ReadOption) ([]*Span, error)
    19  }
    20  
    21  // SpanType describe the nature of the trace span
    22  type SpanType int
    23  
    24  const (
    25  	// SpanTypeRequestInbound is a span created when serving a request
    26  	SpanTypeRequestInbound SpanType = iota
    27  	// SpanTypeRequestOutbound is a span created when making a service call
    28  	SpanTypeRequestOutbound
    29  )
    30  
    31  // Span is used to record an entry
    32  type Span struct {
    33  	// Id of the trace
    34  	Trace string
    35  	// name of the span
    36  	Name string
    37  	// id of the span
    38  	Id string
    39  	// parent span id
    40  	Parent string
    41  	// Start time
    42  	Started time.Time
    43  	// Duration in nano seconds
    44  	Duration time.Duration
    45  	// associated data
    46  	Metadata map[string]string
    47  	// Type
    48  	Type SpanType
    49  }
    50  
    51  const (
    52  	traceIDKey = "Micro-Trace-Id"
    53  	spanIDKey  = "Micro-Span-Id"
    54  )
    55  
    56  // FromContext returns a span from context
    57  func FromContext(ctx context.Context) (traceID string, parentSpanID string, isFound bool) {
    58  	traceID, traceOk := metadata.Get(ctx, traceIDKey)
    59  	microID, microOk := metadata.Get(ctx, "Micro-Id")
    60  	if !traceOk && !microOk {
    61  		isFound = false
    62  		return
    63  	}
    64  	if !traceOk {
    65  		traceID = microID
    66  	}
    67  	parentSpanID, ok := metadata.Get(ctx, spanIDKey)
    68  	return traceID, parentSpanID, ok
    69  }
    70  
    71  // ToContext saves the trace and span ids in the context
    72  func ToContext(ctx context.Context, traceID, parentSpanID string) context.Context {
    73  	return metadata.MergeContext(ctx, map[string]string{
    74  		traceIDKey: traceID,
    75  		spanIDKey:  parentSpanID,
    76  	}, true)
    77  }
    78  
    79  var (
    80  	DefaultTracer Tracer = new(noop)
    81  )
    82  
    83  type noop struct{}
    84  
    85  func (n *noop) Init(...Option) error {
    86  	return nil
    87  }
    88  
    89  func (n *noop) Start(ctx context.Context, name string) (context.Context, *Span) {
    90  	return nil, nil
    91  }
    92  
    93  func (n *noop) Finish(*Span) error {
    94  	return nil
    95  }
    96  
    97  func (n *noop) Read(...ReadOption) ([]*Span, error) {
    98  	return nil, nil
    99  }