-
Notifications
You must be signed in to change notification settings - Fork 0
/
logtarget.go
97 lines (82 loc) · 2.46 KB
/
logtarget.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
// Copyright (c) 2011 The Grumble Authors
// The use of this source code is goverened by a BSD-style
// license that can be found in the LICENSE-file.
// Package logtarget implements a multiplexing logging target
package logtarget
import (
"io"
"os"
"sync"
)
// LogTarget implements the io.Writer interface, allowing
// LogTarget to be registered with the regular Go log package.
// LogTarget multiplexes its incoming writes to multiple optional
// output writers, and one main output writer (the log file).
type LogTarget interface {
io.Writer
Rotate() error
}
// 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.
// 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 *logTarget) Write(out []byte) (int, error) {
target.mu.Lock()
defer target.mu.Unlock()
return target.w.Write(out)
}
// 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 *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 {
return err
}
target.file, err = os.OpenFile(target.logfn, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0650)
if err != nil {
return err
}
target.w = io.MultiWriter(append(target.ws, target.file)...)
return nil
}