Reputation: 501
I have as an assignment to do a nodeJS HTTP server with some form of metrics on it.
For this assignment, I am not allowed to use any form of external libraries & as the metric of the request I'll store the response time.
For route handling ill use a simple switch statement comparing the URL of the request
const http = require("http");
var metrics = []
http.createServer((req, res) => {
switch(req.url){
case "/route"
var start = Date.now();
// some code to process the request, maybe some requests to the database, maybe retrieve some files etc
res.end();
metrics.push(Date.now() - start);
break;
}
}).listen(8080,()=>console.log("Server running!"))
The thing is, if I want to do this app with one or a low number of requests this method would be ok, however, in any other normal scenarios, this would be awful for any further changes to those metrics & much more.
I'm thinking of trying to solve this with some sort of event listeners that I would call at the beginning & the end of my request. Something that would store information about the request at the beginning & launch an event at the end to stop processing the metrics.
server.on('end', (data)=>{
//end metrics somehow
})
Although it seems a little hard to implement, especially as I don't really want to overwrite a nodeJS event to add some data on it ( for instance I may want to add an id of the request, or a timestamp )
Is there a way to properly do this with nodeJS HTTP?
Upvotes: 0
Views: 599
Reputation: 16127
You can handle it by finish
event of res
object. The event will be called when you call res.end()
(or something like that).
My recommendation, to metrics an API service, you will need more information than response times.
const http = require("http");
var metrics = []
http.createServer((req, res) => {
const startPoint = Date.now();
res.on("finish", () => {
if (req.url === "/metrics") {
return; // no metrics for metrics route
}
metrics.push({
path: req.url,
method: req.method,
status: res.statusCode,
dateTime: startPoint,
times: Date.now() - startPoint,
});
});
switch (req.url) {
case "/route":
// some code to process the request, maybe some requests to the database, maybe retrieve some files etc
setTimeout(() => {
res.end();
}, 1000);
break;
case "/metrics":
res.setHeader('Content-Type', 'application/json');
res.write(JSON.stringify(metrics));
res.end()
break;
default:
res.statusCode = 404;
res.end();
break;
}
}).listen(8080, () => console.log("Server running!"))
As you can see, when you call GET http://localhost:8080/metrics
api, the response will look like this:
[
{
"path": "/test",
"method": "GET",
"status": 404,
"dateTime": 1613631702906,
"times": 1
},
{
"path": "/route",
"method": "GET",
"status": 200,
"dateTime": 1613631702906,
"times": 1004
}
]
Upvotes: 1
Reputation: 36
create your own middleware on each routes, if you can't use framework like express or koa
Note: this is the simplest example, but it gives a clue of research
class Middleware {
use(func) {
this.next_func = (
(stack) =>
(next) =>
stack(
func.bind(this, next.bind(this)),
)
)(this.next_func);
}
next_func = (next) => next();
}
Upvotes: 1