forked from janeczku/stdemuxerhook
-
Notifications
You must be signed in to change notification settings - Fork 1
/
stdemuxerhook.go
90 lines (76 loc) · 2.42 KB
/
stdemuxerhook.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
package stdemuxerhook
import (
"io"
"io/ioutil"
"os"
"github.com/sirupsen/logrus"
)
// StdDemuxerHook demuxes logs to io.Writers based on
// severity. By default it uses the following outputs:
// error and higher -> os.Stderr
// warning and lower -> os.Stdout
type StdDemuxerHook struct {
stdErrLogger *logrus.Logger
stdOutLogger *logrus.Logger
level logrus.Level
}
// New returns a new StdDemuxerHook by silencing the parent
// logger and configuring separate loggers for stderr and
// stdout with the parents loggers properties.
func New(parent *logrus.Logger) *StdDemuxerHook {
errLogger := logrus.New()
errLogger.Out = os.Stderr
errLogger.Level = logrus.DebugLevel
outLogger := logrus.New()
outLogger.Out = os.Stdout
outLogger.Level = logrus.DebugLevel
// Inherit formatter and level from parent logger
errLogger.Formatter = parent.Formatter
outLogger.Formatter = parent.Formatter
level := parent.Level
// Make sure parent Logger does not log anything by itself
parent.Out = ioutil.Discard
parent.Formatter = &NopFormatter{}
return &StdDemuxerHook{
stdErrLogger: errLogger,
stdOutLogger: outLogger,
level: level,
}
}
// Fire is triggered on new log entries
func (hook *StdDemuxerHook) Fire(entry *logrus.Entry) error {
if hook.level < entry.Level {
return nil
}
switch entry.Level {
// stderr
case logrus.WarnLevel:
hook.stdErrLogger.WithFields(entry.Data).Warn(entry.Message)
case logrus.ErrorLevel:
hook.stdErrLogger.WithFields(entry.Data).Error(entry.Message)
case logrus.PanicLevel:
hook.stdErrLogger.WithFields(entry.Data).Panic(entry.Message)
case logrus.FatalLevel:
hook.stdErrLogger.WithFields(entry.Data).Fatal(entry.Message)
// stdout
case logrus.DebugLevel:
hook.stdOutLogger.WithFields(entry.Data).Debug(entry.Message)
case logrus.InfoLevel:
hook.stdOutLogger.WithFields(entry.Data).Info(entry.Message)
}
return nil
}
// Levels returns all levels this hook should be registered to
func (*StdDemuxerHook) Levels() []logrus.Level {
return logrus.AllLevels
}
// SetOutput allows to set the info and error level outputs to arbitrary io.Writers
func (hook *StdDemuxerHook) SetOutput(infoLevel io.Writer, errorLevel io.Writer) {
hook.stdOutLogger.Out = infoLevel
hook.stdErrLogger.Out = errorLevel
}
// NopFormatter always yields zero bytes and consumes 0 allocs/op.
type NopFormatter struct{}
func (*NopFormatter) Format(entry *logrus.Entry) ([]byte, error) {
return []byte{}, nil
}