improve performance and write directly (#13)
This commit is contained in:
parent
2b7082d296
commit
bdc77568d7
|
@ -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())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
99
log/log.go
99
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...)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue