Logging all requests in Node.js/Express Logging all requests in Node.js/Express json json

Logging all requests in Node.js/Express


Expressjs adapts its functionality based on what type of callback you give it (this is not common in JS libraries so it is not surprising that people get confused by it).

If you do this where your callback has four arguments:

app.use(function(error, req, res, next) {...});

then Express assumes this is an error-only middleware handler and will only be called when there are errors. In the express doc, see the section labeled Error-handling middleware. Note this specific part of that page:

Define error-handling middleware functions in the same way as other middleware functions, except with four arguments instead of three, specifically with the signature (err, req, res, next)):

And, here's a whole section of the documentation devoted to error handling middleware.

If you use just three arguments:

app.use(function(req, res, next) {...});

then, it is a normal middleware that is called when there are not errors. I'm not sure if they provide a single way to get both. But, certainly as a workaround, you could put your logging code into a function and then call that function from two separate middleware handlers, one for errors and one for non-errors.


Use morgan https://github.com/expressjs/morgan

Install morgan

$ npm install morgan

Include morgan in the index.js or app.js or server.js file (The file that pointed by the script tag in the package.json)

var morgan = require('morgan')

Then add below before all the app call.

app.use(morgan('combined'))

Complete example

var express = require('express')var morgan = require('morgan')var app = express()app.use(morgan('combined'))app.get('/', function (req, res) {  res.send('hello, world!')})

A sample output line looks like this:

::1 - - [31/May/2021:09:03:14 +0000] "GET / HTTP/1.1" 200 2078 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.77 Safari/537.36"


DEBUG='*' or DEBUG='express:router' environment variable

It does not show a lot of information about the request, but it does show the path and method, which might be enough for basic applications, and is convenient as it does not require any extra setup.

DEBUG='*' enables all logs and is slightly easier to type:

DEBUG='*' ./app.js

or the more specific DEBUG='express:router' is what you will generally want in a complex application with a lot of middleware, otherwise the DEBUG='*' could produce mountains of output:

DEBUG='express:router' ./app.js

E.g. with the hello world:

#!/usr/bin/env nodeconst express = require('express')const app = express()const port = 3000app.get('/', (req, res) => {  res.send('Hello World!')})app.listen(port, () => {  console.log(`Example app listening at http://localhost:${port}`)})

Then as I play on the browser with different URLs I can see logs such as:

  express:router dispatching GET / +3m  express:router query  : / +0ms  express:router expressInit  : / +0ms  express:router dispatching GET /asdf +10s  express:router query  : /asdf +0ms  express:router expressInit  : /asdf +0ms  finalhandler default 404 +3m  express:router dispatching GET /asdf?qwer=zxcv +17s  express:router query  : /asdf?qwer=zxcv +0ms  express:router expressInit  : /asdf?qwer=zxcv +0ms  finalhandler default 404 +17s

Documentation at: https://expressjs.com/en/guide/debugging.html

Tested on express 4.17.1.