d0bbc67b by astaxie

Merge pull request #86 from slene/master

fix logrotate
2 parents 4033692d 45355794
Showing 1 changed file with 79 additions and 33 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,37 +131,14 @@ func (w *FileLogWriter) Printf(format string, v ...interface{}) { ...@@ -101,37 +131,14 @@ 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 {
106 _, err := os.Lstat(w.filename)
107 if err == nil { // file exists
108 // Find the next available number
109 num := 1
110 fname := ""
111 for ; err == nil && num <= 999; num++ {
112 fname = w.filename + fmt.Sprintf(".%s.%03d", time.Now().Format("2006-01-02"), num)
113 _, err = os.Lstat(fname)
114 }
115 // return error if the last file checked still existed
116 if err == nil {
117 return fmt.Errorf("Rotate: Cannot find free log number to rename %s\n", w.filename)
118 }
119
120 // Rename the file to its newfound home
121 err = os.Rename(w.filename, fname)
122 if err != nil {
123 return fmt.Errorf("Rotate: %s\n", err)
124 }
125 go w.deleteOldLog()
126 }
127 }
128
129 // Open the log file 135 // Open the log file
130 fd, err := os.OpenFile(w.filename, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0660) 136 fd, err := os.OpenFile(w.filename, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0660)
131 if err != nil { 137 return fd, err
132 return err 138 }
133 } 139
134 w.Logger = log.New(fd, "", log.Ldate|log.Ltime) 140 func (w *FileLogWriter) initFd() error {
141 fd := w.mw.fd
135 finfo, err := fd.Stat() 142 finfo, err := fd.Stat()
136 if err != nil { 143 if err != nil {
137 return fmt.Errorf("get stat err: %s\n", err) 144 return fmt.Errorf("get stat err: %s\n", err)
...@@ -144,11 +151,50 @@ func (w *FileLogWriter) DoRotate(rotate bool) error { ...@@ -144,11 +151,50 @@ func (w *FileLogWriter) DoRotate(rotate bool) error {
144 fmt.Println(err) 151 fmt.Println(err)
145 } 152 }
146 w.maxlines_curlines = len(strings.Split(string(content), "\n")) 153 w.maxlines_curlines = len(strings.Split(string(content), "\n"))
147
148 } else { 154 } else {
149 w.maxlines_curlines = 0 155 w.maxlines_curlines = 0
150 } 156 }
151 BeeLogger = w 157 return nil
158 }
159
160 func (w *FileLogWriter) DoRotate() error {
161 _, err := os.Lstat(w.filename)
162 if err == nil { // file exists
163 // Find the next available number
164 num := 1
165 fname := ""
166 for ; err == nil && num <= 999; num++ {
167 fname = w.filename + fmt.Sprintf(".%s.%03d", time.Now().Format("2006-01-02"), num)
168 _, err = os.Lstat(fname)
169 }
170 // return error if the last file checked still existed
171 if err == nil {
172 return fmt.Errorf("Rotate: Cannot find free log number to rename %s\n", w.filename)
173 }
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
183 // Rename the file to its newfound home
184 err = os.Rename(w.filename, fname)
185 if err != nil {
186 return fmt.Errorf("Rotate: %s\n", err)
187 }
188
189 // re-start logger
190 err = w.StartLogger()
191 if err != nil {
192 return fmt.Errorf("Rotate StartLogger: %s\n", err)
193 }
194
195 go w.deleteOldLog()
196 }
197
152 return nil 198 return nil
153 } 199 }
154 200
......
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!