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