From 686497ea5c9c69b858e672c59e92a49547d01f51 Mon Sep 17 00:00:00 2001 From: lspgn Date: Thu, 27 May 2021 19:33:19 -0700 Subject: [PATCH] feature: implement SIGHUP for log rotation when using transport.destination --- transport/file/transport.go | 56 +++++++++++++++++++++++++++++++++---- 1 file changed, 51 insertions(+), 5 deletions(-) diff --git a/transport/file/transport.go b/transport/file/transport.go index 7cb867ca..b3d4e432 100644 --- a/transport/file/transport.go +++ b/transport/file/transport.go @@ -7,12 +7,17 @@ import ( "github.com/netsampler/goflow2/transport" "io" "os" + "os/signal" + "sync" + "syscall" ) type FileDriver struct { fileDestination string w io.Writer file *os.File + lock *sync.RWMutex + q chan bool } func (d *FileDriver) Prepare() error { @@ -21,33 +26,74 @@ func (d *FileDriver) Prepare() error { return nil } +func (d *FileDriver) openFile() error { + file, err := os.OpenFile(d.fileDestination, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) + if err != nil { + return err + } + d.file = file + d.w = d.file + return err +} + func (d *FileDriver) Init(context.Context) error { + d.q = make(chan bool, 1) + if d.fileDestination == "" { d.w = os.Stdout } else { var err error - d.file, err = os.OpenFile(d.fileDestination, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) + + d.lock.Lock() + err = d.openFile() + d.lock.Unlock() if err != nil { return err } - d.w = d.file + + c := make(chan os.Signal, 1) + signal.Notify(c, syscall.SIGHUP) + go func() { + for { + select { + case <-c: + d.lock.Lock() + d.file.Close() + d.openFile() + d.lock.Unlock() + // if there is an error, keeps using the old file + case <-d.q: + return + } + } + }() + } return nil } func (d *FileDriver) Send(key, data []byte) error { - fmt.Fprintln(d.w, string(data)) - return nil + d.lock.RLock() + w := d.w + d.lock.RUnlock() + _, err := fmt.Fprintln(w, string(data)) + return err } func (d *FileDriver) Close(context.Context) error { if d.fileDestination != "" { + d.lock.Lock() d.file.Close() + d.lock.Unlock() + signal.Ignore(syscall.SIGHUP) } + close(d.q) return nil } func init() { - d := &FileDriver{} + d := &FileDriver{ + lock: &sync.RWMutex{}, + } transport.RegisterTransportDriver("file", d) }