-
Notifications
You must be signed in to change notification settings - Fork 26
/
common.go
307 lines (264 loc) · 7.38 KB
/
common.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
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
package slog
import (
"errors"
"strings"
"time"
)
//
// log level definitions
//
// Level type
type Level uint32
// String get level name
func (l Level) String() string {
return LevelName(l)
}
// Name get level name
func (l Level) Name() string {
return LevelName(l)
}
// LowerName get lower level name
func (l Level) LowerName() string {
if n, ok := lowerLevelNames[l]; ok {
return n
}
return "unknown"
}
// ShouldHandling compare level, if current level <= l, it will be record.
func (l Level) ShouldHandling(curLevel Level) bool {
return curLevel <= l
}
// Levels level list
type Levels []Level
// Contains given level
func (ls Levels) Contains(level Level) bool {
for _, l := range ls {
if l == level {
return true
}
}
return false
}
// These are the different logging levels. You can set the logging level to log handler
const (
// PanicLevel level, the highest level of severity. will call panic() if the logging level <= PanicLevel.
PanicLevel Level = 100
// FatalLevel level. Logs and then calls `logger.Exit(1)`. It will exit even if the
// logging level <= FatalLevel.
FatalLevel Level = 200
// ErrorLevel level. Runtime errors. Used for errors that should definitely be noted.
// Commonly used for hooks to send errors to an error tracking service.
ErrorLevel Level = 300
// WarnLevel level. Non-critical entries that deserve eyes.
WarnLevel Level = 400
// NoticeLevel level Uncommon events
NoticeLevel Level = 500
// InfoLevel level. Examples: User logs in, SQL logs.
InfoLevel Level = 600
// DebugLevel level. Usually only enabled when debugging. Very verbose logging.
DebugLevel Level = 700
// TraceLevel level. Designates finer-grained informational events than the Debug.
TraceLevel Level = 800
)
//
// some commonly definitions
//
// StringMap string map short name
type StringMap = map[string]string
// M short name of map[string]any
type M map[string]any
// String map to string
func (m M) String() string {
return mapToString(m)
}
// ClockFn func
type ClockFn func() time.Time
// Now implements the Clocker
func (fn ClockFn) Now() time.Time {
return fn()
}
// CallerFlagMode Defines the Caller backtrace information mode.
type CallerFlagMode = uint8
// NOTICE: you must set `Logger.ReportCaller=true` for reporting caller.
// then config the Logger.CallerFlag by follow flags.
const (
// CallerFlagFnlFcn report short func name with filename and with line.
// eg: "logger_test.go:48,TestLogger_ReportCaller"
CallerFlagFnlFcn CallerFlagMode = iota
// CallerFlagFull full func name with filename and with line.
// eg: "github.com/gookit/slog_test.TestLogger_ReportCaller(),logger_test.go:48"
CallerFlagFull
// CallerFlagFunc full package with func name.
// eg: "github.com/gookit/slog_test.TestLogger_ReportCaller"
CallerFlagFunc
// CallerFlagFcLine full package with func name and with line.
// eg: "github.com/gookit/slog_test.TestLogger_ReportCaller:48"
CallerFlagFcLine
// CallerFlagPkg report full package name.
// eg: "github.com/gookit/slog_test"
CallerFlagPkg
// CallerFlagPkgFnl report full package name + filename + line.
// eg: "github.com/gookit/slog_test,logger_test.go:48"
CallerFlagPkgFnl
// CallerFlagFpLine report full filepath with line.
// eg: "/work/go/gookit/slog/logger_test.go:48"
CallerFlagFpLine
// CallerFlagFnLine report filename with line.
// eg: "logger_test.go:48"
CallerFlagFnLine
// CallerFlagFcName only report func name.
// eg: "TestLogger_ReportCaller"
CallerFlagFcName
)
var (
// FieldKeyData define the key name for Record.Data
FieldKeyData = "data"
// FieldKeyTime key name
FieldKeyTime = "time"
// FieldKeyDate key name
FieldKeyDate = "date"
// FieldKeyDatetime key name
FieldKeyDatetime = "datetime"
// FieldKeyTimestamp key name
FieldKeyTimestamp = "timestamp"
// FieldKeyCaller the field key name for report caller.
//
// For caller style please see CallerFlagFull, CallerFlagFunc and more.
//
// NOTICE: you must set `Logger.ReportCaller=true` for reporting caller
FieldKeyCaller = "caller"
// FieldKeyLevel name
FieldKeyLevel = "level"
// FieldKeyError Define the key when adding errors using WithError.
FieldKeyError = "error"
// FieldKeyExtra key name
FieldKeyExtra = "extra"
// FieldKeyChannel name
FieldKeyChannel = "channel"
// FieldKeyMessage name
FieldKeyMessage = "message"
)
var (
// DefaultChannelName for log record
DefaultChannelName = "application"
// DefaultTimeFormat define
DefaultTimeFormat = "2006/01/02T15:04:05.000"
// TimeFormatRFC3339 = time.RFC3339
// DoNothingOnExit handle func. use for testing.
DoNothingOnExit = func(code int) {}
// DoNothingOnPanic handle func. use for testing.
DoNothingOnPanic = func(v any) {}
// DefaultPanicFn handle func
DefaultPanicFn = func(v any) {
panic(v)
}
// DefaultClockFn create func
DefaultClockFn = ClockFn(func() time.Time {
return time.Now()
})
)
var (
// PrintLevel for use logger.Print / Printf / Println
PrintLevel = InfoLevel
// AllLevels exposing all logging levels
AllLevels = Levels{
PanicLevel,
FatalLevel,
ErrorLevel,
WarnLevel,
NoticeLevel,
InfoLevel,
DebugLevel,
TraceLevel,
}
// DangerLevels define the commonly danger log levels
DangerLevels = Levels{PanicLevel, FatalLevel, ErrorLevel, WarnLevel}
// NormalLevels define the commonly normal log levels
NormalLevels = Levels{InfoLevel, NoticeLevel, DebugLevel, TraceLevel}
// LevelNames all level mapping name
LevelNames = map[Level]string{
PanicLevel: "PANIC",
FatalLevel: "FATAL",
ErrorLevel: "ERROR",
WarnLevel: "WARN",
NoticeLevel: "NOTICE",
InfoLevel: "INFO",
DebugLevel: "DEBUG",
TraceLevel: "TRACE",
}
// lower level name.
lowerLevelNames = buildLowerLevelName()
// empty time for reset record.
emptyTime = time.Time{}
)
// LevelName match
func LevelName(l Level) string {
if n, ok := LevelNames[l]; ok {
return n
}
return "UNKNOWN"
}
// LevelByName convert name to level
func LevelByName(ln string) Level {
l, err := Name2Level(ln)
if err != nil {
return InfoLevel
}
return l
}
// Name2Level convert name to level
func Name2Level(ln string) (Level, error) {
switch strings.ToLower(ln) {
case "panic":
return PanicLevel, nil
case "fatal":
return FatalLevel, nil
case "err", "error":
return ErrorLevel, nil
case "warn", "warning":
return WarnLevel, nil
case "note", "notice":
return NoticeLevel, nil
case "info", "": // make the zero value useful
return InfoLevel, nil
case "debug":
return DebugLevel, nil
case "trace":
return TraceLevel, nil
}
return 0, errors.New("invalid log level name: " + ln)
}
//
// exit handle logic
//
// global exit handler
var exitHandlers = make([]func(), 0)
func runExitHandlers() {
defer func() {
if err := recover(); err != nil {
printlnStderr("slog: run exit handler(global) recovered, error:", err)
}
}()
for _, handler := range exitHandlers {
handler()
}
}
// ExitHandlers get all global exitHandlers
func ExitHandlers() []func() {
return exitHandlers
}
// RegisterExitHandler register an exit-handler on global exitHandlers
func RegisterExitHandler(handler func()) {
exitHandlers = append(exitHandlers, handler)
}
// PrependExitHandler prepend register an exit-handler on global exitHandlers
func PrependExitHandler(handler func()) {
exitHandlers = append([]func(){handler}, exitHandlers...)
}
// ResetExitHandlers reset all exitHandlers
func ResetExitHandlers(applyToStd bool) {
exitHandlers = make([]func(), 0)
if applyToStd {
std.ResetExitHandlers()
}
}