UNPKG

solive-winston-logger

Version:
104 lines (93 loc) 2.83 kB
import winston from 'winston' import _ from 'lodash' import parse from './parse' import { colors, levels } from './constants' class Logger { /** * creates a loggger and initiates the socket client * to send all the logs to a log-manager * * @param {Object} config * @param {string} config.env - should be one of production|testing|development * @param {Function} config.onNewLog - a function that's called on each log * @param {Object} fields - all the fields that are needed to log * like tag, action, name, error, ... */ constructor({ env, onNewLog }, fields = {}) { this.logger = this.createLogger(env) this.env = env this.fields = { ...fields } this.onNewLog = onNewLog this.populateLogger() } /** * Creates a winston logger based on the env * * @param {String} env - needed to set the logger level * in production, we don't want to log everything like the trace * or the debug should be omitted * @returns {Object} An instance of a Winston logger */ createLogger = env => new (winston.Logger)({ colors, levels, transports: [ new (winston.transports.Console)({ timestamp: false, colorize: env !== 'production', prettyPrint: true, level: env === 'production' ? 'info' : 'trace', }), ], }) /** * Populates the logger with all the logging functions * Once this function executes, this should includes * the following methods: trace, debug, info, warn, error, fatal */ populateLogger = () => _.forEach(levels, (level, key) => { this[key] = this.log(key) }) /** * Will parse then display the log on the stdout or stderr * and send it via socket if the env is "production" * It throws if a required field is not provided * * @param {String} key - one of trace|debug|info|warn|error|fatal * @param {String} message - the message of the log * @param {Object} fields - all the fields that are needed to log * like tag, action, name, error, ... */ log = key => (message, fields = {}) => { const log = { message, ...this.fields, ...fields, date: new Date(), } if (typeof fields !== typeof {}) { const error = 'fields should be an object' console.error(new Error(error)) return error } const err = parse(key, log) if (err) { console.error(new Error(err)) return err } this.logger.log.call(this.logger, key, message, _.omit(log, ['message'])) if (this.onNewLog) { this.onNewLog(log) } } /** * Creates a new logger based on the previous on but with different fields * @param {Object} fields - all the fields that are needed to log * like tag, action, name, error, ... */ create = fields => new Logger( { env: this.env, onNewLog: this.onNewLog }, { ...this.fields, ...fields }, ) } export default ({ env, onNewLog }) => new Logger({ env, onNewLog })