nope/lib/logger/nopeLogger.ts

281 lines
6.4 KiB
TypeScript
Raw Normal View History

import * as Logger from "js-logger";
2021-05-21 17:21:53 +00:00
import { ILogger, ILoggerOpts } from "js-logger";
2020-11-06 13:17:47 +00:00
import { SPLITCHAR } from "../helpers/objectMethods";
import { RUNNINGINNODE } from "../helpers/runtimeMethods";
const colors = {
Reset: "\x1b[0m",
Bright: "\x1b[1m",
Dim: "\x1b[2m",
Underscore: "\x1b[4m",
Blink: "\x1b[5m",
Reverse: "\x1b[7m",
Hidden: "\x1b[8m",
FgBlack: "\x1b[30m",
FgRed: "\x1b[31m",
FgGreen: "\x1b[32m",
FgYellow: "\x1b[33m",
FgBlue: "\x1b[34m",
FgMagenta: "\x1b[35m",
FgCyan: "\x1b[36m",
FgWhite: "\x1b[37m",
BgBlack: "\x1b[40m",
BgRed: "\x1b[41m",
BgGreen: "\x1b[42m",
BgYellow: "\x1b[43m",
BgBlue: "\x1b[44m",
BgMagenta: "\x1b[45m",
BgCyan: "\x1b[46m",
BgWhite: "\x1b[47m"
};
const colorMatching = {
ERROR: colors.FgRed,
WARN: colors.FgYellow,
INFO: colors.FgWhite,
DEBUG: colors.FgGreen,
TRACE: colors.FgCyan
};
const spacer = {
ERROR: "",
WARN: " ",
INFO: " ",
DEBUG: "",
TRACE: ""
};
Logger.useDefaults({
defaultLevel: Logger.DEBUG,
formatter: RUNNINGINNODE
? function (messages, context) {
messages.unshift(
colors.FgBlue,
new Date().toISOString(),
colors.Reset,
"-",
colorMatching[context.level.name],
context.level.name + spacer[context.level.name],
"-",
colors.BgWhite + colors.FgBlack,
context.name,
colors.Reset,
":"
);
}
: function (messages, context) {
messages.unshift(
context.level.name + spacer[context.level.name],
"-",
context.name,
":"
);
}
});
2020-11-06 13:17:47 +00:00
/**
* Contains the Valid Types of the Loger.
*/
export type LoggerLevel = "error" | "warn" | "info" | "debug" | "trace";
export const LoggerLevels = ["error", "warn", "info", "debug", "trace"];
const order: { [K in LoggerLevel]: number } = {
error: 8,
warn: 5,
info: 3,
debug: 2,
trace: 1
2020-11-23 06:09:31 +00:00
};
2020-11-07 10:55:29 +00:00
const mapping: { [K in LoggerLevel]: any } = {
error: Logger.ERROR,
warn: Logger.WARN,
info: Logger.INFO,
debug: Logger.DEBUG,
trace: Logger.TRACE
};
2020-11-07 10:55:29 +00:00
const reverseOrder: { [index: number]: LoggerLevel } = {};
Object.getOwnPropertyNames(order).map(
(key: LoggerLevel) => (reverseOrder[order[key]] = key)
);
2020-11-07 10:55:29 +00:00
const reverseMapping: any = {};
Object.getOwnPropertyNames(mapping).map(
(key: LoggerLevel) => (reverseMapping[mapping[key]] = key)
);
2020-11-06 13:17:47 +00:00
function _selectLevel(master: LoggerLevel, slave: LoggerLevel) {
const masterLevel = order[master];
const slaveLevel = order[slave];
2020-11-06 13:17:47 +00:00
return reverseOrder[Math.max(masterLevel, slaveLevel)];
2020-11-06 13:17:47 +00:00
}
/**
* Helper Function, to create a Logger.
* Therefore it uses a specific Level and a Lable of the
2020-11-06 13:17:47 +00:00
* Logger
*
* @export
* @param {LoggerLevel} level The Level, which should be rendered
* @param {string} [label=''] An Lable for the Logger. Every Message beginns with that lable.
* @return {*} Returns a Logger.
*/
function _getLogger(level: LoggerLevel, label = ""): ILogger {
const logger = Logger.get(label);
logger.setLevel(mapping[level]);
return logger;
2020-11-06 13:17:47 +00:00
}
export class NopeLogger {
protected _logger: ILogger;
protected _loggers: Map<string, ILogger>;
2020-11-06 13:17:47 +00:00
set level(value: LoggerLevel) {
if (!this.isLocked) {
this._level = value;
this.setLoglevel("core" + SPLITCHAR, value);
2020-11-06 13:17:47 +00:00
}
}
2020-11-06 13:17:47 +00:00
get level(): LoggerLevel {
return this._level;
}
public _level: LoggerLevel = "debug";
/**
* Create or returns the provided Logger
* @param name
* @param level
*/
getLogger(name = "", level: LoggerLevel = this.level): ILogger {
if (!this._loggers.has(name)) {
this._loggers.set(
name,
_getLogger(_selectLevel(this.level, level), name)
);
2020-11-06 13:17:47 +00:00
}
return this._loggers.get(name) as ILogger;
}
2020-11-06 13:17:47 +00:00
/**
2021-05-21 17:21:53 +00:00
* Helper function, to update the Logger Defaults.
*
* @param {ILoggerOpts} defaults
* @memberof NopeLogger
*/
2021-05-21 17:21:53 +00:00
setDefaults(defaults: ILoggerOpts): void {
Logger.useDefaults(defaults);
}
/**
* Rewrites the Stream of the Logger to the
* given handler. Watch out, only one handler
* is active.
*
* @param {(msg, context) => void} handler
* @memberof NopeLogger
*/
setHandler(handler: (msg, context) => void): void {
Logger.setHandler(handler);
}
/**
* Function to determine the Logger Level
* @param loggerGroup The specified group, which should be addressed
* @param level The Level to Set
*/
setLoglevel(loggerGroup: string, level: LoggerLevel): void {
if (!loggerGroup.startsWith("core" + SPLITCHAR)) {
loggerGroup = "core" + SPLITCHAR + loggerGroup;
2020-11-06 13:17:47 +00:00
}
if (!loggerGroup.endsWith(SPLITCHAR)) {
loggerGroup += SPLITCHAR;
2020-11-06 13:17:47 +00:00
}
/** Iterate over all Loggers and close the unused Loggers */
for (let [name, logger] of this._loggers.entries()) {
if (!name.startsWith("core" + SPLITCHAR)) {
name = "core" + SPLITCHAR + name;
}
2020-11-06 13:17:47 +00:00
if (!name.endsWith(SPLITCHAR)) {
name += SPLITCHAR;
}
2020-11-06 13:17:47 +00:00
if (name == loggerGroup || name.startsWith(loggerGroup)) {
/** Update the Level */
logger.setLevel(mapping[level]);
}
2020-11-06 13:17:47 +00:00
}
}
2020-11-06 13:17:47 +00:00
/**
* Function, to check, whether a specific logger is logging or not
* @param loggerName Name of the Logger
* @param level The Log-Level to Test
*/
isLogging(loggerName: string, level: LoggerLevel): boolean {
return (
order[reverseMapping[this.getLogger(loggerName).getLevel().name]] >=
order[level]
);
}
2020-11-07 10:55:29 +00:00
/**
* Creates A Logger-Manager
*/
constructor() {
this._loggers = new Map<string, ILogger>();
2020-11-07 10:55:29 +00:00
this._logger = _getLogger("debug", "root");
this._loggers.set("", this._logger);
}
2020-11-06 13:17:47 +00:00
protected _pw = "";
/**
* Lock the Logger Level with a password
*
* @param {string} pw The Password to Lock the Logger
* @memberof NopeLogger
*/
lock(pw: string): void {
if (this._pw !== "") {
this._loggers.get("").error("Please unlock before");
} else {
this._pw = pw;
2020-11-06 13:17:47 +00:00
}
}
2020-11-06 13:17:47 +00:00
/**
* Unlock the Logger, therefore the password used for locking is
* required. After unlocking, the log-level can be adapted.
*
* @param {string} pw
* @memberof NopeLogger
*/
unlock(pw: string): void {
if (this._pw === pw) {
this._pw = "";
} else {
this._loggers.get("").error("Unlocking wasnt successfull");
2020-11-06 13:17:47 +00:00
}
}
2020-11-06 13:17:47 +00:00
/**
* Flag indicating, whether the logger is locked or not.
*
* @readonly
* @memberof NopeLogger
*/
public get isLocked(): boolean {
return this._pw !== "";
}
}