package logger import ( "fmt" "io" "io/ioutil" "os" "sync" "time" ) type defaultLogger struct { logLevel LogLevel mutex *sync.Mutex stdout io.Writer stderr io.Writer } func (dl *defaultLogger) Debug(f string, v ...interface{}) { dl.log(LogLevelDebug, f, v...) } func (dl *defaultLogger) Info(f string, v ...interface{}) { dl.log(LogLevelInfo, f, v...) } func (dl *defaultLogger) Warn(f string, v ...interface{}) { dl.log(LogLevelWarn, f, v...) } func (dl *defaultLogger) Error(f string, v ...interface{}) { dl.log(LogLevelError, f, v...) } func (dl *defaultLogger) Fatal(f string, v ...interface{}) { dl.log(LogLevelFatal, f, v...) os.Exit(1) } func (dl *defaultLogger) log(ll LogLevel, f string, v ...interface{}) { if dl.logLevel > ll { return } layout := "2006/01/02 15:04:05" dw := dl.stdout prefix := "" switch ll { case LogLevelDebug: prefix = "DEBUG" case LogLevelInfo: prefix = "INFO" case LogLevelWarn: prefix = "WARN" case LogLevelError: prefix = "ERROR" dw = dl.stderr case LogLevelFatal: prefix = "FATAL" dw = dl.stderr } dl.mutex.Lock() fmt.Fprintf(dw, "%v %v: %v\n", time.Now().Format(layout), prefix, fmt.Sprintf(f, v...)) dl.mutex.Unlock() } func NewDefaultLogger(logLevel LogLevel) Logger { return &defaultLogger{ logLevel: logLevel, mutex: new(sync.Mutex), stdout: os.Stdout, stderr: os.Stderr, } } func NewCustomLogger(loglevel LogLevel, out io.Writer, err io.Writer) Logger { return &defaultLogger{ logLevel: loglevel, mutex: new(sync.Mutex), stdout: out, stderr: err, } } func NewSilentLogger() Logger { return &defaultLogger{ logLevel: LogLevelDebug, mutex: new(sync.Mutex), stdout: ioutil.Discard, stderr: ioutil.Discard, } }