1 // Copyright (c) 2016 Uber Technologies, Inc.
3 // Permission is hereby granted, free of charge, to any person obtaining a copy
4 // of this software and associated documentation files (the "Software"), to deal
5 // in the Software without restriction, including without limitation the rights
6 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 // copies of the Software, and to permit persons to whom the Software is
8 // furnished to do so, subject to the following conditions:
10 // The above copyright notice and this permission notice shall be included in
11 // all copies or substantial portions of the Software.
13 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
28 "go.uber.org/zap/zapcore"
31 // Field is an alias for Field. Aliasing this type dramatically
32 // improves the navigability of this package's API documentation.
33 type Field = zapcore.Field
35 // Skip constructs a no-op field, which is often useful when handling invalid
36 // inputs in other Field constructors.
38 return Field{Type: zapcore.SkipType}
41 // Binary constructs a field that carries an opaque binary blob.
43 // Binary data is serialized in an encoding-appropriate format. For example,
44 // zap's JSON encoder base64-encodes binary blobs. To log UTF-8 encoded text,
46 func Binary(key string, val []byte) Field {
47 return Field{Key: key, Type: zapcore.BinaryType, Interface: val}
50 // Bool constructs a field that carries a bool.
51 func Bool(key string, val bool) Field {
56 return Field{Key: key, Type: zapcore.BoolType, Integer: ival}
59 // ByteString constructs a field that carries UTF-8 encoded text as a []byte.
60 // To log opaque binary blobs (which aren't necessarily valid UTF-8), use
62 func ByteString(key string, val []byte) Field {
63 return Field{Key: key, Type: zapcore.ByteStringType, Interface: val}
66 // Complex128 constructs a field that carries a complex number. Unlike most
67 // numeric fields, this costs an allocation (to convert the complex128 to
69 func Complex128(key string, val complex128) Field {
70 return Field{Key: key, Type: zapcore.Complex128Type, Interface: val}
73 // Complex64 constructs a field that carries a complex number. Unlike most
74 // numeric fields, this costs an allocation (to convert the complex64 to
76 func Complex64(key string, val complex64) Field {
77 return Field{Key: key, Type: zapcore.Complex64Type, Interface: val}
80 // Float64 constructs a field that carries a float64. The way the
81 // floating-point value is represented is encoder-dependent, so marshaling is
83 func Float64(key string, val float64) Field {
84 return Field{Key: key, Type: zapcore.Float64Type, Integer: int64(math.Float64bits(val))}
87 // Float32 constructs a field that carries a float32. The way the
88 // floating-point value is represented is encoder-dependent, so marshaling is
90 func Float32(key string, val float32) Field {
91 return Field{Key: key, Type: zapcore.Float32Type, Integer: int64(math.Float32bits(val))}
94 // Int constructs a field with the given key and value.
95 func Int(key string, val int) Field {
96 return Int64(key, int64(val))
99 // Int64 constructs a field with the given key and value.
100 func Int64(key string, val int64) Field {
101 return Field{Key: key, Type: zapcore.Int64Type, Integer: val}
104 // Int32 constructs a field with the given key and value.
105 func Int32(key string, val int32) Field {
106 return Field{Key: key, Type: zapcore.Int32Type, Integer: int64(val)}
109 // Int16 constructs a field with the given key and value.
110 func Int16(key string, val int16) Field {
111 return Field{Key: key, Type: zapcore.Int16Type, Integer: int64(val)}
114 // Int8 constructs a field with the given key and value.
115 func Int8(key string, val int8) Field {
116 return Field{Key: key, Type: zapcore.Int8Type, Integer: int64(val)}
119 // String constructs a field with the given key and value.
120 func String(key string, val string) Field {
121 return Field{Key: key, Type: zapcore.StringType, String: val}
124 // Uint constructs a field with the given key and value.
125 func Uint(key string, val uint) Field {
126 return Uint64(key, uint64(val))
129 // Uint64 constructs a field with the given key and value.
130 func Uint64(key string, val uint64) Field {
131 return Field{Key: key, Type: zapcore.Uint64Type, Integer: int64(val)}
134 // Uint32 constructs a field with the given key and value.
135 func Uint32(key string, val uint32) Field {
136 return Field{Key: key, Type: zapcore.Uint32Type, Integer: int64(val)}
139 // Uint16 constructs a field with the given key and value.
140 func Uint16(key string, val uint16) Field {
141 return Field{Key: key, Type: zapcore.Uint16Type, Integer: int64(val)}
144 // Uint8 constructs a field with the given key and value.
145 func Uint8(key string, val uint8) Field {
146 return Field{Key: key, Type: zapcore.Uint8Type, Integer: int64(val)}
149 // Uintptr constructs a field with the given key and value.
150 func Uintptr(key string, val uintptr) Field {
151 return Field{Key: key, Type: zapcore.UintptrType, Integer: int64(val)}
154 // Reflect constructs a field with the given key and an arbitrary object. It uses
155 // an encoding-appropriate, reflection-based function to lazily serialize nearly
156 // any object into the logging context, but it's relatively slow and
157 // allocation-heavy. Outside tests, Any is always a better choice.
159 // If encoding fails (e.g., trying to serialize a map[int]string to JSON), Reflect
160 // includes the error message in the final log output.
161 func Reflect(key string, val interface{}) Field {
162 return Field{Key: key, Type: zapcore.ReflectType, Interface: val}
165 // Namespace creates a named, isolated scope within the logger's context. All
166 // subsequent fields will be added to the new namespace.
168 // This helps prevent key collisions when injecting loggers into sub-components
169 // or third-party libraries.
170 func Namespace(key string) Field {
171 return Field{Key: key, Type: zapcore.NamespaceType}
174 // Stringer constructs a field with the given key and the output of the value's
175 // String method. The Stringer's String method is called lazily.
176 func Stringer(key string, val fmt.Stringer) Field {
177 return Field{Key: key, Type: zapcore.StringerType, Interface: val}
180 // Time constructs a Field with the given key and value. The encoder
181 // controls how the time is serialized.
182 func Time(key string, val time.Time) Field {
183 return Field{Key: key, Type: zapcore.TimeType, Integer: val.UnixNano(), Interface: val.Location()}
186 // Stack constructs a field that stores a stacktrace of the current goroutine
187 // under provided key. Keep in mind that taking a stacktrace is eager and
188 // expensive (relatively speaking); this function both makes an allocation and
189 // takes about two microseconds.
190 func Stack(key string) Field {
191 // Returning the stacktrace as a string costs an allocation, but saves us
192 // from expanding the zapcore.Field union struct to include a byte slice. Since
193 // taking a stacktrace is already so expensive (~10us), the extra allocation
195 return String(key, takeStacktrace())
198 // Duration constructs a field with the given key and value. The encoder
199 // controls how the duration is serialized.
200 func Duration(key string, val time.Duration) Field {
201 return Field{Key: key, Type: zapcore.DurationType, Integer: int64(val)}
204 // Object constructs a field with the given key and ObjectMarshaler. It
205 // provides a flexible, but still type-safe and efficient, way to add map- or
206 // struct-like user-defined types to the logging context. The struct's
207 // MarshalLogObject method is called lazily.
208 func Object(key string, val zapcore.ObjectMarshaler) Field {
209 return Field{Key: key, Type: zapcore.ObjectMarshalerType, Interface: val}
212 // Any takes a key and an arbitrary value and chooses the best way to represent
213 // them as a field, falling back to a reflection-based approach only if
216 // Since byte/uint8 and rune/int32 are aliases, Any can't differentiate between
217 // them. To minimize surprises, []byte values are treated as binary blobs, byte
218 // values are treated as uint8, and runes are always treated as integers.
219 func Any(key string, value interface{}) Field {
220 switch val := value.(type) {
221 case zapcore.ObjectMarshaler:
222 return Object(key, val)
223 case zapcore.ArrayMarshaler:
224 return Array(key, val)
226 return Bool(key, val)
228 return Bools(key, val)
230 return Complex128(key, val)
232 return Complex128s(key, val)
234 return Complex64(key, val)
236 return Complex64s(key, val)
238 return Float64(key, val)
240 return Float64s(key, val)
242 return Float32(key, val)
244 return Float32s(key, val)
248 return Ints(key, val)
250 return Int64(key, val)
252 return Int64s(key, val)
254 return Int32(key, val)
256 return Int32s(key, val)
258 return Int16(key, val)
260 return Int16s(key, val)
262 return Int8(key, val)
264 return Int8s(key, val)
266 return String(key, val)
268 return Strings(key, val)
270 return Uint(key, val)
272 return Uints(key, val)
274 return Uint64(key, val)
276 return Uint64s(key, val)
278 return Uint32(key, val)
280 return Uint32s(key, val)
282 return Uint16(key, val)
284 return Uint16s(key, val)
286 return Uint8(key, val)
288 return Binary(key, val)
290 return Uintptr(key, val)
292 return Uintptrs(key, val)
294 return Time(key, val)
296 return Times(key, val)
298 return Duration(key, val)
299 case []time.Duration:
300 return Durations(key, val)
302 return NamedError(key, val)
304 return Errors(key, val)
306 return Stringer(key, val)
308 return Reflect(key, val)