Best practices for sharing loggers

206 views
Skip to first unread message

Mats Julian Olsen

unread,
Jun 1, 2015, 4:44:51 AM6/1/15
to bunyan-...@googlegroups.com
Hi guys.

Sorry if this has been asked before, or is exceptionally simple to figure out.

In my app I have, say, three components, main.js, a.js and b.js. main.js requires both a.js and b.js, and a.js also requires b.js.
 
I am implementing proper logging for this app. So in main.js I setup a bunyan logger, and when I require modules I send in a child logger for each of them. So from main, a and b are required with each their child logger. But what do I do when a requires b?
  • Do I create a child logger in a and give it to b?
  • Do I inject the 'instance' of b that was initialized in main.js into a?

I'm just struggling to find the best way of structuring this. Perhaps the best way is rethinking the architecture. Any help is much appreciated.

Thanks,

Mats

Trent Mick

unread,
Jun 2, 2015, 1:05:10 AM6/2/15
to Mats Julian Olsen, bunyan-...@googlegroups.com
One way you could do it:

```
[22:00:16 trentm@grape:~/tmp/play]
$ cat main.js
var bunyan = require('bunyan');
var a = require('./a');
var b = require('./b');

var log = bunyan.createLogger({name: 'main'});
a.setLogger(log);
b.setLogger(log);

a.hi();
b.hi();
[22:00:27 trentm@grape:~/tmp/play]
$ cat a.js
var b = require('./b');

var log;

function hi() {
    log.info('hi from a');
}

module.exports = {
    hi: hi,
    setLogger: function (log_) {
        b.setLogger(log_);
        log = log_;
    }
};
[22:00:29 trentm@grape:~/tmp/play]
$ cat b.js
var log;

function hi() {
    log.info('hi from b');
}

module.exports = {
    hi: hi,
    setLogger: function (log_) {
        log = log_;
    }
};
```

Another way, more typical to what I tend to do is have modules' exported functions take a 'log' option:

```
$ cat mylib.js
function something(opts, cb) {
    opts.log.trace('starting doing something')
    // ...
}

module.exports = {
    something: something
};
```

or have modules' exported "classes" take a `log` option to their constructor:

```
$ cat mylib2.js
function Widget(opts) {
    this.log = opts.log;
    // ...
}
Widget.prototype.wuzzle = function (opts, cb) {
    this.log.trace('wuzzle fo shizzle');
    // ...
};

module.exports = Widget;
```

Cheers,
Trent

--
Trent Mick

Mats Julian Olsen

unread,
Jun 2, 2015, 7:24:51 AM6/2/15
to bunyan-...@googlegroups.com, ma...@plysjbyen.net
Thanks a bunch Trent!

The last way is how I tend to do it as well. Passing the log object in the options. However, I think I might have failed explaining my situation well enough.

main.js requires b.js and gives it a child logger.
main.js requires a.js and gives it a child logger too.
a.js requires b.js and .... (what does it do? give it a child logger of the child logger?)

I guess it's not as bunyan specific as I thought it was, but more of a design question and how to make sure the logging is sensible. Any further thoughts?

Trent Mick

unread,
Jun 13, 2015, 2:14:26 AM6/13/15
to Mats Julian Olsen, bunyan-...@googlegroups.com
Mats,


If a.js and b.js have fields that they want to add to the log records (i.e. a reason to use `log.child(...)`), then yes I'd "give it a child logger of the child logger".

Cheers,
Trent
--
Trent Mick
Reply all
Reply to author
Forward
0 new messages