-
Notifications
You must be signed in to change notification settings - Fork 0
/
log.go
106 lines (92 loc) · 3.17 KB
/
log.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
98
99
100
101
102
103
104
105
106
package golib
import (
"bytes"
"flag"
"time"
"github.com/chris-garrett/lfshook"
"github.com/sirupsen/logrus"
log "github.com/sirupsen/logrus"
)
var (
// LogFile can be set to non-empty to make ConfigureLogging output all log
// entries in addition to showing them on the standard error stream.
// All entries are output to the file, regardless of the log-level configured for the
// console output.
LogFile string
// LogVerbose makes the ConfigureLogging() function set the global log level to Debug.
LogVerbose bool
// LogQuiet makes the ConfigureLogging() function set the global log level to Warn, but
// only of LogVerbose is not set.
LogQuiet bool
// LogVeryQuiet makes the ConfigureLogging() function set the global log level to Error,
// but only if LogVerbose and LogQuiet are both not set.
LogVeryQuiet bool
// Log is the package-wide logger for the golib package. It can be configured or disabled.
Log = log.New()
)
func init() {
formatter := newLogFormatter()
log.StandardLogger().SetFormatter(formatter)
Log.SetFormatter(formatter)
}
// RegisterLogFlags registers flags for changing variables that will control
// the log level and other logging parameters when calling ConfigureLogging().
func RegisterLogFlags() {
flag.BoolVar(&LogVerbose, "v", false, "Enable verbose logging output")
flag.BoolVar(&LogQuiet, "q", false, "Suppress logging output (except warnings and errors)")
flag.BoolVar(&LogVeryQuiet, "qq", false, "Suppress logging output (except errors)")
flag.StringVar(&LogFile, "log", "", "Redirect logs to a given file in addition to the console.")
}
// ConfigureLogging configures the logger based on the global Log* variables defined in the package.
// It calls ConfigureLogger() for the standard Logrus logger and the logger of this package.
// This function should be called early in every main() function, preferably before any prior logging output,
// but after calling RegisterLogFlags() and flag.Parse().
func ConfigureLogging() {
ConfigureLogger(Log)
ConfigureLogger(log.StandardLogger())
}
// ConfigureLogger configures the given logger based on Log* variables defined in the package.
func ConfigureLogger(l *log.Logger) {
level := log.InfoLevel
if LogVerbose {
level = log.DebugLevel
} else if LogVeryQuiet {
level = log.ErrorLevel
} else if LogQuiet {
level = log.WarnLevel
}
l.SetLevel(level)
if LogFile != "" {
pathmap := make(lfshook.PathMap)
for i := 0; i < 256; i++ {
pathmap[log.Level(i)] = LogFile
}
hook := lfshook.NewHook(pathmap)
hook.SetFormatter(newLogFormatter())
l.AddHook(hook)
}
}
func newLogFormatter() *myFormatter {
return &myFormatter{
f: log.TextFormatter{
DisableColors: false,
ForceColors: true,
FullTimestamp: true,
TimestampFormat: time.StampMilli,
},
}
}
type myFormatter struct {
f logrus.TextFormatter
}
func (f *myFormatter) Format(e *logrus.Entry) ([]byte, error) {
text, err := f.f.Format(e)
if err != nil {
return text, err
}
// Remove all whitespace and replace with a single trailing newline character
// Many libraries explicitly add a \n character to log lines, which leads to empty lines.
text = bytes.TrimSpace(text)
text = append(text, '\n')
return text, nil
}