blob: b843179dedd1b9389218e6bc65aa313e6b56fc96 [file] [log] [blame]
khenaidooac637102019-01-14 15:44:34 -05001package zerolog
2
3import (
4 "io/ioutil"
5 "net"
6 "time"
7)
8
9// Context configures a new sub-logger with contextual fields.
10type Context struct {
11 l Logger
12}
13
14// Logger returns the logger with the context previously set.
15func (c Context) Logger() Logger {
16 return c.l
17}
18
19// Fields is a helper function to use a map to set fields using type assertion.
20func (c Context) Fields(fields map[string]interface{}) Context {
21 c.l.context = appendFields(c.l.context, fields)
22 return c
23}
24
25// Dict adds the field key with the dict to the logger context.
26func (c Context) Dict(key string, dict *Event) Context {
27 dict.buf = enc.AppendEndMarker(dict.buf)
28 c.l.context = append(enc.AppendKey(c.l.context, key), dict.buf...)
29 putEvent(dict)
30 return c
31}
32
33// Array adds the field key with an array to the event context.
34// Use zerolog.Arr() to create the array or pass a type that
35// implement the LogArrayMarshaler interface.
36func (c Context) Array(key string, arr LogArrayMarshaler) Context {
37 c.l.context = enc.AppendKey(c.l.context, key)
38 if arr, ok := arr.(*Array); ok {
39 c.l.context = arr.write(c.l.context)
40 return c
41 }
42 var a *Array
43 if aa, ok := arr.(*Array); ok {
44 a = aa
45 } else {
46 a = Arr()
47 arr.MarshalZerologArray(a)
48 }
49 c.l.context = a.write(c.l.context)
50 return c
51}
52
53// Object marshals an object that implement the LogObjectMarshaler interface.
54func (c Context) Object(key string, obj LogObjectMarshaler) Context {
55 e := newEvent(levelWriterAdapter{ioutil.Discard}, 0)
56 e.Object(key, obj)
57 c.l.context = enc.AppendObjectData(c.l.context, e.buf)
58 putEvent(e)
59 return c
60}
61
62// EmbedObject marshals and Embeds an object that implement the LogObjectMarshaler interface.
63func (c Context) EmbedObject(obj LogObjectMarshaler) Context {
64 e := newEvent(levelWriterAdapter{ioutil.Discard}, 0)
65 e.EmbedObject(obj)
66 c.l.context = enc.AppendObjectData(c.l.context, e.buf)
67 putEvent(e)
68 return c
69}
70
71// Str adds the field key with val as a string to the logger context.
72func (c Context) Str(key, val string) Context {
73 c.l.context = enc.AppendString(enc.AppendKey(c.l.context, key), val)
74 return c
75}
76
77// Strs adds the field key with val as a string to the logger context.
78func (c Context) Strs(key string, vals []string) Context {
79 c.l.context = enc.AppendStrings(enc.AppendKey(c.l.context, key), vals)
80 return c
81}
82
83// Bytes adds the field key with val as a []byte to the logger context.
84func (c Context) Bytes(key string, val []byte) Context {
85 c.l.context = enc.AppendBytes(enc.AppendKey(c.l.context, key), val)
86 return c
87}
88
89// Hex adds the field key with val as a hex string to the logger context.
90func (c Context) Hex(key string, val []byte) Context {
91 c.l.context = enc.AppendHex(enc.AppendKey(c.l.context, key), val)
92 return c
93}
94
95// RawJSON adds already encoded JSON to context.
96//
97// No sanity check is performed on b; it must not contain carriage returns and
98// be valid JSON.
99func (c Context) RawJSON(key string, b []byte) Context {
100 c.l.context = appendJSON(enc.AppendKey(c.l.context, key), b)
101 return c
102}
103
104// AnErr adds the field key with serialized err to the logger context.
105func (c Context) AnErr(key string, err error) Context {
106 marshaled := ErrorMarshalFunc(err)
107 switch m := marshaled.(type) {
108 case nil:
109 return c
110 case LogObjectMarshaler:
111 return c.Object(key, m)
112 case error:
113 return c.Str(key, m.Error())
114 case string:
115 return c.Str(key, m)
116 default:
117 return c.Interface(key, m)
118 }
119}
120
121// Errs adds the field key with errs as an array of serialized errors to the
122// logger context.
123func (c Context) Errs(key string, errs []error) Context {
124 arr := Arr()
125 for _, err := range errs {
126 marshaled := ErrorMarshalFunc(err)
127 switch m := marshaled.(type) {
128 case LogObjectMarshaler:
129 arr = arr.Object(m)
130 case error:
131 arr = arr.Str(m.Error())
132 case string:
133 arr = arr.Str(m)
134 default:
135 arr = arr.Interface(m)
136 }
137 }
138
139 return c.Array(key, arr)
140}
141
142// Err adds the field "error" with serialized err to the logger context.
143func (c Context) Err(err error) Context {
144 return c.AnErr(ErrorFieldName, err)
145}
146
147// Bool adds the field key with val as a bool to the logger context.
148func (c Context) Bool(key string, b bool) Context {
149 c.l.context = enc.AppendBool(enc.AppendKey(c.l.context, key), b)
150 return c
151}
152
153// Bools adds the field key with val as a []bool to the logger context.
154func (c Context) Bools(key string, b []bool) Context {
155 c.l.context = enc.AppendBools(enc.AppendKey(c.l.context, key), b)
156 return c
157}
158
159// Int adds the field key with i as a int to the logger context.
160func (c Context) Int(key string, i int) Context {
161 c.l.context = enc.AppendInt(enc.AppendKey(c.l.context, key), i)
162 return c
163}
164
165// Ints adds the field key with i as a []int to the logger context.
166func (c Context) Ints(key string, i []int) Context {
167 c.l.context = enc.AppendInts(enc.AppendKey(c.l.context, key), i)
168 return c
169}
170
171// Int8 adds the field key with i as a int8 to the logger context.
172func (c Context) Int8(key string, i int8) Context {
173 c.l.context = enc.AppendInt8(enc.AppendKey(c.l.context, key), i)
174 return c
175}
176
177// Ints8 adds the field key with i as a []int8 to the logger context.
178func (c Context) Ints8(key string, i []int8) Context {
179 c.l.context = enc.AppendInts8(enc.AppendKey(c.l.context, key), i)
180 return c
181}
182
183// Int16 adds the field key with i as a int16 to the logger context.
184func (c Context) Int16(key string, i int16) Context {
185 c.l.context = enc.AppendInt16(enc.AppendKey(c.l.context, key), i)
186 return c
187}
188
189// Ints16 adds the field key with i as a []int16 to the logger context.
190func (c Context) Ints16(key string, i []int16) Context {
191 c.l.context = enc.AppendInts16(enc.AppendKey(c.l.context, key), i)
192 return c
193}
194
195// Int32 adds the field key with i as a int32 to the logger context.
196func (c Context) Int32(key string, i int32) Context {
197 c.l.context = enc.AppendInt32(enc.AppendKey(c.l.context, key), i)
198 return c
199}
200
201// Ints32 adds the field key with i as a []int32 to the logger context.
202func (c Context) Ints32(key string, i []int32) Context {
203 c.l.context = enc.AppendInts32(enc.AppendKey(c.l.context, key), i)
204 return c
205}
206
207// Int64 adds the field key with i as a int64 to the logger context.
208func (c Context) Int64(key string, i int64) Context {
209 c.l.context = enc.AppendInt64(enc.AppendKey(c.l.context, key), i)
210 return c
211}
212
213// Ints64 adds the field key with i as a []int64 to the logger context.
214func (c Context) Ints64(key string, i []int64) Context {
215 c.l.context = enc.AppendInts64(enc.AppendKey(c.l.context, key), i)
216 return c
217}
218
219// Uint adds the field key with i as a uint to the logger context.
220func (c Context) Uint(key string, i uint) Context {
221 c.l.context = enc.AppendUint(enc.AppendKey(c.l.context, key), i)
222 return c
223}
224
225// Uints adds the field key with i as a []uint to the logger context.
226func (c Context) Uints(key string, i []uint) Context {
227 c.l.context = enc.AppendUints(enc.AppendKey(c.l.context, key), i)
228 return c
229}
230
231// Uint8 adds the field key with i as a uint8 to the logger context.
232func (c Context) Uint8(key string, i uint8) Context {
233 c.l.context = enc.AppendUint8(enc.AppendKey(c.l.context, key), i)
234 return c
235}
236
237// Uints8 adds the field key with i as a []uint8 to the logger context.
238func (c Context) Uints8(key string, i []uint8) Context {
239 c.l.context = enc.AppendUints8(enc.AppendKey(c.l.context, key), i)
240 return c
241}
242
243// Uint16 adds the field key with i as a uint16 to the logger context.
244func (c Context) Uint16(key string, i uint16) Context {
245 c.l.context = enc.AppendUint16(enc.AppendKey(c.l.context, key), i)
246 return c
247}
248
249// Uints16 adds the field key with i as a []uint16 to the logger context.
250func (c Context) Uints16(key string, i []uint16) Context {
251 c.l.context = enc.AppendUints16(enc.AppendKey(c.l.context, key), i)
252 return c
253}
254
255// Uint32 adds the field key with i as a uint32 to the logger context.
256func (c Context) Uint32(key string, i uint32) Context {
257 c.l.context = enc.AppendUint32(enc.AppendKey(c.l.context, key), i)
258 return c
259}
260
261// Uints32 adds the field key with i as a []uint32 to the logger context.
262func (c Context) Uints32(key string, i []uint32) Context {
263 c.l.context = enc.AppendUints32(enc.AppendKey(c.l.context, key), i)
264 return c
265}
266
267// Uint64 adds the field key with i as a uint64 to the logger context.
268func (c Context) Uint64(key string, i uint64) Context {
269 c.l.context = enc.AppendUint64(enc.AppendKey(c.l.context, key), i)
270 return c
271}
272
273// Uints64 adds the field key with i as a []uint64 to the logger context.
274func (c Context) Uints64(key string, i []uint64) Context {
275 c.l.context = enc.AppendUints64(enc.AppendKey(c.l.context, key), i)
276 return c
277}
278
279// Float32 adds the field key with f as a float32 to the logger context.
280func (c Context) Float32(key string, f float32) Context {
281 c.l.context = enc.AppendFloat32(enc.AppendKey(c.l.context, key), f)
282 return c
283}
284
285// Floats32 adds the field key with f as a []float32 to the logger context.
286func (c Context) Floats32(key string, f []float32) Context {
287 c.l.context = enc.AppendFloats32(enc.AppendKey(c.l.context, key), f)
288 return c
289}
290
291// Float64 adds the field key with f as a float64 to the logger context.
292func (c Context) Float64(key string, f float64) Context {
293 c.l.context = enc.AppendFloat64(enc.AppendKey(c.l.context, key), f)
294 return c
295}
296
297// Floats64 adds the field key with f as a []float64 to the logger context.
298func (c Context) Floats64(key string, f []float64) Context {
299 c.l.context = enc.AppendFloats64(enc.AppendKey(c.l.context, key), f)
300 return c
301}
302
303type timestampHook struct{}
304
305func (ts timestampHook) Run(e *Event, level Level, msg string) {
306 e.Timestamp()
307}
308
309var th = timestampHook{}
310
311// Timestamp adds the current local time as UNIX timestamp to the logger context with the "time" key.
312// To customize the key name, change zerolog.TimestampFieldName.
313//
314// NOTE: It won't dedupe the "time" key if the *Context has one already.
315func (c Context) Timestamp() Context {
316 c.l = c.l.Hook(th)
317 return c
318}
319
320// Time adds the field key with t formated as string using zerolog.TimeFieldFormat.
321func (c Context) Time(key string, t time.Time) Context {
322 c.l.context = enc.AppendTime(enc.AppendKey(c.l.context, key), t, TimeFieldFormat)
323 return c
324}
325
326// Times adds the field key with t formated as string using zerolog.TimeFieldFormat.
327func (c Context) Times(key string, t []time.Time) Context {
328 c.l.context = enc.AppendTimes(enc.AppendKey(c.l.context, key), t, TimeFieldFormat)
329 return c
330}
331
332// Dur adds the fields key with d divided by unit and stored as a float.
333func (c Context) Dur(key string, d time.Duration) Context {
334 c.l.context = enc.AppendDuration(enc.AppendKey(c.l.context, key), d, DurationFieldUnit, DurationFieldInteger)
335 return c
336}
337
338// Durs adds the fields key with d divided by unit and stored as a float.
339func (c Context) Durs(key string, d []time.Duration) Context {
340 c.l.context = enc.AppendDurations(enc.AppendKey(c.l.context, key), d, DurationFieldUnit, DurationFieldInteger)
341 return c
342}
343
344// Interface adds the field key with obj marshaled using reflection.
345func (c Context) Interface(key string, i interface{}) Context {
346 c.l.context = enc.AppendInterface(enc.AppendKey(c.l.context, key), i)
347 return c
348}
349
350type callerHook struct{}
351
352func (ch callerHook) Run(e *Event, level Level, msg string) {
353 // Three extra frames to skip (added by hook infra).
354 e.caller(CallerSkipFrameCount + 3)
355}
356
357var ch = callerHook{}
358
359// Caller adds the file:line of the caller with the zerolog.CallerFieldName key.
360func (c Context) Caller() Context {
361 c.l = c.l.Hook(ch)
362 return c
363}
364
365// IPAddr adds IPv4 or IPv6 Address to the context
366func (c Context) IPAddr(key string, ip net.IP) Context {
367 c.l.context = enc.AppendIPAddr(enc.AppendKey(c.l.context, key), ip)
368 return c
369}
370
371// IPPrefix adds IPv4 or IPv6 Prefix (address and mask) to the context
372func (c Context) IPPrefix(key string, pfx net.IPNet) Context {
373 c.l.context = enc.AppendIPPrefix(enc.AppendKey(c.l.context, key), pfx)
374 return c
375}
376
377// MACAddr adds MAC address to the context
378func (c Context) MACAddr(key string, ha net.HardwareAddr) Context {
379 c.l.context = enc.AppendMACAddr(enc.AppendKey(c.l.context, key), ha)
380 return c
381}