mwn
Version:
JavaScript & TypeScript MediaWiki bot framework for Node.js
195 lines • 5.16 kB
JavaScript
;
/**
* semlog
* A semantic logger that colors and formats messages automatically according to the content
*
* Adapted from https://github.com/Fannon/semlog
*
* @author Simon Heimler
* @author Siddharth VP - removed use of globals and adapted to TypeScript,
* also removed some unnecessary features like in-memory log retention
* and keeping track of statistics
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.updateLoggingConfig = updateLoggingConfig;
exports.log = log;
exports.message = message;
exports.debug = debug;
exports.error = error;
exports.colorize = colorize;
exports.pad = pad;
exports.getDateArray = getDateArray;
exports.humanDate = humanDate;
const util = require("node:util");
const chalk = require("chalk");
const logConfig = {
printDebug: true,
printVerbose: true,
stream: process.stdout,
};
/**
* Configure global logging options.
*
* Note: To suppress API warnings, use `suppressAPIWarnings` flag in bot instance options instead.
*/
function updateLoggingConfig(options) {
Object.assign(logConfig, options);
}
/**
* Custom Logging function
*
* Writes logs to console or file, stringifies objects first
*
* @param obj
*/
function log(obj) {
if (obj && obj instanceof Error) {
error(obj);
}
else if (obj && typeof obj === 'object') {
debug(obj);
}
else {
message(obj);
}
}
// Functions below are exported only for unit testing
function message(msg) {
if (typeof msg !== 'string') {
try {
msg = '' + JSON.stringify(msg);
}
catch (e) {
msg = `[E] [Logger] Could not stringify given parameter: ${e.message}`;
}
}
msg = colorize(msg);
if (msg.trim && msg.trim().length > 0) {
msg = colorize('[' + humanDate() + '] ', 'gray') + msg;
}
if (!logConfig.printVerbose && msg.indexOf('[V]') >= 0) {
// Supressing output of verbose message
}
else if (!logConfig.printDebug && msg.indexOf('[D]') >= 0) {
// Supressing output of debug message
}
else {
writeToLog(msg);
}
}
/**
* Prints out debugging information for the current model object
* @param obj
*/
function debug(obj) {
// Print indented JSON
let msg = JSON.stringify(obj, null, 4);
writeToLog(colorize(msg, 'gray'));
}
/**
* Prints errors
* @param obj
*/
function error(obj) {
writeToLog(colorize('[E] ' + obj.message, 'red'));
let stringified;
try {
stringified = JSON.stringify(obj, null, 4);
}
catch (e) {
// Circular object?
stringified = `Failed to stringify error: ${e.message}`;
}
writeToLog(colorize(stringified, 'gray'));
if (obj.stack) {
writeToLog(colorize(obj.stack, 'gray'));
}
}
const colorMap = {
'[E]': 'red', // ERROR
'[W]': 'yellow', // WARNING
'[?]': 'yellow', // MISSING
'[S]': 'green', // SUCCESS
'[i]': 'blue', // INFO
'[+]': 'green', // ADDED
'[-]': 'red', // REMOVED
'[C]': 'cyan', // CHANGED
'[U]': 'gray', // UNCHANGED
'[=]': 'gray', // EQUAL
'[/]': 'gray', // SKIPPED
'[V]': 'magenta', // VERBOSE
'[D]': 'magenta', // DEBUG
'[T]': 'magenta', // TO-DO
'[TODO]': 'magenta', // TO-DO
};
/**
* Colors the messages by searching for specific indicator strings
*
* @param {string} msg
* @param {string} colorName
* @returns {string}
*/
function colorize(msg, colorName) {
if (logConfig.stream !== process.stdout) {
return msg;
}
if (colorName) {
return chalk[colorName](msg);
}
for (let [code, color] of Object.entries(colorMap)) {
if (msg && msg.indexOf && msg.startsWith(code)) {
return chalk[color](msg);
}
}
return msg;
}
function writeToLog(message) {
if (logConfig.stream === process.stdout) {
console.log(message);
}
else {
logConfig.stream.write(util.format.apply(null, [message]) + '\n');
}
}
/**
* Pad a number with n digits
*
* @param {number} number number to pad
* @param {number} digits number of total digits
* @returns {string}
*/
function pad(number, digits) {
return new Array(Math.max(digits - String(number).length + 1, 0)).join('0') + number;
}
/**
* Returns an array with date / time information
* Starts with year at index 0 up to index 6 for milliseconds
*
* @param {Date} date Optional date object. If falsy, will take current time.
* @returns {Array}
*/
function getDateArray(date) {
date = date || new Date();
return [
date.getFullYear(),
pad(date.getMonth() + 1, 2),
pad(date.getDate(), 2),
pad(date.getHours(), 2),
pad(date.getMinutes(), 2),
pad(date.getSeconds(), 2),
pad(date.getMilliseconds(), 2),
];
}
/**
* Returns nicely formatted date-time
* @example 2015-02-10 16:01:12
*
* @param {object} [date]
* @returns {string}
*/
function humanDate(date) {
date = date || new Date();
let d = getDateArray(date);
return d[0] + '-' + d[1] + '-' + d[2] + ' ' + d[3] + ':' + d[4] + ':' + d[5];
}
//# sourceMappingURL=log.js.map