This repository has been archived on 2023-04-13. You can view files and clone it, but cannot push or open issues or pull requests.
logger4njs/lib/logging.js

128 lines
3.5 KiB
JavaScript
Raw Normal View History

2022-05-02 19:31:47 +02:00
const conversion = require("./conversion");
class Logger {
/** Logger
*
* @param {{
* output: NodeJS.WritableStream,
* template: string,
* argsPlaceholder: string,
* historySize: number,
* defaultLevel: string
* }} options
*/
constructor(options = {})
{
this.output = options.output || process.stdout;
this.template = options.template || "[{level} {timestamp}] {message}";
this.levelsColors = { // no same colors
debug: "\x1b[32m",
info: "\x1b[36m",
warn: "\x1b[33m",
2022-05-02 19:31:57 +02:00
"warn;": "\x1b[33m",
2022-05-02 19:31:47 +02:00
error: "\x1b[31m",
fatal: "\x1b[35m"
};
this.dict = options.dict || null;
this.argsPlaceholder = options.argsPlaceholder || "{}";
this.defaultLevel = options.defaultLevel || "info";
this.history = [];
this.historySize = options.historySize || 100;
this.onHistoryFull = options.onHistoryFull || function() {
2022-05-02 19:31:57 +02:00
this.alog("warn;", "History is full, dropping 25 oldest entries.");
this.history = this.history.slice(25);
2022-05-02 19:31:47 +02:00
};
}
/** log
*
* @param {string} message
* @param {any} ...args
*
*/
log (message, ...args)
2022-05-02 19:31:57 +02:00
{this.alog(this.defaultLevel, message, args);}
2022-05-02 19:31:47 +02:00
/** alog
*
* @param {string} level
* @param {string} message
* @param {any} ...args
*
*/
2022-05-02 19:31:57 +02:00
alog(level, message, args = [])
2022-05-02 19:31:47 +02:00
{
//replace placeholders with args
let msg = this.template;
msg = msg.replace(/\{level\}/g, level.charAt(0).toUpperCase());
2022-05-02 19:31:57 +02:00
// [I {timestamp}] {message}
msg = msg.replace(/\{timestamp\}/g, new Date().toISOString());
// [I 1/1/1970 00:00:00] {message}
2022-05-02 19:31:47 +02:00
msg = msg.replace(/\{message\}/g, message);
2022-05-02 19:31:57 +02:00
// [I 1/1/1970 00:00:00] spul {} {}
2022-05-02 19:31:47 +02:00
//replace placeholders with args
let argPlaceholder = this.argsPlaceholder;
2022-05-02 19:31:57 +02:00
let matches = (msg.match(new RegExp(argPlaceholder, "g")) || []).length;
let argsFilled = 0;
2022-05-02 19:41:46 +02:00
// args.forEach((v, i, a) => {
// if (Buffer.isBuffer(v))
// v = conversion.properHex(v).str;
// if (typeof v === 'object')
// v = "\x1b[0m" + JSON.stringify(v, null, 2) + "\x1b[0m";
// msg = msg.replace(argPlaceholder, v);
// argsFilled++;
// console.log(`${argPlaceholder} -> ${v}`);
// });
// regexp replace
let regexp = new RegExp(argPlaceholder, "g");
msg = msg.replace(regexp, (match, offset, string) => {
if (argsFilled >= matches)
return match;
let v = args[argsFilled];
2022-05-02 19:31:47 +02:00
if (Buffer.isBuffer(v))
v = conversion.properHex(v).str;
if (typeof v === 'object')
2022-05-02 19:31:57 +02:00
v = "\x1b[0m" + JSON.stringify(v, null, 2) + "\x1b[0m";
argsFilled++;
2022-05-02 19:41:46 +02:00
return v;
2022-05-02 19:31:47 +02:00
});
2022-05-02 19:41:46 +02:00
2022-05-02 19:31:57 +02:00
if (matches !== argsFilled && args.length >= matches)
console.log("warn;", "Not all placeholders were replaced.\n" +
"Placeholders: " + matches + "\n" +
"Args: " + args.length + "\n" +
"Args filled: " + argsFilled + "\n" +
"Message: " + msg);
if (matches < args.length)
msg += ` (${args.length - matches} args overflow.)`;
else if (matches > args.length)
msg += ` (${matches - args.length} args missing.)`;
2022-05-02 19:31:47 +02:00
//replace dictionary keys
if (this.dict)
msg = dictionaryConversion(msg, this.dict);
// add color
msg = this.levelsColors[level] + msg + "\x1b[0m";
//log
this.output.write(msg + "\n");
//save to history
this.history.push({
level: level,
message: message,
args: args
});
2022-05-02 19:31:57 +02:00
if (this.history.length >= this.historySize && level !== "warn;")
2022-05-02 19:31:47 +02:00
this.onHistoryFull();
}
}
module.exports = Logger;