github.com/andy2046/gopie@v0.7.0/pkg/log/log.go (about)

     1  // Package log implements a minimalistic Logger interface.
     2  package log
     3  
     4  import (
     5  	"io"
     6  	"log"
     7  	"os"
     8  	"sync"
     9  )
    10  
    11  type (
    12  	// Level defines Logging level.
    13  	Level int
    14  
    15  	// Logger is the Logging interface.
    16  	Logger interface {
    17  		Debug(v ...interface{})
    18  		Info(v ...interface{})
    19  		Warn(v ...interface{})
    20  		Error(v ...interface{})
    21  		Debugf(format string, v ...interface{})
    22  		Infof(format string, v ...interface{})
    23  		Warnf(format string, v ...interface{})
    24  		Errorf(format string, v ...interface{})
    25  		SetLevel(l Level)
    26  		LevelLogger(l Level) *log.Logger
    27  	}
    28  
    29  	// Config used to init Logger.
    30  	Config struct {
    31  		Level        Level
    32  		Prefix       string
    33  		Flag         int
    34  		DebugHandler io.Writer
    35  		InfoHandler  io.Writer
    36  		WarnHandler  io.Writer
    37  		ErrorHandler io.Writer
    38  	}
    39  
    40  	// Option applies config to Logger Config.
    41  	Option = func(*Config) error
    42  
    43  	defaultLogger struct {
    44  		loggerz map[Level]*log.Logger
    45  		config  *Config
    46  		sync.RWMutex
    47  	}
    48  )
    49  
    50  // Logging Levels.
    51  const (
    52  	DEBUG Level = iota
    53  	INFO
    54  	WARN
    55  	ERROR
    56  )
    57  
    58  var (
    59  	// DefaultConfig is the default Logger Config.
    60  	DefaultConfig = Config{
    61  		Level:        INFO,
    62  		Prefix:       "",
    63  		Flag:         log.Ldate | log.Ltime,
    64  		DebugHandler: os.Stdout,
    65  		InfoHandler:  os.Stdout,
    66  		WarnHandler:  os.Stdout,
    67  		ErrorHandler: os.Stderr,
    68  	}
    69  
    70  	_ Logger = &defaultLogger{}
    71  )
    72  
    73  // NewLogger returns a new Logger.
    74  func NewLogger(options ...Option) Logger {
    75  	logConfig := DefaultConfig
    76  	setOption(&logConfig, options...)
    77  
    78  	return &defaultLogger{
    79  		config:  &logConfig,
    80  		loggerz: setLoggerz(&logConfig),
    81  	}
    82  }
    83  
    84  // SetLevel sets the Logging level.
    85  func (dl *defaultLogger) SetLevel(l Level) {
    86  	dl.Lock()
    87  	dl.config.Level = l
    88  	dl.Unlock()
    89  }
    90  
    91  func (dl *defaultLogger) Debug(v ...interface{}) {
    92  	dl.log(DEBUG, v...)
    93  }
    94  
    95  func (dl *defaultLogger) Info(v ...interface{}) {
    96  	dl.log(INFO, v...)
    97  }
    98  
    99  func (dl *defaultLogger) Warn(v ...interface{}) {
   100  	dl.log(WARN, v...)
   101  }
   102  
   103  func (dl *defaultLogger) Error(v ...interface{}) {
   104  	dl.log(ERROR, v...)
   105  }
   106  
   107  func (dl *defaultLogger) Debugf(format string, v ...interface{}) {
   108  	dl.logf(DEBUG, format, v...)
   109  }
   110  
   111  func (dl *defaultLogger) Infof(format string, v ...interface{}) {
   112  	dl.logf(INFO, format, v...)
   113  }
   114  
   115  func (dl *defaultLogger) Warnf(format string, v ...interface{}) {
   116  	dl.logf(WARN, format, v...)
   117  }
   118  
   119  func (dl *defaultLogger) Errorf(format string, v ...interface{}) {
   120  	dl.logf(ERROR, format, v...)
   121  }
   122  
   123  func (dl *defaultLogger) LevelLogger(l Level) *log.Logger {
   124  	dl.RLock()
   125  	defer dl.RUnlock()
   126  	return dl.loggerz[l]
   127  }
   128  
   129  func (dl *defaultLogger) log(level Level, v ...interface{}) {
   130  	dl.RLock()
   131  	defer dl.RUnlock()
   132  	if dl.config.Level <= level {
   133  		dl.loggerz[level].Println(v...)
   134  	}
   135  }
   136  
   137  func (dl *defaultLogger) logf(level Level, format string, v ...interface{}) {
   138  	dl.RLock()
   139  	defer dl.RUnlock()
   140  	if dl.config.Level <= level {
   141  		dl.loggerz[level].Printf(format, v...)
   142  	}
   143  }
   144  
   145  func setOption(c *Config, options ...func(*Config) error) error {
   146  	for _, opt := range options {
   147  		if err := opt(c); err != nil {
   148  			return err
   149  		}
   150  	}
   151  	return nil
   152  }
   153  
   154  func setLoggerz(logConfig *Config) map[Level]*log.Logger {
   155  	loggerz := make(map[Level]*log.Logger)
   156  	nonErrorLogger := log.New(os.Stdout, logConfig.Prefix, logConfig.Flag)
   157  	errorLogger := log.New(os.Stderr, logConfig.Prefix, logConfig.Flag)
   158  
   159  	loggerz[DEBUG] = nonErrorLogger
   160  	loggerz[INFO] = nonErrorLogger
   161  	loggerz[WARN] = nonErrorLogger
   162  	loggerz[ERROR] = errorLogger
   163  
   164  	if logConfig.DebugHandler != os.Stdout {
   165  		loggerz[DEBUG] = log.New(logConfig.DebugHandler, logConfig.Prefix, logConfig.Flag)
   166  	}
   167  	if logConfig.InfoHandler != os.Stdout {
   168  		loggerz[INFO] = log.New(logConfig.InfoHandler, logConfig.Prefix, logConfig.Flag)
   169  	}
   170  	if logConfig.WarnHandler != os.Stdout {
   171  		loggerz[WARN] = log.New(logConfig.WarnHandler, logConfig.Prefix, logConfig.Flag)
   172  	}
   173  	if logConfig.ErrorHandler != os.Stderr {
   174  		loggerz[ERROR] = log.New(logConfig.ErrorHandler, logConfig.Prefix, logConfig.Flag)
   175  	}
   176  
   177  	return loggerz
   178  }