package logger import ( "fmt" "io" "log" "os" "path/filepath" "runtime" "time" ) // Settings stores config for logger type Settings struct { Path string `yaml:"path"` Name string `yaml:"name"` Ext string `yaml:"ext"` TimeFormat string `yaml:"time-format"` } var ( logFile *os.File defaultPrefix = "" defaultCallerDepth = 2 logger *log.Logger logPrefix = "" levelFlags = []string{"DEBUG", "INFO", "WARN", "ERROR", "FATAL"} ) type logLevel int // log levels const ( DEBUG logLevel = iota INFO WARNING ERROR FATAL ) const flags = log.LstdFlags func init() { logger = log.New(os.Stdout, defaultPrefix, flags) } // Setup initializes logger func Setup(settings *Settings) { var err error dir := settings.Path fileName := fmt.Sprintf("%s-%s.%s", settings.Name, time.Now().Format(settings.TimeFormat), settings.Ext) logFile, err := mustOpen(fileName, dir) if err != nil { log.Fatalf("logging.Setup err: %s", err) } mw := io.MultiWriter(os.Stdout, logFile) logger = log.New(mw, defaultPrefix, flags) } func setPrefix(level logLevel) { _, file, line, ok := runtime.Caller(defaultCallerDepth) if ok { logPrefix = fmt.Sprintf("[%s][%s:%d] ", levelFlags[level], filepath.Base(file), line) } else { logPrefix = fmt.Sprintf("[%s] ", levelFlags[level]) } logger.SetPrefix(logPrefix) } // Debug prints debug log func Debug(v ...interface{}) { setPrefix(DEBUG) logger.Println(v...) } // Info prints normal log func Info(v ...interface{}) { setPrefix(INFO) logger.Println(v...) } // Warn prints warning log func Warn(v ...interface{}) { setPrefix(WARNING) logger.Println(v...) } // Error prints error log func Error(v ...interface{}) { setPrefix(ERROR) logger.Println(v...) } // Fatal prints error log then stop the program func Fatal(v ...interface{}) { setPrefix(FATAL) logger.Fatalln(v...) }