github.com/songzhibin97/gkit@v1.2.13/log/value.go (about) 1 package log 2 3 import ( 4 "context" 5 "runtime" 6 "strconv" 7 "strings" 8 "time" 9 10 "go.opentelemetry.io/otel/trace" 11 ) 12 13 var ( 14 // DefaultCaller is a Valuer that returns the file and line. 15 DefaultCaller = Caller(3) 16 17 // DefaultTimestamp is a Valuer that returns the current wallclock time. 18 DefaultTimestamp = Timestamp(time.RFC3339) 19 ) 20 21 type ( 22 // Valuer log返回携带值 23 Valuer func(ctx context.Context) interface{} 24 ) 25 26 // Value 尝试调用Valuer接口返回 27 func Value(ctx context.Context, value interface{}) interface{} { 28 if v, ok := value.(Valuer); ok { 29 return v(ctx) 30 } 31 return value 32 } 33 34 // Caller 返回调用方的堆信息 35 func Caller(depth int) Valuer { 36 return func(ctx context.Context) interface{} { 37 _, file, line, _ := runtime.Caller(depth) 38 if strings.LastIndex(file, "gkit/log") > 0 { 39 _, file, line, _ = runtime.Caller(depth + 1) 40 } 41 idx := strings.LastIndexByte(file, '/') 42 return file[idx+1:] + ":" + strconv.Itoa(line) 43 } 44 } 45 46 // Timestamp 返回指定layout的时间戳 Valuer 47 func Timestamp(layout string) Valuer { 48 return func(context.Context) interface{} { 49 return time.Now().Format(layout) 50 } 51 } 52 53 // TraceID 返回链路追踪使用的tranceID Valuer 54 // TraceID 来将一个请求在各个服务器上的调用日志串联起来 55 func TraceID() Valuer { 56 return func(ctx context.Context) interface{} { 57 if span := trace.SpanContextFromContext(ctx); span.HasTraceID() { 58 return span.TraceID().String() 59 } 60 return "" 61 } 62 } 63 64 // SpanID 返回链路定位的 SpanID Valuer 65 // SpanID 代表本次调用在整个调用链路树中的位置 66 func SpanID() Valuer { 67 return func(ctx context.Context) interface{} { 68 if span := trace.SpanContextFromContext(ctx); span.HasSpanID() { 69 return span.SpanID().String() 70 } 71 return "" 72 } 73 } 74 75 // bindValues 判断 kvs 的 v 是否是 Valuer对象 如果是的话将ctx传入保存 76 func bindValues(ctx context.Context, kvs []interface{}) { 77 for i := 1; i < len(kvs); i += 2 { 78 if v, ok := kvs[i].(Valuer); ok { 79 kvs[i] = v(ctx) 80 } 81 } 82 } 83 84 // containsValuer 判断 kvs 中 v是否是 Valuer 如果有立即返回true 85 func containsValuer(kvs []interface{}) bool { 86 for i := 1; i < len(kvs); i += 2 { 87 if _, ok := kvs[i].(Valuer); ok { 88 return true 89 } 90 } 91 return false 92 }