package logger import ( "fmt" "log" "os" "path/filepath" "strconv" "time" ) /* Zoraxy Logger This script is designed to make a managed log for the Zoraxy and replace the ton of log.Println in the system core */ type Logger struct { LogToFile bool //Set enable write to file Prefix string //Prefix for log files LogFolder string //Folder to store the log file CurrentLogFile string //Current writing filename file *os.File } func NewLogger(logFilePrefix string, logFolder string, logToFile bool) (*Logger, error) { err := os.MkdirAll(logFolder, 0775) if err != nil { return nil, err } thisLogger := Logger{ LogToFile: logToFile, Prefix: logFilePrefix, LogFolder: logFolder, } logFilePath := thisLogger.getLogFilepath() f, err := os.OpenFile(logFilePath, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0755) if err != nil { return nil, err } thisLogger.CurrentLogFile = logFilePath thisLogger.file = f return &thisLogger, nil } func (l *Logger) getLogFilepath() string { year, month, _ := time.Now().Date() return filepath.Join(l.LogFolder, l.Prefix+"_"+strconv.Itoa(year)+"-"+strconv.Itoa(int(month))+".log") } // PrintAndLog will log the message to file and print the log to STDOUT func (l *Logger) PrintAndLog(title string, message string, originalError error) { go func() { l.Log(title, message, originalError) }() log.Println("[" + title + "] " + message) } // Println is a fast snap-in replacement for log.Println func (l *Logger) Println(v ...interface{}) { //Convert the array of interfaces into string message := fmt.Sprint(v...) go func() { l.Log("info", string(message), nil) }() log.Println("[INFO] " + string(message)) } func (l *Logger) Log(title string, errorMessage string, originalError error) { l.ValidateAndUpdateLogFilepath() if l.LogToFile { if originalError == nil { l.file.WriteString(time.Now().Format("2006-01-02 15:04:05.000000") + "|" + fmt.Sprintf("%-16s", title) + " [INFO]" + errorMessage + "\n") } else { l.file.WriteString(time.Now().Format("2006-01-02 15:04:05.000000") + "|" + fmt.Sprintf("%-16s", title) + " [ERROR]" + errorMessage + " " + originalError.Error() + "\n") } } } // Validate if the logging target is still valid (detect any months change) func (l *Logger) ValidateAndUpdateLogFilepath() { expectedCurrentLogFilepath := l.getLogFilepath() if l.CurrentLogFile != expectedCurrentLogFilepath { //Change of month. Update to a new log file l.file.Close() f, err := os.OpenFile(expectedCurrentLogFilepath, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0755) if err != nil { log.Println("[Logger] Unable to create new log. Logging to file disabled.") l.LogToFile = false return } l.CurrentLogFile = expectedCurrentLogFilepath l.file = f } } func (l *Logger) Close() { l.file.Close() }