@kwiz/common
Version:
KWIZ common utilities and helpers for M365 platform
284 lines • 11.4 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.ConsoleLogger = exports.LoggerLevel = void 0;
const _dependencies_1 = require("../_dependencies");
const date_1 = require("../helpers/date");
const debug_1 = require("../helpers/debug");
const objects_1 = require("../helpers/objects");
const strings_1 = require("../helpers/strings");
const typecheckers_1 = require("../helpers/typecheckers");
const DEFAULT_LOGGER_NAME = "DEFAULT";
const LoggerPrefix = "[kw]";
// eslint-disable-next-line no-shadow
var LoggerLevel;
(function (LoggerLevel) {
LoggerLevel[LoggerLevel["VERBOSE"] = 0] = "VERBOSE";
LoggerLevel[LoggerLevel["DEBUG"] = 1] = "DEBUG";
LoggerLevel[LoggerLevel["INFO"] = 2] = "INFO";
LoggerLevel[LoggerLevel["LOG"] = 3] = "LOG";
/** shows when debug=off */
LoggerLevel[LoggerLevel["WARN"] = 4] = "WARN";
/** shows when debug=off */
LoggerLevel[LoggerLevel["TRACE"] = 5] = "TRACE";
/** shows when debug=off */
LoggerLevel[LoggerLevel["ERROR"] = 6] = "ERROR";
LoggerLevel[LoggerLevel["OFF"] = 10] = "OFF";
})(LoggerLevel || (exports.LoggerLevel = LoggerLevel = {}));
class ConsoleLogger {
constructor(context) {
this.context = context;
}
static get(name, prefix) {
var global = ConsoleLogger._getGlobal();
var loggers = global.loggers;
if (!global.loggedBuild) {
global.loggedBuild = true;
console.debug(`${ConsoleLogger.commonPrefix()} KWIZ build ${_dependencies_1.ReleaseStatus}.${_dependencies_1.BuildNumber}`);
}
return loggers[name] || (loggers[name] = new ConsoleLogger({ name: name, prefix: prefix }));
}
static _getGlobal() {
var global = (0, objects_1.getGlobal)("loggers", {
loggedBuild: false,
loggers: {}
}, true);
return global;
}
static _getDefaultLogger() {
return ConsoleLogger.get(DEFAULT_LOGGER_NAME);
}
static setLevel(newLevel) {
ConsoleLogger._getDefaultLogger().setLevel(newLevel);
}
static getLevel() {
return ConsoleLogger._getDefaultLogger().getLevel();
}
static debug(message) {
ConsoleLogger._getDefaultLogger().debug(message);
}
static info(message) {
ConsoleLogger._getDefaultLogger().info(message);
}
static log(message) {
ConsoleLogger._getDefaultLogger().log(message);
}
static warn(message) {
ConsoleLogger._getDefaultLogger().warn(message);
}
static error(message) {
ConsoleLogger._getDefaultLogger().error(message);
}
static trace(message) {
ConsoleLogger._getDefaultLogger().trace(message);
}
static commonPrefix(prefix) {
var d = new Date();
var timestamp = (0, strings_1.padLeft)(d.getHours().toString(), 2, "0")
+ ":" + (0, strings_1.padLeft)(d.getMinutes().toString(), 2, "0")
+ ":" + (0, strings_1.padLeft)(d.getSeconds().toString(), 2, "0")
+ "." + (0, strings_1.padRight)(d.getMilliseconds().toString(), 3, "0");
return `[${timestamp}] ${prefix || LoggerPrefix}`;
}
contextPrefix() {
return `${ConsoleLogger.commonPrefix(this.context.prefix)} [${this.context.name}]`;
}
format(message) {
return `${this.contextPrefix()} ${message}`;
}
setLevel(newLevel) {
if ((0, typecheckers_1.isNumeric)(newLevel)) {
this.context.filterLevel = newLevel;
}
}
getLevel() {
if ((0, typecheckers_1.isNumeric)(this.context.filterLevel))
return this.context.filterLevel;
else
return (0, debug_1.isDebug)() ? LoggerLevel.VERBOSE : LoggerLevel.WARN;
}
enabledFor(level) {
if ((0, debug_1.consoleLoggerFilter)().indexOf(this.context.name) >= 0)
return false;
var filterLevel = this.getLevel();
return level >= filterLevel;
}
debug(message) {
this.logWithLevel(LoggerLevel.DEBUG, message);
}
info(message) {
this.logWithLevel(LoggerLevel.INFO, message);
}
log(message) {
this.logWithLevel(LoggerLevel.LOG, message);
}
/** output a message when debug is off */
warn(message) {
this.logWithLevel(LoggerLevel.WARN, message);
}
/** output a message when debug is off */
error(message) {
this.logWithLevel(LoggerLevel.ERROR, message);
}
/** output a message when debug is off */
trace(message) {
this.logWithLevel(LoggerLevel.TRACE, message);
}
/**start timer on a label, call timeEnd with the same label to print out the time that passed */
time(label) {
if (this.enabledFor(LoggerLevel.DEBUG) && (0, typecheckers_1.isFunction)(console.time))
console.time(`[timer] [kw] [${this.context.name}] ${label}`);
}
/**start timer on a label, call timeEnd with the same label to print out the time that passed */
timeEnd(label) {
if (this.enabledFor(LoggerLevel.DEBUG) && (0, typecheckers_1.isFunction)(console.timeEnd))
console.timeEnd(`[timer] [kw] [${this.context.name}] ${label}`);
}
/**prints an array or dictionary to the console inside a group */
table(data, groupLabel, groupCollapsed) {
if (this.enabledFor(LoggerLevel.DEBUG) && (0, typecheckers_1.isFunction)(console.table)) {
this.group(() => console.table(data), groupLabel, groupCollapsed);
}
}
/**prints a JSON object to the console inside a group */
json(data, groupLabel, groupCollapsed) {
if (this.enabledFor(LoggerLevel.DEBUG) && (0, typecheckers_1.isFunction)(console.dir)) {
this.group(() => console.dir(data), groupLabel, groupCollapsed);
}
}
/**prints an XML object to the console inside a group. If data is string that looks like an XML - will try to parse it. */
xml(data, groupLabel, groupCollapsed) {
if (this.enabledFor(LoggerLevel.DEBUG) && (0, typecheckers_1.isFunction)(console.dirxml)) {
this.group(() => {
if ((0, typecheckers_1.isString)(data) && data.startsWith('<')) {
try {
//maybe this string is an html element?
data = new DOMParser().parseFromString(data, "text/html");
}
catch (e) { }
}
console.dirxml(data);
}, groupLabel, groupCollapsed);
}
}
/** render messages inside a group, and closes the group when done. if a label is not provided - a group will not be rendered */
group(renderContent, label, collapsed) {
let hadGroup = false;
if (this.enabledFor(LoggerLevel.DEBUG) && (0, typecheckers_1.isFunction)(console.group) && !(0, typecheckers_1.isNullOrEmptyString)(label)) {
if (collapsed) {
console.groupCollapsed(`${this.contextPrefix()} ${label}`);
}
else {
console.group(`${this.contextPrefix()} ${label}`);
}
hadGroup = true;
}
if (hadGroup)
this.time(label);
//we must run render content even if no groups - since this might hold other code the caller needs to run
renderContent();
if (hadGroup) {
this.timeEnd(label);
console.groupEnd();
}
}
groupSync(label, renderContent, options) {
if ((0, typecheckers_1.isNullOrEmptyString)(label))
label = "SyncGroup";
let { logMessages, start, logMessage } = this.$startGroup();
let result;
try {
result = renderContent(logMessage);
}
catch (e) {
logMessage(`Unhandled exception: ${e}`);
throw this.$finishGroup(label, e, start, logMessages, options);
}
return this.$finishGroup(label, result, start, logMessages, options);
}
async groupAsync(label, renderContent, options) {
if ((0, typecheckers_1.isNullOrEmptyString)(label))
label = "AsyncGroup";
let { logMessages, start, logMessage } = this.$startGroup();
let result;
try {
result = await renderContent(logMessage);
}
catch (e) {
logMessage(`Unhandled exception: ${e}`);
throw this.$finishGroup(label, e, start, logMessages, options);
}
return this.$finishGroup(label, result, start, logMessages, options);
}
$startGroup() {
let logMessages = [];
let start = new Date();
let lastMessage = start;
let logMessage = (message) => {
logMessages.push({
message: (0, typecheckers_1.isString)(message) || (0, typecheckers_1.isNullOrUndefined)(message)
? message
: (0, objects_1.jsonClone)(message), seconds: (0, date_1.getSecondsElapsed)(lastMessage)
});
lastMessage = new Date();
};
return { logMessage, logMessages, start };
}
$finishGroup(label, result, start, logMessages, options) {
if (options && options.supress)
return result;
label = `${label} (${(0, date_1.getSecondsElapsed)(start)}s)`;
if (this.enabledFor(LoggerLevel.DEBUG) && (0, typecheckers_1.isFunction)(console.group) && !(0, typecheckers_1.isNullOrEmptyString)(label)) {
if (options && options.expand) {
console.group(`${this.contextPrefix()} ${label}`);
}
else {
console.groupCollapsed(`${this.contextPrefix()} ${label}`);
}
}
else
return result;
//drop directly, without a prefix, in the group
logMessages.forEach(m => {
if ((0, typecheckers_1.isString)(m.message))
console.debug(`(${m.seconds}s) ${m.message}`);
else {
console.debug(`(${m.seconds}s) ${m.message.label}`);
console.dir(m.message.value);
}
});
console.groupEnd();
return result;
}
logWithLevel(level, message) {
try {
if (this.enabledFor(level)) {
var isSimpleObject = (0, typecheckers_1.isString)(message) || (0, typecheckers_1.isNumber)(message);
var logMessage = this.format(isSimpleObject ? "%s" : "%o");
switch (level) {
case LoggerLevel.DEBUG:
console.debug(logMessage, message);
break;
case LoggerLevel.ERROR:
console.error(logMessage, message);
break;
case LoggerLevel.WARN:
console.warn(logMessage, message);
break;
case LoggerLevel.INFO:
console.info(logMessage, message);
break;
case LoggerLevel.TRACE:
console.trace(logMessage, message);
break;
default:
console.log(logMessage, message);
}
}
}
catch (ex) {
//empty
}
}
}
exports.ConsoleLogger = ConsoleLogger;
//# sourceMappingURL=consolelogger.js.map