blob: a0e090a36c308870ea15b80d565fae3f521cb020 [file] [log] [blame]
khenaidooac637102019-01-14 15:44:34 -05001package zerolog
2
3import (
4 "fmt"
5 "net"
6 "os"
7 "runtime"
8 "strconv"
9 "sync"
10 "time"
11)
12
13var eventPool = &sync.Pool{
14 New: func() interface{} {
15 return &Event{
16 buf: make([]byte, 0, 500),
17 }
18 },
19}
20
21// ErrorMarshalFunc allows customization of global error marshaling
22var ErrorMarshalFunc = func(err error) interface{} {
23 return err
24}
25
26// Event represents a log event. It is instanced by one of the level method of
27// Logger and finalized by the Msg or Msgf method.
28type Event struct {
29 buf []byte
30 w LevelWriter
31 level Level
32 done func(msg string)
33 ch []Hook // hooks from context
34}
35
36func putEvent(e *Event) {
37 // Proper usage of a sync.Pool requires each entry to have approximately
38 // the same memory cost. To obtain this property when the stored type
39 // contains a variably-sized buffer, we add a hard limit on the maximum buffer
40 // to place back in the pool.
41 //
42 // See https://golang.org/issue/23199
43 const maxSize = 1 << 16 // 64KiB
44 if cap(e.buf) > maxSize {
45 return
46 }
47 eventPool.Put(e)
48}
49
50// LogObjectMarshaler provides a strongly-typed and encoding-agnostic interface
51// to be implemented by types used with Event/Context's Object methods.
52type LogObjectMarshaler interface {
53 MarshalZerologObject(e *Event)
54}
55
56// LogArrayMarshaler provides a strongly-typed and encoding-agnostic interface
57// to be implemented by types used with Event/Context's Array methods.
58type LogArrayMarshaler interface {
59 MarshalZerologArray(a *Array)
60}
61
62func newEvent(w LevelWriter, level Level) *Event {
63 e := eventPool.Get().(*Event)
64 e.buf = e.buf[:0]
65 e.ch = nil
66 e.buf = enc.AppendBeginMarker(e.buf)
67 e.w = w
68 e.level = level
69 return e
70}
71
72func (e *Event) write() (err error) {
73 if e == nil {
74 return nil
75 }
76 if e.level != Disabled {
77 e.buf = enc.AppendEndMarker(e.buf)
78 e.buf = enc.AppendLineBreak(e.buf)
79 if e.w != nil {
80 _, err = e.w.WriteLevel(e.level, e.buf)
81 }
82 }
83 putEvent(e)
84 return
85}
86
87// Enabled return false if the *Event is going to be filtered out by
88// log level or sampling.
89func (e *Event) Enabled() bool {
90 return e != nil && e.level != Disabled
91}
92
93// Discard disables the event so Msg(f) won't print it.
94func (e *Event) Discard() *Event {
95 if e == nil {
96 return e
97 }
98 e.level = Disabled
99 return nil
100}
101
102// Msg sends the *Event with msg added as the message field if not empty.
103//
104// NOTICE: once this method is called, the *Event should be disposed.
105// Calling Msg twice can have unexpected result.
106func (e *Event) Msg(msg string) {
107 if e == nil {
108 return
109 }
110 e.msg(msg)
111}
112
113// Msgf sends the event with formated msg added as the message field if not empty.
114//
115// NOTICE: once this methid is called, the *Event should be disposed.
116// Calling Msg twice can have unexpected result.
117func (e *Event) Msgf(format string, v ...interface{}) {
118 if e == nil {
119 return
120 }
121 e.msg(fmt.Sprintf(format, v...))
122}
123
124func (e *Event) msg(msg string) {
125 if len(e.ch) > 0 {
126 e.ch[0].Run(e, e.level, msg)
127 if len(e.ch) > 1 {
128 for _, hook := range e.ch[1:] {
129 hook.Run(e, e.level, msg)
130 }
131 }
132 }
133 if msg != "" {
134 e.buf = enc.AppendString(enc.AppendKey(e.buf, MessageFieldName), msg)
135 }
136 if e.done != nil {
137 defer e.done(msg)
138 }
139 if err := e.write(); err != nil {
140 if ErrorHandler != nil {
141 ErrorHandler(err)
142 } else {
143 fmt.Fprintf(os.Stderr, "zerolog: could not write event: %v\n", err)
144 }
145 }
146}
147
148// Fields is a helper function to use a map to set fields using type assertion.
149func (e *Event) Fields(fields map[string]interface{}) *Event {
150 if e == nil {
151 return e
152 }
153 e.buf = appendFields(e.buf, fields)
154 return e
155}
156
157// Dict adds the field key with a dict to the event context.
158// Use zerolog.Dict() to create the dictionary.
159func (e *Event) Dict(key string, dict *Event) *Event {
160 if e == nil {
161 return e
162 }
163 dict.buf = enc.AppendEndMarker(dict.buf)
164 e.buf = append(enc.AppendKey(e.buf, key), dict.buf...)
165 putEvent(dict)
166 return e
167}
168
169// Dict creates an Event to be used with the *Event.Dict method.
170// Call usual field methods like Str, Int etc to add fields to this
171// event and give it as argument the *Event.Dict method.
172func Dict() *Event {
173 return newEvent(nil, 0)
174}
175
176// Array adds the field key with an array to the event context.
177// Use zerolog.Arr() to create the array or pass a type that
178// implement the LogArrayMarshaler interface.
179func (e *Event) Array(key string, arr LogArrayMarshaler) *Event {
180 if e == nil {
181 return e
182 }
183 e.buf = enc.AppendKey(e.buf, key)
184 var a *Array
185 if aa, ok := arr.(*Array); ok {
186 a = aa
187 } else {
188 a = Arr()
189 arr.MarshalZerologArray(a)
190 }
191 e.buf = a.write(e.buf)
192 return e
193}
194
195func (e *Event) appendObject(obj LogObjectMarshaler) {
196 e.buf = enc.AppendBeginMarker(e.buf)
197 obj.MarshalZerologObject(e)
198 e.buf = enc.AppendEndMarker(e.buf)
199}
200
201// Object marshals an object that implement the LogObjectMarshaler interface.
202func (e *Event) Object(key string, obj LogObjectMarshaler) *Event {
203 if e == nil {
204 return e
205 }
206 e.buf = enc.AppendKey(e.buf, key)
207 e.appendObject(obj)
208 return e
209}
210
211// Object marshals an object that implement the LogObjectMarshaler interface.
212func (e *Event) EmbedObject(obj LogObjectMarshaler) *Event {
213 if e == nil {
214 return e
215 }
216 obj.MarshalZerologObject(e)
217 return e
218}
219
220// Str adds the field key with val as a string to the *Event context.
221func (e *Event) Str(key, val string) *Event {
222 if e == nil {
223 return e
224 }
225 e.buf = enc.AppendString(enc.AppendKey(e.buf, key), val)
226 return e
227}
228
229// Strs adds the field key with vals as a []string to the *Event context.
230func (e *Event) Strs(key string, vals []string) *Event {
231 if e == nil {
232 return e
233 }
234 e.buf = enc.AppendStrings(enc.AppendKey(e.buf, key), vals)
235 return e
236}
237
238// Bytes adds the field key with val as a string to the *Event context.
239//
240// Runes outside of normal ASCII ranges will be hex-encoded in the resulting
241// JSON.
242func (e *Event) Bytes(key string, val []byte) *Event {
243 if e == nil {
244 return e
245 }
246 e.buf = enc.AppendBytes(enc.AppendKey(e.buf, key), val)
247 return e
248}
249
250// Hex adds the field key with val as a hex string to the *Event context.
251func (e *Event) Hex(key string, val []byte) *Event {
252 if e == nil {
253 return e
254 }
255 e.buf = enc.AppendHex(enc.AppendKey(e.buf, key), val)
256 return e
257}
258
259// RawJSON adds already encoded JSON to the log line under key.
260//
261// No sanity check is performed on b; it must not contain carriage returns and
262// be valid JSON.
263func (e *Event) RawJSON(key string, b []byte) *Event {
264 if e == nil {
265 return e
266 }
267 e.buf = appendJSON(enc.AppendKey(e.buf, key), b)
268 return e
269}
270
271// AnErr adds the field key with serialized err to the *Event context.
272// If err is nil, no field is added.
273func (e *Event) AnErr(key string, err error) *Event {
274 marshaled := ErrorMarshalFunc(err)
275 switch m := marshaled.(type) {
276 case nil:
277 return e
278 case LogObjectMarshaler:
279 return e.Object(key, m)
280 case error:
281 return e.Str(key, m.Error())
282 case string:
283 return e.Str(key, m)
284 default:
285 return e.Interface(key, m)
286 }
287}
288
289// Errs adds the field key with errs as an array of serialized errors to the
290// *Event context.
291func (e *Event) Errs(key string, errs []error) *Event {
292 if e == nil {
293 return e
294 }
295
296 arr := Arr()
297 for _, err := range errs {
298 marshaled := ErrorMarshalFunc(err)
299 switch m := marshaled.(type) {
300 case LogObjectMarshaler:
301 arr = arr.Object(m)
302 case error:
303 arr = arr.Err(m)
304 case string:
305 arr = arr.Str(m)
306 default:
307 arr = arr.Interface(m)
308 }
309 }
310
311 return e.Array(key, arr)
312}
313
314// Err adds the field "error" with serialized err to the *Event context.
315// If err is nil, no field is added.
316// To customize the key name, change zerolog.ErrorFieldName.
317func (e *Event) Err(err error) *Event {
318 return e.AnErr(ErrorFieldName, err)
319}
320
321// Bool adds the field key with val as a bool to the *Event context.
322func (e *Event) Bool(key string, b bool) *Event {
323 if e == nil {
324 return e
325 }
326 e.buf = enc.AppendBool(enc.AppendKey(e.buf, key), b)
327 return e
328}
329
330// Bools adds the field key with val as a []bool to the *Event context.
331func (e *Event) Bools(key string, b []bool) *Event {
332 if e == nil {
333 return e
334 }
335 e.buf = enc.AppendBools(enc.AppendKey(e.buf, key), b)
336 return e
337}
338
339// Int adds the field key with i as a int to the *Event context.
340func (e *Event) Int(key string, i int) *Event {
341 if e == nil {
342 return e
343 }
344 e.buf = enc.AppendInt(enc.AppendKey(e.buf, key), i)
345 return e
346}
347
348// Ints adds the field key with i as a []int to the *Event context.
349func (e *Event) Ints(key string, i []int) *Event {
350 if e == nil {
351 return e
352 }
353 e.buf = enc.AppendInts(enc.AppendKey(e.buf, key), i)
354 return e
355}
356
357// Int8 adds the field key with i as a int8 to the *Event context.
358func (e *Event) Int8(key string, i int8) *Event {
359 if e == nil {
360 return e
361 }
362 e.buf = enc.AppendInt8(enc.AppendKey(e.buf, key), i)
363 return e
364}
365
366// Ints8 adds the field key with i as a []int8 to the *Event context.
367func (e *Event) Ints8(key string, i []int8) *Event {
368 if e == nil {
369 return e
370 }
371 e.buf = enc.AppendInts8(enc.AppendKey(e.buf, key), i)
372 return e
373}
374
375// Int16 adds the field key with i as a int16 to the *Event context.
376func (e *Event) Int16(key string, i int16) *Event {
377 if e == nil {
378 return e
379 }
380 e.buf = enc.AppendInt16(enc.AppendKey(e.buf, key), i)
381 return e
382}
383
384// Ints16 adds the field key with i as a []int16 to the *Event context.
385func (e *Event) Ints16(key string, i []int16) *Event {
386 if e == nil {
387 return e
388 }
389 e.buf = enc.AppendInts16(enc.AppendKey(e.buf, key), i)
390 return e
391}
392
393// Int32 adds the field key with i as a int32 to the *Event context.
394func (e *Event) Int32(key string, i int32) *Event {
395 if e == nil {
396 return e
397 }
398 e.buf = enc.AppendInt32(enc.AppendKey(e.buf, key), i)
399 return e
400}
401
402// Ints32 adds the field key with i as a []int32 to the *Event context.
403func (e *Event) Ints32(key string, i []int32) *Event {
404 if e == nil {
405 return e
406 }
407 e.buf = enc.AppendInts32(enc.AppendKey(e.buf, key), i)
408 return e
409}
410
411// Int64 adds the field key with i as a int64 to the *Event context.
412func (e *Event) Int64(key string, i int64) *Event {
413 if e == nil {
414 return e
415 }
416 e.buf = enc.AppendInt64(enc.AppendKey(e.buf, key), i)
417 return e
418}
419
420// Ints64 adds the field key with i as a []int64 to the *Event context.
421func (e *Event) Ints64(key string, i []int64) *Event {
422 if e == nil {
423 return e
424 }
425 e.buf = enc.AppendInts64(enc.AppendKey(e.buf, key), i)
426 return e
427}
428
429// Uint adds the field key with i as a uint to the *Event context.
430func (e *Event) Uint(key string, i uint) *Event {
431 if e == nil {
432 return e
433 }
434 e.buf = enc.AppendUint(enc.AppendKey(e.buf, key), i)
435 return e
436}
437
438// Uints adds the field key with i as a []int to the *Event context.
439func (e *Event) Uints(key string, i []uint) *Event {
440 if e == nil {
441 return e
442 }
443 e.buf = enc.AppendUints(enc.AppendKey(e.buf, key), i)
444 return e
445}
446
447// Uint8 adds the field key with i as a uint8 to the *Event context.
448func (e *Event) Uint8(key string, i uint8) *Event {
449 if e == nil {
450 return e
451 }
452 e.buf = enc.AppendUint8(enc.AppendKey(e.buf, key), i)
453 return e
454}
455
456// Uints8 adds the field key with i as a []int8 to the *Event context.
457func (e *Event) Uints8(key string, i []uint8) *Event {
458 if e == nil {
459 return e
460 }
461 e.buf = enc.AppendUints8(enc.AppendKey(e.buf, key), i)
462 return e
463}
464
465// Uint16 adds the field key with i as a uint16 to the *Event context.
466func (e *Event) Uint16(key string, i uint16) *Event {
467 if e == nil {
468 return e
469 }
470 e.buf = enc.AppendUint16(enc.AppendKey(e.buf, key), i)
471 return e
472}
473
474// Uints16 adds the field key with i as a []int16 to the *Event context.
475func (e *Event) Uints16(key string, i []uint16) *Event {
476 if e == nil {
477 return e
478 }
479 e.buf = enc.AppendUints16(enc.AppendKey(e.buf, key), i)
480 return e
481}
482
483// Uint32 adds the field key with i as a uint32 to the *Event context.
484func (e *Event) Uint32(key string, i uint32) *Event {
485 if e == nil {
486 return e
487 }
488 e.buf = enc.AppendUint32(enc.AppendKey(e.buf, key), i)
489 return e
490}
491
492// Uints32 adds the field key with i as a []int32 to the *Event context.
493func (e *Event) Uints32(key string, i []uint32) *Event {
494 if e == nil {
495 return e
496 }
497 e.buf = enc.AppendUints32(enc.AppendKey(e.buf, key), i)
498 return e
499}
500
501// Uint64 adds the field key with i as a uint64 to the *Event context.
502func (e *Event) Uint64(key string, i uint64) *Event {
503 if e == nil {
504 return e
505 }
506 e.buf = enc.AppendUint64(enc.AppendKey(e.buf, key), i)
507 return e
508}
509
510// Uints64 adds the field key with i as a []int64 to the *Event context.
511func (e *Event) Uints64(key string, i []uint64) *Event {
512 if e == nil {
513 return e
514 }
515 e.buf = enc.AppendUints64(enc.AppendKey(e.buf, key), i)
516 return e
517}
518
519// Float32 adds the field key with f as a float32 to the *Event context.
520func (e *Event) Float32(key string, f float32) *Event {
521 if e == nil {
522 return e
523 }
524 e.buf = enc.AppendFloat32(enc.AppendKey(e.buf, key), f)
525 return e
526}
527
528// Floats32 adds the field key with f as a []float32 to the *Event context.
529func (e *Event) Floats32(key string, f []float32) *Event {
530 if e == nil {
531 return e
532 }
533 e.buf = enc.AppendFloats32(enc.AppendKey(e.buf, key), f)
534 return e
535}
536
537// Float64 adds the field key with f as a float64 to the *Event context.
538func (e *Event) Float64(key string, f float64) *Event {
539 if e == nil {
540 return e
541 }
542 e.buf = enc.AppendFloat64(enc.AppendKey(e.buf, key), f)
543 return e
544}
545
546// Floats64 adds the field key with f as a []float64 to the *Event context.
547func (e *Event) Floats64(key string, f []float64) *Event {
548 if e == nil {
549 return e
550 }
551 e.buf = enc.AppendFloats64(enc.AppendKey(e.buf, key), f)
552 return e
553}
554
555// Timestamp adds the current local time as UNIX timestamp to the *Event context with the "time" key.
556// To customize the key name, change zerolog.TimestampFieldName.
557//
558// NOTE: It won't dedupe the "time" key if the *Event (or *Context) has one
559// already.
560func (e *Event) Timestamp() *Event {
561 if e == nil {
562 return e
563 }
564 e.buf = enc.AppendTime(enc.AppendKey(e.buf, TimestampFieldName), TimestampFunc(), TimeFieldFormat)
565 return e
566}
567
568// Time adds the field key with t formated as string using zerolog.TimeFieldFormat.
569func (e *Event) Time(key string, t time.Time) *Event {
570 if e == nil {
571 return e
572 }
573 e.buf = enc.AppendTime(enc.AppendKey(e.buf, key), t, TimeFieldFormat)
574 return e
575}
576
577// Times adds the field key with t formated as string using zerolog.TimeFieldFormat.
578func (e *Event) Times(key string, t []time.Time) *Event {
579 if e == nil {
580 return e
581 }
582 e.buf = enc.AppendTimes(enc.AppendKey(e.buf, key), t, TimeFieldFormat)
583 return e
584}
585
586// Dur adds the field key with duration d stored as zerolog.DurationFieldUnit.
587// If zerolog.DurationFieldInteger is true, durations are rendered as integer
588// instead of float.
589func (e *Event) Dur(key string, d time.Duration) *Event {
590 if e == nil {
591 return e
592 }
593 e.buf = enc.AppendDuration(enc.AppendKey(e.buf, key), d, DurationFieldUnit, DurationFieldInteger)
594 return e
595}
596
597// Durs adds the field key with duration d stored as zerolog.DurationFieldUnit.
598// If zerolog.DurationFieldInteger is true, durations are rendered as integer
599// instead of float.
600func (e *Event) Durs(key string, d []time.Duration) *Event {
601 if e == nil {
602 return e
603 }
604 e.buf = enc.AppendDurations(enc.AppendKey(e.buf, key), d, DurationFieldUnit, DurationFieldInteger)
605 return e
606}
607
608// TimeDiff adds the field key with positive duration between time t and start.
609// If time t is not greater than start, duration will be 0.
610// Duration format follows the same principle as Dur().
611func (e *Event) TimeDiff(key string, t time.Time, start time.Time) *Event {
612 if e == nil {
613 return e
614 }
615 var d time.Duration
616 if t.After(start) {
617 d = t.Sub(start)
618 }
619 e.buf = enc.AppendDuration(enc.AppendKey(e.buf, key), d, DurationFieldUnit, DurationFieldInteger)
620 return e
621}
622
623// Interface adds the field key with i marshaled using reflection.
624func (e *Event) Interface(key string, i interface{}) *Event {
625 if e == nil {
626 return e
627 }
628 if obj, ok := i.(LogObjectMarshaler); ok {
629 return e.Object(key, obj)
630 }
631 e.buf = enc.AppendInterface(enc.AppendKey(e.buf, key), i)
632 return e
633}
634
635// Caller adds the file:line of the caller with the zerolog.CallerFieldName key.
636func (e *Event) Caller() *Event {
637 return e.caller(CallerSkipFrameCount)
638}
639
640func (e *Event) caller(skip int) *Event {
641 if e == nil {
642 return e
643 }
644 _, file, line, ok := runtime.Caller(skip)
645 if !ok {
646 return e
647 }
648 e.buf = enc.AppendString(enc.AppendKey(e.buf, CallerFieldName), file+":"+strconv.Itoa(line))
649 return e
650}
651
652// IPAddr adds IPv4 or IPv6 Address to the event
653func (e *Event) IPAddr(key string, ip net.IP) *Event {
654 if e == nil {
655 return e
656 }
657 e.buf = enc.AppendIPAddr(enc.AppendKey(e.buf, key), ip)
658 return e
659}
660
661// IPPrefix adds IPv4 or IPv6 Prefix (address and mask) to the event
662func (e *Event) IPPrefix(key string, pfx net.IPNet) *Event {
663 if e == nil {
664 return e
665 }
666 e.buf = enc.AppendIPPrefix(enc.AppendKey(e.buf, key), pfx)
667 return e
668}
669
670// MACAddr adds MAC address to the event
671func (e *Event) MACAddr(key string, ha net.HardwareAddr) *Event {
672 if e == nil {
673 return e
674 }
675 e.buf = enc.AppendMACAddr(enc.AppendKey(e.buf, key), ha)
676 return e
677}