Last active
December 9, 2016 13:06
-
-
Save zerobias/15b273b367b2be5c2780dead21deb414 to your computer and use it in GitHub Desktop.
Logger
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
const winston = require('winston') | |
const R = require('ramda') | |
const chalk = require('chalk') //console colorizer | |
const P = R.pipe //Short form for pipe: the most frequently used function | |
const yellowTag = chalk.bold.yellow | |
const redTag = chalk.bold.bgRed.black | |
//Simply write 'error' and its will be marked red, | |
//and any other wiil be yellow if its hasnt have color yet | |
const colorize = R.ifElse( | |
R.equals(`[ERROR]`), | |
redTag, | |
R.unless(chalk.hasColor, yellowTag)) | |
//' raw tag ' => '[RAW TAG]' | |
const normalizeTag = P( | |
R.trim, | |
R.toUpper, | |
e => `[${e}]`, | |
colorize) | |
//Split tag strings and reject emtpy | |
//'tag1,tag2,,tag4' | |
// => [ 'tag1', 'tag2', '', 'tag4' ] | |
// => [ 'tag1', 'tag2', 'tag4' ] | |
const splitTagArray = P( | |
R.split(','), | |
R.reject(R.isNil)) | |
const normalizeTags = P( | |
R.flatten, | |
// allow to send any combination of tags arrays: | |
// [ 'tag1', [ 'special tag', 'custom tag', [ 'index tag' ] ] ] => | |
// [ 'tag1', 'special tag', 'custom tag', 'index tag' ] | |
R.map(splitTagArray), // [ 'tag1,tag2', 'tag3' ] into [ 'tag1', 'tag2', 'tag3' ] | |
R.flatten, // | |
R.map(normalizeTag), | |
R.join('')) | |
const isArray = R.is(Array) | |
const normalizeDefaults = R.ifElse( | |
R.isEmpty, | |
() => '', //TODO replace with R.identity | |
normalizeTags) //Normalize every non-empty tag | |
const throwNonArray = e => { throw new TypeError(`Recieved ${R.type(e)} (non-array) object`) } | |
//function arrayPrint allows ony arrays | |
const arrayCheck = R.unless( isArray, throwNonArray ) | |
const maxArrayLn = 50 | |
//trim arrays to first 50 elements | |
const messageArrayProtect = R.map( | |
R.when( | |
isArray, | |
R.take( maxArrayLn ) ) ) | |
/** | |
* Allow to select log level | |
* @function genericLog | |
* @param {LoggerInstance} logger Winston logger instance | |
* @param {string} logLevel Log level | |
*/ | |
function genericLog(logger, logLevel='info'){ | |
const levelLogger = logger[logLevel] | |
/** | |
* tagged Logger | |
* @function taggedLog | |
* @param {...string} tags Optional message tags | |
*/ | |
function taggedLog(...tags){ | |
const tag = normalizeDefaults(tags) | |
/** | |
* message Logger | |
* @function messageLog | |
* @param {...string} message message | |
* @returns {void} | |
*/ | |
function messageLog(...message) { | |
const protectedMessage = messageArrayProtect(message) | |
levelLogger(tag, ...protectedMessage) | |
} | |
function printArray(message) { | |
arrayCheck(message) | |
//count length + 2. Also handles edge case with objects without 'length' field | |
const spaceLn = P( | |
R.length, | |
R.defaultTo(0), | |
R.add(2) ) | |
const ln = R.sum( R.map( spaceLn, tags ) ) | |
const spaces = new Array(ln) | |
.fill(' ') | |
.join('') | |
const getFormatted = num => chalk.green(`<${num}>`) | |
levelLogger( tag, getFormatted(0), R.head( message ) ) | |
const printTail = (e, i) => levelLogger(spaces, getFormatted(i+1), e) | |
//Special declaration in ramda to create common map function: (object,index)=>... | |
//Because R.map by default allow only object=>... form | |
const indexedMap = R.addIndex(R.map) | |
P( | |
R.tail, | |
indexedMap(printTail) | |
)(message) | |
} | |
messageLog.map = printArray | |
return messageLog | |
} | |
return taggedLog | |
} | |
/** | |
* Logging function based on winston library | |
* @function winLog | |
* @param {string} moduletag Name of apps module | |
*/ | |
function winLog(moduletag) { | |
winston.loggers.add(moduletag, { | |
console: { | |
colorize: true, | |
label : moduletag | |
} | |
}) | |
const logger = winston.loggers.get(moduletag) | |
const defs = genericLog(logger) | |
defs.warn = genericLog(logger, 'warn') | |
defs.error = genericLog(logger, 'error') | |
defs.debug = genericLog(logger, 'debug') | |
defs.info = genericLog(logger, 'info') | |
return defs | |
} | |
//TODO Implement preview print | |
const printable = maxLen => P( R.toString, R.take( maxLen ) ) | |
const printable100 = printable(100) | |
module.exports = winLog |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment