ng2-logger
Version:
isomorphic logger for browser/server in typescript
310 lines • 8.54 kB
JavaScript
//#region imports
import chalk from 'chalk'; // @backend
import * as stringify from 'json-stringify-safe';
import { Helpers__NS__contain, Helpers__NS__error, Helpers__NS__info, Helpers__NS__log, Helpers__NS__success, Helpers__NS__taskDone, Helpers__NS__taskStarted, Helpers__NS__warn, UtilsOs__NS__isNode } from 'tnp-core/lib-prod';
//#region @backend
const randomcolor = require('randomcolor').default ?? require('randomcolor');
//#endregion
//#endregion
//#region level
export var Level;
(function (Level) {
Level[Level["DATA"] = 0] = "DATA";
Level[Level["INFO"] = 1] = "INFO";
Level[Level["WARN"] = 2] = "WARN";
Level[Level["ERROR"] = 3] = "ERROR";
Level[Level["SUCCESS"] = 4] = "SUCCESS";
Level[Level["TASK_STARTED"] = 5] = "TASK_STARTED";
Level[Level["TASK_DONE"] = 6] = "TASK_DONE";
})(Level || (Level = {}));
//#endregion
//#region constants
export const LevelKey = {
[Level.DATA]: 'data',
[Level.INFO]: 'info',
[Level.WARN]: 'warn',
[Level.ERROR]: 'error',
[Level.SUCCESS]: 'success',
[Level.TASK_STARTED]: 'taskstarted',
[Level.TASK_DONE]: 'taskdone',
};
export const LevelOrder = [
LevelKey[Level.DATA],
LevelKey[Level.TASK_STARTED],
LevelKey[Level.TASK_DONE],
LevelKey[Level.INFO],
LevelKey[Level.SUCCESS],
LevelKey[Level.WARN],
LevelKey[Level.ERROR],
];
const levelIcon = {
[Level.INFO]: 'ℹ️',
[Level.ERROR]: '❌',
[Level.WARN]: '⚠️',
[Level.SUCCESS]: '✅',
[Level.TASK_STARTED]: '🚀',
[Level.TASK_DONE]: '🏁',
[Level.DATA]: '',
};
//#endregion
//#region log namespace
//namespace Log
//#region internal state
const instances = new Map();
let originalConsole = null;
let permanentlyDisabled = false;
const consoleMethods = ['log', 'info', 'warn', 'error'];
let globalLevel = null;
//#endregion
//#region settings
export const Log__NS__settings = {
mutedModules: [],
showTimestamp: false,
};
//#endregion
//#region helpers
const isMutedModule = (moduleName) => {
if (Log__NS__settings.mutedModules.length === 0)
return false;
return !Helpers__NS__contain(Log__NS__settings.mutedModules, moduleName);
};
//#endregion
//#region public api
export const Log__NS__create = (moduleName, ...level) => {
const log = new Logger(moduleName, getRandomColor(), level, isMutedModule(moduleName), undefined);
instances.set(moduleName, log);
return log;
};
export const Log__NS__setGlobalLevel = (level) => {
globalLevel = level;
};
export const Log__NS__onlyLevel = (...levels) => {
instances.forEach(instance => {
instance.allowed = levels;
});
};
export const Log__NS__onlyModules = (...modules) => {
instances.forEach(instance => {
const moduleName = instance.moduleName;
const isAllowed = modules.some(m => {
if (typeof m === 'string') {
return m === moduleName;
}
if (m instanceof RegExp) {
return m.test(moduleName);
}
return false;
});
// mute if NOT allowed
instance.isMuted = !isAllowed;
});
};
export const Log__NS__disableAllLogsPermanetly = () => {
if (permanentlyDisabled)
return;
if (!originalConsole) {
originalConsole = {};
consoleMethods.forEach(m => {
originalConsole[m] = console[m];
});
}
consoleMethods.forEach(m => {
console[m] = () => { };
});
permanentlyDisabled = true;
};
export const Log__NS__disableAllLogs = () => {
if (permanentlyDisabled)
return;
if (!originalConsole) {
originalConsole = {};
consoleMethods.forEach(m => {
originalConsole[m] = console[m];
});
}
consoleMethods.forEach(m => {
console[m] = () => { };
});
};
export const Log__NS__enableAllLogs = () => {
if (permanentlyDisabled)
return;
if (!originalConsole)
return;
consoleMethods.forEach(m => {
if (originalConsole && originalConsole[m]) {
console[m] = originalConsole[m];
}
});
};
//#endregion
//#region logger class
class Logger {
moduleName;
color;
allowed;
isMuted;
moduleWidth;
constructor(moduleName, color, allowed, isMuted,
/**
* Set how much characters in terminal/console
* your module name should take
*/
moduleWidth) {
this.moduleName = moduleName;
this.color = color;
this.allowed = allowed;
this.isMuted = isMuted;
this.moduleWidth = moduleWidth;
this.createLevelMethod(Level.DATA);
this.createLevelMethod(Level.DATA, 'd');
this.createLevelMethod(Level.INFO);
this.createLevelMethod(Level.INFO, 'i');
this.createLevelMethod(Level.WARN);
this.createLevelMethod(Level.WARN, 'w');
this.createLevelMethod(Level.ERROR);
this.createLevelMethod(Level.ERROR, 'er');
this.createLevelMethod(Level.SUCCESS);
this.createLevelMethod(Level.TASK_STARTED);
this.createLevelMethod(Level.TASK_DONE);
}
setLevel(l) {
this.allowed = [l];
return this;
}
mute() {
this.isMuted = true;
return this;
}
logOnlyWhen(expression) {
this.isMuted =
typeof expression === 'function' ? !expression() : !expression;
}
createLevelMethod(level, overrideMethodName) {
const methodName = overrideMethodName
? overrideMethodName
: LevelKey[level];
this[methodName] = (message, ...data) => {
if (this.isMuted)
return this;
if (globalLevel !== null && level < globalLevel) {
return this;
}
if (this.allowed.length === 0 || Helpers__NS__contain(this.allowed, level)) {
displayMsg(message, data.length === 0 ? undefined : data, this.moduleName, this.color, level, this.moduleWidth, permanentlyDisabled);
}
return this;
};
}
}
//#endregion
//end of namespace Log
//#endregion
//#region get random color
const getRandomColor = () => {
//#region @backend
if (UtilsOs__NS__isNode) {
return randomcolor({ luminosity: 'light' });
}
//#endregion
const letters = '0123456789ABCDEF';
return ('#' +
Array.from({ length: 6 })
.map(() => letters[Math.floor(Math.random() * 16)])
.join(''));
};
//#endregion
//#region console log
const consoleLog = (data, level) => {
//#region @backend
if (level === Level.INFO)
Helpers__NS__info(data);
else if (level === Level.ERROR)
Helpers__NS__error(data, true, true);
else if (level === Level.WARN)
Helpers__NS__warn(data, false);
else if (level === Level.SUCCESS)
Helpers__NS__success(data);
else if (level === Level.TASK_STARTED)
Helpers__NS__taskStarted(data);
else if (level === Level.TASK_DONE)
Helpers__NS__taskDone(data);
else
Helpers__NS__log(data, 0, true);
//#endregion
};
//#endregion
//#region display message
const displayMsg = (message, params, moduleName, moduleColor, level, moduleWidth, permanentlyDisabled) => {
if (permanentlyDisabled)
return;
if (message) {
message = `${levelIcon[level]} ${message?.toString()}`;
}
else {
message = levelIcon[level];
}
const timestamp = Log__NS__settings
? `[${new Date().toISOString()}] `
: '';
if (moduleWidth) {
const diff = moduleWidth - moduleName.length;
if (diff > 0) {
for (let i = 0; i < diff; i++) {
moduleName += ' ';
}
}
}
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
//#region @backend
if (UtilsOs__NS__isNode) {
const header = chalk.bgHex(moduleColor)(chalk.black(moduleName)) +
' ' +
chalk.dim(timestamp + message);
consoleLog(header, level);
if (params) {
params.forEach(p => consoleLog(stringify(p, null, 2), level));
}
}
//#endregion
};
//#endregion
//# sourceMappingURL=ng2-logger.js.map