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 package zerolog
100
101 import (
102 "errors"
103 "fmt"
104 "io"
105 "io/ioutil"
106 "os"
107 "strconv"
108 )
109
110
111 type Level int8
112
113 const (
114
115 DebugLevel Level = iota
116
117 InfoLevel
118
119 WarnLevel
120
121 ErrorLevel
122
123 FatalLevel
124
125 PanicLevel
126
127 NoLevel
128
129 Disabled
130
131
132 TraceLevel Level = -1
133
134 )
135
136 func (l Level) String() string {
137 switch l {
138 case TraceLevel:
139 return LevelTraceValue
140 case DebugLevel:
141 return LevelDebugValue
142 case InfoLevel:
143 return LevelInfoValue
144 case WarnLevel:
145 return LevelWarnValue
146 case ErrorLevel:
147 return LevelErrorValue
148 case FatalLevel:
149 return LevelFatalValue
150 case PanicLevel:
151 return LevelPanicValue
152 case Disabled:
153 return "disabled"
154 case NoLevel:
155 return ""
156 }
157 return strconv.Itoa(int(l))
158 }
159
160
161
162 func ParseLevel(levelStr string) (Level, error) {
163 switch levelStr {
164 case LevelFieldMarshalFunc(TraceLevel):
165 return TraceLevel, nil
166 case LevelFieldMarshalFunc(DebugLevel):
167 return DebugLevel, nil
168 case LevelFieldMarshalFunc(InfoLevel):
169 return InfoLevel, nil
170 case LevelFieldMarshalFunc(WarnLevel):
171 return WarnLevel, nil
172 case LevelFieldMarshalFunc(ErrorLevel):
173 return ErrorLevel, nil
174 case LevelFieldMarshalFunc(FatalLevel):
175 return FatalLevel, nil
176 case LevelFieldMarshalFunc(PanicLevel):
177 return PanicLevel, nil
178 case LevelFieldMarshalFunc(Disabled):
179 return Disabled, nil
180 case LevelFieldMarshalFunc(NoLevel):
181 return NoLevel, nil
182 }
183 i, err := strconv.Atoi(levelStr)
184 if err != nil {
185 return NoLevel, fmt.Errorf("Unknown Level String: '%s', defaulting to NoLevel", levelStr)
186 }
187 if i > 127 || i < -128 {
188 return NoLevel, fmt.Errorf("Out-Of-Bounds Level: '%d', defaulting to NoLevel", i)
189 }
190 return Level(i), nil
191 }
192
193
194 func (l *Level) UnmarshalText(text []byte) error {
195 if l == nil {
196 return errors.New("can't unmarshal a nil *Level")
197 }
198 var err error
199 *l, err = ParseLevel(string(text))
200 return err
201 }
202
203
204 func (l Level) MarshalText() ([]byte, error) {
205 return []byte(LevelFieldMarshalFunc(l)), nil
206 }
207
208
209
210
211
212
213 type Logger struct {
214 w LevelWriter
215 level Level
216 sampler Sampler
217 context []byte
218 hooks []Hook
219 stack bool
220 }
221
222
223
224
225
226
227
228
229 func New(w io.Writer) Logger {
230 if w == nil {
231 w = ioutil.Discard
232 }
233 lw, ok := w.(LevelWriter)
234 if !ok {
235 lw = levelWriterAdapter{w}
236 }
237 return Logger{w: lw, level: TraceLevel}
238 }
239
240
241 func Nop() Logger {
242 return New(nil).Level(Disabled)
243 }
244
245
246 func (l Logger) Output(w io.Writer) Logger {
247 l2 := New(w)
248 l2.level = l.level
249 l2.sampler = l.sampler
250 l2.stack = l.stack
251 if len(l.hooks) > 0 {
252 l2.hooks = append(l2.hooks, l.hooks...)
253 }
254 if l.context != nil {
255 l2.context = make([]byte, len(l.context), cap(l.context))
256 copy(l2.context, l.context)
257 }
258 return l2
259 }
260
261
262 func (l Logger) With() Context {
263 context := l.context
264 l.context = make([]byte, 0, 500)
265 if context != nil {
266 l.context = append(l.context, context...)
267 } else {
268
269
270 l.context = enc.AppendBeginMarker(l.context)
271 }
272 return Context{l}
273 }
274
275
276
277
278 func (l *Logger) UpdateContext(update func(c Context) Context) {
279 if l == disabledLogger {
280 return
281 }
282 if cap(l.context) == 0 {
283 l.context = make([]byte, 0, 500)
284 }
285 if len(l.context) == 0 {
286 l.context = enc.AppendBeginMarker(l.context)
287 }
288 c := update(Context{*l})
289 l.context = c.l.context
290 }
291
292
293 func (l Logger) Level(lvl Level) Logger {
294 l.level = lvl
295 return l
296 }
297
298
299 func (l Logger) GetLevel() Level {
300 return l.level
301 }
302
303
304 func (l Logger) Sample(s Sampler) Logger {
305 l.sampler = s
306 return l
307 }
308
309
310 func (l Logger) Hook(h Hook) Logger {
311 l.hooks = append(l.hooks, h)
312 return l
313 }
314
315
316
317
318 func (l *Logger) Trace() *Event {
319 return l.newEvent(TraceLevel, nil)
320 }
321
322
323
324
325 func (l *Logger) Debug() *Event {
326 return l.newEvent(DebugLevel, nil)
327 }
328
329
330
331
332 func (l *Logger) Info() *Event {
333 return l.newEvent(InfoLevel, nil)
334 }
335
336
337
338
339 func (l *Logger) Warn() *Event {
340 return l.newEvent(WarnLevel, nil)
341 }
342
343
344
345
346 func (l *Logger) Error() *Event {
347 return l.newEvent(ErrorLevel, nil)
348 }
349
350
351
352
353
354 func (l *Logger) Err(err error) *Event {
355 if err != nil {
356 return l.Error().Err(err)
357 }
358
359 return l.Info()
360 }
361
362
363
364
365
366 func (l *Logger) Fatal() *Event {
367 return l.newEvent(FatalLevel, func(msg string) { os.Exit(1) })
368 }
369
370
371
372
373
374 func (l *Logger) Panic() *Event {
375 return l.newEvent(PanicLevel, func(msg string) { panic(msg) })
376 }
377
378
379
380
381
382
383 func (l *Logger) WithLevel(level Level) *Event {
384 switch level {
385 case TraceLevel:
386 return l.Trace()
387 case DebugLevel:
388 return l.Debug()
389 case InfoLevel:
390 return l.Info()
391 case WarnLevel:
392 return l.Warn()
393 case ErrorLevel:
394 return l.Error()
395 case FatalLevel:
396 return l.newEvent(FatalLevel, nil)
397 case PanicLevel:
398 return l.newEvent(PanicLevel, nil)
399 case NoLevel:
400 return l.Log()
401 case Disabled:
402 return nil
403 default:
404 return l.newEvent(level, nil)
405 }
406 }
407
408
409
410
411
412 func (l *Logger) Log() *Event {
413 return l.newEvent(NoLevel, nil)
414 }
415
416
417
418 func (l *Logger) Print(v ...interface{}) {
419 if e := l.Debug(); e.Enabled() {
420 e.CallerSkipFrame(1).Msg(fmt.Sprint(v...))
421 }
422 }
423
424
425
426 func (l *Logger) Printf(format string, v ...interface{}) {
427 if e := l.Debug(); e.Enabled() {
428 e.CallerSkipFrame(1).Msg(fmt.Sprintf(format, v...))
429 }
430 }
431
432
433
434 func (l Logger) Write(p []byte) (n int, err error) {
435 n = len(p)
436 if n > 0 && p[n-1] == '\n' {
437
438 p = p[0 : n-1]
439 }
440 l.Log().CallerSkipFrame(1).Msg(string(p))
441 return
442 }
443
444 func (l *Logger) newEvent(level Level, done func(string)) *Event {
445 enabled := l.should(level)
446 if !enabled {
447 if done != nil {
448 done("")
449 }
450 return nil
451 }
452 e := newEvent(l.w, level)
453 e.done = done
454 e.ch = l.hooks
455 if level != NoLevel && LevelFieldName != "" {
456 e.Str(LevelFieldName, LevelFieldMarshalFunc(level))
457 }
458 if l.context != nil && len(l.context) > 1 {
459 e.buf = enc.AppendObjectData(e.buf, l.context)
460 }
461 if l.stack {
462 e.Stack()
463 }
464 return e
465 }
466
467
468 func (l *Logger) should(lvl Level) bool {
469 if lvl < l.level || lvl < GlobalLevel() {
470 return false
471 }
472 if l.sampler != nil && !samplingDisabled() {
473 return l.sampler.Sample(lvl)
474 }
475 return true
476 }
477
View as plain text