diff --git a/logs/file.go b/logs/file.go index 8cf20372..b87664bd 100644 --- a/logs/file.go +++ b/logs/file.go @@ -167,6 +167,9 @@ func (w *fileLogWriter) initFd() error { w.dailyOpenTime = time.Now() w.dailyOpenDate = w.dailyOpenTime.Day() w.maxLinesCurLines = 0 + if w.Daily { + go w.dailyRotate(w.dailyOpenTime) + } if fInfo.Size() > 0 { count, err := w.lines() if err != nil { @@ -177,6 +180,22 @@ func (w *fileLogWriter) initFd() error { return nil } +func (w *fileLogWriter) dailyRotate(openTime time.Time) { + y, m, d := openTime.Add(24 * time.Hour).Date() + nextDay := time.Date(y, m, d, 0, 0, 0, 0, openTime.Location()) + tm := time.NewTimer(time.Duration(nextDay.UnixNano() - openTime.UnixNano() + 100)) + select { + case <-tm.C: + w.Lock() + if w.needRotate(0, time.Now().Day()) { + if err := w.doRotate(time.Now()); err != nil { + fmt.Fprintf(os.Stderr, "FileLogWriter(%q): %s\n", w.Filename, err) + } + } + w.Unlock() + } +} + func (w *fileLogWriter) lines() (int, error) { fd, err := os.Open(w.Filename) if err != nil { diff --git a/logs/file_test.go b/logs/file_test.go index 176f4c1e..d468606c 100644 --- a/logs/file_test.go +++ b/logs/file_test.go @@ -17,6 +17,7 @@ package logs import ( "bufio" "fmt" + "io/ioutil" "os" "strconv" "testing" @@ -125,6 +126,21 @@ func TestFileRotate_03(t *testing.T) { os.Remove(fn) } +func TestFileRotate_04(t *testing.T) { + fn1 := "rotate_day.log" + fn2 := "rotate_day." + time.Now().Add(-24*time.Hour).Format("2006-01-02") + ".log" + testFileDailyRotate(t, fn1, fn2) +} + +func TestFileRotate_05(t *testing.T) { + fn1 := "rotate_day.log" + fn := "rotate_day." + time.Now().Add(-24*time.Hour).Format("2006-01-02") + ".log" + os.Create(fn) + fn2 := "rotate_day." + time.Now().Add(-24*time.Hour).Format("2006-01-02") + ".001.log" + testFileDailyRotate(t, fn1, fn2) + os.Remove(fn) +} + func testFileRotate(t *testing.T, fn1, fn2 string) { fw := &fileLogWriter{ Daily: true, @@ -145,6 +161,38 @@ func testFileRotate(t *testing.T, fn1, fn2 string) { } os.Remove(file) } + fw.Destroy() +} + +func testFileDailyRotate(t *testing.T, fn1, fn2 string) { + fw := &fileLogWriter{ + Daily: true, + MaxDays: 7, + Rotate: true, + Level: LevelTrace, + Perm: 0660, + } + fw.Init(fmt.Sprintf(`{"filename":"%v","maxdays":1}`, fn1)) + fw.dailyOpenTime = time.Now().Add(-24 * time.Hour) + fw.dailyOpenDate = fw.dailyOpenTime.Day() + today, _ := time.ParseInLocation("2006-01-02", time.Now().Format("2006-01-02"), fw.dailyOpenTime.Location()) + today = today.Add(-1 * time.Second) + fw.dailyRotate(today) + for _, file := range []string{fn1, fn2} { + _, err := os.Stat(file) + if err != nil { + t.FailNow() + } + content, err := ioutil.ReadFile(file) + if err != nil { + t.FailNow() + } + if len(content) > 0 { + t.FailNow() + } + os.Remove(file) + } + fw.Destroy() } func exists(path string) (bool, error) {