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
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())
}
}

View File

@ -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...)
}