-
Notifications
You must be signed in to change notification settings - Fork 0
/
term.go
112 lines (97 loc) · 2.33 KB
/
term.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
107
108
109
110
111
112
package golog
import (
"bytes"
"fmt"
"io"
"log"
"sync"
"github.com/fatih/color"
)
// WriteFunc is log writer function.
type WriteFunc func(w io.Writer, a ...interface{})
var colorFunc map[Level]WriteFunc
func init() {
colorFunc = map[Level]WriteFunc{
LevelDebug: color.New(color.FgCyan).FprintlnFunc(),
LevelInfo: color.New(color.FgGreen).FprintlnFunc(),
LevelWarn: color.New(color.FgYellow).FprintlnFunc(),
LevelError: color.New(color.FgRed).FprintlnFunc(),
LevelFatal: color.New(color.FgRed, color.BgWhite).FprintlnFunc(),
}
}
type termLogger struct {
log *log.Logger
colorful bool
pool *sync.Pool
defaultWriteFunc WriteFunc
}
// NewTermLogger new an optimized logger for terminal with writer.
func NewTermLogger(w io.Writer, colorful bool) Logger {
return &termLogger{
log: log.New(w, "", 0),
colorful: colorful,
pool: &sync.Pool{
New: func() interface{} {
return new(bytes.Buffer)
},
},
defaultWriteFunc: func(w io.Writer, a ...interface{}) {
fmt.Fprintln(w, a...)
},
}
}
func extractDefaultTSCallerMsg(kvs ...interface{}) (ts, caller, msg interface{}) {
for i := 0; i < len(kvs); i += 2 {
k, ok := kvs[i].(string)
if !ok {
continue
}
if k == DefaultTimestampKeyName {
ts = kvs[i+1]
} else if k == DefaultCallerKeyName {
caller = kvs[i+1]
} else if k == DefaultMsgKey {
msg = kvs[i+1]
} else {
continue
}
}
return
}
// Log write the kv pairs log.
func (l *termLogger) Log(level Level, kvs ...interface{}) {
if len(kvs) == 0 {
return
}
if (len(kvs) & 1) == 1 {
kvs = append(kvs, "KEY VALUES UNPAIRED")
}
ts, caller, msg := extractDefaultTSCallerMsg(kvs...)
buf := l.pool.Get().(*bytes.Buffer)
if ts != nil {
_, _ = fmt.Fprintf(buf, "[%v]", ts)
}
if caller != nil {
_, _ = fmt.Fprintf(buf, "[%v]", caller)
}
_, _ = fmt.Fprintf(buf, "[%v]", level)
if msg != nil {
_, _ = fmt.Fprintf(buf, " %v", msg)
}
for i := 0; i < len(kvs); i += 2 {
if k, ok := kvs[i].(string); ok &&
(k == DefaultTimestampKeyName || k == DefaultCallerKeyName || k == DefaultMsgKey) {
continue
}
_, _ = fmt.Fprintf(buf, ` %v:%v`, kvs[i], kvs[i+1])
}
writeFunc := l.defaultWriteFunc
if l.colorful {
if fn, ok := colorFunc[level]; ok {
writeFunc = fn
}
}
writeFunc(l.log.Writer(), buf.String())
buf.Reset()
l.pool.Put(buf)
}