How to use Winston in several modules?

前端 未结 11 1515
隐瞒了意图╮
隐瞒了意图╮ 2020-12-22 23:40

I have several modules - let\'s say server.js, module1.js,...,moduleN.js.

I would like define the log file in my server.js:

winston.add(winston.trans         


        
相关标签:
11条回答
  • 2020-12-23 00:00

    if you want to make the logger a global variable- you have to do specifically by assign it to the global variable like so

    logger.js

    var winston = require('winston')
    
    var winston = winston.createLogger({
    transports: [
      new (winston.transports.Console)(),
      new (winston.transports.File)({
        filename: './logs/logger.log'
      })
    ]
    });
    module.exports=winston;
    

    app.js

    let logger  = require('./logger')
    global.__logger = logger
    

    someController.js

    __logger.info('created log successfully')
    

    Note: it's good practice to assign a prefix for every global variable so you will know that is a global one. i'm using __ as prefix (double low dash)

    0 讨论(0)
  • 2020-12-23 00:00

    In my team we have created a private npm package with all default configs (as you've shown in previous answers)

    I've just one question: would it be a good practice to declare the logger object as a global in order to avoid import in each and every module?

    0 讨论(0)
  • 2020-12-23 00:01

    The default logger concept handles this nicely.

    Winston defines a default logger that any straight require (and subsequent require) to winston will retrieve. Thus you simply configure this default logger once, and it's available for subsequent module use via vanilla require('winston') in its glorious tweaked multi-transport mode.

    e.g. here is my complete logging setup that defines 3 transports. I swap Loggly for MongoDB sometimes.

    server.js

    var logger=require('./log.js'); 
    // requires winston and configures transports for winstons default logger- see code below.
    

    all other .js files

    var logger=require('winston'); // this retrieves default logger which was configured in log.js
    logger.info("the default logger with my tricked out transports is rockin this module");
    

    log.js - this is a one time configuration of the DEFAULT logger

    var logger = require('winston');
    var Loggly = require('winston-loggly').Loggly;
    var loggly_options={ subdomain: "mysubdomain", inputToken: "efake000-000d-000e-a000-xfakee000a00" }
    logger.add(Loggly, loggly_options);
    logger.add(winston.transports.File, { filename: "../logs/production.log" });
    logger.info('Chill Winston, the logs are being captured 3 ways- console, file, and Loggly');
    module.exports=logger;
    

    Alternatively for more complex scenarios you can use winston containers and retrieve the logger from a named container in other modules. I haven't used this.

    My only issue with this was a missing logs directories on my deployment host which was easily fixed.

    Hope this helps.

    0 讨论(0)
  • 2020-12-23 00:09

    I wanted to use custom colours and levels.

    So I removed the default console-transport and set a colorized one

    here is my logger.js

    var logger = require('winston');
    
    logger.setLevels({
        debug:0,
        info: 1,
        silly:2,
        warn: 3,
        error:4,
    });
    logger.addColors({
        debug: 'green',
        info:  'cyan',
        silly: 'magenta',
        warn:  'yellow',
        error: 'red'
    });
    
    logger.remove(logger.transports.Console);
    logger.add(logger.transports.Console, { level: 'debug', colorize:true });
    
    module.exports = logger;
    



    Loading from app.js:

    var logger = require('./lib/log.js');  
    



    Loading from other modules:

     var logger = require('winston');        
    
    0 讨论(0)
  • 2020-12-23 00:09

    Slightly off topic (as the OP asks about Winston), but I like the 'child-logger' approach by Bunyan:

    var bunyan = require('bunyan');
    var log = bunyan.createLogger({name: 'myapp'});
    
    app.use(function(req, res, next) {
      req.log = log.child({reqId: uuid()});
      next();
    });
    
    app.get('/', function(req, res) {
      req.log.info({user: ...});
    });
    

    It solves the OP's problem as the logger is available through the req object (hence no need for 'require(log)' in each module). Additionally, all log entries belonging to a particular request will have a unique ID that connects them together.

    {"name":"myapp","hostname":"pwony-2","pid":14837,"level":30,"reqId":"XXXX-XX-XXXX","user":"...@gmail.com","time":"2014-05-26T18:27:43.530Z","v":0}
    

    I'm not sure if Winston supports this as well.

    0 讨论(0)
  • 2020-12-23 00:19

    What I do ( which may not be the best way ) is use a 'global' module where I export all the stuff that I use through my applications. For instance:

    //Define your winston instance
    winston.add(winston.transports.File, { filename: 'mylogfile.log' });
    exports.logger = winston;
    
    exports.otherGlobals = ....
    

    Now just require this globally used module from your other modules

    var Global = require(/path/to/global.js);
    

    Because the file is cached after the first time it is loaded (which you can verify by including a log statement in your global; it will only log once), there's very little overhead in including it again. Putting it all into one file is also easier than requiring ALL your globally used modules on every page.

    0 讨论(0)
提交回复
热议问题