diff --git a/backend.go b/backend.go index 6b08155..fe6359a 100644 --- a/backend.go +++ b/backend.go @@ -14,6 +14,7 @@ type Backend interface { SetLevel(Level) Level() Level Reopen() error + Close() error } // @@ -95,6 +96,22 @@ func (b *FileBackend) SetFormatter(f *Formatter) { // Reopen closes and reopens the file it writes to. It should be used after log // rotation func (b *FileBackend) Reopen() error { + if err := b.Close(); err != nil { + return err + } + + fd, err := os.OpenFile(b.filepath, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0644) //nolint: gosec + if err != nil { + return fmt.Errorf("Cannot open log file %s: %w", b.filepath, err) + } + + b.l = fd + + return nil +} + +// Close closes the underlying file used by the backend +func (b *FileBackend) Close() error { if b.filepath == "" { return nil } @@ -105,13 +122,6 @@ func (b *FileBackend) Reopen() error { } } - fd, err := os.OpenFile(b.filepath, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0644) //nolint: gosec - if err != nil { - return fmt.Errorf("Cannot open log file %s: %w", b.filepath, err) - } - - b.l = fd - return nil } @@ -147,3 +157,8 @@ func (nb *NoopBackend) Level() Level { func (nb *NoopBackend) Reopen() error { return nil } + +// Close is a noop +func (nb *NoopBackend) Close() error { + return nil +} diff --git a/backend_syslog_linux.go b/backend_syslog_linux.go index 8d6eb27..e0f62f1 100644 --- a/backend_syslog_linux.go +++ b/backend_syslog_linux.go @@ -78,6 +78,11 @@ func (sb *SyslogBackend) Reopen() error { return nil } +// Close closes the connection to the syslog daemon +func (sb *SyslogBackend) Close() error { + return sb.w.Close() +} + var facilities = map[string]syslog.Priority{ "kern": syslog.LOG_KERN, "user": syslog.LOG_USER, diff --git a/logger.go b/logger.go index a39e043..4393d49 100644 --- a/logger.go +++ b/logger.go @@ -32,7 +32,6 @@ func (l *Logger) AddBackend(b Backend) { } // SetBackend sets the backend list to the logger. Any existing backend will be lost. -// FIXME must close file backends to avoid fd leaks func (l *Logger) SetBackend(b ...Backend) { l.backends = b } diff --git a/logging.go b/logging.go index 137f2c2..7e43ce6 100644 --- a/logging.go +++ b/logging.go @@ -1,3 +1,21 @@ +// Package logging provides a multi-backend leveled logging facility. +/* + +Backends + +package logging defines the following builtin backends: +* NoopBackend, which discards all messages +* FileBackend, which redirects logs to an io.Writer object. It has constructors + for files, stdout and stderr +* SyslogBackend, only available in unix-like systems, writes log entryies to a + syslog daemon. + +A backend can safely be used by multiple loggers. + +It is the caller's responsability to call Close on backends when they are not +used anymore to free their resources. + +*/ package logging import (