Search code examples
node.jssails.jswinston

Why Winston 3.0.0 is not working with Sails 0.12?


I have these settings in the file config/log.js

let {transports: transp, createLogger} = require('winston');    
let commonSettings = {
    colorize: false,
    maxsize: 10000000,
    maxfiles: 10,
    timestamp: true
};

let settings = [{ filename: 'logs/warn.log', level: 'warn' }];    
let logger = createLogger({
    transports: settings.map(s => new transp.File({...s, ...commonSettings}))
});

module.exports.log = {
    custom: logger,
    inspect: false
};

When I'm trying to start the Sails server using this command sails lift, I'm getting the following error:

Uncaught TypeError: this.write is not a function
  at Function.DerivedLogger.(anonymous function) (node_modules/winston/lib/winston/create-logger.js:45:14)
  at Function._writeLogToConsole [as error] (node_modules/captains-log/lib/write.js:78:16)
  at Sails.runBootstrap (node_modules/sails/lib/app/private/bootstrap.js:56:17)
  at Sails.bound [as runBootstrap] (node_modules/sails/node_modules/lodash/dist/lodash.js:729:21)
  at Sails.initialize (node_modules/sails/lib/app/private/initialize.js:48:9)
  at bound (node_modules/sails/node_modules/lodash/dist/lodash.js:729:21)
  at /Users/egomezr/Documents/stack/backend/node_modules/sails/node_modules/async/lib/async.js:607:21
  at /Users/egomezr/Documents/stack/backend/node_modules/sails/node_modules/async/lib/async.js:246:17
  at iterate (node_modules/sails/node_modules/async/lib/async.js:146:13)
  at /Users/egomezr/Documents/stack/backend/node_modules/sails/node_modules/async/lib/async.js:157:25
  at /Users/egomezr/Documents/stack/backend/node_modules/sails/node_modules/async/lib/async.js:248:21
  at /Users/egomezr/Documents/stack/backend/node_modules/sails/node_modules/async/lib/async.js:612:34
  at /Users/egomezr/Documents/stack/backend/node_modules/sails/lib/app/load.js:201:13
  at /Users/egomezr/Documents/stack/backend/node_modules/sails/node_modules/async/lib/async.js:451:17
  at /Users/egomezr/Documents/stack/backend/node_modules/sails/node_modules/async/lib/async.js:441:17
  at _each (node_modules/sails/node_modules/async/lib/async.js:46:13)
  at Immediate.taskComplete (node_modules/sails/node_modules/async/lib/async.js:440:13)
  at process.topLevelDomainCallback (domain.js:101:23)

What could be the problem?


Solution

  • It looks Sails makes a sort of binding into the Winston logger, therefore, the logger loses some functionalities.

    Open issue: issues/4337

    I found a workaround to get it work:

    let commonSettings = {
        colorize: false,
        maxsize: 10000000,
        maxfiles: 10,
        json: false
    };
    
    let settings = [
        {filename: `${__dirname}/../logs/warn.log`, level: 'warn'},
        {filename: `${__dirname}/../logs/error.log`, level: 'error'},
        {filename: `${__dirname}/../logs/debug.log`, level: 'debug'},
        {filename: `${__dirname}/../logs/info.log`, level: 'info'}
    ];
    
    let {transports, createLogger, format} = require('winston');
    let loggerSettings = {
        transports: [...settings.map(s => new transports.File({...s, ...commonSettings})), new transports.Console({
            format: format.simple()
        })],
        exitOnError: false
    };
    
    // This is the workaround
    let winstonLogger = createLogger(loggerSettings);
    let logger = {
        'info': function () {
            winstonLogger.info(...arguments);
        },
        'debug': function () {
            winstonLogger.debug(...arguments);
        },
        'error': function () {
            winstonLogger.error(...arguments);
        },
        'warn': function () {
            winstonLogger.warn(...arguments);
        },
        'log': function () {
            winstonLogger.log(...arguments);
        }
    };
    // End of workaround
    
    module.exports.log = {
        custom: logger,
        inspect: false
    };