package gologger import ( "fmt" "os" "path/filepath" "runtime" "sync" "time" ) var muEv = &sync.Mutex{} var muEr = &sync.Mutex{} const MaxLogFileSize5MB int64 = 5 * 1024 * 1024 const MaxLogFileSize1MB int64 = 1 * 1024 * 1024 const MaxLogFileSize500KB int64 = 500 * 1024 const MaxLogFileSize100KB int64 = 100 * 1024 const MaxLogFileSize512B int64 = 512 const ErrDirName = "error-logs" const EvtDirName = "event-logs" type Logger struct { eventf *os.File eventFileName string errorf *os.File errorFileName string } var logger Logger func Init(eventFileName, errorFileName string) error { timestamp := "_" + time.Now().Format(time.RFC3339) // create directories to keep log files err := os.Mkdir(EvtDirName, os.ModePerm) if err != nil { if !os.IsExist(err) { fmt.Printf("logger: mkdir: couldn't create event log directory\n") return err } } err = os.Mkdir(ErrDirName, os.ModePerm) if err != nil { if !os.IsExist(err) { fmt.Printf("logger: new: couldn't create error log directory\n") return err } } // create files logger.eventFileName = eventFileName logger.errorFileName = errorFileName path := filepath.Join(EvtDirName, eventFileName+timestamp) logger.eventf, err = os.Create(path) if err != nil { fmt.Printf("logger: new: couldn't create event log file\n") return err } path = filepath.Join(ErrDirName, errorFileName+timestamp) logger.errorf, err = os.Create(path) if err != nil { fmt.Printf("logger: new: couldn't create error log file\n") return err } return nil } func LogEvent(event string) { muEv.Lock() defer muEv.Unlock() logger.eventf.WriteString(time.Now().Format(time.RFC3339) + ": " + event + "\n") logger.splitEventLog() } func LogError(comment string, err error) { muEr.Lock() defer muEr.Unlock() logger.errorf.WriteString(time.Now().Format(time.RFC3339) + ": " + comment + ": " + err.Error() + "\n") logger.splitErrorLog() } func LogDetailedEvent(event string) { muEv.Lock() defer muEv.Unlock() _, file, line, ok := runtime.Caller(1) var s string if ok { s = fmt.Sprintf("%s: %s %d: %s\n", time.Now().Format(time.RFC3339), file, line, event) } else { s = fmt.Sprintf(time.Now().Format(time.RFC3339) + ": [can't retreive stack details]:" + event + "\n") } logger.eventf.WriteString(s) logger.splitEventLog() } func LogDetailedError(err error) { muEr.Lock() defer muEr.Unlock() _, file, line, ok := runtime.Caller(1) var s string if ok { s = fmt.Sprintf("%s %s %d: %s\n", time.Now().Format(time.RFC3339), file, line, err.Error()) } else { s = fmt.Sprintf(time.Now().Format(time.RFC3339) + ": [can't retreive stack details]:" + err.Error() + "\n") } logger.errorf.WriteString(s) logger.splitErrorLog() } func Close() { // close files err := logger.eventf.Close() if err != nil { fmt.Printf("logger: on exit: couldn't close event log file\n") } err = logger.errorf.Close() if err != nil { fmt.Printf("logger: on exit: couldn't close error log file\n") } } func (l *Logger) splitEventLog() { timestamp := "_" + time.Now().Format(time.RFC3339) evfstats, _ := l.eventf.Stat() if evfstats.Size() >= MaxLogFileSize100KB { // close old file err := l.eventf.Close() if err != nil { fmt.Printf("logger: split: couldn't close event file\n") return } // open new file var errnew error path := filepath.Join(EvtDirName, l.eventFileName+timestamp) l.eventf, errnew = os.Create(path) if errnew != nil { fmt.Printf("logger: split: couldn't create event log file\n") } } } func (l *Logger) splitErrorLog() { timestamp := "_" + time.Now().Format(time.RFC3339) erfstats, _ := l.errorf.Stat() if erfstats.Size() >= MaxLogFileSize100KB { // close old file err := l.errorf.Close() if err != nil { fmt.Printf("logger: split: couldn't close error file\n") return } // open new file var errnew error path := filepath.Join(ErrDirName, l.errorFileName+timestamp) l.errorf, errnew = os.Create(path) if errnew != nil { fmt.Printf("logger: split: couldn't create error log file\n") } } }