-
Notifications
You must be signed in to change notification settings - Fork 1
/
logger.go
139 lines (119 loc) · 2.67 KB
/
logger.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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
package confucius
import (
"fmt"
"io"
"log"
"runtime"
)
type LogCallback func(level LogLevel, message string, file string, line int)
type LogOption func(l *logger)
type LogLevel int
func (l LogLevel) String() string {
switch l {
case DebugLevel:
return "DEBUG"
case TraceLevel:
return "TRACE"
case InfoLevel:
return "INFO"
case WarningLevel:
return "WARNING"
case ErrorLevel:
return "ERROR"
case PanicLevel:
return "PANIC"
case FatalLevel:
return "FATAL"
}
return "UNKNOWN"
}
const (
DebugLevel LogLevel = iota
TraceLevel
InfoLevel
WarningLevel
ErrorLevel
PanicLevel
FatalLevel
)
func defaultLogger() *logger {
return &logger{
level: DebugLevel,
output: io.Discard,
useCallback: false,
callback: defaultCallback(io.Discard),
}
}
func defaultCallback(output io.Writer) LogCallback {
return func(level LogLevel, message string, file string, line int) {
l := log.New(output, fmt.Sprintf("%-8s", level), log.LstdFlags)
switch level {
case PanicLevel:
l.Panic(message)
case FatalLevel:
l.Fatal(message)
default:
l.Print(message)
}
}
}
func Callback(callback LogCallback) LogOption {
return func(l *logger) {
l.useCallback = true
l.callback = callback
l.output = io.Discard
}
}
func SetLevel(level LogLevel) LogOption {
return func(l *logger) {
l.level = level
}
}
func SetOutput(writer io.Writer) LogOption {
return func(l *logger) {
if !l.useCallback {
l.output = writer
l.callback = defaultCallback(writer)
} else {
l.Warn("log output feature is not usable when using callback")
}
}
}
type logger struct {
useCallback bool
callback LogCallback
level LogLevel
output io.Writer
}
func (l *logger) Print(level LogLevel, message string, args ...interface{}) {
if level < l.level {
return
}
msg := fmt.Sprintf(message, args...)
if _, file, line, ok := runtime.Caller(2); ok {
l.callback(level, msg, file, line)
} else {
l.callback(level, msg, "n/a", -1)
}
}
func (l *logger) Debug(message string, args ...interface{}) {
l.Print(DebugLevel, message, args...)
}
func (l *logger) Trace(message string, args ...interface{}) {
l.Print(TraceLevel, message, args...)
}
func (l *logger) Info(message string, args ...interface{}) {
l.Print(InfoLevel, message, args...)
}
func (l *logger) Warn(message string, args ...interface{}) {
l.Print(WarningLevel, message, args...)
}
func (l *logger) Error(message string, args ...interface{}) {
l.Print(ErrorLevel, message, args...)
}
func (l *logger) Fatal(message string, args ...interface{}) {
l.Print(FatalLevel, message, args...)
}
func (l *logger) Panic(message string, args ...interface{}) {
l.Print(PanicLevel, message, args...)
}