1
0
mirror of https://github.com/astaxie/beego.git synced 2024-11-22 20:20:56 +00:00

embedding file writer

This commit is contained in:
JessonChan 2016-01-12 19:25:33 +08:00
parent 9507e59c2f
commit 5511e03b52

View File

@ -32,32 +32,32 @@ import (
// 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 {
*log.Logger *log.Logger
mw *MuxWriter *MuxWriter
// The opened file // The opened file
Filename string `json:"filename"` Filename string `json:"filename"`
MaxLines int `json:"maxlines"` MaxLines int `json:"maxlines"`
maxLinesCurLines int maxLinesCurLines int
// Rotate at size // Rotate at size
MaxSize int `json:"maxsize"` MaxSize int `json:"maxsize"`
maxSizeCurSize int maxSizeCurSize int
// Rotate daily // Rotate daily
Daily bool `json:"daily"` Daily bool `json:"daily"`
MaxDays int64 `json:"maxdays"` MaxDays int64 `json:"maxdays"`
dailyOpenDate int dailyOpenDate int
Rotate bool `json:"rotate"` Rotate bool `json:"rotate"`
startLock sync.Mutex // Only one log can write to the file startLock sync.Mutex // Only one log can write to the file
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. // MuxWriter is an *os.File writer with locker,lock write when rotate
type MuxWriter struct { type MuxWriter struct {
sync.Mutex sync.Mutex
fd *os.File fd *os.File
@ -81,19 +81,18 @@ func (l *MuxWriter) SetFd(fd *os.File) {
// NewFileWriter create a FileLogWriter returning as LoggerInterface. // NewFileWriter create a FileLogWriter returning as LoggerInterface.
func newFileWriter() Logger { func newFileWriter() Logger {
w := &fileLogWriter{ w := &fileLogWriter{
Filename: "", Filename: "",
MaxLines: 1000000, MaxLines: 1000000,
MaxSize: 1 << 28, //256 MB MaxSize: 1 << 28, //256 MB
Daily: true, Daily: true,
MaxDays: 7, MaxDays: 7,
Rotate: true, Rotate: true,
Level: LevelTrace, Level: LevelTrace,
Perm: 0660, Perm: 0660,
MuxWriter: new(MuxWriter),
} }
// use MuxWriter instead direct use os.File for lock write when rotate
w.mw = new(MuxWriter)
// set MuxWriter as Logger's io.Writer // set MuxWriter as Logger's io.Writer
w.Logger = log.New(w.mw, "", log.Ldate|log.Ltime) w.Logger = log.New(w, "", log.Ldate|log.Ltime)
return w return w
} }
@ -126,7 +125,7 @@ func (w *fileLogWriter) startLogger() error {
if err != nil { if err != nil {
return err return err
} }
w.mw.SetFd(fd) w.SetFd(fd)
return w.initFd() return w.initFd()
} }
@ -163,7 +162,7 @@ func (w *fileLogWriter) createLogFile() (*os.File, error) {
} }
func (w *fileLogWriter) initFd() error { func (w *fileLogWriter) initFd() error {
fd := w.mw.fd fd := w.fd
finfo, err := fd.Stat() finfo, err := fd.Stat()
if err != nil { if err != nil {
return fmt.Errorf("get stat err: %s\n", err) return fmt.Errorf("get stat err: %s\n", err)
@ -215,15 +214,15 @@ func (w *fileLogWriter) DoRotate() error {
if err == nil { // file exists if err == nil { // file exists
// Find the next available number // Find the next available number
num := 1 num := 1
fname := "" fName := ""
suffix := filepath.Ext(w.Filename) suffix := filepath.Ext(w.Filename)
filenameOnly := strings.TrimSuffix(w.Filename, suffix) filenameOnly := strings.TrimSuffix(w.Filename, suffix)
if suffix == "" { if suffix == "" {
suffix = ".log" suffix = ".log"
} }
for ; err == nil && num <= 999; num++ { for ; err == nil && num <= 999; num++ {
fname = filenameOnly + fmt.Sprintf(".%s.%03d%s", time.Now().Format("2006-01-02"), num, suffix) fName = filenameOnly + fmt.Sprintf(".%s.%03d%s", time.Now().Format("2006-01-02"), num, suffix)
_, err = os.Lstat(fname) _, err = os.Lstat(fName)
} }
// return error if the last file checked still existed // return error if the last file checked still existed
if err == nil { if err == nil {
@ -231,15 +230,15 @@ func (w *fileLogWriter) DoRotate() error {
} }
// block Logger's io.Writer // block Logger's io.Writer
w.mw.Lock() w.Lock()
defer w.mw.Unlock() defer w.Unlock()
fd := w.mw.fd fd := w.fd
fd.Close() fd.Close()
// close fd before rename // close fd before rename
// Rename the file to its newfound home // Rename the file to its newfound home
err = os.Rename(w.Filename, fname) err = os.Rename(w.Filename, fName)
if err != nil { if err != nil {
return fmt.Errorf("Rotate: %s\n", err) return fmt.Errorf("Rotate: %s\n", err)
} }
@ -277,14 +276,14 @@ func (w *fileLogWriter) deleteOldLog() {
// Destroy close the file description, close file writer. // Destroy close the file description, close file writer.
func (w *fileLogWriter) Destroy() { func (w *fileLogWriter) Destroy() {
w.mw.fd.Close() w.fd.Close()
} }
// Flush flush file logger. // Flush flush file logger.
// there are no buffering messages in file logger in memory. // there are no buffering messages in file logger in memory.
// flush file means sync file from disk. // flush file means sync file from disk.
func (w *fileLogWriter) Flush() { func (w *fileLogWriter) Flush() {
w.mw.fd.Sync() w.fd.Sync()
} }
func init() { func init() {