简体   繁体   中英

NodeJS http server metrics

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?

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();
}

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
  }
]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM