mirror of
https://github.com/astaxie/beego.git
synced 2024-11-26 07:11:29 +00:00
remove the lock writer
This commit is contained in:
parent
58730e3528
commit
7663d50c97
106
logs/file.go
106
logs/file.go
@ -30,10 +30,12 @@ import (
|
|||||||
// fileLogWriter implements LoggerInterface.
|
// fileLogWriter implements LoggerInterface.
|
||||||
// It writes messages by lines limit, file size limit, or time frequency.
|
// It writes messages by lines limit, file size limit, or time frequency.
|
||||||
type fileLogWriter struct {
|
type fileLogWriter struct {
|
||||||
*MuxWriter
|
sync.Mutex // write log order by order and atomic incr maxLinesCurLines and maxSizeCurSize
|
||||||
// The opened file
|
// The opened file
|
||||||
Filename string `json:"filename"`
|
Filename string `json:"filename"`
|
||||||
|
fileWriter *os.File
|
||||||
|
|
||||||
|
// Rotate at line
|
||||||
MaxLines int `json:"maxlines"`
|
MaxLines int `json:"maxlines"`
|
||||||
maxLinesCurLines int
|
maxLinesCurLines int
|
||||||
|
|
||||||
@ -48,35 +50,11 @@ type fileLogWriter struct {
|
|||||||
|
|
||||||
Rotate bool `json:"rotate"`
|
Rotate bool `json:"rotate"`
|
||||||
|
|
||||||
startLock sync.Mutex // atomic incr maxLinesCurLines and maxSizeCurSize
|
|
||||||
|
|
||||||
Level int `json:"level"`
|
Level int `json:"level"`
|
||||||
|
|
||||||
Perm os.FileMode `json:"perm"`
|
Perm os.FileMode `json:"perm"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// MuxWriter is an *os.File writer with locker,lock write when rotate
|
|
||||||
type MuxWriter struct {
|
|
||||||
sync.Mutex
|
|
||||||
fileWriter *os.File
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write to os.File.
|
|
||||||
func (mw *MuxWriter) Write(b []byte) (int, error) {
|
|
||||||
mw.Lock()
|
|
||||||
n, e := mw.fileWriter.Write(b)
|
|
||||||
mw.Unlock()
|
|
||||||
return n, e
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetFileWriter set os.File in writer.
|
|
||||||
func (mw *MuxWriter) SetFileWriter(fd *os.File) {
|
|
||||||
if mw.fileWriter != nil {
|
|
||||||
mw.fileWriter.Close()
|
|
||||||
}
|
|
||||||
mw.fileWriter = fd
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewFileWriter create a FileLogWriter returning as LoggerInterface.
|
// NewFileWriter create a FileLogWriter returning as LoggerInterface.
|
||||||
func newFileWriter() Logger {
|
func newFileWriter() Logger {
|
||||||
w := &fileLogWriter{
|
w := &fileLogWriter{
|
||||||
@ -88,7 +66,6 @@ func newFileWriter() Logger {
|
|||||||
Rotate: true,
|
Rotate: true,
|
||||||
Level: LevelTrace,
|
Level: LevelTrace,
|
||||||
Perm: 0660,
|
Perm: 0660,
|
||||||
MuxWriter: new(MuxWriter),
|
|
||||||
}
|
}
|
||||||
return w
|
return w
|
||||||
}
|
}
|
||||||
@ -122,24 +99,18 @@ func (w *fileLogWriter) startLogger() error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
w.SetFileWriter(file)
|
if w.fileWriter != nil {
|
||||||
|
w.fileWriter.Close()
|
||||||
|
}
|
||||||
|
w.fileWriter = file
|
||||||
return w.initFd()
|
return w.initFd()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *fileLogWriter) doCheck(size int) {
|
func (w *fileLogWriter) needRotate(size int, day int) bool {
|
||||||
w.startLock.Lock()
|
return (w.MaxLines > 0 && w.maxLinesCurLines >= w.MaxLines) ||
|
||||||
if w.Rotate {
|
|
||||||
if (w.MaxLines > 0 && w.maxLinesCurLines >= w.MaxLines) ||
|
|
||||||
(w.MaxSize > 0 && w.maxSizeCurSize >= w.MaxSize) ||
|
(w.MaxSize > 0 && w.maxSizeCurSize >= w.MaxSize) ||
|
||||||
(w.Daily && time.Now().Day() != w.dailyOpenDate) {
|
(w.Daily && day != w.dailyOpenDate)
|
||||||
if err := w.DoRotate(); err != nil {
|
|
||||||
fmt.Fprintf(os.Stderr, "FileLogWriter(%q): %s\n", w.Filename, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
w.maxLinesCurLines++
|
|
||||||
w.maxSizeCurSize += size
|
|
||||||
w.startLock.Unlock()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// WriteMsg write logger message into file.
|
// WriteMsg write logger message into file.
|
||||||
@ -185,11 +156,29 @@ func (w *fileLogWriter) WriteMsg(msg string, level int) error {
|
|||||||
t = s / 10
|
t = s / 10
|
||||||
buf[17] = byte('0' + t)
|
buf[17] = byte('0' + t)
|
||||||
buf[18] = byte('0' + s - t*10)
|
buf[18] = byte('0' + s - t*10)
|
||||||
buf[18] = ' '
|
buf[19] = ' '
|
||||||
msg = string(buf[0:]) + msg + "\n"
|
msg = string(buf[0:]) + msg + "\n"
|
||||||
|
|
||||||
w.doCheck(len(msg))
|
if w.Rotate {
|
||||||
_, err := w.Write([]byte(msg))
|
if w.needRotate(len(msg), d) {
|
||||||
|
w.Lock()
|
||||||
|
if w.needRotate(len(msg), d) {
|
||||||
|
if err := w.doRotate(); err != nil {
|
||||||
|
fmt.Fprintf(os.Stderr, "FileLogWriter(%q): %s\n", w.Filename, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
w.Unlock()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
w.Lock()
|
||||||
|
_, err := w.fileWriter.Write([]byte(msg))
|
||||||
|
if err == nil {
|
||||||
|
w.maxLinesCurLines++
|
||||||
|
w.maxSizeCurSize += len(msg)
|
||||||
|
}
|
||||||
|
w.Unlock()
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -247,7 +236,7 @@ func (w *fileLogWriter) lines() (int, error) {
|
|||||||
|
|
||||||
// DoRotate means it need to write file in new file.
|
// DoRotate means it need to write file in new file.
|
||||||
// new file name like xx.2013-01-01.2.log
|
// new file name like xx.2013-01-01.2.log
|
||||||
func (w *fileLogWriter) DoRotate() error {
|
func (w *fileLogWriter) doRotate() error {
|
||||||
_, err := os.Lstat(w.Filename)
|
_, err := os.Lstat(w.Filename)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
// file exists
|
// file exists
|
||||||
@ -268,27 +257,22 @@ func (w *fileLogWriter) DoRotate() error {
|
|||||||
return fmt.Errorf("Rotate: Cannot find free log number to rename %s\n", w.Filename)
|
return fmt.Errorf("Rotate: Cannot find free log number to rename %s\n", w.Filename)
|
||||||
}
|
}
|
||||||
|
|
||||||
// block Logger's io.Writer
|
// close fileWriter before rename
|
||||||
w.Lock()
|
w.fileWriter.Close()
|
||||||
defer w.Unlock()
|
|
||||||
|
|
||||||
fd := w.fileWriter
|
|
||||||
fd.Close()
|
|
||||||
|
|
||||||
// close fd before rename
|
|
||||||
// Rename the file to its new found name
|
// Rename the file to its new found name
|
||||||
err = os.Rename(w.Filename, fName)
|
// even if occurs error,we MUST guarantee to restart new logger
|
||||||
if err != nil {
|
renameErr := os.Rename(w.Filename, fName)
|
||||||
return fmt.Errorf("Rotate: %s\n", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// re-start logger
|
// re-start logger
|
||||||
err = w.startLogger()
|
startLoggerErr := w.startLogger()
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("Rotate StartLogger: %s\n", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
go w.deleteOldLog()
|
go w.deleteOldLog()
|
||||||
|
|
||||||
|
if startLoggerErr != nil {
|
||||||
|
return fmt.Errorf("Rotate StartLogger: %s\n", startLoggerErr)
|
||||||
|
}
|
||||||
|
if renameErr != nil {
|
||||||
|
return fmt.Errorf("Rotate: %s\n", renameErr)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
Loading…
Reference in New Issue
Block a user