Last active
October 4, 2016 04:01
-
-
Save axefrog/b85a336290d3bccdb21e to your computer and use it in GitHub Desktop.
Logging driver for cycle.js
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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$() | |
| }; | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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