diff --git a/log/logrotate/logrotate.go b/log/logrotate/logrotate.go index ff922e1..727b5e3 100644 --- a/log/logrotate/logrotate.go +++ b/log/logrotate/logrotate.go @@ -27,15 +27,16 @@ import ( // Logrotate is a special case of sink which writes to a file and is capable of // rotating that file when certain conditions are met. type Logrotate struct { - file *os.File - buf *bufio.Writer - filename string - format string - interval time.Duration - fields []string - err chan error - stop chan bool - mux sync.Mutex + file *os.File + buf *bufio.Writer + filename string + format string + interval time.Duration + fields []string + err chan error + stop chan bool + mux sync.Mutex + subscribers []Subscriber } func (l *Logrotate) open() error { @@ -69,6 +70,7 @@ func (l *Logrotate) reload() error { if err := l.open(); err != nil { return err } + return nil } @@ -83,10 +85,18 @@ func (l *Logrotate) rotate(t time.Time) error { if err := l.close(); err != nil { return err } + target := l.filename + "." + t.Format(dateFormat) if err := os.Rename(l.filename, target); err != nil { return err } + + for _, subcriber := range l.subscribers { + if err := subcriber.OnRotate(target); err != nil { + return err + } + } + if err := l.open(); err != nil { return err } @@ -188,6 +198,13 @@ func (l *Logrotate) Stop() { l.stop <- true } +// AddSubscriber appends a subscriber to handle events. +// The user can add multiple subscribers, each subcriber +// will be called in the order as it is appended. +func (l *Logrotate) AddSubscriber(sub Subscriber) { + l.subscribers = append(l.subscribers, sub) +} + // New returns a new Logrotate using the supplied arguments. func New(file string, interval time.Duration, format string, fields []string) (*Logrotate, error) { l := &Logrotate{ @@ -200,3 +217,9 @@ func New(file string, interval time.Duration, format string, fields []string) (* } return l, l.open() } + +// Subscriber defines event handler functions inside logrotate. +// handle is called when the file is rotated. +type Subscriber interface { + OnRotate(filename string) error +} diff --git a/log/logrotate/logrotate_test.go b/log/logrotate/logrotate_test.go index df44d92..a3910e0 100644 --- a/log/logrotate/logrotate_test.go +++ b/log/logrotate/logrotate_test.go @@ -28,6 +28,15 @@ import ( var tmpdir = fmt.Sprintf("%s%x/", os.TempDir(), rand.Int()) +type SubscriberMock struct { + Buf bytes.Buffer +} + +func (sub *SubscriberMock) OnRotate(rotateFilename string) error { + sub.Buf.WriteString(rotateFilename + "\n") + return nil +} + func TestRotate(t *testing.T) { err := os.MkdirAll(tmpdir, 0777) if err != nil { @@ -43,6 +52,8 @@ func TestRotate(t *testing.T) { } defer sink.Close() + subscriber := &SubscriberMock{} + sink.AddSubscriber(subscriber) log.New(sink).Info("hello!") // now rotate @@ -50,6 +61,10 @@ func TestRotate(t *testing.T) { t.Fatal(err) } + if subscriber.Buf.Len() == 0 { + t.Fatalf("subscriber is not called") + } + // lets check if the rotated file exists files, err := ioutil.ReadDir(tmpdir) if err != nil {