UNPKG

express-middleware-server-timing

Version:
78 lines (66 loc) 2.18 kB
const onHeaders = require("on-headers"); const headerName = "Server-Timing"; module.exports = function (app, options = {}) { const name = options.name || "mw"; const description = options.description; const listen = app.listen; const disabled = app.disabled === true; function appendHeader(res, startTime, name, description) { if (disabled) { return; } const diff = process.hrtime(startTime); const headerString = [] .concat(res.getHeader(headerName) || []) .concat(toServerTimingEntry(name, diff, description)) .join(","); res.setHeader(headerName, headerString); } app.listen = function () { // add our middleware to the end app.use(function (req, res, next) { const startTime = process.hrtime(); onHeaders(res, function () { appendHeader(res, startTime, name, description); }); const timers = {}; res.serverTimingStart = function (name, description) { const startTime = process.hrtime(); timers[name] = { startTime, description, }; }; res.serverTimingStop = function (name) { const timer = timers[name]; if (!timer) { console.warn(`no timer named ${name}`); return; } appendHeader(this, timer.startTime, name, timer.description); delete timers[name]; }; res.serverTimingSync = function (method, name, description) { const startTime = process.hrtime(); const returnValue = method(); appendHeader(this, startTime, name, description); return returnValue; }; next(); }); // move the Layer we just added from last to first // yes, this is probably a bad idea that won't work forever, but... app._router.stack.unshift(app._router.stack.pop()); // let the listening begin return listen.apply(app, arguments); }; }; function toServerTimingEntry(name, diff, description) { const entry = []; entry.push(name); entry.push(`dur=${diff[0] * 1e3 + diff[1] / 1e6}`); if (description) { entry.push(`desc=${JSON.stringify(description)}`); } return entry.join("; "); }