I am working on a solution that makes http requests to different web services, and I need to measure the response times (detailed), I am currently using the "node:https" module, but I would like to know if there is a Library or package that is not " request" since it is deprecated and with axios I have not managed to do it
I leave here an example of the code I use
import https from "node:https";
const NS_PER_SEC = 1e9;
const MS_PER_NS = 1e6;
const timings = {
// use process.hrtime() as it's not a subject of clock drift
startAt: process.hrtime(),
dnsLookupAt: undefined,
tcpConnectionAt: undefined,
tlsHandshakeAt: undefined,
firstByteAt: undefined,
endAt: undefined,
};
let responseBody = "";
const req = https.request(
{
hostname: SERVICE_URL,
port: 443,
path: "/",
method: "GET",
timeout: 5000,
headers: {
"User-Agent":
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36",
Accept: "*/*",
"Accept-Language": "en-US,en;q=0.9",
"Accept-Encoding": "gzip, deflate, br",
},
},
onAnyMessage
);
async function onAnyMessage(res) {
res.once("readable", () => {
timings.firstByteAt = process.hrtime();
});
res.on("data", (chunk) => {
responseBody += chunk;
});
res.on("end", () => {
timings.endAt = process.hrtime();
console.log(responseBody);
console.log(getTimings(timings));
});
}
function getTimings(eventTimes) {
return {
// There is no DNS lookup with IP address
dnsLookup:
eventTimes.dnsLookupAt !== undefined
? getHrTimeDurationInMs(eventTimes.startAt, eventTimes.dnsLookupAt)
: undefined,
tcpConnection: getHrTimeDurationInMs(
eventTimes.dnsLookupAt || eventTimes.startAt,
eventTimes.tcpConnectionAt
),
// There is no TLS handshake without https
tlsHandshake:
eventTimes.tlsHandshakeAt !== undefined
? getHrTimeDurationInMs(
eventTimes.tcpConnectionAt,
eventTimes.tlsHandshakeAt
)
: undefined,
firstByte: getHrTimeDurationInMs(
eventTimes.tlsHandshakeAt || eventTimes.tcpConnectionAt,
eventTimes.firstByteAt
),
contentTransfer: getHrTimeDurationInMs(
eventTimes.firstByteAt,
eventTimes.endAt
),
total: getHrTimeDurationInMs(eventTimes.startAt, eventTimes.endAt),
};
}
/**
* Get duration in milliseconds from process.hrtime()
* @function getHrTimeDurationInMs
* @param {Array} startTime - [seconds, nanoseconds]
* @param {Array} endTime - [seconds, nanoseconds]
* @return {Number} durationInMs
*/
function getHrTimeDurationInMs(startTime, endTime) {
const secondDiff = endTime[0] - startTime[0];
const nanoSecondDiff = endTime[1] - startTime[1];
const diffInNanoSecond = secondDiff * NS_PER_SEC + nanoSecondDiff;
return diffInNanoSecond / MS_PER_NS;
}
req.on("socket", (socket) => {
socket.on("lookup", () => {
timings.dnsLookupAt = process.hrtime();
});
socket.on("connect", () => {
timings.tcpConnectionAt = process.hrtime();
});
socket.on("secureConnect", () => {
timings.tlsHandshakeAt = process.hrtime();
});
});
req.on("error", (err) => {
console.log(err);
});
req.end();
got
provides timings:
import got from 'got';
const response = await got.get('https://stackoverflow.com');
console.log(response.timings);
Result:
{
start: 1731862688177,
socket: 1731862688178,
lookup: 1731862688191,
connect: 1731862689031,
secureConnect: 1731862689048,
upload: 1731862689048,
response: 1731862689214,
end: 1731862689228,
error: undefined,
abort: undefined,
phases: {
wait: 1,
dns: 13,
tcp: 840,
tls: 17,
request: 0,
firstByte: 166,
download: 14,
total: 1051
}
}