Merge pull request #86 from slene/master
fix logrotate
Showing
1 changed file
with
72 additions
and
26 deletions
| ... | @@ -14,6 +14,7 @@ import ( | ... | @@ -14,6 +14,7 @@ import ( |
| 14 | 14 | ||
| 15 | type FileLogWriter struct { | 15 | type FileLogWriter struct { |
| 16 | *log.Logger | 16 | *log.Logger |
| 17 | mw *MuxWriter | ||
| 17 | // The opened file | 18 | // The opened file |
| 18 | filename string | 19 | filename string |
| 19 | 20 | ||
| ... | @@ -34,6 +35,24 @@ type FileLogWriter struct { | ... | @@ -34,6 +35,24 @@ type FileLogWriter struct { |
| 34 | startLock sync.Mutex //only one log can writer to the file | 35 | startLock sync.Mutex //only one log can writer to the file |
| 35 | } | 36 | } |
| 36 | 37 | ||
| 38 | type MuxWriter struct { | ||
| 39 | sync.Mutex | ||
| 40 | fd *os.File | ||
| 41 | } | ||
| 42 | |||
| 43 | func (l *MuxWriter) Write(b []byte) (int, error) { | ||
| 44 | l.Lock() | ||
| 45 | defer l.Unlock() | ||
| 46 | return l.fd.Write(b) | ||
| 47 | } | ||
| 48 | |||
| 49 | func (l *MuxWriter) SetFd(fd *os.File) { | ||
| 50 | if l.fd != nil { | ||
| 51 | l.fd.Close() | ||
| 52 | } | ||
| 53 | l.fd = fd | ||
| 54 | } | ||
| 55 | |||
| 37 | func NewFileWriter(fname string, rotate bool) *FileLogWriter { | 56 | func NewFileWriter(fname string, rotate bool) *FileLogWriter { |
| 38 | w := &FileLogWriter{ | 57 | w := &FileLogWriter{ |
| 39 | filename: fname, | 58 | filename: fname, |
| ... | @@ -43,6 +62,10 @@ func NewFileWriter(fname string, rotate bool) *FileLogWriter { | ... | @@ -43,6 +62,10 @@ func NewFileWriter(fname string, rotate bool) *FileLogWriter { |
| 43 | maxdays: 7, | 62 | maxdays: 7, |
| 44 | rotate: rotate, | 63 | rotate: rotate, |
| 45 | } | 64 | } |
| 65 | // use MuxWriter instead direct use os.File for lock write when rotate | ||
| 66 | w.mw = new(MuxWriter) | ||
| 67 | // set MuxWriter as Logger's io.Writer | ||
| 68 | w.Logger = log.New(w.mw, "", log.Ldate|log.Ltime) | ||
| 46 | return w | 69 | return w |
| 47 | } | 70 | } |
| 48 | 71 | ||
| ... | @@ -71,9 +94,16 @@ func (w *FileLogWriter) SetRotateMaxDays(maxdays int64) *FileLogWriter { | ... | @@ -71,9 +94,16 @@ func (w *FileLogWriter) SetRotateMaxDays(maxdays int64) *FileLogWriter { |
| 71 | } | 94 | } |
| 72 | 95 | ||
| 73 | func (w *FileLogWriter) StartLogger() error { | 96 | func (w *FileLogWriter) StartLogger() error { |
| 74 | if err := w.DoRotate(false); err != nil { | 97 | fd, err := w.createLogFile() |
| 98 | if err != nil { | ||
| 75 | return err | 99 | return err |
| 76 | } | 100 | } |
| 101 | w.mw.SetFd(fd) | ||
| 102 | err = w.initFd() | ||
| 103 | if err != nil { | ||
| 104 | return err | ||
| 105 | } | ||
| 106 | BeeLogger = w | ||
| 77 | return nil | 107 | return nil |
| 78 | } | 108 | } |
| 79 | 109 | ||
| ... | @@ -83,7 +113,7 @@ func (w *FileLogWriter) docheck(size int) { | ... | @@ -83,7 +113,7 @@ func (w *FileLogWriter) docheck(size int) { |
| 83 | if (w.maxlines > 0 && w.maxlines_curlines >= w.maxlines) || | 113 | if (w.maxlines > 0 && w.maxlines_curlines >= w.maxlines) || |
| 84 | (w.maxsize > 0 && w.maxsize_cursize >= w.maxsize) || | 114 | (w.maxsize > 0 && w.maxsize_cursize >= w.maxsize) || |
| 85 | (w.daily && time.Now().Day() != w.daily_opendate) { | 115 | (w.daily && time.Now().Day() != w.daily_opendate) { |
| 86 | if err := w.DoRotate(true); err != nil { | 116 | if err := w.DoRotate(); err != nil { |
| 87 | fmt.Fprintf(os.Stderr, "FileLogWriter(%q): %s\n", w.filename, err) | 117 | fmt.Fprintf(os.Stderr, "FileLogWriter(%q): %s\n", w.filename, err) |
| 88 | return | 118 | return |
| 89 | } | 119 | } |
| ... | @@ -101,8 +131,33 @@ func (w *FileLogWriter) Printf(format string, v ...interface{}) { | ... | @@ -101,8 +131,33 @@ func (w *FileLogWriter) Printf(format string, v ...interface{}) { |
| 101 | w.Logger.Printf(format, v...) | 131 | w.Logger.Printf(format, v...) |
| 102 | } | 132 | } |
| 103 | 133 | ||
| 104 | func (w *FileLogWriter) DoRotate(rotate bool) error { | 134 | func (w *FileLogWriter) createLogFile() (*os.File, error) { |
| 105 | if rotate { | 135 | // Open the log file |
| 136 | fd, err := os.OpenFile(w.filename, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0660) | ||
| 137 | return fd, err | ||
| 138 | } | ||
| 139 | |||
| 140 | func (w *FileLogWriter) initFd() error { | ||
| 141 | fd := w.mw.fd | ||
| 142 | finfo, err := fd.Stat() | ||
| 143 | if err != nil { | ||
| 144 | return fmt.Errorf("get stat err: %s\n", err) | ||
| 145 | } | ||
| 146 | w.maxsize_cursize = int(finfo.Size()) | ||
| 147 | w.daily_opendate = time.Now().Day() | ||
| 148 | if finfo.Size() > 0 { | ||
| 149 | content, err := ioutil.ReadFile(w.filename) | ||
| 150 | if err != nil { | ||
| 151 | fmt.Println(err) | ||
| 152 | } | ||
| 153 | w.maxlines_curlines = len(strings.Split(string(content), "\n")) | ||
| 154 | } else { | ||
| 155 | w.maxlines_curlines = 0 | ||
| 156 | } | ||
| 157 | return nil | ||
| 158 | } | ||
| 159 | |||
| 160 | func (w *FileLogWriter) DoRotate() error { | ||
| 106 | _, err := os.Lstat(w.filename) | 161 | _, err := os.Lstat(w.filename) |
| 107 | if err == nil { // file exists | 162 | if err == nil { // file exists |
| 108 | // Find the next available number | 163 | // Find the next available number |
| ... | @@ -117,38 +172,29 @@ func (w *FileLogWriter) DoRotate(rotate bool) error { | ... | @@ -117,38 +172,29 @@ func (w *FileLogWriter) DoRotate(rotate bool) error { |
| 117 | return fmt.Errorf("Rotate: Cannot find free log number to rename %s\n", w.filename) | 172 | return fmt.Errorf("Rotate: Cannot find free log number to rename %s\n", w.filename) |
| 118 | } | 173 | } |
| 119 | 174 | ||
| 175 | // block Logger's io.Writer | ||
| 176 | w.mw.Lock() | ||
| 177 | defer w.mw.Unlock() | ||
| 178 | |||
| 179 | fd := w.mw.fd | ||
| 180 | fd.Close() | ||
| 181 | |||
| 182 | // close fd before rename | ||
| 120 | // Rename the file to its newfound home | 183 | // Rename the file to its newfound home |
| 121 | err = os.Rename(w.filename, fname) | 184 | err = os.Rename(w.filename, fname) |
| 122 | if err != nil { | 185 | if err != nil { |
| 123 | return fmt.Errorf("Rotate: %s\n", err) | 186 | return fmt.Errorf("Rotate: %s\n", err) |
| 124 | } | 187 | } |
| 125 | go w.deleteOldLog() | ||
| 126 | } | ||
| 127 | } | ||
| 128 | 188 | ||
| 129 | // Open the log file | 189 | // re-start logger |
| 130 | fd, err := os.OpenFile(w.filename, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0660) | 190 | err = w.StartLogger() |
| 131 | if err != nil { | 191 | if err != nil { |
| 132 | return err | 192 | return fmt.Errorf("Rotate StartLogger: %s\n", err) |
| 133 | } | 193 | } |
| 134 | w.Logger = log.New(fd, "", log.Ldate|log.Ltime) | ||
| 135 | finfo, err := fd.Stat() | ||
| 136 | if err != nil { | ||
| 137 | return fmt.Errorf("get stat err: %s\n", err) | ||
| 138 | } | ||
| 139 | w.maxsize_cursize = int(finfo.Size()) | ||
| 140 | w.daily_opendate = time.Now().Day() | ||
| 141 | if finfo.Size() > 0 { | ||
| 142 | content, err := ioutil.ReadFile(w.filename) | ||
| 143 | if err != nil { | ||
| 144 | fmt.Println(err) | ||
| 145 | } | ||
| 146 | w.maxlines_curlines = len(strings.Split(string(content), "\n")) | ||
| 147 | 194 | ||
| 148 | } else { | 195 | go w.deleteOldLog() |
| 149 | w.maxlines_curlines = 0 | ||
| 150 | } | 196 | } |
| 151 | BeeLogger = w | 197 | |
| 152 | return nil | 198 | return nil |
| 153 | } | 199 | } |
| 154 | 200 | ... | ... |
-
Please register or sign in to post a comment