12

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.

user2771142
  • 123
  • 1
  • 1
  • 5

2 Answers2

7

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 version 3.x.x, new (winston.Logger) has been replaced by winston.createLogger (https://github.com/bithavoc/express-winston/issues/175)

Al1
  • 308
  • 3
  • 9
Terry Lennox
  • 29,471
  • 5
  • 28
  • 40
  • This worked, thank you! This is actually close to what I had originally, but I kept getting errors. Not sure what's different, but it works now. – user2771142 Mar 14 '18 at 17:47
  • 1
    Great, it's often a line or two of code but it is still a pain to find the problem! – Terry Lennox Mar 14 '18 at 18:27
  • NB: This will still work even without exporting the loggers from the module - the difference in the code is that your `logger.js` module is now being loaded/executed in `index.js`, which will trigger the `winston.loggers.add` calls, thereby making the loggers available for use by `winston.loggers.get` – bspink Oct 26 '18 at 09:06
  • I don't think this is the *right* answer just because it works. This avoids using the `loggers.add` and `logggers.get` methods of the package -- which was OPs original question; instead you're creating instance of the logger and exporting them from the module. – Schalton Jan 24 '21 at 05:18
2

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..");
mel3kings
  • 8,857
  • 3
  • 60
  • 68