sequence

This paper mainly studies the send of Zerolog

The instance

func sendDemo() {
	zerolog.TimeFieldFormat = zerolog.TimeFormatUnix

	log.Info().
		Str("Name", "Tom").
		Send()

	log.Info().
		Str("Name", "Tom").
		Msg("hello world")
}
Copy the code

Use Send or Msg to Send logs

The output

{"level":"info","Name":"Tom","time":1609509525}
{"level":"info","Name":"Tom","time":1609509525,"message":"hello world"}
Copy the code

Send

github.com/rs/[email protected]/event.go

// Send is equivalent to calling Msg("").
//
// NOTICE: once this method is called, the *Event should be disposed.
func (e *Event) Send() {
	if e == nil {
		return
	}
	e.msg("")
}
Copy the code

The Send method is equivalent to Msg(“”)

msg

github.com/rs/[email protected]/event.go

func (e *Event) msg(msg string) { for _, hook := range e.ch { hook.Run(e, e.level, msg) } if msg ! = "" { e.buf = enc.AppendString(enc.AppendKey(e.buf, MessageFieldName), msg) } if e.done ! = nil { defer e.done(msg) } if err := e.write(); err ! = nil { if ErrorHandler ! = nil { ErrorHandler(err) } else { fmt.Fprintf(os.Stderr, "zerolog: could not write event: %v\n", err) } } }Copy the code

The MSG method executes hook first, then for the added message field with MSG, defer registers the callback if done is not nil, and then executes e.rite ()

write

github.com/rs/[email protected]/event.go

func (e *Event) write() (err error) { if e == nil { return nil } if e.level ! = Disabled { e.buf = enc.AppendEndMarker(e.buf) e.buf = enc.AppendLineBreak(e.buf) if e.w ! = nil { _, err = e.w.WriteLevel(e.level, e.buf) } } putEvent(e) return }Copy the code

Write If the level is not Disabled, endMarker and lineBreaker will be added. If e.w is not nil, execute e.W. riteLevel(e.level, e.bof) to output; PutEvent return event is then executed

putEvent

github.com/rs/[email protected]/event.go

func putEvent(e *Event) {
	// Proper usage of a sync.Pool requires each entry to have approximately
	// the same memory cost. To obtain this property when the stored type
	// contains a variably-sized buffer, we add a hard limit on the maximum buffer
	// to place back in the pool.
	//
	// See https://golang.org/issue/23199
	const maxSize = 1 << 16 // 64KiB
	if cap(e.buf) > maxSize {
		return
	}
	eventPool.Put(e)
}
Copy the code

PutEvent checks whether the size of e.bouf exceeds maxSize. If the size exceeds maxSize, the event is returned. Otherwise, eventPool.put (e) is executed to return the event to the eventPool

Info

github.com/rs/[email protected]/log.go

// Info starts a new message with info level.
//
// You must call Msg on the returned event in order to send the event.
func (l *Logger) Info() *Event {
	return l.newEvent(InfoLevel, nil)
}
Copy the code

Info method execution l.newevent (InfoLevel, nil)

newEvent

github.com/rs/[email protected]/log.go

func (l *Logger) newEvent(level Level, done func(string)) *Event { enabled := l.should(level) if ! enabled { return nil } e := newEvent(l.w, level) e.done = done e.ch = l.hooks if level ! = NoLevel { e.Str(LevelFieldName, LevelFieldMarshalFunc(level)) } if l.context ! = nil && len(l.context) > 1 { e.buf = enc.AppendObjectData(e.buf, l.context) } return e } func newEvent(w LevelWriter, level Level) *Event { e := eventPool.Get().(*Event) e.buf = e.buf[:0] e.ch = nil e.buf = enc.AppendBeginMarker(e.buf) e.w = w e.level = level e.stack = false return e }Copy the code

The newEvent method gets the Event from the eventPool and sets the done, hooks, and other properties

summary

The Send method of Zerolog is equivalent to Msg(“”); The newEvent method gets the Event from the eventPool and sets the done, hooks, etc. Write If the level is not Disabled, endMarker and lineBreaker will be added. If e.w is not nil, execute e.W. riteLevel(e.level, e.bof) to output; PutEvent return event is then executed;

doc

  • zerolog