package logx import ( "context" "fmt" "git.diulo.com/mogfee/kit/core/timex" "git.diulo.com/mogfee/kit/core/trace" "time" ) func WithCallerSkip(skip int) Logger { if skip == 0 { return new(richLogger) } return &richLogger{ callerSkip: skip, } } func WithContext(ctx context.Context) Logger { return &richLogger{ ctx: ctx, } } func WithDuration(d time.Duration) Logger { return &richLogger{ fields: []LogField{Field(durationKey, timex.ReprOfDuration(d))}, } } type richLogger struct { ctx context.Context callerSkip int fields []LogField } func (l *richLogger) Info(a ...any) { l.info(fmt.Sprint(a...)) } func (l *richLogger) Infof(s string, a ...any) { l.info(fmt.Sprintf(s, a...)) } func (l *richLogger) Slow(a ...any) { l.slow(fmt.Sprint(a...)) } func (l *richLogger) Slowf(s string, a ...any) { l.slow(fmt.Sprintf(s, a...)) } func (l *richLogger) Debug(a ...any) { l.debug(fmt.Sprint(a...)) } func (l *richLogger) Debugf(s string, a ...any) { l.debug(fmt.Sprintf(s, a...)) } func (l *richLogger) Error(a ...any) { l.error(fmt.Sprint(a...)) } func (l *richLogger) Errorf(s string, a ...any) { l.error(fmt.Sprintf(s, a...)) } func (l *richLogger) WithCallerSkip(skip int) Logger { if skip == 0 { return l } l.callerSkip = skip return l } func (l *richLogger) WithContext(ctx context.Context) Logger { l.ctx = ctx return l } func (l *richLogger) WithDuration(d time.Duration) Logger { l.fields = append(l.fields, Field(durationKey, timex.ReprOfDuration(d))) return l } func (l *richLogger) WithFields(fields ...LogField) Logger { l.fields = append(l.fields, fields...) return l } func (l *richLogger) buildFields(fields ...LogField) []LogField { fields = append(l.fields, fields...) fields = append(fields, Field(callerKey, getCaller(callerDepth+l.callerSkip))) traceID := trace.TraceIDFromContext(l.ctx) if len(traceID) > 0 { fields = append(fields, Field(traceKey, traceID)) } spanID := trace.SpanIDFromContext(l.ctx) if len(spanID) > 0 { fields = append(fields, Field(spanKey, spanID)) } val := l.ctx.Value(fieldsContextKey) if val != nil { if arr, ok := val.([]LogField); ok { fields = append(fields, arr...) } } return fields } func (l *richLogger) debug(v any, fields ...LogField) { if shallLog(DebugLevel) { getWriter().Debug(v, l.buildFields(fields...)...) } } func (l *richLogger) error(v any, fields ...LogField) { if shallLog(ErrorLevel) { getWriter().Error(v, l.buildFields(fields...)...) } } func (l *richLogger) info(v any, fields ...LogField) { if shallLog(InfoLevel) { getWriter().Info(v, l.buildFields(fields...)...) } } func (l *richLogger) slow(v any, fields ...LogField) { if shallLog(ErrorLevel) { getWriter().Slow(v, l.buildFields(fields...)...) } }