Skip to content

Instantly share code, notes, and snippets.

@axefrog
Last active October 4, 2016 04:01
Show Gist options
  • Select an option

  • Save axefrog/b85a336290d3bccdb21e to your computer and use it in GitHub Desktop.

Select an option

Save axefrog/b85a336290d3bccdb21e to your computer and use it in GitHub Desktop.
Logging driver for cycle.js
import {Rx} from '@cycle/core';
export default function (responses, strings) {
var log = responses.log.create('Sample');
var str$ = Rx.Observable
.from(strings)
.do(str => {
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'));
})
.map(str => '[' + strings + ']')
.doOnCompleted(() => {
log.info('Finished doing stuff with strings.');
log.close();
});
return {
str$: str$,
log$: log.get$()
};
}
import _ from 'lodash';
import {Rx} from '@cycle/core';
function makeLogMessage(level, category, args) {
return {
level: level,
category: category,
args: args
};
}
function createLogger(category) {
let subject = new Rx.ReplaySubject();
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)); }
logger.close = function() { subject.onCompleted(); }
logger.get$ = function() { return subject.asObservable(); }
return logger;
}
function decomposeMessage(msg) {
// todo: introduce serilog-flavoured log arguments, rather than discarding extra args
var 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 {
message = args[0];
args = args.slice(1);
}
return [msg.level, msg.category, message, error, args];
}
function initializeLogMessageConsumer(msg$, options) {
function write(msg) {
var data = decomposeMessage(msg);
if(options.console) {
writeConsole(data);
}
// todo: write to other targets
}
function writeConsole([level, category, message, error, args]) {
var 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);
}
}
return {
subscription: msg$.subscribe(write)
};
}
export function makeLogDriver(options) {
options = _.extend({
console: true
}, options);
let broadcastSubject = new Rx.Subject();
let state = initializeLogMessageConsumer(broadcastSubject, options);
return function(message$) {
message$.subscribe(msg => broadcastSubject.onNext(msg));
return {
create: createLogger,
message$: broadcastSubject.asObservable(),
_state: state
};
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment