forked from koajs/logger
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
140 lines (117 loc) · 2.83 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
/**
* Module dependencies.
*/
var Counter = require('passthrough-counter');
var humanize = require('humanize-number');
var bytes = require('bytes');
var chalk = require('chalk');
/**
* TTY check for dev format.
*/
var isatty = process.stdout.isTTY;
/**
* Expose logger.
*/
module.exports = dev;
/**
* Color map.
*/
var colorCodes = {
5: 'red',
4: 'yellow',
3: 'cyan',
2: 'green',
1: 'green'
};
/**
* Development logger.
*/
function dev(opts) {
return function *logger(next) {
// request
var start = new Date;
console.log(' ' + chalk.gray('<--')
+ ' ' + chalk.bold('%s')
+ ' ' + chalk.gray('%s'),
this.method,
this.originalUrl);
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.response.length;
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 color = colorCodes[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 ? chalk.red('xxx')
: event === 'close' ? chalk.yellow('-x-')
: chalk.gray('-->')
console.log(' ' + upstream
+ ' ' + chalk.bold('%s')
+ ' ' + chalk.gray('%s')
+ ' ' + chalk[color]('%s')
+ ' ' + chalk.gray('%s')
+ ' ' + chalk.gray('%s'),
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);
}