@tobes31415/console-logger
Version:
Formats console logs while preserving stack trace info
129 lines (128 loc) • 3.91 kB
JavaScript
import { Subject } from "@tobes31415/basic-observables";
import { deepAssign, isNullorUndefined, nullishCoalesce } from "./util.js";
const APP_START_TIME = Date.now();
var LogLevel = /* @__PURE__ */ ((LogLevel2) => {
LogLevel2["debug"] = "debug";
LogLevel2["error"] = "error";
LogLevel2["info"] = "info";
LogLevel2["warn"] = "warn";
return LogLevel2;
})(LogLevel || {});
function LevelToNumber(level) {
switch (level) {
case "debug" /* debug */:
return 0;
case "info" /* info */:
return 1;
case "warn" /* warn */:
return 2;
case "error" /* error */:
return 3;
}
}
const DEFUALT_STYLE = {
namespace: "color: dimgray",
level: "color: dimgray",
uptime: "color: darkgray",
time: "color: lightgray"
};
const DEFAULT_FORMAT = {
namespace: "[${namespace}]",
uptime: (uptime) => `${uptime / 1e3}s`,
time: (time) => time.toISOString(),
level: (level) => level.toUpperCase(),
message: "${message}"
};
const DEFAULT_CONFIG = {
defaultLogLevel: "debug" /* debug */,
logThreshold: "debug" /* debug */,
include: ["namespace", "uptime", "-", "message"],
style: Object.assign({}, DEFUALT_STYLE),
format: Object.assign({}, DEFAULT_FORMAT),
delimiter: " "
};
const currentGlobalConfig = deepAssign({}, DEFAULT_CONFIG);
const broadcastEvent = new Subject();
const onLogEvent = broadcastEvent;
function customizeDefaultLogConfig(newConfig) {
deepAssign(currentGlobalConfig, DEFAULT_CONFIG, currentGlobalConfig, newConfig);
}
function createLoggerFor(namespace, config) {
let currentConfig = config;
const getConfig = () => deepAssign({}, currentGlobalConfig, currentConfig);
const result = handleLog.bind(this, getConfig, namespace, void 0);
Object.values(LogLevel).forEach((level) => result[level] = handleLog.bind(this, getConfig, namespace, level));
result.config = (newConfig) => {
let previousConfig = currentConfig;
currentConfig = deepAssign({}, previousConfig, newConfig);
};
return result;
}
function handleLog(configFn, namespace, level, message, ...extras) {
const config = configFn();
const actualLevel = level || config.defaultLogLevel;
if (LevelToNumber(actualLevel) < LevelToNumber(config.logThreshold)) {
return [];
}
const time = /* @__PURE__ */ new Date();
const logEvent = {
message,
namespace,
level: actualLevel,
extras,
time,
uptime: time.getTime() - APP_START_TIME
};
try {
broadcastEvent.next(logEvent);
} catch (ignored) {
}
return formatLog(config, logEvent);
}
function formatLog(config, event) {
const result = [];
const styles = [];
let isStyleApplied = false;
config.include.forEach((section) => {
const value = event[section];
const interim = [];
const clearStyle = () => {
if (isStyleApplied) {
interim.push("%c");
styles.push("");
isStyleApplied = false;
}
};
if (isNullorUndefined(value)) {
clearStyle();
interim.push(section);
} else {
if (config.style && config.style[section]) {
interim.push("%c");
styles.push(config.style[section]);
isStyleApplied = true;
} else {
clearStyle();
}
const formatter = config.format ? config.format[section] : void 0;
if (!formatter) {
interim.push("" + value);
} else if (typeof formatter === "string") {
interim.push(formatter.replace("${" + section + "}", "" + value));
} else if (typeof formatter === "function") {
interim.push(formatter(value));
} else {
console.error(formatter, config);
throw new Error("Log Formatter invalid, must be string or function");
}
}
result.push(interim.join(""));
});
return [result.join(nullishCoalesce(config.delimiter, " ")), ...styles, ...event.extras];
}
export {
LogLevel,
createLoggerFor,
customizeDefaultLogConfig,
onLogEvent
};