You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
kratos/log/value.go

92 lines
2.1 KiB

package log
import (
"context"
"runtime"
"strconv"
"strings"
"time"
"go.opentelemetry.io/otel/trace"
)
var (
// DefaultCaller is a Valuer that returns the file and line.
DefaultCaller = Caller(3)
// DefaultTimestamp is a Valuer that returns the current wallclock time.
DefaultTimestamp = Timestamp(time.RFC3339)
)
// Valuer is returns a log value.
type Valuer func(ctx context.Context) interface{}
// Value return the function value.
func Value(ctx context.Context, v interface{}) interface{} {
if v, ok := v.(Valuer); ok {
return v(ctx)
}
return v
}
// Caller returns returns a Valuer that returns a pkg/file:line description of the caller.
func Caller(depth int) Valuer {
return func(context.Context) interface{} {
_, file, line, _ := runtime.Caller(depth)
4 years ago
if strings.LastIndex(file, "/log/helper.go") > 0 {
depth++
_, file, line, _ = runtime.Caller(depth)
}
if strings.LastIndex(file, "/log/filter.go") > 0 {
depth++
_, file, line, _ = runtime.Caller(depth)
}
idx := strings.LastIndexByte(file, '/')
return file[idx+1:] + ":" + strconv.Itoa(line)
}
}
// Timestamp returns a timestamp Valuer with a custom time format.
func Timestamp(layout string) Valuer {
return func(context.Context) interface{} {
return time.Now().Format(layout)
}
}
// TraceID returns a traceid valuer.
func TraceID() Valuer {
return func(ctx context.Context) interface{} {
4 years ago
if span := trace.SpanContextFromContext(ctx); span.HasTraceID() {
return span.TraceID().String()
}
return ""
}
}
// SpanID returns a spanid valuer.
func SpanID() Valuer {
return func(ctx context.Context) interface{} {
4 years ago
if span := trace.SpanContextFromContext(ctx); span.HasSpanID() {
return span.SpanID().String()
}
return ""
}
}
func bindValues(ctx context.Context, keyvals []interface{}) {
for i := 1; i < len(keyvals); i += 2 {
if v, ok := keyvals[i].(Valuer); ok {
keyvals[i] = v(ctx)
}
}
}
func containsValuer(keyvals []interface{}) bool {
for i := 1; i < len(keyvals); i += 2 {
if _, ok := keyvals[i].(Valuer); ok {
return true
}
}
return false
}