1package zerolog 2 3import ( 4 "net" 5 "sort" 6 "time" 7 "unsafe" 8) 9 10func isNilValue(i interface{}) bool { 11 return (*[2]uintptr)(unsafe.Pointer(&i))[1] == 0 12} 13 14func appendFields(dst []byte, fields map[string]interface{}) []byte { 15 keys := make([]string, 0, len(fields)) 16 for key := range fields { 17 keys = append(keys, key) 18 } 19 sort.Strings(keys) 20 for _, key := range keys { 21 dst = enc.AppendKey(dst, key) 22 val := fields[key] 23 if val, ok := val.(LogObjectMarshaler); ok { 24 e := newEvent(nil, 0) 25 e.buf = e.buf[:0] 26 e.appendObject(val) 27 dst = append(dst, e.buf...) 28 putEvent(e) 29 continue 30 } 31 switch val := val.(type) { 32 case string: 33 dst = enc.AppendString(dst, val) 34 case []byte: 35 dst = enc.AppendBytes(dst, val) 36 case error: 37 switch m := ErrorMarshalFunc(val).(type) { 38 case LogObjectMarshaler: 39 e := newEvent(nil, 0) 40 e.buf = e.buf[:0] 41 e.appendObject(m) 42 dst = append(dst, e.buf...) 43 putEvent(e) 44 case error: 45 if m == nil || isNilValue(m) { 46 dst = enc.AppendNil(dst) 47 } else { 48 dst = enc.AppendString(dst, m.Error()) 49 } 50 case string: 51 dst = enc.AppendString(dst, m) 52 default: 53 dst = enc.AppendInterface(dst, m) 54 } 55 case []error: 56 dst = enc.AppendArrayStart(dst) 57 for i, err := range val { 58 switch m := ErrorMarshalFunc(err).(type) { 59 case LogObjectMarshaler: 60 e := newEvent(nil, 0) 61 e.buf = e.buf[:0] 62 e.appendObject(m) 63 dst = append(dst, e.buf...) 64 putEvent(e) 65 case error: 66 if m == nil || isNilValue(m) { 67 dst = enc.AppendNil(dst) 68 } else { 69 dst = enc.AppendString(dst, m.Error()) 70 } 71 case string: 72 dst = enc.AppendString(dst, m) 73 default: 74 dst = enc.AppendInterface(dst, m) 75 } 76 77 if i < (len(val) - 1) { 78 enc.AppendArrayDelim(dst) 79 } 80 } 81 dst = enc.AppendArrayEnd(dst) 82 case bool: 83 dst = enc.AppendBool(dst, val) 84 case int: 85 dst = enc.AppendInt(dst, val) 86 case int8: 87 dst = enc.AppendInt8(dst, val) 88 case int16: 89 dst = enc.AppendInt16(dst, val) 90 case int32: 91 dst = enc.AppendInt32(dst, val) 92 case int64: 93 dst = enc.AppendInt64(dst, val) 94 case uint: 95 dst = enc.AppendUint(dst, val) 96 case uint8: 97 dst = enc.AppendUint8(dst, val) 98 case uint16: 99 dst = enc.AppendUint16(dst, val) 100 case uint32: 101 dst = enc.AppendUint32(dst, val) 102 case uint64: 103 dst = enc.AppendUint64(dst, val) 104 case float32: 105 dst = enc.AppendFloat32(dst, val) 106 case float64: 107 dst = enc.AppendFloat64(dst, val) 108 case time.Time: 109 dst = enc.AppendTime(dst, val, TimeFieldFormat) 110 case time.Duration: 111 dst = enc.AppendDuration(dst, val, DurationFieldUnit, DurationFieldInteger) 112 case *string: 113 if val != nil { 114 dst = enc.AppendString(dst, *val) 115 } else { 116 dst = enc.AppendNil(dst) 117 } 118 case *bool: 119 if val != nil { 120 dst = enc.AppendBool(dst, *val) 121 } else { 122 dst = enc.AppendNil(dst) 123 } 124 case *int: 125 if val != nil { 126 dst = enc.AppendInt(dst, *val) 127 } else { 128 dst = enc.AppendNil(dst) 129 } 130 case *int8: 131 if val != nil { 132 dst = enc.AppendInt8(dst, *val) 133 } else { 134 dst = enc.AppendNil(dst) 135 } 136 case *int16: 137 if val != nil { 138 dst = enc.AppendInt16(dst, *val) 139 } else { 140 dst = enc.AppendNil(dst) 141 } 142 case *int32: 143 if val != nil { 144 dst = enc.AppendInt32(dst, *val) 145 } else { 146 dst = enc.AppendNil(dst) 147 } 148 case *int64: 149 if val != nil { 150 dst = enc.AppendInt64(dst, *val) 151 } else { 152 dst = enc.AppendNil(dst) 153 } 154 case *uint: 155 if val != nil { 156 dst = enc.AppendUint(dst, *val) 157 } else { 158 dst = enc.AppendNil(dst) 159 } 160 case *uint8: 161 if val != nil { 162 dst = enc.AppendUint8(dst, *val) 163 } else { 164 dst = enc.AppendNil(dst) 165 } 166 case *uint16: 167 if val != nil { 168 dst = enc.AppendUint16(dst, *val) 169 } else { 170 dst = enc.AppendNil(dst) 171 } 172 case *uint32: 173 if val != nil { 174 dst = enc.AppendUint32(dst, *val) 175 } else { 176 dst = enc.AppendNil(dst) 177 } 178 case *uint64: 179 if val != nil { 180 dst = enc.AppendUint64(dst, *val) 181 } else { 182 dst = enc.AppendNil(dst) 183 } 184 case *float32: 185 if val != nil { 186 dst = enc.AppendFloat32(dst, *val) 187 } else { 188 dst = enc.AppendNil(dst) 189 } 190 case *float64: 191 if val != nil { 192 dst = enc.AppendFloat64(dst, *val) 193 } else { 194 dst = enc.AppendNil(dst) 195 } 196 case *time.Time: 197 if val != nil { 198 dst = enc.AppendTime(dst, *val, TimeFieldFormat) 199 } else { 200 dst = enc.AppendNil(dst) 201 } 202 case *time.Duration: 203 if val != nil { 204 dst = enc.AppendDuration(dst, *val, DurationFieldUnit, DurationFieldInteger) 205 } else { 206 dst = enc.AppendNil(dst) 207 } 208 case []string: 209 dst = enc.AppendStrings(dst, val) 210 case []bool: 211 dst = enc.AppendBools(dst, val) 212 case []int: 213 dst = enc.AppendInts(dst, val) 214 case []int8: 215 dst = enc.AppendInts8(dst, val) 216 case []int16: 217 dst = enc.AppendInts16(dst, val) 218 case []int32: 219 dst = enc.AppendInts32(dst, val) 220 case []int64: 221 dst = enc.AppendInts64(dst, val) 222 case []uint: 223 dst = enc.AppendUints(dst, val) 224 // case []uint8: 225 // dst = enc.AppendUints8(dst, val) 226 case []uint16: 227 dst = enc.AppendUints16(dst, val) 228 case []uint32: 229 dst = enc.AppendUints32(dst, val) 230 case []uint64: 231 dst = enc.AppendUints64(dst, val) 232 case []float32: 233 dst = enc.AppendFloats32(dst, val) 234 case []float64: 235 dst = enc.AppendFloats64(dst, val) 236 case []time.Time: 237 dst = enc.AppendTimes(dst, val, TimeFieldFormat) 238 case []time.Duration: 239 dst = enc.AppendDurations(dst, val, DurationFieldUnit, DurationFieldInteger) 240 case nil: 241 dst = enc.AppendNil(dst) 242 case net.IP: 243 dst = enc.AppendIPAddr(dst, val) 244 case net.IPNet: 245 dst = enc.AppendIPPrefix(dst, val) 246 case net.HardwareAddr: 247 dst = enc.AppendMACAddr(dst, val) 248 default: 249 dst = enc.AppendInterface(dst, val) 250 } 251 } 252 return dst 253} 254