概览

Entry - 图1
Core 通过 With 方法,生成 CheckedEntry,CheckedEntry 记录自己归属的 Core 实例。写入日志时,真正执行的还是记录的 Core 实例的 Write(Entry, []Field) 方法。

实现

生成方式

使用 sync.Pool 有效减少对象分配次数

  1. var (
  2. _cePool = sync.Pool{New: func() interface{} {
  3. // Pre-allocate some space for cores.
  4. return &CheckedEntry{
  5. cores: make([]Core, 4),
  6. }
  7. }}
  8. )

获取方法

  1. func getCheckedEntry() *CheckedEntry {
  2. ce := _cePool.Get().(*CheckedEntry)
  3. ce.reset()
  4. return ce
  5. }

日志记录

记录需要打印本条 Entry 的 Core 实例

  1. func (ce *CheckedEntry) AddCore(ent Entry, core Core) *CheckedEntry {
  2. if ce == nil {
  3. ce = getCheckedEntry()
  4. ce.Entry = ent
  5. }
  6. ce.cores = append(ce.cores, core)
  7. return ce
  8. }

记录日志

  1. func (ce *CheckedEntry) Write(fields ...Field) {
  2. if ce == nil {
  3. return
  4. }
  5. if ce.dirty {
  6. if ce.ErrorOutput != nil {
  7. // 检查重复使用 CheckedEntry 的情况
  8. fmt.Fprintf(ce.ErrorOutput, "%v Unsafe CheckedEntry re-use near Entry %+v.\n", time.Now(), ce.Entry)
  9. ce.ErrorOutput.Sync()
  10. }
  11. return
  12. }
  13. ce.dirty = true
  14. var err error
  15. for i := range ce.cores { // 记录日志
  16. err = multierr.Append(err, ce.cores[i].Write(ce.Entry, fields))
  17. }
  18. if ce.ErrorOutput != nil { // 记录日志错误
  19. if err != nil {
  20. fmt.Fprintf(ce.ErrorOutput, "%v write error: %v\n", time.Now(), err)
  21. ce.ErrorOutput.Sync()
  22. }
  23. }
  24. should, msg := ce.should, ce.Message
  25. putCheckedEntry(ce) // 将 CheckedEntry 放回 Pool
  26. switch should {
  27. case WriteThenPanic:
  28. panic(msg)
  29. case WriteThenFatal:
  30. exit.Exit()
  31. }
  32. }