Skip to content
Alexander I.Grafov edited this page Sep 24, 2016 · 9 revisions

Three stages of logging

It explains how a log message passed to the sink. It assumed that logger instance initialized before alongside with a number of sinks.

Stage 1: forming a record

Firstly you add key/value pairs to a log record. There are a lot methods for it around Logger struct. They stored in Logger but not passed further to output until you call Logger.Log(). This method flushes current record.

Stage 2: filtering

Each flushed record passed to all sinks. The each sink can has arbitrary number of filters. After using a new sink it has no defined filters. You add them with methods of Sink struct. There are two groups of filtering methods:

  • first group allows drop out unwanted records
  • second group allows drop out unwanted pairs for more compact record display

By default no restrictions so a new sink will pass all records logged by application. Combination of filters defines which records will pass to each sink. It is normal when the same record passed to several sinks.

Stage 3: formatting & writing

After record passed for writing it should be appropriately formatted. Each sink declares which format it wants. Currently there are two predefined formats: Logfmt and JSON. You can pass a custom format by implementing Formatter interface.

Formatter interface has three methods:

  • Begin() for prefixing each record
  • Pair(key, val string, quoted bool) called for each pair inside a record
  • Finish() []byte should return formatter record as a byte array.

With Begin and Finish you can define prefix and suffix for each record. It is their main purpose. See the sample realization in formatter.go for Logfmt and JSON formatters.

After formatting bytes passed to io.Writer of the selected Sink.

Architecture view of a logger