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