My Code:
import winston from 'winston';
Meteor.startup(() => {
const env = process.env.NODE_ENV || 'development';
const tsFormat = () => (new Date()).toLocaleTimeString();
const logDir = 'log';
const logger1 = new (winston.Logger)({
transports: [
// colorize the output to the console
new (winston.transports.Console)({
timestamp: tsFormat,
colorize: true,
level: 'info',
}),
new (winston.transports.File)({
filename: `${logDir}/results.log`,
timestamp: tsFormat,
level: env === 'development' ? 'debug' : 'info',
}),
],
});
logger1.info('Hello world');
//logger1.warn('Warning message');
//logger1.debug('Debugging info');
});
Output:
I20170717-11:39:11.027(2)? 11:39:10 - info: Hello world
W20170717-11:39:11.150(2)? (STDERR)
W20170717-11:39:11.151(2)? (STDERR) events.js:72
W20170717-11:39:11.152(2)? (STDERR) throw er; // Unhandled 'error' event
W20170717-11:39:11.152(2)? (STDERR) ^
W20170717-11:39:11.153(2)? (STDERR) Error: ENOENT, open 'log/results.log'
The results.log is not even created
Update: When i use only a filename without a path then it works).
Related but not helped solving:
Node.js, can't open files. Error: ENOENT, stat './path/to/file'
What is the problem?
Winston doesn't actually create the directory where you want the logfile to go, which is why you get the ENOENT
.
(I'm not very familiar with Meteor, but the following instructions work on "plain" Node.js)
You can create the directory manually before instantiating Winston to make sure it exists, using fs.mkdirSync
, although that would only go one level deep (it won't create intermediate directories, if there are any in the path).
There's also mkdirp.sync()
, which does create intermediate directories.
Using the synchronous versions is a bit easier, and since it's an operation that only occurs once during the start of the app, it's not a bottleneck.