github.com/nikandfor/tlog@v0.21.5-0.20231108111739-3ef89426a96d/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 }