improve performance and write directly (#13)

This commit is contained in:
dearplain 2018-06-04 17:05:27 +08:00 committed by siddontang
parent 2b7082d296
commit bdc77568d7
2 changed files with 61 additions and 63 deletions

View File

@ -45,12 +45,13 @@ type RotatingFileHandler struct {
fileName string fileName string
maxBytes int maxBytes int
curBytes int
backupCount int backupCount int
} }
func NewRotatingFileHandler(fileName string, maxBytes int, backupCount int) (*RotatingFileHandler, error) { func NewRotatingFileHandler(fileName string, maxBytes int, backupCount int) (*RotatingFileHandler, error) {
dir := path.Dir(fileName) dir := path.Dir(fileName)
os.Mkdir(dir, 0777) os.MkdirAll(dir, 0777)
h := new(RotatingFileHandler) h := new(RotatingFileHandler)
@ -68,12 +69,20 @@ func NewRotatingFileHandler(fileName string, maxBytes int, backupCount int) (*Ro
return nil, err return nil, err
} }
f, err := h.fd.Stat()
if err != nil {
return nil, err
}
h.curBytes = int(f.Size())
return h, nil return h, nil
} }
func (h *RotatingFileHandler) Write(p []byte) (n int, err error) { func (h *RotatingFileHandler) Write(p []byte) (n int, err error) {
h.doRollover() h.doRollover()
return h.fd.Write(p) n, err = h.fd.Write(p)
h.curBytes += n
return
} }
func (h *RotatingFileHandler) Close() error { func (h *RotatingFileHandler) Close() error {
@ -84,6 +93,11 @@ func (h *RotatingFileHandler) Close() error {
} }
func (h *RotatingFileHandler) doRollover() { func (h *RotatingFileHandler) doRollover() {
if h.curBytes < h.maxBytes {
return
}
f, err := h.fd.Stat() f, err := h.fd.Stat()
if err != nil { if err != nil {
return return
@ -92,6 +106,7 @@ func (h *RotatingFileHandler) doRollover() {
if h.maxBytes <= 0 { if h.maxBytes <= 0 {
return return
} else if f.Size() < int64(h.maxBytes) { } else if f.Size() < int64(h.maxBytes) {
h.curBytes = int(f.Size())
return return
} }
@ -109,6 +124,12 @@ func (h *RotatingFileHandler) doRollover() {
os.Rename(h.fileName, dfn) os.Rename(h.fileName, dfn)
h.fd, _ = os.OpenFile(h.fileName, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666) 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())
} }
} }

View File

@ -50,14 +50,9 @@ type Logger struct {
hMutex sync.Mutex hMutex sync.Mutex
handler Handler handler Handler
quit chan struct{}
msg chan []byte
bufMutex sync.Mutex bufMutex sync.Mutex
bufs [][]byte bufs [][]byte
wg sync.WaitGroup
closed atomicInt32 closed atomicInt32
} }
@ -70,16 +65,10 @@ func New(handler Handler, flag int) *Logger {
l.flag = flag l.flag = flag
l.quit = make(chan struct{})
l.closed.Set(0) l.closed.Set(0)
l.msg = make(chan []byte, 1024)
l.bufs = make([][]byte, 0, 16) l.bufs = make([][]byte, 0, 16)
l.wg.Add(1)
go l.run()
return l return l
} }
@ -95,24 +84,6 @@ func newStdHandler() *StreamHandler {
var std = NewDefault(newStdHandler()) 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 { func (l *Logger) popBuf() []byte {
l.bufMutex.Lock() l.bufMutex.Lock()
var buf []byte var buf []byte
@ -142,12 +113,6 @@ func (l *Logger) Close() {
} }
l.closed.Set(1) l.closed.Set(1)
close(l.quit)
l.wg.Wait()
l.quit = nil
l.handler.Close() l.handler.Close()
} }
@ -188,7 +153,7 @@ func (l *Logger) SetHandler(h Handler) {
l.hMutex.Unlock() 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 { if l.closed.Get() == 1 {
// closed // closed
return return
@ -199,6 +164,13 @@ func (l *Logger) Output(callDepth int, level int, s string) {
return return
} }
var s string
if format == "" {
s = fmt.Sprint(v...)
} else {
s = fmt.Sprintf(format, v...)
}
buf := l.popBuf() buf := l.popBuf()
if l.flag&Ltime > 0 { if l.flag&Ltime > 0 {
@ -241,67 +213,72 @@ func (l *Logger) Output(callDepth int, level int, s string) {
buf = append(buf, '\n') 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 //log with Trace level
func (l *Logger) Trace(v ...interface{}) { func (l *Logger) Trace(v ...interface{}) {
l.Output(2, LevelTrace, fmt.Sprint(v...)) l.Output(2, LevelTrace, "", v...)
} }
//log with Debug level //log with Debug level
func (l *Logger) Debug(v ...interface{}) { func (l *Logger) Debug(v ...interface{}) {
l.Output(2, LevelDebug, fmt.Sprint(v...)) l.Output(2, LevelDebug, "", v...)
} }
//log with info level //log with info level
func (l *Logger) Info(v ...interface{}) { func (l *Logger) Info(v ...interface{}) {
l.Output(2, LevelInfo, fmt.Sprint(v...)) l.Output(2, LevelInfo, "", v...)
} }
//log with warn level //log with warn level
func (l *Logger) Warn(v ...interface{}) { func (l *Logger) Warn(v ...interface{}) {
l.Output(2, LevelWarn, fmt.Sprint(v...)) l.Output(2, LevelWarn, "", v...)
} }
//log with error level //log with error level
func (l *Logger) Error(v ...interface{}) { func (l *Logger) Error(v ...interface{}) {
l.Output(2, LevelError, fmt.Sprint(v...)) l.Output(2, LevelError, "", v...)
} }
//log with fatal level //log with fatal level
func (l *Logger) Fatal(v ...interface{}) { func (l *Logger) Fatal(v ...interface{}) {
l.Output(2, LevelFatal, fmt.Sprint(v...)) l.Output(2, LevelFatal, "", v...)
} }
//log with Trace level //log with Trace level
func (l *Logger) Tracef(format string, v ...interface{}) { 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 //log with Debug level
func (l *Logger) Debugf(format string, v ...interface{}) { 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 //log with info level
func (l *Logger) Infof(format string, v ...interface{}) { 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 //log with warn level
func (l *Logger) Warnf(format string, v ...interface{}) { 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 //log with error level
func (l *Logger) Errorf(format string, v ...interface{}) { 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 //log with fatal level
func (l *Logger) Fatalf(format string, v ...interface{}) { 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) { func SetLevel(level int) {
@ -318,49 +295,49 @@ func SetHandler(h Handler) {
} }
func Trace(v ...interface{}) { func Trace(v ...interface{}) {
std.Output(2, LevelTrace, fmt.Sprint(v...)) std.Output(2, LevelTrace, "", v...)
} }
func Debug(v ...interface{}) { func Debug(v ...interface{}) {
std.Output(2, LevelDebug, fmt.Sprint(v...)) std.Output(2, LevelDebug, "", v...)
} }
func Info(v ...interface{}) { func Info(v ...interface{}) {
std.Output(2, LevelInfo, fmt.Sprint(v...)) std.Output(2, LevelInfo, "", v...)
} }
func Warn(v ...interface{}) { func Warn(v ...interface{}) {
std.Output(2, LevelWarn, fmt.Sprint(v...)) std.Output(2, LevelWarn, "", v...)
} }
func Error(v ...interface{}) { func Error(v ...interface{}) {
std.Output(2, LevelError, fmt.Sprint(v...)) std.Output(2, LevelError, "", v...)
} }
func Fatal(v ...interface{}) { func Fatal(v ...interface{}) {
std.Output(2, LevelFatal, fmt.Sprint(v...)) std.Output(2, LevelFatal, "", v...)
} }
func Tracef(format string, v ...interface{}) { 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{}) { 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{}) { 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{}) { 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{}) { 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{}) { func Fatalf(format string, v ...interface{}) {
std.Output(2, LevelFatal, fmt.Sprintf(format, v...)) std.Output(2, LevelFatal, format, v...)
} }