Reputation: 1884
I am building an app in which I am trying to build my own logging system for each request.
For each request, I'd like to log the timestamp, the method used, the route, and finally the response code that has been sent to the client.
I have the following code for the moment :
// index.js
const express = require('express');
const bodyParser = require('body-parser');
const cors = require('cors');
const app = express();
app.use(bodyParser.json());
app.use(cors());
app.use(require('./lib/logging'));
app.get('/', (req, res, next) => {
res.send('hello world !');
});
app.listen(3001);
// ./lib/logging.js
const moment = require('moment');
const chalk = require('chalk');
const log = console.log;
module.exports = (req, res, next) => {
let now = `[${chalk.green(moment().format('HH:mm:ss'))}]`;
let method = chalk.magenta(req.method);
let route = chalk.blue(req.url);
let code = chalk.yellow(res.statusCode); // Always 200
log(`${now} ${method} request received on ${route} ${code}`);
next();
}
Unfortunately, even if I do res.status(201).send('hello world')
It will always catch a 200
status code...
Is there a way to catch any response outgoing to the client and fetch its status code ?
Upvotes: 11
Views: 11062
Reputation: 2762
The Express response extends the Node.js http.ServerResponse
, so you can listen for the 'finish'
event:
Event: 'finish'
Emitted when the response has been sent. More specifically, this event is emitted when the last segment of the response headers and body have been handed off to the operating system for transmission over the network. It does not imply that the client has received anything yet.
app.use((req, res, next) => {
res.on('finish', () => {
console.log(`Responded with status ${res.statusCode}`);
});
next();
});
Upvotes: 11
Reputation: 1884
Using the finish
event from the response was indeed the good solution. The problem was in the finish
event callback, I just couldn't use the arrow function because it wouldn't bind the this
keyword, and this is were was stored the response data.
So the following code is working :
// ./lib/logging.js
const moment = require('moment');
const chalk = require('chalk');
const log = console.log;
module.exports = (req, res, next) => {
let now = `[${chalk.green(moment().format('HH:mm:ss'))}]`;
let method = chalk.magenta(req.method);
let route = chalk.blue(req.url);
res.on('finish', function() {
let code = chalk.yellow(this.statusCode);
log(`${now} ${method} request received on ${route} with code ${code}`);
})
next();
}
Upvotes: 22
Reputation: 10111
Create middleware and Override send function
app.use(function (req, res) {
var send = res.send;
res.send = function (body) {
// Do something
send.call(this, body);
};
});
Upvotes: 2
Reputation: 5858
What I understand is you need to add some status codes in the response
You can simply set status codes like this
let code = {
serverError:500,
forbidden:401
}
res.status(code.serverError).json({
message:'Server error'
})
If you want to set in the middleware
middleware.js
const statuscode = function middleware(req,res,next){
let code = {
serverError:500,
forbidden:401
}
req.statusCode =code.serverError
next()
}
module.exports = {
statuscode
}
In the index.js
const middleware = require('./middleware');
app.get('/',middleware.statuscode, (req, res, next) => {
console.log("Code from middleware",req.statusCode);
res.send('hello world !');
});
Upvotes: 0