0

I have looked for the answer to this for a while and just have not come up with a solution. I understand that I have access to the builtin logger from req.log.xxxxx(...), but what about a module that I have required into my controller? For example:

in my controller file, someController.js

var myModule = require('myModule');

SomeController.listUsers = function listUsers(req, res, next){
    req.log.info('Some log message'); // <---- this works just fine
    //... 
}

In myModule.js:

module.exports = {
    getUsers: function () {
        // ...
        // I would like to be able to log from here, but don't have access to the req object.
    }
}

I don't really like the idea of passing the log object to the module's method, as that seems sloppy to me. If that's the only solution, then I'll live with it.

Aaron Wagner
  • 317
  • 1
  • 3
  • 15

3 Answers3

1

Restify uses bunyan to provide logging.

Looking through the documentation, the logger that's used for req.log is the one that's created at server startup (or at least a child of that logger). Since you can also create your own logger instance, I think that this should work:

// logger.js
var bunyan = require('bunyan');
module.exports = bunyan.createLogger(...);

// app.js
var server = restify.createServer({
  log : require('./logger')
});

// someController.js
var logger = require('./logger');
...

This shares the same logger between the Restify server and other parts of your application. If you don't necessarily require that the logger is the same, you can also just create a new Bunyan instance in someController.js.

robertklep
  • 198,204
  • 35
  • 394
  • 381
  • Excellent solution. I thought about creating a new instance of the logger, and I guess that would have been okay, but I like this a lot better. Thanks for pointing me in the right direction! – Aaron Wagner Dec 16 '15 at 20:52
0

There aren't many options here. Typically I pass the "req" object. Another way around it is utilizing the "this" argument as a context. Something like this:

function listUsers(req, res, next) {
    req.log.info('Some log message');
    myModule.getUsers.call({log: req.log});
}

and...

module.exports = {
    getUsers: function () {
        (this.log || logger.log)() // ...
    }
}
Louay Alakkad
  • 7,132
  • 2
  • 22
  • 45
  • I thought about this, but hated the idea of muddying up each method. See the accepted answer for what I did. Thanks for the input! – Aaron Wagner Dec 16 '15 at 20:53
  • 1
    Oh, that's a different story then. What I thought was that `req.log` is unique per request. I.e. each request has a different ID and you can get logs per request (we do have such a setup). – Louay Alakkad Dec 17 '15 at 10:57
0

Usually, loggers get required into modules, implemented in the middleware, or inside a custom error object.

Another option you have in Events. Node.js is an Event driven language. You can just create a logger module that listens for log events. That's called neat programming.

However, I'd choose to require my logger into files, so that when we go into prod I have it deactivated/replaced with another more specific logger object with the exact interface.