javascript - Winston not displaying text when comma is used as concatenation operator - Stack Overflow

My project is right now making use of winston logger to log to console. The problem is, ma is used as c

My project is right now making use of winston logger to log to console. The problem is, ma is used as concatenation operator in most areas, Like logger.info("here is data", data )

data is a string always, but what gets logged is "here is data" only and nothing else.

Project uses ma as concat in most places so replacing with '+' is tedious. Please favour on how to display data in presence of ma itself

My project is right now making use of winston logger to log to console. The problem is, ma is used as concatenation operator in most areas, Like logger.info("here is data", data )

data is a string always, but what gets logged is "here is data" only and nothing else.

Project uses ma as concat in most places so replacing with '+' is tedious. Please favour on how to display data in presence of ma itself

Share asked Aug 17, 2018 at 8:13 GayathriGayathri 1,9066 gold badges28 silver badges57 bronze badges
Add a ment  | 

4 Answers 4

Reset to default 3

you have basically two ways around it

1) manually change your logger.info function to take multi parameters, or write a logger wrapper that will concatenate the string before passing on to logger.info

info = (...args) => {
   const data = args.reduce((acc, item) => acc += item);
   // or such kind of manual concatenation logic
   logger.info(data);
}

2) use es6 Template literals. so instead of logger.info("here is data", data), use

logger.info(`here is data ${data}`)

Based on Pressana answer, on my createLogger function that its the responsible of creating winston logger and exporting this to the modules that needs to log, I created a logger middleware.

Here it is an example

let env;

exports.createLogger = (envP) => {
  env = envP;
  const logger = winston.createLogger({
    level: 'debug',
    transports: [
      new winston.transports.File({
        filename: __dirname + '/error.log',
        level: 'error'
      }),
      new winston.transports.File({
        filename: __dirname + '/bined.log'
      })
    ],
    'colorize': true
  });

  const customLogger = getCustomLoggerMiddleware(logger);

  if (env !== 'production') {
    logger.add(new winston.transports.Console({
      format: winston.format.simple()
    }));
  }
  return customLogger;
}

function getCustomLoggerMiddleware(logger) {
  const customLogger = {};
  customLogger.error = reduceLogger(logger.error)
  customLogger.warn = reduceLogger(logger.warn)
  customLogger.info = reduceLogger(logger.info)
  customLogger.http = reduceLogger(logger.http)
  customLogger.verbose = reduceLogger(logger.verbose)
  customLogger.debug = reduceLogger(logger.debug)
  customLogger.silly = reduceLogger(logger.silly)
  return customLogger;
}

function reduceLogger(loggerFun) {
  return (...args) => {
    const data = args.reduce((acc, item) => acc += item);
    loggerFun(data);
  }
}

createLogger function its a normal winston logger builder, the magic happens on getCustomLoggerMiddleware

Expanding on Mauricio answer here's another take. Distinction is that it also logs arrays, objects (including circular).

logger.jsm

const path = require('path');
const winston = require('winston');
const safeStringify = require('fast-safe-stringify'); // es with winston

const logger = (forceDev) => {
  //

  const DEVELOPMENT = forceDev || (process.env.NODE_ENV === 'development');

  const logger = winston.createLogger({
    level: (DEVELOPMENT) ? 'silly' : 'info',
    levels: winston.config.npm.levels,
    format: winston.format.bine(
      winston.format.timestamp(),
      winston.format.align(),
      winston.format.printf((info) => `${info.timestamp} [${info.level}] ${info.message}`)
    ),
    transports: DEVELOPMENT
      ? [
        // Output logs to console
        new winston.transports.Console({
          format: winston.format.bine(
            winston.format.colorize(),
            winston.format.timestamp(),
            winston.format.align(),
            winston.format.printf((info) => `${info.timestamp} [${info.level}] ${info.message}`)
          )
        })
      ]
      : [
        // Write all logs to files
        // With level `error` and below to `error.log`
        new winston.transports.File({
          filename: path.join(__dirname, '../logs/winston-error.log'),
          level: 'error'
        }),
        // With level `info` and below to `bined.log`
        new winston.transports.File({
          filename: path.join(__dirname, '../logs/winston-bined.log')
        })
      ]
  });

  process.on('unhandledRejection', (error) => {
    logger.error(error.stack);
  });

  process.on('uncaughtException', (error) => {
    logger.error(error.stack);
  });

  const wrapperFcn = (orgFcn, ...args) => {
    orgFcn(
      args
        // .filter((arg) => arg !== 'whatever') // custom filter
        .reduce((previous, current) => {
          const replacer = null;
          const space = null;
          return `${previous} ${(typeof current === 'string' || current instanceof String) ? current : safeStringify(current, replacer, space)}`;
        }, '')
    );
  };

  const getWrappedLogger = (loggerOrgObj) => {
    const wrappedObject = Object.create(loggerOrgObj);
    Object.assign(wrappedObject, {
      error: wrapperFcn.bind(wrapperFcn, loggerOrgObj.error),
      warn: wrapperFcn.bind(wrapperFcn, loggerOrgObj.warn),
      info: wrapperFcn.bind(wrapperFcn, loggerOrgObj.info),
      http: wrapperFcn.bind(wrapperFcn, loggerOrgObj.http),
      verbose: wrapperFcn.bind(wrapperFcn, loggerOrgObj.verbose),
      debug: wrapperFcn.bind(wrapperFcn, loggerOrgObj.debug),
      silly: wrapperFcn.bind(wrapperFcn, loggerOrgObj.silly)
    });
    return wrappedObject;
  };

  return getWrappedLogger(logger);
};

module.exports = logger;

index.js

const logger = require('./logger.jsm')(true);

const circ = {x: 1};
circ.circ = circ;

// example of non-overridden method, which still works
logger.log({
  level: 'info',
  message: 'Logger launching.'
});

// examples of overridden methods, new behaviour
logger.error('This', 'is', 'log', 'level', 'error', 1, [2, 3], true, {foo: 'bar'}, circ);
logger.warn('This', 'is', 'log', 'level', 'warn', 1, [2, 3], true, {foo: 'bar'}, circ);
logger.info('This', 'is', 'log', 'level', 'info', 1, [2, 3], true, {foo: 'bar'}, circ);
logger.http('This', 'is', 'log', 'level', 'http', 1, [2, 3], true, {foo: 'bar'}, circ);
logger.verbose('This', 'is', 'log', 'level', 'verbose', 1, [2, 3], true, {foo: 'bar'}, circ);
logger.debug('This', 'is', 'log', 'level', 'debug', 1, [2, 3], true, {foo: 'bar'}, circ);
logger.silly('This', 'is', 'log', 'level', 'silly', 1, [2, 3], true, {foo: 'bar'}, circ);

// console.log parison
console.log('This', 'is', 'pure', 'console', 'test', 1, [2, 3], true, {foo: 'bar'}, circ);

The simplest solution is to create a wrapper function anywhere in your codebase to make Winston function more like console.log:

const util = require('util');
log: (...msg) => {
  const customLog = util.format(...msg); //or apply any other custom logic
  winston.info(customLog);
}

You can then use the function like so: log.('param1', 'param2')

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744818119a4595450.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信