fields.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458
  1. package log
  2. import (
  3. "context"
  4. "fmt"
  5. "time"
  6. )
  7. const (
  8. // DefaultErrorFieldName is the default field name used for errors
  9. DefaultErrorFieldName = "error"
  10. )
  11. // FieldType is a type of data Field can represent
  12. type FieldType int
  13. const (
  14. // FieldTypeNil is for a pure nil
  15. FieldTypeNil FieldType = iota
  16. // FieldTypeString is for a string
  17. FieldTypeString
  18. // FieldTypeBinary is for a binary array
  19. FieldTypeBinary
  20. // FieldTypeBoolean is for boolean
  21. FieldTypeBoolean
  22. // FieldTypeSigned is for signed integers
  23. FieldTypeSigned
  24. // FieldTypeUnsigned is for unsigned integers
  25. FieldTypeUnsigned
  26. // FieldTypeFloat is for float
  27. FieldTypeFloat
  28. // FieldTypeTime is for time.Time
  29. FieldTypeTime
  30. // FieldTypeDuration is for time.Duration
  31. FieldTypeDuration
  32. // FieldTypeError is for an error
  33. FieldTypeError
  34. // FieldTypeArray is for an array of any type
  35. FieldTypeArray
  36. // FieldTypeAny is for any type
  37. FieldTypeAny
  38. // FieldTypeReflect is for unknown types
  39. FieldTypeReflect
  40. // FieldTypeByteString is for a bytes that can be represented as UTF-8 string
  41. FieldTypeByteString
  42. // FieldTypeContext wraps context for lazy context fields evaluation if possible
  43. FieldTypeContext
  44. )
  45. // Field stores one structured logging field
  46. type Field struct {
  47. key string
  48. ftype FieldType
  49. string string
  50. signed int64
  51. unsigned uint64
  52. float float64
  53. iface interface{}
  54. }
  55. // Key returns field key
  56. func (f Field) Key() string {
  57. return f.key
  58. }
  59. // Type returns field type
  60. func (f Field) Type() FieldType {
  61. return f.ftype
  62. }
  63. // String returns field string
  64. func (f Field) String() string {
  65. return f.string
  66. }
  67. // Binary constructs field of []byte
  68. func (f Field) Binary() []byte {
  69. if f.iface == nil {
  70. return nil
  71. }
  72. return f.iface.([]byte)
  73. }
  74. // Bool returns field bool
  75. func (f Field) Bool() bool {
  76. return f.Signed() != 0
  77. }
  78. // Signed returns field int64
  79. func (f Field) Signed() int64 {
  80. return f.signed
  81. }
  82. // Unsigned returns field uint64
  83. func (f Field) Unsigned() uint64 {
  84. return f.unsigned
  85. }
  86. // Float returns field float64
  87. func (f Field) Float() float64 {
  88. return f.float
  89. }
  90. // Time returns field time.Time
  91. func (f Field) Time() time.Time {
  92. return time.Unix(0, f.signed)
  93. }
  94. // Duration returns field time.Duration
  95. func (f Field) Duration() time.Duration {
  96. return time.Nanosecond * time.Duration(f.signed)
  97. }
  98. // Error constructs field of error type
  99. func (f Field) Error() error {
  100. if f.iface == nil {
  101. return nil
  102. }
  103. return f.iface.(error)
  104. }
  105. // Interface returns field interface
  106. func (f Field) Interface() interface{} {
  107. return f.iface
  108. }
  109. // Any returns contained data as interface{}
  110. // nolint: gocyclo
  111. func (f Field) Any() interface{} {
  112. switch f.Type() {
  113. case FieldTypeNil:
  114. return nil
  115. case FieldTypeString:
  116. return f.String()
  117. case FieldTypeBinary:
  118. return f.Interface()
  119. case FieldTypeBoolean:
  120. return f.Bool()
  121. case FieldTypeSigned:
  122. return f.Signed()
  123. case FieldTypeUnsigned:
  124. return f.Unsigned()
  125. case FieldTypeFloat:
  126. return f.Float()
  127. case FieldTypeTime:
  128. return f.Time()
  129. case FieldTypeDuration:
  130. return f.Duration()
  131. case FieldTypeError:
  132. return f.Error()
  133. case FieldTypeArray:
  134. return f.Interface()
  135. case FieldTypeAny:
  136. return f.Interface()
  137. case FieldTypeReflect:
  138. return f.Interface()
  139. case FieldTypeByteString:
  140. return f.Interface()
  141. case FieldTypeContext:
  142. return f.Interface()
  143. default:
  144. // For when new field type is not added to this func
  145. panic(fmt.Sprintf("unknown field type: %d", f.Type()))
  146. }
  147. }
  148. // Nil constructs field of nil type
  149. func Nil(key string) Field {
  150. return Field{key: key, ftype: FieldTypeNil}
  151. }
  152. // String constructs field of string type
  153. func String(key, value string) Field {
  154. return Field{key: key, ftype: FieldTypeString, string: value}
  155. }
  156. // Sprintf constructs field of string type with formatting
  157. func Sprintf(key, format string, args ...interface{}) Field {
  158. return Field{key: key, ftype: FieldTypeString, string: fmt.Sprintf(format, args...)}
  159. }
  160. // Strings constructs Field from []string
  161. func Strings(key string, value []string) Field {
  162. return Array(key, value)
  163. }
  164. // Binary constructs field of []byte type
  165. func Binary(key string, value []byte) Field {
  166. return Field{key: key, ftype: FieldTypeBinary, iface: value}
  167. }
  168. // Bool constructs field of bool type
  169. func Bool(key string, value bool) Field {
  170. field := Field{key: key, ftype: FieldTypeBoolean}
  171. if value {
  172. field.signed = 1
  173. } else {
  174. field.signed = 0
  175. }
  176. return field
  177. }
  178. // Bools constructs Field from []bool
  179. func Bools(key string, value []bool) Field {
  180. return Array(key, value)
  181. }
  182. // Int constructs Field from int
  183. func Int(key string, value int) Field {
  184. return Int64(key, int64(value))
  185. }
  186. // Ints constructs Field from []int
  187. func Ints(key string, value []int) Field {
  188. return Array(key, value)
  189. }
  190. // Int8 constructs Field from int8
  191. func Int8(key string, value int8) Field {
  192. return Int64(key, int64(value))
  193. }
  194. // Int8s constructs Field from []int8
  195. func Int8s(key string, value []int8) Field {
  196. return Array(key, value)
  197. }
  198. // Int16 constructs Field from int16
  199. func Int16(key string, value int16) Field {
  200. return Int64(key, int64(value))
  201. }
  202. // Int16s constructs Field from []int16
  203. func Int16s(key string, value []int16) Field {
  204. return Array(key, value)
  205. }
  206. // Int32 constructs Field from int32
  207. func Int32(key string, value int32) Field {
  208. return Int64(key, int64(value))
  209. }
  210. // Int32s constructs Field from []int32
  211. func Int32s(key string, value []int32) Field {
  212. return Array(key, value)
  213. }
  214. // Int64 constructs Field from int64
  215. func Int64(key string, value int64) Field {
  216. return Field{key: key, ftype: FieldTypeSigned, signed: value}
  217. }
  218. // Int64s constructs Field from []int64
  219. func Int64s(key string, value []int64) Field {
  220. return Array(key, value)
  221. }
  222. // UInt constructs Field from uint
  223. func UInt(key string, value uint) Field {
  224. return UInt64(key, uint64(value))
  225. }
  226. // UInts constructs Field from []uint
  227. func UInts(key string, value []uint) Field {
  228. return Array(key, value)
  229. }
  230. // UInt8 constructs Field from uint8
  231. func UInt8(key string, value uint8) Field {
  232. return UInt64(key, uint64(value))
  233. }
  234. // UInt8s constructs Field from []uint8
  235. func UInt8s(key string, value []uint8) Field {
  236. return Array(key, value)
  237. }
  238. // UInt16 constructs Field from uint16
  239. func UInt16(key string, value uint16) Field {
  240. return UInt64(key, uint64(value))
  241. }
  242. // UInt16s constructs Field from []uint16
  243. func UInt16s(key string, value []uint16) Field {
  244. return Array(key, value)
  245. }
  246. // UInt32 constructs Field from uint32
  247. func UInt32(key string, value uint32) Field {
  248. return UInt64(key, uint64(value))
  249. }
  250. // UInt32s constructs Field from []uint32
  251. func UInt32s(key string, value []uint32) Field {
  252. return Array(key, value)
  253. }
  254. // UInt64 constructs Field from uint64
  255. func UInt64(key string, value uint64) Field {
  256. return Field{key: key, ftype: FieldTypeUnsigned, unsigned: value}
  257. }
  258. // UInt64s constructs Field from []uint64
  259. func UInt64s(key string, value []uint64) Field {
  260. return Array(key, value)
  261. }
  262. // Float32 constructs Field from float32
  263. func Float32(key string, value float32) Field {
  264. return Float64(key, float64(value))
  265. }
  266. // Float32s constructs Field from []float32
  267. func Float32s(key string, value []float32) Field {
  268. return Array(key, value)
  269. }
  270. // Float64 constructs Field from float64
  271. func Float64(key string, value float64) Field {
  272. return Field{key: key, ftype: FieldTypeFloat, float: value}
  273. }
  274. // Float64s constructs Field from []float64
  275. func Float64s(key string, value []float64) Field {
  276. return Array(key, value)
  277. }
  278. // Time constructs field of time.Time type
  279. func Time(key string, value time.Time) Field {
  280. return Field{key: key, ftype: FieldTypeTime, signed: value.UnixNano()}
  281. }
  282. // Times constructs Field from []time.Time
  283. func Times(key string, value []time.Time) Field {
  284. return Array(key, value)
  285. }
  286. // Duration constructs field of time.Duration type
  287. func Duration(key string, value time.Duration) Field {
  288. return Field{key: key, ftype: FieldTypeDuration, signed: value.Nanoseconds()}
  289. }
  290. // Durations constructs Field from []time.Duration
  291. func Durations(key string, value []time.Duration) Field {
  292. return Array(key, value)
  293. }
  294. // NamedError constructs field of error type
  295. func NamedError(key string, value error) Field {
  296. return Field{key: key, ftype: FieldTypeError, iface: value}
  297. }
  298. // Error constructs field of error type with default field name
  299. func Error(value error) Field {
  300. return NamedError(DefaultErrorFieldName, value)
  301. }
  302. // Errors constructs Field from []error
  303. func Errors(key string, value []error) Field {
  304. return Array(key, value)
  305. }
  306. // Array constructs field of array type
  307. func Array(key string, value interface{}) Field {
  308. return Field{key: key, ftype: FieldTypeArray, iface: value}
  309. }
  310. // Reflect constructs field of unknown type
  311. func Reflect(key string, value interface{}) Field {
  312. return Field{key: key, ftype: FieldTypeReflect, iface: value}
  313. }
  314. // ByteString constructs field of bytes that could represent UTF-8 string
  315. func ByteString(key string, value []byte) Field {
  316. return Field{key: key, ftype: FieldTypeByteString, iface: value}
  317. }
  318. // Context constructs field for lazy context fields evaluation if possible
  319. func Context(ctx context.Context) Field {
  320. return Field{ftype: FieldTypeContext, iface: ctx}
  321. }
  322. // Any tries to deduce interface{} underlying type and constructs Field from it.
  323. // Use of this function is ok only for the sole purpose of not repeating its entire code
  324. // or parts of it in user's code (when you need to log interface{} types with unknown content).
  325. // Otherwise please use specialized functions.
  326. // nolint: gocyclo
  327. func Any(key string, value interface{}) Field {
  328. switch val := value.(type) {
  329. case bool:
  330. return Bool(key, val)
  331. case float64:
  332. return Float64(key, val)
  333. case float32:
  334. return Float32(key, val)
  335. case int:
  336. return Int(key, val)
  337. case []int:
  338. return Ints(key, val)
  339. case int64:
  340. return Int64(key, val)
  341. case []int64:
  342. return Int64s(key, val)
  343. case int32:
  344. return Int32(key, val)
  345. case []int32:
  346. return Int32s(key, val)
  347. case int16:
  348. return Int16(key, val)
  349. case []int16:
  350. return Int16s(key, val)
  351. case int8:
  352. return Int8(key, val)
  353. case []int8:
  354. return Int8s(key, val)
  355. case string:
  356. return String(key, val)
  357. case []string:
  358. return Strings(key, val)
  359. case uint:
  360. return UInt(key, val)
  361. case []uint:
  362. return UInts(key, val)
  363. case uint64:
  364. return UInt64(key, val)
  365. case []uint64:
  366. return UInt64s(key, val)
  367. case uint32:
  368. return UInt32(key, val)
  369. case []uint32:
  370. return UInt32s(key, val)
  371. case uint16:
  372. return UInt16(key, val)
  373. case []uint16:
  374. return UInt16s(key, val)
  375. case uint8:
  376. return UInt8(key, val)
  377. case []byte:
  378. return Binary(key, val)
  379. case time.Time:
  380. return Time(key, val)
  381. case []time.Time:
  382. return Times(key, val)
  383. case time.Duration:
  384. return Duration(key, val)
  385. case []time.Duration:
  386. return Durations(key, val)
  387. case error:
  388. return NamedError(key, val)
  389. case []error:
  390. return Errors(key, val)
  391. case context.Context:
  392. return Context(val)
  393. default:
  394. return Field{key: key, ftype: FieldTypeAny, iface: value}
  395. }
  396. }