123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227 |
- package zap
- import (
- "context"
- "fmt"
- "io"
- "os"
- "sync"
- "go.uber.org/zap"
- "go.uber.org/zap/zapcore"
- "gogs.baozhida.cn/zoie/OAuth-core/logger"
- )
- type zaplog struct {
- cfg zap.Config
- zap *zap.Logger
- opts logger.Options
- sync.RWMutex
- fields map[string]interface{}
- }
- func (l *zaplog) Init(opts ...logger.Option) error {
- //var err error
- for _, o := range opts {
- o(&l.opts)
- }
- zapConfig := zap.NewProductionConfig()
- if zconfig, ok := l.opts.Context.Value(configKey{}).(zap.Config); ok {
- zapConfig = zconfig
- }
- if zcconfig, ok := l.opts.Context.Value(encoderConfigKey{}).(zapcore.EncoderConfig); ok {
- zapConfig.EncoderConfig = zcconfig
- }
- writer, ok := l.opts.Context.Value(writerKey{}).(io.Writer)
- if !ok {
- writer = os.Stdout
- }
- skip, ok := l.opts.Context.Value(callerSkipKey{}).(int)
- if !ok || skip < 1 {
- skip = 1
- }
- // Set log Level if not default
- zapConfig.Level = zap.NewAtomicLevel()
- if l.opts.Level != logger.InfoLevel {
- zapConfig.Level.SetLevel(loggerToZapLevel(l.opts.Level))
- }
- zapConfig.EncoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder
- logCore := zapcore.NewCore(
- zapcore.NewConsoleEncoder(zapConfig.EncoderConfig),
- zapcore.NewMultiWriteSyncer(zapcore.AddSync(writer)),
- zapConfig.Level)
- log := zap.New(logCore, zap.AddCaller(), zap.AddCallerSkip(skip), zap.AddStacktrace(zap.DPanicLevel))
- //log, err := zapConfig.Build(zap.AddCallerSkip(skip))
- //if err != nil {
- // return err
- //}
- // Adding seed fields if exist
- if l.opts.Fields != nil {
- data := []zap.Field{}
- for k, v := range l.opts.Fields {
- data = append(data, zap.Any(k, v))
- }
- log = log.With(data...)
- }
- // Adding namespace
- if namespace, ok := l.opts.Context.Value(namespaceKey{}).(string); ok {
- log = log.With(zap.Namespace(namespace))
- }
- // defer log.Sync() ??
- l.cfg = zapConfig
- l.zap = log
- l.fields = make(map[string]interface{})
- return nil
- }
- func (l *zaplog) Fields(fields map[string]interface{}) logger.Logger {
- l.Lock()
- nfields := make(map[string]interface{}, len(l.fields))
- for k, v := range l.fields {
- nfields[k] = v
- }
- l.Unlock()
- for k, v := range fields {
- nfields[k] = v
- }
- data := make([]zap.Field, 0, len(nfields))
- for k, v := range fields {
- data = append(data, zap.Any(k, v))
- }
- zl := &zaplog{
- cfg: l.cfg,
- zap: l.zap,
- opts: l.opts,
- fields: nfields,
- }
- return zl
- }
- func (l *zaplog) Error(err error) logger.Logger {
- return l.Fields(map[string]interface{}{"error": err})
- }
- func (l *zaplog) Log(level logger.Level, args ...interface{}) {
- l.RLock()
- data := make([]zap.Field, 0, len(l.fields))
- for k, v := range l.fields {
- data = append(data, zap.Any(k, v))
- }
- l.RUnlock()
- lvl := loggerToZapLevel(level)
- msg := fmt.Sprint(args...)
- switch lvl {
- case zap.DebugLevel:
- l.zap.Debug(msg, data...)
- case zap.InfoLevel:
- l.zap.Info(msg, data...)
- case zap.WarnLevel:
- l.zap.Warn(msg, data...)
- case zap.ErrorLevel:
- l.zap.Error(msg, data...)
- case zap.FatalLevel:
- l.zap.Fatal(msg, data...)
- }
- }
- func (l *zaplog) Logf(level logger.Level, format string, args ...interface{}) {
- l.RLock()
- data := make([]zap.Field, 0, len(l.fields))
- for k, v := range l.fields {
- data = append(data, zap.Any(k, v))
- }
- l.RUnlock()
- lvl := loggerToZapLevel(level)
- msg := fmt.Sprintf(format, args...)
- switch lvl {
- case zap.DebugLevel:
- l.zap.Debug(msg, data...)
- case zap.InfoLevel:
- l.zap.Info(msg, data...)
- case zap.WarnLevel:
- l.zap.Warn(msg, data...)
- case zap.ErrorLevel:
- l.zap.Error(msg, data...)
- case zap.FatalLevel:
- l.zap.Fatal(msg, data...)
- }
- }
- func (l *zaplog) String() string {
- return "zap"
- }
- func (l *zaplog) Options() logger.Options {
- return l.opts
- }
- // New builds a new logger based on options
- func NewLogger(opts ...logger.Option) (logger.Logger, error) {
- // Default options
- options := logger.Options{
- Level: logger.InfoLevel,
- Fields: make(map[string]interface{}),
- Out: os.Stderr,
- Context: context.Background(),
- }
- l := &zaplog{opts: options}
- if err := l.Init(opts...); err != nil {
- return nil, err
- }
- return l, nil
- }
- func loggerToZapLevel(level logger.Level) zapcore.Level {
- switch level {
- case logger.TraceLevel, logger.DebugLevel:
- return zap.DebugLevel
- case logger.InfoLevel:
- return zap.InfoLevel
- case logger.WarnLevel:
- return zap.WarnLevel
- case logger.ErrorLevel:
- return zap.ErrorLevel
- case logger.FatalLevel:
- return zap.FatalLevel
- default:
- return zap.InfoLevel
- }
- }
- func zapToLoggerLevel(level zapcore.Level) logger.Level {
- switch level {
- case zap.DebugLevel:
- return logger.DebugLevel
- case zap.InfoLevel:
- return logger.InfoLevel
- case zap.WarnLevel:
- return logger.WarnLevel
- case zap.ErrorLevel:
- return logger.ErrorLevel
- case zap.FatalLevel:
- return logger.FatalLevel
- default:
- return logger.InfoLevel
- }
- }
|