Life cycle
Any created log will pass between four phases:
sync
Creation: The log is created andAdHoc fields
are collectedsync
Pre handling:PreHooks
are evaluatedsync
/async
Post handling:Base fields
,PreHooks
,AdHoc fields
are applied andPostHooks
are evaluated and appliedsync
/async
Output: The final log fields are forwarded to every configuredOutput
#
Sync Phase 1: CreationThis phase is characterized by the call to the Logger
log level method itself:
someLogger.Trace("some msg", logger.LogFields{ ...someFields... })
At this point, the AdHoc fields
are collected and a referece to them is stored, in order to be able to process them by the following phases.
#
Sync Phase 2: Pre handlingRight after the AdHoc fields
are collected, the PreHooks
are evaluated. It means that all the configured PreHooks
functions will be called at this stage, in a synchronous way. The returned PreHooks
function values will be stored inside the created log, in order to be applied later.
note
At this stage, the log fields aren't ready yet. We're just calculating the possible values of the fields. These values can be overriden by AdHoc fields
or PostHooks
, at later phases, but we don't know for sure.
#
(A)Sync Phase 3: Post handlingThis is the most expensive phase, since it's responsible to let the log fields ready to be used by the Outputs
.
Here, the Base fields
are copied from the Logger
instance that created the log into a new LogFields
map, followed by the copy of the evaluated PreHooks
(from phase 2), followed by the copy of the AdHoc fields
(from phase 1). The PostHooks
values will be last to be evaluated and copied to the final log fields. More information, see the Fields override order page.
At the end of the phase 3, the message
and level
log fields will be applied to the LogFields
map, overriding any previous value that used the keys respectively configured. Something like this:
logFields[lvlFieldKey] = log.lvllogFields[msgFieldKey] = log.msg
info
If the Logger
is set to be async
, this phase will be executed by a different go routine than the one that created the log
#
(A)Sync Phase 4: OutputJust a for
loop over the Logger
configured Outputs
slice, forwarding the final log fields, created at the phase 3:
// Not real production-code (just to illustrate)for _, output := range logger.outputs { output(lvl, msg, logFields)}
info
If the Logger
is set to be async
, this phase will be executed by a different go routine than the one that created the log