encoder.go 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504
  1. // Package zapx 提供了 zap 日志的对接
  2. package zapx
  3. import (
  4. "encoding/base64"
  5. "encoding/json"
  6. "fmt"
  7. "strconv"
  8. "time"
  9. "go.uber.org/zap/buffer"
  10. "go.uber.org/zap/zapcore"
  11. )
  12. var pool = buffer.NewPool()
  13. // 创建新的 encoder 对象
  14. func NewEncoder(category string, formatter CallerFormatFunc) zapcore.Encoder {
  15. return &encoder{
  16. key: "",
  17. category: category,
  18. formatCallerPath: formatter,
  19. entries: &recordEntries{
  20. stringEntries: []StringEntry{},
  21. floatEntries: []FloatEntry{},
  22. intEntries: []IntEntry{},
  23. boolEntries: []BoolEntry{},
  24. },
  25. }
  26. }
  27. // 调用方路径格式化函数类型
  28. type CallerFormatFunc = func(zapcore.EntryCaller) string
  29. // 格式化为全路径
  30. func CallerFullPath(c zapcore.EntryCaller) string { return c.FullPath() }
  31. // 格式化为相对路径
  32. func CallerTrimmedPath(c zapcore.EntryCaller) string { return c.TrimmedPath() }
  33. // 日志记录的参数
  34. type recordEntries struct {
  35. stringEntries []StringEntry
  36. floatEntries []FloatEntry
  37. intEntries []IntEntry
  38. boolEntries []BoolEntry
  39. }
  40. // 因为 json number 都是 double 型数字,最高有效位只有 53 位。所以为了避免精度丢失,需要对 int64 类型数据做以下处理:
  41. // - 能被 int32 表示的数据当作 int 数字处理。
  42. // - 在 double 类型安全范围内的数字当作 float64 数字处理。
  43. // - 无法用 double 表示的数字当作 string 处理。
  44. func addInt64(r *recordEntries, key string, value int64) {
  45. switch {
  46. case int64(int32(value)) == value:
  47. r.intEntries = append(r.intEntries, IntEntry{Key: key, Value: int32(value)})
  48. case int64(float64(value)) == value:
  49. r.floatEntries = append(r.floatEntries, FloatEntry{Key: key, Value: float64(value)})
  50. default:
  51. r.stringEntries = append(r.stringEntries, StringEntry{Key: key, Value: strconv.FormatInt(value, 10)})
  52. }
  53. }
  54. // uint 情况同上,转换规则为:
  55. // - 能被 int32 表示的数据当作 int 数字处理。
  56. // - 在 double 类型安全范围内的数字当作 float64 数字处理。
  57. // - 无法用 double 表示的数字当作 string 处理。
  58. func addUint64(r *recordEntries, key string, value uint64) {
  59. switch {
  60. case uint64(int32(value)) == value:
  61. r.intEntries = append(r.intEntries, IntEntry{Key: key, Value: int32(value)})
  62. case uint64(float64(value)) == value:
  63. r.floatEntries = append(r.floatEntries, FloatEntry{Key: key, Value: float64(value)})
  64. default:
  65. r.stringEntries = append(r.stringEntries, StringEntry{Key: key, Value: strconv.FormatUint(value, 10)})
  66. }
  67. }
  68. type encoder struct {
  69. key string
  70. category string
  71. formatCallerPath func(zapcore.EntryCaller) string
  72. entries *recordEntries
  73. }
  74. func (e *encoder) EncodeEntry(entry zapcore.Entry, fields []zapcore.Field) (*buffer.Buffer, error) {
  75. var caller string
  76. if entry.Caller != (zapcore.EntryCaller{}) {
  77. caller = e.formatCallerPath(entry.Caller)
  78. }
  79. r := LogRecord{
  80. EventTime: entry.Time,
  81. Category: e.category,
  82. Level: entry.Level.String(),
  83. Caller: caller,
  84. Message: entry.Message,
  85. StringEntries: e.entries.stringEntries,
  86. FloatEntries: e.entries.floatEntries,
  87. IntEntries: e.entries.intEntries,
  88. BoolEntries: e.entries.boolEntries,
  89. }
  90. enc := &objectEncoder{
  91. key: e.key,
  92. entries: &recordEntries{
  93. stringEntries: []StringEntry{},
  94. floatEntries: []FloatEntry{},
  95. intEntries: []IntEntry{},
  96. boolEntries: []BoolEntry{},
  97. },
  98. }
  99. if entry.LoggerName != "" {
  100. enc.AddString("loggerName", entry.LoggerName)
  101. }
  102. for _, field := range fields {
  103. field.AddTo(enc)
  104. }
  105. if entry.Stack != "" {
  106. enc.AddString("stack", entry.Stack)
  107. }
  108. r.StringEntries = append(r.StringEntries, enc.entries.stringEntries...)
  109. r.FloatEntries = append(r.FloatEntries, enc.entries.floatEntries...)
  110. r.IntEntries = append(r.IntEntries, enc.entries.intEntries...)
  111. r.BoolEntries = append(r.BoolEntries, enc.entries.boolEntries...)
  112. bs, err := json.Marshal(r)
  113. if err != nil {
  114. return nil, err
  115. }
  116. buf := pool.Get()
  117. _, err = buf.Write(bs)
  118. if err != nil {
  119. return nil, err
  120. }
  121. return buf, nil
  122. }
  123. func (e *encoder) AddArray(key string, marshaler zapcore.ArrayMarshaler) error {
  124. return marshaler.MarshalLogArray(&sliceEncoder{key: addKey(e.key, key)})
  125. }
  126. func (e *encoder) AddObject(key string, marshaler zapcore.ObjectMarshaler) error {
  127. return marshaler.MarshalLogObject(&objectEncoder{key: addKey(e.key, key)})
  128. }
  129. // 不支持纯二进制类型,用 Base64 编码一下。
  130. func (e *encoder) AddBinary(key string, value []byte) {
  131. v := base64.StdEncoding.EncodeToString(value)
  132. e.entries.stringEntries = append(e.entries.stringEntries, StringEntry{Key: addKey(e.key, key), Value: v})
  133. }
  134. func (e *encoder) AddByteString(key string, value []byte) {
  135. e.entries.stringEntries = append(e.entries.stringEntries, StringEntry{Key: addKey(e.key, key), Value: string(value)})
  136. }
  137. func (e *encoder) AddBool(key string, value bool) {
  138. e.entries.boolEntries = append(e.entries.boolEntries, BoolEntry{Key: addKey(e.key, key), Value: value})
  139. }
  140. func (e *encoder) AddComplex128(key string, value complex128) {
  141. v := strconv.FormatComplex(value, 'f', -1, 128)
  142. e.entries.stringEntries = append(e.entries.stringEntries, StringEntry{Key: addKey(e.key, key), Value: v})
  143. }
  144. func (e *encoder) AddComplex64(key string, value complex64) {
  145. v := strconv.FormatComplex(complex128(value), 'f', -1, 64)
  146. e.entries.stringEntries = append(e.entries.stringEntries, StringEntry{Key: addKey(e.key, key), Value: v})
  147. }
  148. func (e *encoder) AddDuration(key string, value time.Duration) {
  149. e.entries.stringEntries = append(e.entries.stringEntries, StringEntry{Key: addKey(e.key, key), Value: value.String()})
  150. }
  151. func (e *encoder) AddFloat64(key string, value float64) {
  152. e.entries.floatEntries = append(e.entries.floatEntries, FloatEntry{Key: addKey(e.key, key), Value: value})
  153. }
  154. func (e *encoder) AddFloat32(key string, value float32) {
  155. e.entries.floatEntries = append(e.entries.floatEntries, FloatEntry{Key: addKey(e.key, key), Value: float64(value)})
  156. }
  157. func (e *encoder) AddInt(key string, value int) {
  158. addInt64(e.entries, addKey(e.key, key), int64(value))
  159. }
  160. func (e *encoder) AddInt64(key string, value int64) {
  161. addInt64(e.entries, addKey(e.key, key), value)
  162. }
  163. func (e *encoder) AddInt32(key string, value int32) {
  164. e.entries.intEntries = append(e.entries.intEntries, IntEntry{Key: addKey(e.key, key), Value: value})
  165. }
  166. func (e *encoder) AddInt16(key string, value int16) {
  167. e.entries.intEntries = append(e.entries.intEntries, IntEntry{Key: addKey(e.key, key), Value: int32(value)})
  168. }
  169. func (e *encoder) AddInt8(key string, value int8) {
  170. e.entries.intEntries = append(e.entries.intEntries, IntEntry{Key: addKey(e.key, key), Value: int32(value)})
  171. }
  172. func (e *encoder) AddString(key string, value string) {
  173. e.entries.stringEntries = append(e.entries.stringEntries, StringEntry{Key: addKey(e.key, key), Value: value})
  174. }
  175. func (e *encoder) AddTime(key string, value time.Time) {
  176. e.entries.stringEntries = append(e.entries.stringEntries, StringEntry{Key: addKey(e.key, key), Value: value.Format(time.RFC3339Nano)})
  177. }
  178. func (e *encoder) AddUint(key string, value uint) {
  179. addUint64(e.entries, addKey(e.key, key), uint64(value))
  180. }
  181. func (e *encoder) AddUint64(key string, value uint64) {
  182. addUint64(e.entries, addKey(e.key, key), value)
  183. }
  184. func (e *encoder) AddUint32(key string, value uint32) {
  185. addUint64(e.entries, addKey(e.key, key), uint64(value))
  186. }
  187. func (e *encoder) AddUint16(key string, value uint16) {
  188. e.entries.intEntries = append(e.entries.intEntries, IntEntry{Key: addKey(e.key, key), Value: int32(value)})
  189. }
  190. func (e *encoder) AddUint8(key string, value uint8) {
  191. e.entries.intEntries = append(e.entries.intEntries, IntEntry{Key: addKey(e.key, key), Value: int32(value)})
  192. }
  193. func (e *encoder) AddUintptr(key string, value uintptr) {
  194. addUint64(e.entries, addKey(e.key, key), uint64(value))
  195. }
  196. func (e *encoder) AddReflected(key string, value any) error {
  197. v := fmt.Sprint(value)
  198. e.entries.stringEntries = append(e.entries.stringEntries, StringEntry{Key: addKey(e.key, key), Value: v})
  199. return nil
  200. }
  201. func (e *encoder) OpenNamespace(key string) {
  202. e.key = addKey(e.key, key)
  203. }
  204. func (e *encoder) Clone() zapcore.Encoder {
  205. return &encoder{
  206. key: e.key,
  207. category: e.category,
  208. formatCallerPath: e.formatCallerPath,
  209. entries: &recordEntries{
  210. stringEntries: e.entries.stringEntries,
  211. floatEntries: e.entries.floatEntries,
  212. intEntries: e.entries.intEntries,
  213. boolEntries: e.entries.boolEntries,
  214. },
  215. }
  216. }
  217. func addKey(parent, child string) string {
  218. if parent == "" {
  219. return child
  220. }
  221. return parent + "." + child
  222. }
  223. func addIndex(parent string, index int) string {
  224. return fmt.Sprintf("%s[%d]", parent, index)
  225. }
  226. type objectEncoder struct {
  227. key string
  228. entries *recordEntries
  229. }
  230. func (e *objectEncoder) AddArray(key string, marshaler zapcore.ArrayMarshaler) error {
  231. return marshaler.MarshalLogArray(&sliceEncoder{key: addKey(e.key, key), entries: e.entries})
  232. }
  233. func (e *objectEncoder) AddObject(key string, marshaler zapcore.ObjectMarshaler) error {
  234. return marshaler.MarshalLogObject(&objectEncoder{key: addKey(e.key, key), entries: e.entries})
  235. }
  236. // 不支持纯二进制类型,用 Base64 编码一下。
  237. func (e *objectEncoder) AddBinary(key string, value []byte) {
  238. v := base64.StdEncoding.EncodeToString(value)
  239. e.entries.stringEntries = append(e.entries.stringEntries, StringEntry{Key: addKey(e.key, key), Value: v})
  240. }
  241. func (e *objectEncoder) AddByteString(key string, value []byte) {
  242. e.entries.stringEntries = append(e.entries.stringEntries, StringEntry{Key: addKey(e.key, key), Value: string(value)})
  243. }
  244. func (e *objectEncoder) AddBool(key string, value bool) {
  245. e.entries.boolEntries = append(e.entries.boolEntries, BoolEntry{Key: addKey(e.key, key), Value: value})
  246. }
  247. func (e *objectEncoder) AddComplex128(key string, value complex128) {
  248. v := strconv.FormatComplex(value, 'f', -1, 128)
  249. e.entries.stringEntries = append(e.entries.stringEntries, StringEntry{Key: addKey(e.key, key), Value: v})
  250. }
  251. func (e *objectEncoder) AddComplex64(key string, value complex64) {
  252. v := strconv.FormatComplex(complex128(value), 'f', -1, 64)
  253. e.entries.stringEntries = append(e.entries.stringEntries, StringEntry{Key: addKey(e.key, key), Value: v})
  254. }
  255. func (e *objectEncoder) AddDuration(key string, value time.Duration) {
  256. e.entries.stringEntries = append(e.entries.stringEntries, StringEntry{Key: addKey(e.key, key), Value: value.String()})
  257. }
  258. func (e *objectEncoder) AddFloat64(key string, value float64) {
  259. e.entries.floatEntries = append(e.entries.floatEntries, FloatEntry{Key: addKey(e.key, key), Value: value})
  260. }
  261. func (e *objectEncoder) AddFloat32(key string, value float32) {
  262. e.entries.floatEntries = append(e.entries.floatEntries, FloatEntry{Key: addKey(e.key, key), Value: float64(value)})
  263. }
  264. func (e *objectEncoder) AddInt(key string, value int) {
  265. addInt64(e.entries, addKey(e.key, key), int64(value))
  266. }
  267. func (e *objectEncoder) AddInt64(key string, value int64) {
  268. addInt64(e.entries, addKey(e.key, key), value)
  269. }
  270. func (e *objectEncoder) AddInt32(key string, value int32) {
  271. e.entries.intEntries = append(e.entries.intEntries, IntEntry{Key: addKey(e.key, key), Value: value})
  272. }
  273. func (e *objectEncoder) AddInt16(key string, value int16) {
  274. e.entries.intEntries = append(e.entries.intEntries, IntEntry{Key: addKey(e.key, key), Value: int32(value)})
  275. }
  276. func (e *objectEncoder) AddInt8(key string, value int8) {
  277. e.entries.intEntries = append(e.entries.intEntries, IntEntry{Key: addKey(e.key, key), Value: int32(value)})
  278. }
  279. func (e *objectEncoder) AddString(key string, value string) {
  280. e.entries.stringEntries = append(e.entries.stringEntries, StringEntry{Key: addKey(e.key, key), Value: value})
  281. }
  282. func (e *objectEncoder) AddTime(key string, value time.Time) {
  283. e.entries.stringEntries = append(e.entries.stringEntries, StringEntry{Key: addKey(e.key, key), Value: value.Format(time.RFC3339Nano)})
  284. }
  285. func (e *objectEncoder) AddUint(key string, value uint) {
  286. addUint64(e.entries, addKey(e.key, key), uint64(value))
  287. }
  288. func (e *objectEncoder) AddUint64(key string, value uint64) {
  289. addUint64(e.entries, addKey(e.key, key), value)
  290. }
  291. func (e *objectEncoder) AddUint32(key string, value uint32) {
  292. addUint64(e.entries, addKey(e.key, key), uint64(value))
  293. }
  294. func (e *objectEncoder) AddUint16(key string, value uint16) {
  295. e.entries.intEntries = append(e.entries.intEntries, IntEntry{Key: addKey(e.key, key), Value: int32(value)})
  296. }
  297. func (e *objectEncoder) AddUint8(key string, value uint8) {
  298. e.entries.intEntries = append(e.entries.intEntries, IntEntry{Key: addKey(e.key, key), Value: int32(value)})
  299. }
  300. func (e *objectEncoder) AddUintptr(key string, value uintptr) {
  301. addUint64(e.entries, addKey(e.key, key), uint64(value))
  302. }
  303. func (e *objectEncoder) AddReflected(key string, value any) error {
  304. v := fmt.Sprint(value)
  305. e.entries.stringEntries = append(e.entries.stringEntries, StringEntry{Key: addKey(e.key, key), Value: v})
  306. return nil
  307. }
  308. func (e *objectEncoder) OpenNamespace(key string) {
  309. e.key = addKey(e.key, key)
  310. }
  311. type sliceEncoder struct {
  312. key string
  313. index int
  314. entries *recordEntries
  315. }
  316. func (e *sliceEncoder) AppendBool(value bool) {
  317. e.entries.boolEntries = append(e.entries.boolEntries, BoolEntry{Key: addIndex(e.key, e.index), Value: value})
  318. e.index++
  319. }
  320. func (e *sliceEncoder) AppendByteString(value []byte) {
  321. e.entries.stringEntries = append(e.entries.stringEntries, StringEntry{Key: addIndex(e.key, e.index), Value: string(value)})
  322. e.index++
  323. }
  324. func (e *sliceEncoder) AppendComplex128(value complex128) {
  325. v := strconv.FormatComplex(value, 'f', -1, 128)
  326. e.entries.stringEntries = append(e.entries.stringEntries, StringEntry{Key: addIndex(e.key, e.index), Value: v})
  327. e.index++
  328. }
  329. func (e *sliceEncoder) AppendComplex64(value complex64) {
  330. v := strconv.FormatComplex(complex128(value), 'f', -1, 64)
  331. e.entries.stringEntries = append(e.entries.stringEntries, StringEntry{Key: addIndex(e.key, e.index), Value: v})
  332. e.index++
  333. }
  334. func (e *sliceEncoder) AppendFloat64(value float64) {
  335. e.entries.floatEntries = append(e.entries.floatEntries, FloatEntry{Key: addIndex(e.key, e.index), Value: value})
  336. e.index++
  337. }
  338. func (e *sliceEncoder) AppendFloat32(value float32) {
  339. e.entries.floatEntries = append(e.entries.floatEntries, FloatEntry{Key: addIndex(e.key, e.index), Value: float64(value)})
  340. e.index++
  341. }
  342. func (e *sliceEncoder) AppendInt(value int) {
  343. addInt64(e.entries, addIndex(e.key, e.index), int64(value))
  344. e.index++
  345. }
  346. func (e *sliceEncoder) AppendInt64(value int64) {
  347. addInt64(e.entries, addIndex(e.key, e.index), value)
  348. e.index++
  349. }
  350. func (e *sliceEncoder) AppendInt32(value int32) {
  351. e.entries.intEntries = append(e.entries.intEntries, IntEntry{Key: addIndex(e.key, e.index), Value: value})
  352. e.index++
  353. }
  354. func (e *sliceEncoder) AppendInt16(value int16) {
  355. e.entries.intEntries = append(e.entries.intEntries, IntEntry{Key: addIndex(e.key, e.index), Value: int32(value)})
  356. e.index++
  357. }
  358. func (e *sliceEncoder) AppendInt8(value int8) {
  359. e.entries.intEntries = append(e.entries.intEntries, IntEntry{Key: addIndex(e.key, e.index), Value: int32(value)})
  360. e.index++
  361. }
  362. func (e *sliceEncoder) AppendString(value string) {
  363. e.entries.stringEntries = append(e.entries.stringEntries, StringEntry{Key: addIndex(e.key, e.index), Value: value})
  364. e.index++
  365. }
  366. func (e *sliceEncoder) AppendUint(value uint) {
  367. addUint64(e.entries, addIndex(e.key, e.index), uint64(value))
  368. e.index++
  369. }
  370. func (e *sliceEncoder) AppendUint64(value uint64) {
  371. addUint64(e.entries, addIndex(e.key, e.index), value)
  372. e.index++
  373. }
  374. func (e *sliceEncoder) AppendUint32(value uint32) {
  375. addUint64(e.entries, addIndex(e.key, e.index), uint64(value))
  376. e.index++
  377. }
  378. func (e *sliceEncoder) AppendUint16(value uint16) {
  379. e.entries.intEntries = append(e.entries.intEntries, IntEntry{Key: addIndex(e.key, e.index), Value: int32(value)})
  380. e.index++
  381. }
  382. func (e *sliceEncoder) AppendUint8(value uint8) {
  383. e.entries.intEntries = append(e.entries.intEntries, IntEntry{Key: addIndex(e.key, e.index), Value: int32(value)})
  384. e.index++
  385. }
  386. func (e *sliceEncoder) AppendUintptr(value uintptr) {
  387. addUint64(e.entries, addIndex(e.key, e.index), uint64(value))
  388. e.index++
  389. }
  390. func (e *sliceEncoder) AppendDuration(value time.Duration) {
  391. e.entries.stringEntries = append(e.entries.stringEntries, StringEntry{Key: addIndex(e.key, e.index), Value: value.String()})
  392. e.index++
  393. }
  394. func (e *sliceEncoder) AppendTime(value time.Time) {
  395. e.entries.stringEntries = append(e.entries.stringEntries, StringEntry{Key: addIndex(e.key, e.index), Value: value.Format(time.RFC3339Nano)})
  396. e.index++
  397. }
  398. func (e *sliceEncoder) AppendArray(value zapcore.ArrayMarshaler) error {
  399. err := value.MarshalLogArray(&sliceEncoder{key: addIndex(e.key, e.index), entries: e.entries})
  400. e.index++
  401. return err
  402. }
  403. func (e *sliceEncoder) AppendObject(value zapcore.ObjectMarshaler) error {
  404. err := value.MarshalLogObject(&objectEncoder{key: addIndex(e.key, e.index), entries: e.entries})
  405. e.index++
  406. return err
  407. }
  408. func (e *sliceEncoder) AppendReflected(value any) error {
  409. v := fmt.Sprint(value)
  410. e.entries.stringEntries = append(e.entries.stringEntries, StringEntry{Key: addIndex(e.key, e.index), Value: v})
  411. e.index++
  412. return nil
  413. }