package gologger import ( "fmt" "os" "path/filepath" "runtime" "sync" "time" ) type Option uint8 const ( Events Option = 0x01 Errors Option = 0x02 ) const ( MaxLogSize5MB int64 = 5 * 1024 * 1024 MaxLogSize1MB int64 = 1 * 1024 * 1024 MaxLogSize500KB int64 = 500 * 1024 MaxLogSize100KB int64 = 100 * 1024 MaxLogSize512B int64 = 512 ) const ErrDirName = "error-logs" const EvtDirName = "event-logs" type goLogger struct { muEv *sync.Mutex eventf *os.File eventFileName string muEr *sync.Mutex errorf *os.File errorFileName string splitSize int64 } var logger goLogger func Init(flags Option, splitSize int64) error { timestamp := "_" + time.Now().Format(time.RFC3339) var err error logger.splitSize = splitSize // event file/dir if flags&Events > 0 { 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 } } logger.eventFileName = "events" path := filepath.Join(EvtDirName, logger.eventFileName+timestamp+".txt") logger.eventf, err = os.Create(path) if err != nil { fmt.Printf("logger: new: couldn't create event log file\n") return err } logger.muEv = &sync.Mutex{} } // error file/dir if flags&Errors > 0 { 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 } } logger.errorFileName = "errors" path := filepath.Join(ErrDirName, logger.errorFileName+timestamp+".txt") logger.errorf, err = os.Create(path) if err != nil { fmt.Printf("logger: new: couldn't create error log file\n") return err } logger.muEr = &sync.Mutex{} } return nil } func Print(s string) { fmt.Printf(time.Now().Format(time.RFC3339) + ": " + s + "\n") } func LogEvent(event string) { if logger.eventf != nil { logger.muEv.Lock() defer logger.muEv.Unlock() logger.eventf.WriteString(time.Now().Format(time.RFC3339) + ": " + event + "\n") logger.splitEventLog() } } func LogError(comment string, err error) { if logger.errorf != nil { logger.muEr.Lock() defer logger.muEr.Unlock() logger.errorf.WriteString(time.Now().Format(time.RFC3339) + ": " + comment + ": " + err.Error() + "\n") logger.splitErrorLog() } } func TraceEvent(event string) { if logger.eventf != nil { logger.muEv.Lock() defer logger.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 TraceError(err error) { if logger.errorf != nil { logger.muEr.Lock() defer logger.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() { if logger.eventf != nil { err := logger.eventf.Close() if err != nil { fmt.Printf("logger: on exit: couldn't close event log file\n") } } if logger.errorf != nil { err := logger.errorf.Close() if err != nil { fmt.Printf("logger: on exit: couldn't close error log file\n") } } } func (l *goLogger) splitEventLog() { timestamp := "_" + time.Now().Format(time.RFC3339) evfstats, _ := l.eventf.Stat() if evfstats.Size() >= l.splitSize { // 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 *goLogger) splitErrorLog() { timestamp := "_" + time.Now().Format(time.RFC3339) erfstats, _ := l.errorf.Stat() if erfstats.Size() >= l.splitSize { // 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") } } }