package log import ( "context" "log" ) var DefaultLogger = NewStdLogger(log.Writer()) type Logger interface { Log(level Level, keyvals ...any) error } type logger struct { logger Logger prefix []any hasValuer bool ctx context.Context } func (l *logger) Log(level Level, keyvals ...any) error { kvs := make([]any, 0, len(l.prefix)+len(keyvals)) kvs = append(kvs, l.prefix...) if l.hasValuer { bindValues(l.ctx, kvs) } kvs = append(kvs, keyvals...) return l.logger.Log(level, kvs...) } func With(l Logger, kv ...any) Logger { c, ok := l.(*logger) if !ok { return &logger{ logger: l, prefix: kv, hasValuer: containsValuer(kv), ctx: context.Background(), } } kvs := make([]any, 0, len(c.prefix)+len(kv)) kvs = append(kvs, c.prefix...) kvs = append(kvs, kv...) return &logger{ logger: c.logger, prefix: kvs, hasValuer: containsValuer(kvs), ctx: c.ctx, } } func WithContext(ctx context.Context, l Logger) Logger { c, ok := l.(*logger) if !ok { return &logger{ logger: l, ctx: ctx, } } return &logger{ logger: c.logger, prefix: c.prefix, hasValuer: c.hasValuer, ctx: ctx, } }