Production Logging With Morgan In Express

At the top of a newly generated express app using express’s application generator you’ll see one of the bundled dependencies:

1
var logger = require('morgan');

Later we see it initialized with the other middleware like:

1
app.use(logger('dev'));

Here is the output that is produced:
Dev logs

Now, in a hurry to get my code out and on the web I never paid close attention to what was happening. The ‘dev’ aspect just went right over my head. When bugs crept up in production, the log files were very difficult to utilize since there wasn’t much information. Specifically, there is no date and no way to tell who is making each request.

If we simply look at the Morgan documentation we will see many useful pre-defined formats. I like the combined setting becuause it provides user agent info. In my stint in customer support, identifying user agents has been helpful.

We can make our change like this:

1
2
3
4
5
if (app.get('env') === 'production') {
app.use(logger('combined'));
} else {
app.use(logger('dev'));
}

Let’s look at our logs now:
Default production logs

Lots more info! But… if you look closely, you’ll see the IP address looks awfully useless. I’m running a reverse proxy setup with NGINX to serve my site, so it actually makes sense that the IP addresses would all be internal. We need a way to get at the source IP address.

Configure NGINX to forward the real IP address

To do this we need to update the location block in our site configuration file in the sites-available directory.

1
proxy_set_header X-Forwarded-For $remote_addr;

And then of course we’ll need to restart NGINX (sudo service nginx restart).

Tell Express to use the remote IP address

In the Express proxy documentation we can see how to take advantage or our newly forwarded IP address. By enabling the trust proxy feature, the IP address will be updated in the correct places with the forwarded IP. It will also be available on the req object. We can enable the trust proxy feature after initializing the app.

1
2
var app = express();
app.set('trust proxy', true);

The final result:
Final production logs

We now have IP addresses. No we can see dates, IP addresses, user agents and lots more when looking through our logs.

avatar

Dev Blog