|
CX Framework
Cross-platform C utility framework
|
#include <log.h>
Data Fields | |
| int | level |
| Log severity level (LOG_Fatal, LOG_Error, etc.) | |
| LogChannel * | chan |
| Channel this record was logged to, never NULL. | |
| int64 | timestamp |
| Wall clock timestamp when the record was created. | |
| uint64 | seq |
| Increasing sequence number, ordering records across threads. | |
| const LogSite * | site |
| Call site identity, or NULL if logged dynamically. | |
| strref | msgtmpl |
| Message template, or the literal message when istmpl is false. | |
| const stvar * | args |
| Arguments the record was logged with, NULL if none. | |
| int | nargs |
| Number of arguments. | |
| int | trigger |
| bool | istmpl |
| const LogCtx * | ctx |
| Context in scope when the record was logged, or NULL. | |
| uint32 | batchid |
| Opaque batch identifier for grouping related records. | |
| uint32 | sample |
| strref | origin |
| uint8 | hops |
| How many instances this record has been forwarded through, 0 for a local one. | |
| bool | localonly |
One log record as a destination sees it
A record is not a formatted line. It carries the message template and a copy of the arguments that were logged with it, so that a text destination renders a sentence and a structured destination emits named fields – from the same record, with no parallel API and no possibility of a structured-only record reaching a console.
Formatting therefore happens here, on the drain thread, rather than at the call site. Call logRecordRender() to get the flat text; repeat calls within one dispatch are cheap because the rendering is shared across destinations.
Structured destinations read args directly. Keyed arguments (stvark()) become named fields; unkeyed ones are positional and belong to the template. Note that the two are disjoint – a keyed argument is never matched by an unkeyed placeholder, so both have to be read through their own accessors.
ctx carries the fields that were in scope on the logging thread (see Log Context). They are fields exactly like keyed arguments are, from a different source, and logRecordRender() makes them available to the template under their keys – so ${string:reqid} resolves against the context when the call site did not supply a reqid argument of its own.
| bool LogRecord::istmpl |
True if msgtmpl is a format template, false if it is a literal message
logFmt() sets this and logStr() does not. It is what keeps a literal message containing ${...} from being substituted into: an unformatted record has nothing to expand even when a context is in scope, and the two cannot be told apart by argument count.
| bool LogRecord::localonly |
True if this record must not leave the machine
Set on anything logged inside withLogLocal(), and on everything a destination's own callbacks log while they are running. A forwarder never receives one; local destinations receive it normally, so the transport that produced it stays diagnosable.
| strref LogRecord::origin |
Instance this record was forwarded from, or NULL if it was logged in this process
The channel path stays exactly what the sender logged it to, so a rule written for a subsystem matches whether the record came from here or from somewhere else; this is the field that says where "somewhere else" was.
| uint32 LogRecord::sample |
Sampling rate this record survived, or 0/1 if the channel was not being sampled
A structured destination scales counts back up by this (see logChanSetSampling()); text destinations ignore it, because a sampled log is a thing you configured and a line that says so every time is noise.
| int LogRecord::trigger |
Severity of the event that released this record from a retention ring, or -1
A record with a trigger was retained by a debug ring and let out by something more severe (see logChanSetDebugRing()). Destinations filter on this instead of the record's own level, so the context of a failure reaches whoever would have seen the failure. Its own level is unchanged and is still what a destination renders.