lib/koaLogger.js
'use strict';
var MODULE_NAME = 'requests';
//This module is a copy from koa-logger with log4js feature
var logger = require('log4js').getLogger(MODULE_NAME);
var Counter = require('passthrough-counter');
var humanize = require('humanize-number');
var bytes = require('bytes');
var colors = {
5: 31,
4: 33,
3: 36,
2: 32,
1: 32
};
/**
* Development logger.
*/
module.exports = function (opts) {
return function *(next) {
// request
var start = new Date;
logger.debug(' \x1B[90m<-- \x1B[;1m%s\x1B[0;90m %s\x1B[0m', this.method, this.url);
try {
yield next;
} catch (err) {
// log uncaught downstream errors
log(this, 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.
var length = this.responseLength;
var body = this.body;
var counter;
if (null == length && body && body.readable) {
this.body = body
.pipe(counter = Counter())
.on('error', this.onerror);
}
// log when the response is finished or closed,
// whichever happens first.
var ctx = this;
var res = this.res;
var onfinish = done.bind(null, 'finish');
var 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(ctx, start, counter ? counter.length : length, null, event);
}
}
}
/**
* Log helper.
*/
function log(ctx, start, len, err, event) {
// get the status code of the response
var status = err
? (err.status || 500)
: (ctx.status || 404);
// set the color of the status code;
var s = status / 100 | 0;
var c = colors[s];
// get the human readable response length
var length;
if (~[204, 205, 304].indexOf(status)) {
length = '';
} else if (null == len) {
length = '-';
} else {
length = bytes(len);
}
var upstream = err ? '\x1B[31mxxx'
: event === 'close' ? '\x1B[33m-x-'
: '\x1B[90m-->';
logger.debug(' ' + upstream + ' \x1B[;1m%s\x1B[0;90m %s \x1B[' + c + 'm%s\x1B[90m %s %s\x1B[0m',
ctx.method,
ctx.originalUrl,
status,
time(start),
length);
}
/**
* Show the response time in a human readable format.
* In milliseconds if less than 10 seconds,
* in seconds otherwise.
*/
function time(start) {
var delta = new Date - start;
delta = delta < 10000
? delta + 'ms'
: Math.round(delta / 1000) + 's';
return humanize(delta);
}