A simple logger class, which mostly just structures messages, data, and some metadata as JSON and spews it, by default, to Console.
Supports basic scrubbing of well-defined sensitive fields, detection of circular references, and an extensible set of JSON replacer functions for common objects.
If provided with an asyncLocalStorage instance, it expects a stored object which will be spread over the resulting logged JSON.
Intended to be specific to Squeep Framework Applications, this module has some opinions.
-
new Logger(options, commonObject, asyncLocalStorage, backend)
-
commonObject
will be merged into every log -
asyncLocalStorage
, if provided, should store an object, which will also be merged into log -
backend
isconsole
by default, but may be anything implementing the same log-level functions
-
-
error(scope, message, data, ...)
-
scope
- identifies source of message, e.g. 'class:method' -
message
- text to be logged -
data
- object to be logged, can be scrubbed of sensitive fields, and will be serialized with provided replacers - any additional arguments are included as an array
-
-
warn(scope, message, data, ...)
-
info(scope, message, data, ...)
-
log(scope, message, data, ...)
-
debug(scope, message, data, ...)
Includes replacers for these objects:
- Error
- BigInt
- http.IncomingMessage
- http.OutgoingMessage
- http.ServerResponse
Additional replacers may be inserted into the logger instance's jsonReplacers
array.
Sanitizers may be inserted into the logger instance's dataSanitizers
array.
const http = require('node:http');
const { AsyncLocalStorage } = require('node:async_hooks');
const uuid = require('uuid');
const Logger = require('@squeep/logger-json-console');
const loggerOptions = {
ignoreBelowLevel: 'info',
};
const commonObject = {
nodeIdentifier: uuid.v1(),
};
const asyncLocalStorage = new AsyncLocalStorage();
const logger = new Logger(loggerOptions, commonObject, asyncLocalStorage);
const scope = 'exampleServer';
http.createServer((req, res) => {
asyncLocalStorage.run({ requestId: uuid.v1() }, () => {
logger.debug(scope, 'start', { req, res });
setImmediate(() => {
res.end();
logger.info(scope, 'finish', { req, res }, 'other stuff');
});
});
}).listen(8088);
Results in messages such as this:
{
"nodeIdentifier": "64610280-fc17-11ed-a918-1dd19f027d43",
"timestamp": "2023-05-26T22:48:17.995Z",
"timestampMs": 1685141297995,
"level": "info",
"scope": "exampleServer",
"message": "finish",
"data": {
"req": {
"method": "GET",
"url": "/",
"httpVersion": "1.1",
"headers": {
"host": "localhost:8088",
"user-agent": "curl/7.83.1",
"accept": "*/*"
},
"trailers": {}
},
"res": {
"statusCode": 200,
"statusMessage": "OK",
"headers": {}
}
},
"other": [
"other stuff"
],
"requestId": "68233aa0-fc17-11ed-a918-1dd19f027d43"
}