Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mumble-voip/grumble.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOla Bini <ola@autonomia.digital>2020-03-26 17:20:13 +0300
committerOla Bini <ola@autonomia.digital>2020-03-26 17:20:13 +0300
commit8b2c7901ee2512c4adfd33ee59be5c3b787c05e7 (patch)
treee782356ffd4596b934430ee0aaf3d0661d808219
parentd6c4d9f766137c7115eaa38e7a6206bd087e091a (diff)
Use MultiWriter to simplify the writing implementation. Also make it possible to initialize the log target to variable amounts of writers, and doesn't hardcode the use of StdErr as output
-rw-r--r--cmd/grumble/grumble.go2
-rw-r--r--pkg/logtarget/logtarget.go52
2 files changed, 32 insertions, 22 deletions
diff --git a/cmd/grumble/grumble.go b/cmd/grumble/grumble.go
index 04f87c7..139eadc 100644
--- a/cmd/grumble/grumble.go
+++ b/cmd/grumble/grumble.go
@@ -37,7 +37,7 @@ func main() {
dataDir.Close()
// Set up logging
- logtarget.Default, err = logtarget.OpenFile(Args.LogPath)
+ logtarget.Default, err = logtarget.OpenFile(Args.LogPath, os.Stderr)
if err != nil {
fmt.Fprintf(os.Stderr, "Unable to open log file (%v): %v", Args.LogPath, err)
return
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
}