Search code examples
node.jsherokuwinston

Can I use Winston logger in Heroku


I setup a Winston logger in my development machine with a Node.js server. Based on the dbState I change the name of the log file:

const { createLogger, transports, format } = require('winston');
const keys = require('../config/keys');

const dbState = keys.db.state;

const customFormat = format.combine(format.timestamp(), format.printf((info) => `${info.timestamp} [${info.level.padEnd()}]: ${info.message}`));

const logger = createLogger({
  format: customFormat,

  transports: [
    new transports.File({ filename: `${dbState}-error.log`, level: 'error' }),
    // After it reaches 10MB, it will create a new file and start writing to that
    new transports.File({ filename: `${dbState}-combined.log`, maxsize: 10000000 }),
  ],
});

logger.stream = {
  write(message, _encoding) {
    console.log(message.trim());
    logger.info(message.trim());
  },
};

module.exports = logger;

I have pushed this update to Heroku now, where the log file is probably increasing. Is there a way to access this log file?


Solution

  • You can use Winston, but avoid its file transports. File-based logging is an antipattern on Heroku:

    • Any changes to the filesystem (e.g. log files ) are lost whenever the dyno restarts due to its ephemeral filesystem

    • Dynos restart frequently and unpredictably:

      Cycling happens for all dynos, including one-off dynos, so dynos will run for a maximum of 24 hours + 216 minutes.

    • Logging to a local file breaks as soon as you want to scale horizontally by adding more dynos

    Heroku treats logs as event streams, so consider using Winston's Console transport. This should make logs from all of your dynos show up in the standard event stream.

    If you wish, you can use a logging addon like Logtail or Papertrail to query your logs downstream.