var log = require('bole')('budo') var onResHeaders = require('on-headers') var onResFinished = require('on-finished') module.exports = simpleHttpLoggerMiddleware function simpleHttpLoggerMiddleware (opts) { opts = opts || {} var httpLogger = function simpleHttpLogger (req, res, next) { if (httpLogger.ignores.indexOf(req.url) >= 0) return next() if (!req.url) return next() // request data req._startAt = undefined // response data res._startAt = undefined // record request start recordStartTime.call(req) var byteLength = 0 var logRequest = function () { if (!req._startAt || !res._startAt) { // missing request and/or response start time return } // calculate diff var ms = (res._startAt[0] - req._startAt[0]) * 1000 + (res._startAt[1] - req._startAt[1]) * 1e-6 log.info({ elapsed: ms, contentLength: byteLength, method: (req.method || 'GET').toUpperCase(), url: req.url, statusCode: res.statusCode, type: httpLogger.type === 'static' ? undefined : httpLogger.type, colors: { elapsed: ms > 1000 ? 'yellow' : 'dim' } }) } var isAlreadyLogging = res._simpleHttpLogger res._simpleHttpLogger = true if (!isAlreadyLogging) { // record response start onResHeaders(res, recordStartTime) // log when response finished onResFinished(res, logRequest) var writeFn = res.write // catch content-length of payload res.write = function (payload) { if (payload) byteLength += payload.length return writeFn.apply(res, arguments) } } next() } httpLogger.ignores = [].concat(opts.ignores).filter(Boolean) httpLogger.type = 'static' return httpLogger } function recordStartTime () { this._startAt = process.hrtime() }