|
|
|
@ -1,6 +1,7 @@ |
|
|
|
|
package log |
|
|
|
|
|
|
|
|
|
import ( |
|
|
|
|
"context" |
|
|
|
|
"log" |
|
|
|
|
) |
|
|
|
|
|
|
|
|
@ -14,17 +15,18 @@ type Logger interface { |
|
|
|
|
Log(level Level, keyvals ...interface{}) error |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
type context struct { |
|
|
|
|
type logger struct { |
|
|
|
|
logs []Logger |
|
|
|
|
prefix []interface{} |
|
|
|
|
hasValuer bool |
|
|
|
|
ctx context.Context |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func (c *context) Log(level Level, keyvals ...interface{}) error { |
|
|
|
|
func (c *logger) Log(level Level, keyvals ...interface{}) error { |
|
|
|
|
kvs := make([]interface{}, 0, len(c.prefix)+len(keyvals)) |
|
|
|
|
kvs = append(kvs, c.prefix...) |
|
|
|
|
if c.hasValuer { |
|
|
|
|
bindValues(kvs) |
|
|
|
|
bindValues(c.ctx, kvs) |
|
|
|
|
} |
|
|
|
|
kvs = append(kvs, keyvals...) |
|
|
|
|
for _, l := range c.logs { |
|
|
|
@ -37,20 +39,35 @@ func (c *context) Log(level Level, keyvals ...interface{}) error { |
|
|
|
|
|
|
|
|
|
// With with logger fields.
|
|
|
|
|
func With(l Logger, kv ...interface{}) Logger { |
|
|
|
|
if c, ok := l.(*context); ok { |
|
|
|
|
if c, ok := l.(*logger); ok { |
|
|
|
|
kvs := make([]interface{}, 0, len(c.prefix)+len(kv)) |
|
|
|
|
kvs = append(kvs, kv...) |
|
|
|
|
kvs = append(kvs, c.prefix...) |
|
|
|
|
return &context{ |
|
|
|
|
return &logger{ |
|
|
|
|
logs: c.logs, |
|
|
|
|
prefix: kvs, |
|
|
|
|
hasValuer: containsValuer(kvs), |
|
|
|
|
ctx: c.ctx, |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
return &context{logs: []Logger{l}, prefix: kv, hasValuer: containsValuer(kv)} |
|
|
|
|
return &logger{logs: []Logger{l}, prefix: kv, hasValuer: containsValuer(kv)} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// WithContext returns a shallow copy of l with its context changed
|
|
|
|
|
// to ctx. The provided ctx must be non-nil.
|
|
|
|
|
func WithContext(ctx context.Context, l Logger) Logger { |
|
|
|
|
if c, ok := l.(*logger); ok { |
|
|
|
|
return &logger{ |
|
|
|
|
logs: c.logs, |
|
|
|
|
prefix: c.prefix, |
|
|
|
|
hasValuer: c.hasValuer, |
|
|
|
|
ctx: ctx, |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
return &logger{logs: []Logger{l}, ctx: ctx} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// MultiLogger wraps multi logger.
|
|
|
|
|
func MultiLogger(logs ...Logger) Logger { |
|
|
|
|
return &context{logs: logs} |
|
|
|
|
return &logger{logs: logs} |
|
|
|
|
} |
|
|
|
|