Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added support for Request ID generators #670

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
/tmp
/node_modules
/.idea/
/tmp/
/node_modules/

*.log
!/test/corpus/*.log
/*.tgz
Expand Down
63 changes: 32 additions & 31 deletions AUTHORS
Original file line number Diff line number Diff line change
@@ -1,42 +1,43 @@
Trent Mick (http://trentm.com)
Mark Cavage (https://github.com/mcavage)
Dave Pacheco (https://github.com/davepacheco)
Michael Hart (https://github.com/mhart)
Isaac Schlueter (https://github.com/isaacs)
Rob Gulewich (https://github.com/rgulewich)
Bryan Cantrill (https://github.com/bcantrill)
Michael Hart (https://github.com/mhart)
Simon Wade (https://github.com/aexmachina)
https://github.com/glenn-murray-bse
Chakrit Wichian (https://github.com/chakrit)
Patrick Mooney (https://github.com/pfmooney)
Johan Nordberg (https://github.com/jnordberg)
https://github.com/timborodin
Ryan Graham (https://github.com/rmg)
Adam Lynch (https://github.com/adam-lynch)
Alex Kocharin (https://github.com/rlidwka)
Alexander Ray (https://github.com/aray12)
Andrei Neculau (https://github.com/andreineculau)
Mihai Tomescu (https://github.com/matomesc)
Daniel Juhl (https://github.com/danieljuhl)
Bryan Cantrill (https://github.com/bcantrill)
Chakrit Wichian (https://github.com/chakrit)
Charly Koza (https://github.com/Cactusbone)
Chris Barber (https://github.com/cb1kenobi)
Manuel Schneider (https://github.com/manuelschneider)
Martin Gausby (https://github.com/gausby)
Stéphan Kochen (https://github.com/stephank)
Shakeel Mohamed (https://github.com/shakeelmohamed)
Cody Mello (https://github.com/melloc)
Daniel Juhl (https://github.com/danieljuhl)
Dave Pacheco (https://github.com/davepacheco)
David M. Lee (https://github.com/leedm777)
Denis Izmaylov (https://github.com/DenisIzmaylov)
Frankie O'Rourke (https://github.com/psfrankie)
Guillermo Grau Panea (https://github.com/guigrpa)
Mark LeMerise (https://github.com/MarkLeMerise)
https://github.com/sometimesalready
Charly Koza (https://github.com/Cactusbone)
Thomas Heymann (https://github.com/cyberthom)
David M. Lee (https://github.com/leedm777)
Isaac Schlueter (https://github.com/isaacs)
Johan Nordberg (https://github.com/jnordberg)
Manuel Schneider (https://github.com/manuelschneider)
Marc Udoff (https://github.com/mlucool)
Mark Cavage (https://github.com/mcavage)
Mark LeMerise (https://github.com/MarkLeMerise)
Mark Stosberg (https://github.com/markstos)
Alexander Ray (https://github.com/aray12)
Adam Lynch (https://github.com/adam-lynch)
Michael Nisi (https://github.com/michaelnisi)
Martijn Schrage (https://github.com/Oblosys)
Martin Gausby (https://github.com/gausby)
Michael Hart (https://github.com/mhart)
Michael Hart (https://github.com/mhart)
Michael Nisi (https://github.com/michaelnisi)
Mihai Tomescu (https://github.com/matomesc)
Patrick Mooney (https://github.com/pfmooney)
Paul Milham (https://github.com/domrein)
Frankie O'Rourke (https://github.com/psfrankie)
Cody Mello (https://github.com/melloc)
Rob Gulewich (https://github.com/rgulewich)
Ryan Graham (https://github.com/rmg)
Shakeel Mohamed (https://github.com/shakeelmohamed)
Simon Wade (https://github.com/aexmachina)
Slava Fomin II (https://github.com/slavafomin)
Stéphan Kochen (https://github.com/stephank)
Thomas Heymann (https://github.com/cyberthom)
Todd Whiteman (https://github.com/twhiteman)
Trent Mick (http://trentm.com)
Zach Bjornson (https://github.com/zbjornson)
https://github.com/glenn-murray-bse
https://github.com/sometimesalready
https://github.com/timborodin
96 changes: 96 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ record (see below).
- [Log Record Fields](#log-record-fields)
* [Core fields](#core-fields)
* [Recommended/Best Practice Fields](#recommendedbest-practice-fields)
* [Request ID](#request-id)
* [Other fields to consider](#other-fields-to-consider)
- [Streams](#streams)
* [Adding a Stream](#adding-a-stream)
Expand Down Expand Up @@ -154,6 +155,7 @@ var log = bunyan.createLogger({
streams: [<bunyan streams>, ...], // Optional, see "Streams" section
serializers: <serializers mapping>, // Optional, see "Serializers" section
src: <boolean>, // Optional, see "src" section
req_id: <string | function>, // Optional, see "Request ID" section

// Any other fields are added to all log records as is.
foo: 'bar',
Expand Down Expand Up @@ -727,6 +729,100 @@ follow (feedback from actual users welcome).
}
```


## Request ID

When processing HTTP requests, it's a good practice to specify a unique request ID
value for each log entry. This way, multiple log entries could be grouped together according to the
specified request ID, which dramatically helps in debugging/analysing
requests processing.

This can be done globally for the entire logger instance
or locally when adding individual entries:

```js
// Global request ID example

var logger = bunyan.createLogger({
req_id: '66e925ba-ee2b-11eb-9a03-0242ac130003',
// ...
});
```

```js
// Local request ID example

// First log entry:
logger.info(
{ req_id: '66e925ba-ee2b-11eb-9a03-0242ac130003' },
'Processing some HTTP request'
);

// Some time later:
logger.info(
{ req_id: '66e925ba-ee2b-11eb-9a03-0242ac130003' }, // the same value as above ^
'Finished processing the HTTP request'
);
```


### Handling request IDs automatically

However, in any serious application it's absolutely unpractical
to manually generate and specify request ID for each log entry.

Thanks to bunyan, it could be easily automated. You just need to specify
the request ID generator function to the logger constructor:

```js
var logger = bunyan.createLogger({
req_id: () => {
// @todo: generate your uqniue request ID here
return '66e925ba-ee2b-11eb-9a03-0242ac130003';
},
...
});
```

The main problem here, is that you need to return the same request ID value
for all the logging calls made in terms of the same request.
However, the [cls-rtracer](https://github.com/puzpuzpuz/cls-rtracer)
library could be utilized for exactly this purpose:

```js
const express = require('express')
const rTracer = require('cls-rtracer')

const app = express();

app.use(rTracer.expressMiddleware());

var logger = bunyan.createLogger({

// Using the rTracer to generate stable request IDs
req_id: rTracer.id,

// ...

});


// The same Request ID will be added automatically
// to the both log entries below:
app.get('/foo', (req, res, next) => {

logger.info('Starting to process HTTP request');

setTimeout(() => {
logger.info('Finished processing the HTTP request');
next();

}, 3000);

});
```


## Other fields to consider

- `req.username`: Authenticated user (or for a 401, the user attempting to
Expand Down
10 changes: 10 additions & 0 deletions lib/bunyan.js
Original file line number Diff line number Diff line change
Expand Up @@ -524,6 +524,9 @@ function Logger(options, _childOptions, _childSimple) {
Object.keys(fields).forEach(function (k) {
self.fields[k] = fields[k];
});
if (typeof (options.req_id) === 'function') {
self._req_id_generator = options.req_id;
}
}

util.inherits(Logger, EventEmitter);
Expand Down Expand Up @@ -989,6 +992,13 @@ function mkRecord(log, minLevel, args) {
}
rec.v = LOG_VERSION;

if ((!recFields || !recFields.req_id) && log._req_id_generator) {
var requestId = log._req_id_generator();
if (requestId) {
rec.req_id = requestId;
}
}

return rec;
};

Expand Down
Loading