monkey-logger
A logger that creates a log-dir, that may change the logger's filename, that may use a formatter and that allows and extending various logger types.
npm i monkey-logger
const { Logger, logger } = require("monkey-logger");
Table of Contents
- Class: Logger
- logger
- logger[type]
- Event: 'ready'
- logger[type].filepath
- logger[type].once(event, callback)
- logger[type].setName(name)
- delete(logger[type])
- Example
Logger
Class: new Logger(type[,options])
-
type
<string> -
options
<Object> -
dir
<string> Default:loggers
-
name
<string> Default:monkey
-
autoRemoveEmpty
<Boolean> Default:true
-
formatter
<Function> Default:(data, callback) => callback(data.join(" "))
-
data
<Array> -
callback
<Function> Required! - Returns <Promise>
- Resolves <undefined>
dir
option allows the developer to specify in which main-branch the logger will document it's log file(s). The type
option allows the developer to specify in which sub-branch the logger will document it's log file(s). It also determines how you can access the log function from the logger Object. The name
option allows the developer to specify how the log file will be named.The autoRemoveEmpty
option automatically removes a log file when the name
has been changed by setName
and if the content is empty, unless set to false
. The formatter
is a function that allows the developer to manipulate the log string into desired format, the function's second parameter callback
must be used to pass through the self-formatted string. The extend
option allows the developer to extend a logger[type2] with a logger[type1] so that logger[type2] will also log it's data to the log file from logger[type1]. Checkout out the example below to see how multiple modules with callbacks can be chained in a formatter function and to see how logger.error is extended from logger.log.
logger
(async function loadApplication() {
await new Logger("log");
// OUTPUT: ./loggers/log/monkey.log
await new Logger("error");
// OUTPUT: ./loggers/error/monkey.log
// ...
console.log(logger);
// returns:
// {
// log: [Function: log] {
// filepath: 'loggers\\log\\monkey.log',
// once: [Function],
// setName: [Function]
// },
// error: [Function: log] {
// filepath: 'loggers\\error\\monkey.log',
// once: [Function],
// setName: [Function]
// }
// }
}());
logger[type]
'ready'
This event runs the Event: callback
as soon as all calls to logger[type](...data)
, that have been called before listening to the 'ready' event, have finished writing to the log file. This event can also be used to fire the callback after a call to setName
has finished.
(async function loadApplication() {
const { Logger, logger } = require("monkey-logger");
// ...
await new Logger("log");
await new Logger("error", { extend: [logger.log] });
// ...
process.on("SIGINT", () => {
logger.error("Node JS is now shutting down due to ctrl + c");
logger.error.on("ready", () => process.exit());
});
}());
logger[type].filepath
The filepath
property is internally created by path.join(dir
, type
, name
). Overwriting this property does not break the code, however it might break yours.
logger[type].once(event, callback)
-
event
<string> -
callback
<Function>
callback
function for the event
.
logger[type].setName(name)
-
name
<string>
name
to the filepath
property and creates a new log file in the sub branch. This opens the possibility to create a new log file on a clock's tick event. The internal WriteStream will only be overwritten by the new WriteStream until all previous logs have finished writing. Any logs that have been fired after the setName
method was called will only start writing once the new WriteStream is ready. If the option autoRemoveEmpty
was not set to false
, an log file that was empty will be removed.
delete(logger[type])
Deleting a type
from the logger
Object also causes the Logger
instance to be removed from the internal WeakMap. Caution: if there was still a reference to logger[type]
, delete(logger[type])
will only remove the type
from the logger
Object, but will fail at removing the Logger
instance from the internal WeakMap until the reference to logger[type]
is gone.
(async function loadApplication() {
const { Logger, logger } = require("monkey-logger");
// ...
await new Logger("noob");
console.log(logger);
// {
// noob: [Function: log] {
// filepath: 'loggers\\noob\\monkey.log',
// once: [Function],
// setName: [Function]
// },
// }
delete(logger.noob);
console.log(logger);
// {}
}());
Example
(async function loadApplication() {
const { Logger, logger } = require("monkey-logger");
const { localeTimezoneDate, dateNotation, utc0 } = require("locale-timezone-date");
const IndentModel = require("indent-model");
const TaskClock = require("task-clock");
// ...
const tabs5_4 = new IndentModel({ spaces: 5, spaced: 4 });
const formatter = (data, callback) => localeTimezoneDate.toISOString(new Date(),
isoStr => tabs5_4.tabify(isoStr, ...data, logString => {
callback(logString);
console.log(logString);
}));
// ...
await new Logger("log", { name: dateNotation.yyyymmdd(new Date()), formatter });
await new Logger("error", { name: dateNotation.yyyymmdd(new Date()), formatter, extend: [logger.log] });
// ...
new TaskClock({ start: new Date(new Date().setHours(0, 0, 0, 0)), interval: { h: 24 } },
(now) => {
const yyyymmdd = dateNotation.yyyymmdd(now)
logger.log.setName(yyyymmdd);
logger.error.setName(yyyymmdd);
});
// ...
logger.log("GET", "/v1/someapi/mongol/1", "spider", "monkey");
logger.log("CLOSED", "/v1/someapi/mongol/1", "spider", "monkey");
logger.error("FAILED", "/v1/someapi/mongol/1", "find errors in " + logger.error.filepath, "monkey!");
logger.error("FAILED", "/v1/someapi/mongol/2", "find errors in " + logger.error.filepath, "monkey!");
logger.log.setName("test");
logger.error.setName("noob"); // is empty so auto removed
logger.error.setName("mongol"); // is empty so auto removed
logger.error.setName("monkey");
logger.error("FAILED", "/v1/someapi/mongol/3", "find errors in " + logger.error.filepath, "monkey!");
logger.log("GET", "/v1/someapi/mongol/2", "spider", "monkey");
logger.log("CLOSED", "/v1/someapi/mongol/2", "spider", "monkey");
// ...
// 2020-08-30T21:46:16.143+0200 GET /v1/someapi/mongol/1 spider monkey
// 2020-08-30T21:46:16.150+0200 CLOSED /v1/someapi/mongol/1 spider monkey
// 2020-08-30T21:46:16.151+0200 FAILED /v1/someapi/mongol/1 find errors in loggers\error\2020-08-30.log monkey!
// 2020-08-30T21:46:16.153+0200 FAILED /v1/someapi/mongol/2 find errors in loggers\error\2020-08-30.log monkey!
// 2020-08-30T21:46:16.155+0200 FAILED /v1/someapi/mongol/3 find errors in loggers\error\noob.log monkey!
// 2020-08-30T21:46:16.156+0200 GET /v1/someapi/mongol/2 spider monkey
// 2020-08-30T21:46:16.157+0200 CLOSED /v1/someapi/mongol/2 spider monkey
// 2020-08-30T19:46:16.158Z done
// ...
// 1st OUTPUT: /loggers/log/2020-08-30.log
// 2nd OUTPUT: /loggers/log/2020-08-30.log
// 3rd OUTPUT: /loggers/error/2020-08-30.log + OUTPUT: /loggers/log/2020-08-30.log
// 4th OUTPUT: /loggers/error/2020-08-30.log + OUTPUT: /loggers/log/2020-08-30.log
// 5th OUTPUT: /loggers/error/monkey.log + OUTPUT: /loggers/log/test.log
// 6th OUTPUT: /loggers/log/test.log
// 7th OUTPUT: /loggers/log/test.log
}());