tlog.app/go/tlog@v0.23.1/context.go (about)

     1  package tlog
     2  
     3  import (
     4  	"context"
     5  )
     6  
     7  type (
     8  	ctxspankey struct{}
     9  )
    10  
    11  // ContextWithSpan creates new context with Span ID context.Value.
    12  // It returns the same context if id is zero.
    13  func ContextWithSpan(ctx context.Context, s Span) context.Context {
    14  	if s.Logger == nil && SpanFromContext(ctx) == (Span{}) {
    15  		return ctx
    16  	}
    17  
    18  	return context.WithValue(ctx, ctxspankey{}, s)
    19  }
    20  
    21  // SpanFromContext loads saved by ContextWithSpan Span from Context.
    22  // It returns valid empty (no-op) Span if none was found.
    23  func SpanFromContext(ctx context.Context) (s Span) {
    24  	v := ctx.Value(ctxspankey{})
    25  	s, _ = v.(Span)
    26  
    27  	return
    28  }
    29  
    30  // SpawnFromContext spawns new Span derived form Span or ID from Context.
    31  // It returns empty (no-op) Span if no ID found.
    32  func SpawnFromContext(ctx context.Context, name string, kvs ...interface{}) Span {
    33  	s, ok := ctx.Value(ctxspankey{}).(Span)
    34  	if !ok {
    35  		return Span{}
    36  	}
    37  
    38  	return newspan(s.Logger, s.ID, 0, name, kvs)
    39  }
    40  
    41  func SpawnFromContextOrStart(ctx context.Context, name string, kvs ...interface{}) Span {
    42  	v := ctx.Value(ctxspankey{})
    43  	s, ok := v.(Span)
    44  	if ok {
    45  		return newspan(s.Logger, s.ID, 0, name, kvs)
    46  	}
    47  
    48  	return newspan(DefaultLogger, ID{}, 0, name, kvs)
    49  }
    50  
    51  func SpawnFromContextAndWrap(ctx context.Context, name string, kvs ...interface{}) (Span, context.Context) {
    52  	s, ok := ctx.Value(ctxspankey{}).(Span)
    53  	if !ok {
    54  		return Span{}, ctx
    55  	}
    56  
    57  	s = newspan(s.Logger, s.ID, 0, name, kvs)
    58  	ctx = context.WithValue(ctx, ctxspankey{}, s)
    59  
    60  	return s, ctx
    61  }