I'm trying to set up an access log and an error log for my express server using Winston, but I seem to be doing something wrong.
Here is my attempt at a config file:
const winston = require('winston'),
fs = require('fs');
const tsFormat = () => (new Date()).toLocaleTimeString();
winston.loggers.add('errorLog', {
file: {
filename: '<path>/errors.log', //<path> is replaced by the
timestamp: tsFormat, //absolute path of the log
level: 'info'
}
});
winston.loggers.add('accessLog', {
file: {
filename: '<path>/access.log', //same as before
timestamp: tsFormat,
level: 'info'
}
});
And this is how I'm including it in my other files:
var winston = require('winston'),
accessLog = winston.loggers.get('accessLog'),
errorLog = winston.loggers.get('errorLog');
This seems to me like it follows the documentation (https://github.com/winstonjs/winston/tree/2.4.0#working-with-multiple-loggers-in-winston)
but I'm getting this error when I try to log to it:
[winston] Attempt to write logs with no transports {"message":"pls","level":"info"}
[winston] Attempt to write logs with no transports {"message":"Bad request: undefined","level":"warn"}
Any help would be greatly appreciated, I've been pretty stumped for a couple days now.
I'd try something like this, put all the logger related stuff into a module logger.js:
logger.js
var winston = require('winston');
var path = require('path');
// Set this to whatever, by default the path of the script.
var logPath = __dirname;
const tsFormat = () => (new Date().toISOString());
const errorLog = winston.createLogger({
transports: [
new winston.transports.File({
filename: path.join(logPath, 'errors.log'),
timestamp: tsFormat,
level: 'info'})
]
});
const accessLog = winston.createLogger({
transports: [
new winston.transports.File({
filename: path.join(logPath, 'access.log'),
timestamp: tsFormat,
level: 'info'})
]
});
module.exports = {
errorLog: errorLog,
accessLog: accessLog
};
and then test in index.js:
index.js
var logger = require('./logger');
logger.errorLog.info('Test error log');
logger.accessLog.info('Test access log');
You should see log lines like:
errors.log:
{"level":"info","message":"Test access log","timestamp":"2018-03-14T07:51:11.185Z"}
access.log:
{"level":"info","message":"Test error log","timestamp":"2018-03-14T07:51:11.182Z"}
EDIT
On Winston last version, new (winston.Logger)
has been replaced by winston.createLogger
(https://github.com/bithavoc/express-winston/issues/175)
1 Logger + console logging for development purpose:
logger.js
var logPath = '';
var log_level = '';
const log = winston.createLogger({
level: log_level,
format: winston.format.json(),
transports: [
new winston.transports.File({
filename: path.join(logPath, 'access.log'),
timestamp: tsFormat,
level: log_level
}),
new winston.transports.File({
filename: path.join(logPath, 'error.log'),
timestamp: tsFormat,
level: 'error'
}),
]
});
if (process.env.NODE_ENV !== 'production') {
log.add(new winston.transports.Console({
format: winston.format.simple()
}));
}
module.exports = {
log: log
};
app.js
const logger = require('./logger');
logger.log.info("starting application..");
Since you were creating the winston
variable in the original code as const winston
it wasn't able to add transports and other options in the following lines. The proposed solution moves the similar code into a module but assigns winston
variable into var winston
.