-
Notifications
You must be signed in to change notification settings - Fork 1.4k
/
logger.go
203 lines (163 loc) · 5.69 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
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
package logger
import (
"fmt"
"github.com/revel/config"
"time"
)
// The LogHandler defines the interface to handle the log records
type (
// The Multilogger reduces the number of exposed defined logging variables,
// and allows the output to be easily refined
MultiLogger interface {
// New returns a new Logger that has this logger's context plus the given context
New(ctx ...interface{}) MultiLogger
// SetHandler updates the logger to write records to the specified handler.
SetHandler(h LogHandler)
// Set the stack depth for the logger
SetStackDepth(int) MultiLogger
// Log a message at the given level with context key/value pairs
Debug(msg string, ctx ...interface{})
// Log a message at the given level formatting message with the parameters
Debugf(msg string, params ...interface{})
// Log a message at the given level with context key/value pairs
Info(msg string, ctx ...interface{})
// Log a message at the given level formatting message with the parameters
Infof(msg string, params ...interface{})
// Log a message at the given level with context key/value pairs
Warn(msg string, ctx ...interface{})
// Log a message at the given level formatting message with the parameters
Warnf(msg string, params ...interface{})
// Log a message at the given level with context key/value pairs
Error(msg string, ctx ...interface{})
// Log a message at the given level formatting message with the parameters
Errorf(msg string, params ...interface{})
// Log a message at the given level with context key/value pairs
Crit(msg string, ctx ...interface{})
// Log a message at the given level formatting message with the parameters
Critf(msg string, params ...interface{})
// Log a message at the given level with context key/value pairs and exits
Fatal(msg string, ctx ...interface{})
// Log a message at the given level formatting message with the parameters and exits
Fatalf(msg string, params ...interface{})
// Log a message at the given level with context key/value pairs and panics
Panic(msg string, ctx ...interface{})
// Log a message at the given level formatting message with the parameters and panics
Panicf(msg string, params ...interface{})
}
// The log handler interface
LogHandler interface {
Log(*Record) error
//log15.Handler
}
// The log stack handler interface
LogStackHandler interface {
LogHandler
GetStack() int
}
// The log handler interface which has child logs
ParentLogHandler interface {
SetChild(handler LogHandler) LogHandler
}
// The log format interface
LogFormat interface {
Format(r *Record) []byte
}
// The log level type
LogLevel int
// Used for the callback to LogFunctionMap
LogOptions struct {
Ctx *config.Context
ReplaceExistingHandler bool
HandlerWrap ParentLogHandler
Levels []LogLevel
ExtendedOptions map[string]interface{}
}
// The log record
Record struct {
Message string // The message
Time time.Time // The time
Level LogLevel //The level
Call CallStack // The call stack if built
Context ContextMap // The context
}
// The lazy structure to implement a function to be invoked only if needed
Lazy struct {
Fn interface{} // the function
}
// Currently the only requirement for the callstack is to support the Formatter method
// which stack.Call does so we use that
CallStack interface {
fmt.Formatter // Requirement
}
)
// FormatFunc returns a new Format object which uses
// the given function to perform record formatting.
func FormatFunc(f func(*Record) []byte) LogFormat {
return formatFunc(f)
}
type formatFunc func(*Record) []byte
func (f formatFunc) Format(r *Record) []byte {
return f(r)
}
func NewRecord(message string, level LogLevel) *Record {
return &Record{Message: message, Context: ContextMap{}, Level: level}
}
const (
LvlCrit LogLevel = iota // Critical
LvlError // Error
LvlWarn // Warning
LvlInfo // Information
LvlDebug // Debug
)
// A list of all the log levels
var LvlAllList = []LogLevel{LvlDebug, LvlInfo, LvlWarn, LvlError, LvlCrit}
// Implements the ParentLogHandler
type parentLogHandler struct {
setChild func(handler LogHandler) LogHandler
}
// Create a new parent log handler
func NewParentLogHandler(callBack func(child LogHandler) LogHandler) ParentLogHandler {
return &parentLogHandler{callBack}
}
// Sets the child of the log handler
func (p *parentLogHandler) SetChild(child LogHandler) LogHandler {
return p.setChild(child)
}
// Create a new log options
func NewLogOptions(cfg *config.Context, replaceHandler bool, phandler ParentLogHandler, lvl ...LogLevel) (logOptions *LogOptions) {
logOptions = &LogOptions{
Ctx: cfg,
ReplaceExistingHandler: replaceHandler,
HandlerWrap: phandler,
Levels: lvl,
ExtendedOptions: map[string]interface{}{},
}
return
}
// Assumes options will be an even number and have a string, value syntax
func (l *LogOptions) SetExtendedOptions(options ...interface{}) {
for x := 0; x < len(options); x += 2 {
l.ExtendedOptions[options[x].(string)] = options[x+1]
}
}
// Gets a string option with default
func (l *LogOptions) GetStringDefault(option, value string) string {
if v, found := l.ExtendedOptions[option]; found {
return v.(string)
}
return value
}
// Gets an int option with default
func (l *LogOptions) GetIntDefault(option string, value int) int {
if v, found := l.ExtendedOptions[option]; found {
return v.(int)
}
return value
}
// Gets a boolean option with default
func (l *LogOptions) GetBoolDefault(option string, value bool) bool {
if v, found := l.ExtendedOptions[option]; found {
return v.(bool)
}
return value
}