Under the hood
Logging Levels
Each log record holds a level to represent its importance to the workflow. Although you could use any custom number value, oddlog provides some predefined standard levels:
0 - SILENT
1 - TRACE
2 - DEBUG
3 - VERBOSE
4 - INFO
5 - WARN
6 - ERROR
7 - FATAL
It is best practice to scatter logging messages over as many levels as there are distinct levels of significance
within a module. If the module has some messages to tell that are more relevant than INFO
but less relevant than
WARN
it's completely fine to use a level like 4.5
.
We chose the ascending level in contrast to some popular logging libraries due to two reasons:
- exit codes of programs being
0
is fine,>=1
is error; thus ascending to error. - there is no possible severity level below silent, but one could imagine an open range upwards.
Raw log record
At least @oddlog/cli@1.0.0
is required for the current schema.
[
{Number} SCHEMA_VERSION, // 3
{?String} typeKey, // default: "_type"
{?Object} meta, // default: [ os.release(), os.hostname(), process.pid ]
{String} loggerName,
{Number} timestamp,
{Number} severity,
{?Array} source: [
{String} file,
{Number} row,
{Number} col
],
{?String} message,
{?Object} [payload],
]
Example:
[3,"_type",["4.17.8-1-ARCH","zerg",31522],"my-app:http",1533429331401,4,["lib/index.js",42,21],"hello world",{"lorem":"ipsum",answer:42}]
The Array syntax has been chosen due to high parsing performance and compactness. The actual record gets written part by
part instead of a single JSON.stringify
on an actual array object; this provides the highest possible record stringify
speed as only the meta
and payload
fields need to be stringified generically. The order of the fields is chosen to
use the order of specificity according to SCHEMA < PROCESS < LOGGER < LOG
. Thus building the prefix string of the
schema, process and logger does not have to happen for each log record; saving quite some computation time.
The typeKey
allows customization regarding how to handle attributes of the payload within the interpreting tool (e.g.
cli). By default, everything within the payload has the default type "plain"
; except for the top-level attributes
"err"
and "error"
, they have the default type "error"
. Types can be overwritten for any object that is (part of)
the payload by setting the value of its typeKey
attribute (e.g. {"_type":"error"}
).