-# @squeep/logger
+# @squeep/logger-json-console
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 data, and an extensible set of JSON replacer functions for common objects.
+Supports basic scrubbing of well-defined sensitive fields, detection of circular references, and an extensible set of JSON replacer functions for common objects.
-Intended to be specific to Squeep Framework Applications, this module has opinions.
+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.
## API
-Expects these fields in any log call:
+- `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` is `console` 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, ...)`
+
+## JSON Replacers
+
+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.
+
+## Data Sanitizers
+
+Sanitizers may be inserted into the logger instance's `dataSanitizers` array.
+
+## Example
+
+```javascript
+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:
-- `scope` - file:method
-- `message` - text
-- `data` - object
-- any additional parameters are included as an array, but not scrubbed
+```json
+{
+ "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"
+}
+```