diff options
Diffstat (limited to 'pkg/logtarget/logtarget.go')
-rw-r--r-- | pkg/logtarget/logtarget.go | 52 |
1 files changed, 31 insertions, 21 deletions
diff --git a/pkg/logtarget/logtarget.go b/pkg/logtarget/logtarget.go index 5cf99da..1b69a3b 100644 --- a/pkg/logtarget/logtarget.go +++ b/pkg/logtarget/logtarget.go @@ -21,57 +21,66 @@ type LogTarget interface { Rotate() error } -type fileLogTarget struct { +// logTarget is the default implementation of a log +// target. It can write to more than one writer at the same time +// but only rotate one file +type logTarget struct { mu sync.Mutex logfn string file *os.File + w io.Writer + ws []io.Writer } +// Default is the default log target for the application +// It has to be initialized before used var Default LogTarget +// OpenWriters returns a log target that will +// log to all the given writers at the same time +func OpenWriters(ws ...io.Writer) LogTarget { + target := &logTarget{} + target.w = io.MultiWriter(ws...) + return target +} + // OpenFile creates a LogTarget pointing to a log file // and returns it. // This method will open the file in append-only mode. -func OpenFile(fileName string) (t LogTarget, err error) { - target := &fileLogTarget{} +// It also takes a variable number of writers that are +// other log targets +func OpenFile(fileName string, ws ...io.Writer) (t LogTarget, err error) { + target := &logTarget{} target.logfn = fileName target.file, err = os.OpenFile(fileName, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0650) if err != nil { return nil, err } + target.ws = ws + target.w = io.MultiWriter(append(ws, target.file)...) return target, nil } // Write writes a log message to all registered io.Writers -func (target *fileLogTarget) Write(in []byte) (int, error) { +func (target *logTarget) Write(out []byte) (int, error) { target.mu.Lock() defer target.mu.Unlock() - if target.file == nil { - panic("no log file opened") - } - - n, err := os.Stderr.Write(in) - if err != nil { - return n, err - } - - n, err = target.file.Write(in) - if err != nil { - return n, err - } - - return len(in), nil + return target.Write(out) } -// Rotate rotates the current log file. +// Rotate rotates the current log file, if one is opened. // This method holds a lock while rotating the log file, // and all log writes will be held back until the rotation // is complete. -func (target *fileLogTarget) Rotate() error { +func (target *logTarget) Rotate() error { target.mu.Lock() defer target.mu.Unlock() + if target.file == nil { + return nil + } + // Close the existing log file err := target.file.Close() if err != nil { @@ -82,6 +91,7 @@ func (target *fileLogTarget) Rotate() error { if err != nil { return err } + target.w = io.MultiWriter(append(target.ws, target.file)...) return nil } |