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 badges4 Answers
Reset to default 3you 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条)