Skip to content

Instantly share code, notes, and snippets.

@Dmitri-Sintsov
Last active December 16, 2024 13:43
Show Gist options
  • Save Dmitri-Sintsov/28d636e44a18be92cfea041cf2cd0ce0 to your computer and use it in GitHub Desktop.
Save Dmitri-Sintsov/28d636e44a18be92cfea041cf2cd0ce0 to your computer and use it in GitHub Desktop.
JavaScript logger with simultaneous console / dom output.
// https://www.reddit.com/r/javascript/comments/n2td8/implementing_printf_in_javascript/
// https://stackoverflow.com/questions/29085197/how-do-you-json-stringify-an-es6-map
function sprintf(msg, ...args) {
return msg.replace(/(%[disv])/g, (match, val) => {
let arg = args.shift();
if (typeof arg !== 'undefined') {
switch(val.charCodeAt(1)) {
case 100: return +arg; // d
case 105: return Math.round(+arg); // i
case 115: return String(arg); // s
case 118: return arg; // v
}
}
return val;
});
}
class Logger {
constructor(consoleInstance, logQuerySelector, space) {
this.console = consoleInstance;
this.logQuerySelector = logQuerySelector;
this.space = (typeof space === 'undefined') ? 4 : space;
}
replacer(key, value) {
if (value instanceof HTMLElement ) {
return value.outerHTML;
} else if (value instanceof Map) {
return Array.from(value.entries());
} else if (value instanceof Set) {
return Array.from(value.values());
} else {
return value;
}
}
log(msg, ...subst) {
this.logAny('log', msg, ...subst);
}
error(msg, ...subst) {
this.logAny('error', msg, ...subst);
}
warn(msg, ...subst) {
this.logAny('warn', msg, ...subst);
}
dir(obj, options) {
this.logAny('dir', obj, options);
}
logAny(method, msg, ...subst) {
console[method].apply(console, [msg, ...subst]);
if (subst.length > 0) {
if (method === 'dir') {
msg = [msg, subst];
} else {
msg = sprintf(msg, ...subst)
}
}
let msgStr = (typeof msg === 'string') ? msg : JSON.stringify(msg, this.replacer, this.space);
const pre = document.createElement('pre');
pre.classList.add(method);
pre.appendChild(document.createTextNode(msgStr));
const logElement = document.querySelector(this.logQuerySelector);
logElement.appendChild(pre);
}
test(el) {
this.dir(el, {colors: true});
this.log({'element': el});
this.warn({'test': 123});
this.error('Hello, %s!', 'world');
}
}
export { sprintf, Logger };
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment