Skip to content

Instantly share code, notes, and snippets.

@axefrog
Last active September 8, 2015 14:14
Show Gist options
  • Save axefrog/2f372e40049428154710 to your computer and use it in GitHub Desktop.
Save axefrog/2f372e40049428154710 to your computer and use it in GitHub Desktop.
Simple logger for my Cycle.js apps. Writes pretty console output and exposes an observable message stream if further processing is desired.
import logger from './logger';
let log = logger('Category');
log.trace('Just tracing stuff');
log.debug('Here is a debug message');
log.success('The successful thing happened that we wanted to happen');
log.info('Information makes the world go around, and here is that string:', str);
log('An info message can be logged using short form');
log.warn('You better be careful about this kind of thing');
log.error('Argh, something bad happened');
log.error(new Error('Your code has an error'));
log.fatal('Oh no! The world is ending!', new Error('Your code has a fatal error'));
'use strict';
import _ from 'lodash';
import {Rx} from '@cycle/core';
function makeLogMessage(level, category, args) {
return {
level: level,
category: category,
args: args
};
}
function decomposeMessage(msg) {
// todo: introduce serilog-flavoured log arguments, rather than discarding extra args
let message, error = null, args = msg.args;
if(args[0] instanceof Error) {
error = args[0];
message = error.message;
args = args.slice(1);
}
else if(args[args.length - 1] instanceof Error) {
message = args[0];
error = args[args.length - 1];
args = args.slice(0, args.length - 1);
}
else if(_.isObject(args[0])) {
message = '';
}
else {
message = args[0];
args = args.slice(1);
}
return [msg.level, msg.category, message, error, args];
}
function writeConsole([level, category, message, error, args]) {
let catbg, catfg, msgbg, msgfg, levelLabel;
switch(level) {
case 'trace': [levelLabel, catbg, catfg, msgbg, msgfg] = [' TRACE ', '#eee', '#999', 'default', '#bbb']; break;
case 'debug': [levelLabel, catbg, catfg, msgbg, msgfg] = [' DEBUG ', '#63c', 'white', 'default', '#63c']; break;
case 'info': [levelLabel, catbg, catfg, msgbg, msgfg] = [' INFO ', '#333', '#eee', 'default', 'default']; break;
case 'success': [levelLabel, catbg, catfg, msgbg, msgfg] = ['SUCCESS', '#9d9', '#262', 'default', '#090']; break;
case 'warn': [levelLabel, catbg, catfg, msgbg, msgfg] = ['WARNING', '#ee0', '#933', '#ffe', '#933']; break;
case 'error': [levelLabel, catbg, catfg, msgbg, msgfg] = [' ERROR ', '#900', '#ff3', 'default', '#c00']; break;
case 'fatal': [levelLabel, catbg, catfg, msgbg, msgfg] = [' FATAL ', '#c00', '#ff0', '#ff3', '#c00']; break;
default: return;
}
console.log(`%c ${levelLabel} %c %c[${category||'General'}] ${message}`,
`background: ${catbg}; color: ${catfg};`, '',
`background: ${msgbg}; color: ${msgfg};`, ...args);
if(error) {
console.error(error);
}
}
let subject = new Rx.Subject();
subject.subscribe(msg => {
let data = decomposeMessage(msg);
writeConsole(data);
});
function createLogger(category) {
function logger(...args) {
subject.onNext(makeLogMessage('info', category, args));
}
logger.trace = function(...args) { subject.onNext(makeLogMessage('trace', category, args)); }
logger.debug = function(...args) { subject.onNext(makeLogMessage('debug', category, args)); }
logger.success = function(...args) { subject.onNext(makeLogMessage('success', category, args)); }
logger.info = logger;
logger.warn = function(...args) { subject.onNext(makeLogMessage('warn', category, args)); }
logger.error = function(...args) { subject.onNext(makeLogMessage('error', category, args)); }
logger.fatal = function(...args) { subject.onNext(makeLogMessage('fatal', category, args)); }
return logger;
}
createLogger.message$ = subject.asObservable();
export default createLogger;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment