koa-logger源码解析以GET申请“/”为例子,koa-logger会打印以下日志:
<-- GET /GET / - 790ms --> GET / 200 803ms 185b分为是申请与响应的日志
// koa-logger 主函数function dev (opts) { // print函数,默认参数为空时是调用console.log,如果有transporter选项,则调用transporter函数代替 const print = (function () { let transporter if (typeof opts === 'function') { transporter = opts } else if (opts && opts.transporter) { transporter = opts.transporter } return function printFunc (...args) { // 留神:这里做了格局说明符替换 const str = util.format(...args) if (transporter) { transporter(str, args) } else { console.log(...args) } } }()) return async function logger (ctx, next) { // request const start = ctx[Symbol.for('request-received.startTime')] ? ctx[Symbol.for('request-received.startTime')].getTime() : Date.now() // 打印申请日志 print(' ' + chalk.gray('<--') + ' ' + chalk.bold('%s') + ' ' + chalk.gray('%s'), ctx.method, ctx.originalUrl) try { await next() } catch (err) { // log uncaught downstream errors log(print, ctx, start, null, err) throw err } // calculate the length of a streaming response // by intercepting the stream with a counter. // only necessary if a content-length header is currently not set. // 通过应用计数器拦挡流来计算响应流的长度。只有在以后没有设置Content-Length的响应报头时才须要。 const length = ctx.response.length const body = ctx.body let counter if (length == null && body && body.readable) { ctx.body = body .pipe(counter = Counter()) .on('error', ctx.onerror) } // log when the response is finished or closed, // whichever happens first. // 记录响应实现或敞开的工夫,以先产生的工夫为准。个别都是触发finish事件 const res = ctx.res const onfinish = done.bind(null, 'finish') const onclose = done.bind(null, 'close') // 重点:判断一个流申请是否完结 res.once('finish', onfinish) res.once('close', onclose) function done (event) { res.removeListener('finish', onfinish) res.removeListener('close', onclose) // 打印 申请形式 门路 状态码 响应工夫 报文长度 log(print, ctx, start, counter ? counter.length : length, null, event) } }}还有个logger辅助函数:
...