From bdc77568d726a8702315ec4eafda030b6abc4f43 Mon Sep 17 00:00:00 2001 From: dearplain Date: Mon, 4 Jun 2018 17:05:27 +0800 Subject: [PATCH] improve performance and write directly (#13) --- log/filehandler.go | 25 +++++++++++- log/log.go | 99 ++++++++++++++++++---------------------------- 2 files changed, 61 insertions(+), 63 deletions(-) diff --git a/log/filehandler.go b/log/filehandler.go index 308896a..2c158e2 100644 --- a/log/filehandler.go +++ b/log/filehandler.go @@ -45,12 +45,13 @@ type RotatingFileHandler struct { fileName string maxBytes int + curBytes int backupCount int } func NewRotatingFileHandler(fileName string, maxBytes int, backupCount int) (*RotatingFileHandler, error) { dir := path.Dir(fileName) - os.Mkdir(dir, 0777) + os.MkdirAll(dir, 0777) h := new(RotatingFileHandler) @@ -68,12 +69,20 @@ func NewRotatingFileHandler(fileName string, maxBytes int, backupCount int) (*Ro return nil, err } + f, err := h.fd.Stat() + if err != nil { + return nil, err + } + h.curBytes = int(f.Size()) + return h, nil } func (h *RotatingFileHandler) Write(p []byte) (n int, err error) { h.doRollover() - return h.fd.Write(p) + n, err = h.fd.Write(p) + h.curBytes += n + return } func (h *RotatingFileHandler) Close() error { @@ -84,6 +93,11 @@ func (h *RotatingFileHandler) Close() error { } func (h *RotatingFileHandler) doRollover() { + + if h.curBytes < h.maxBytes { + return + } + f, err := h.fd.Stat() if err != nil { return @@ -92,6 +106,7 @@ func (h *RotatingFileHandler) doRollover() { if h.maxBytes <= 0 { return } else if f.Size() < int64(h.maxBytes) { + h.curBytes = int(f.Size()) return } @@ -109,6 +124,12 @@ func (h *RotatingFileHandler) doRollover() { os.Rename(h.fileName, dfn) h.fd, _ = os.OpenFile(h.fileName, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666) + h.curBytes = 0 + f, err := h.fd.Stat() + if err != nil { + return + } + h.curBytes = int(f.Size()) } } diff --git a/log/log.go b/log/log.go index f2e5ef2..371f601 100644 --- a/log/log.go +++ b/log/log.go @@ -50,14 +50,9 @@ type Logger struct { hMutex sync.Mutex handler Handler - quit chan struct{} - msg chan []byte - bufMutex sync.Mutex bufs [][]byte - wg sync.WaitGroup - closed atomicInt32 } @@ -70,16 +65,10 @@ func New(handler Handler, flag int) *Logger { l.flag = flag - l.quit = make(chan struct{}) l.closed.Set(0) - l.msg = make(chan []byte, 1024) - l.bufs = make([][]byte, 0, 16) - l.wg.Add(1) - go l.run() - return l } @@ -95,24 +84,6 @@ func newStdHandler() *StreamHandler { var std = NewDefault(newStdHandler()) -func (l *Logger) run() { - defer l.wg.Done() - for { - select { - case msg := <-l.msg: - l.hMutex.Lock() - l.handler.Write(msg) - l.hMutex.Unlock() - l.putBuf(msg) - case <-l.quit: - //we must log all msg - if len(l.msg) == 0 { - return - } - } - } -} - func (l *Logger) popBuf() []byte { l.bufMutex.Lock() var buf []byte @@ -142,12 +113,6 @@ func (l *Logger) Close() { } l.closed.Set(1) - close(l.quit) - - l.wg.Wait() - - l.quit = nil - l.handler.Close() } @@ -188,7 +153,7 @@ func (l *Logger) SetHandler(h Handler) { l.hMutex.Unlock() } -func (l *Logger) Output(callDepth int, level int, s string) { +func (l *Logger) Output(callDepth int, level int, format string, v ...interface{}) { if l.closed.Get() == 1 { // closed return @@ -199,6 +164,13 @@ func (l *Logger) Output(callDepth int, level int, s string) { return } + var s string + if format == "" { + s = fmt.Sprint(v...) + } else { + s = fmt.Sprintf(format, v...) + } + buf := l.popBuf() if l.flag&Ltime > 0 { @@ -241,67 +213,72 @@ func (l *Logger) Output(callDepth int, level int, s string) { buf = append(buf, '\n') } - l.msg <- buf + // l.msg <- buf + + l.hMutex.Lock() + l.handler.Write(buf) + l.hMutex.Unlock() + l.putBuf(buf) } //log with Trace level func (l *Logger) Trace(v ...interface{}) { - l.Output(2, LevelTrace, fmt.Sprint(v...)) + l.Output(2, LevelTrace, "", v...) } //log with Debug level func (l *Logger) Debug(v ...interface{}) { - l.Output(2, LevelDebug, fmt.Sprint(v...)) + l.Output(2, LevelDebug, "", v...) } //log with info level func (l *Logger) Info(v ...interface{}) { - l.Output(2, LevelInfo, fmt.Sprint(v...)) + l.Output(2, LevelInfo, "", v...) } //log with warn level func (l *Logger) Warn(v ...interface{}) { - l.Output(2, LevelWarn, fmt.Sprint(v...)) + l.Output(2, LevelWarn, "", v...) } //log with error level func (l *Logger) Error(v ...interface{}) { - l.Output(2, LevelError, fmt.Sprint(v...)) + l.Output(2, LevelError, "", v...) } //log with fatal level func (l *Logger) Fatal(v ...interface{}) { - l.Output(2, LevelFatal, fmt.Sprint(v...)) + l.Output(2, LevelFatal, "", v...) } //log with Trace level func (l *Logger) Tracef(format string, v ...interface{}) { - l.Output(2, LevelTrace, fmt.Sprintf(format, v...)) + l.Output(2, LevelTrace, format, v...) } //log with Debug level func (l *Logger) Debugf(format string, v ...interface{}) { - l.Output(2, LevelDebug, fmt.Sprintf(format, v...)) + l.Output(2, LevelDebug, format, v...) } //log with info level func (l *Logger) Infof(format string, v ...interface{}) { - l.Output(2, LevelInfo, fmt.Sprintf(format, v...)) + l.Output(2, LevelInfo, format, v...) } //log with warn level func (l *Logger) Warnf(format string, v ...interface{}) { - l.Output(2, LevelWarn, fmt.Sprintf(format, v...)) + l.Output(2, LevelWarn, format, v...) } //log with error level func (l *Logger) Errorf(format string, v ...interface{}) { - l.Output(2, LevelError, fmt.Sprintf(format, v...)) + l.Output(2, LevelError, format, v...) } //log with fatal level func (l *Logger) Fatalf(format string, v ...interface{}) { - l.Output(2, LevelFatal, fmt.Sprintf(format, v...)) + l.Output(2, LevelFatal, format, v...) } func SetLevel(level int) { @@ -318,49 +295,49 @@ func SetHandler(h Handler) { } func Trace(v ...interface{}) { - std.Output(2, LevelTrace, fmt.Sprint(v...)) + std.Output(2, LevelTrace, "", v...) } func Debug(v ...interface{}) { - std.Output(2, LevelDebug, fmt.Sprint(v...)) + std.Output(2, LevelDebug, "", v...) } func Info(v ...interface{}) { - std.Output(2, LevelInfo, fmt.Sprint(v...)) + std.Output(2, LevelInfo, "", v...) } func Warn(v ...interface{}) { - std.Output(2, LevelWarn, fmt.Sprint(v...)) + std.Output(2, LevelWarn, "", v...) } func Error(v ...interface{}) { - std.Output(2, LevelError, fmt.Sprint(v...)) + std.Output(2, LevelError, "", v...) } func Fatal(v ...interface{}) { - std.Output(2, LevelFatal, fmt.Sprint(v...)) + std.Output(2, LevelFatal, "", v...) } func Tracef(format string, v ...interface{}) { - std.Output(2, LevelTrace, fmt.Sprintf(format, v...)) + std.Output(2, LevelTrace, format, v...) } func Debugf(format string, v ...interface{}) { - std.Output(2, LevelDebug, fmt.Sprintf(format, v...)) + std.Output(2, LevelDebug, format, v...) } func Infof(format string, v ...interface{}) { - std.Output(2, LevelInfo, fmt.Sprintf(format, v...)) + std.Output(2, LevelInfo, format, v...) } func Warnf(format string, v ...interface{}) { - std.Output(2, LevelWarn, fmt.Sprintf(format, v...)) + std.Output(2, LevelWarn, format, v...) } func Errorf(format string, v ...interface{}) { - std.Output(2, LevelError, fmt.Sprintf(format, v...)) + std.Output(2, LevelError, format, v...) } func Fatalf(format string, v ...interface{}) { - std.Output(2, LevelFatal, fmt.Sprintf(format, v...)) + std.Output(2, LevelFatal, format, v...) }