1 |
|
2 | (function() {
|
3 | var BunyanDebugStream, EXPRESS_BUNYAN_LOGGER_FIELDS, FIELDS_TO_IGNORE, INDENT, LEVELS, Writable, applyColors, bunyan, colors, dateToString, exceptionFormatter, exports, isString, path, ref, ref1, serializer, serializerName, serializers, srcToString,
|
4 | extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
|
5 | hasProp = {}.hasOwnProperty;
|
6 |
|
7 | path = require('path');
|
8 |
|
9 | Writable = require('stream').Writable;
|
10 |
|
11 | bunyan = require('bunyan');
|
12 |
|
13 | colors = require('colors/safe');
|
14 |
|
15 | exceptionFormatter = require('exception-formatter');
|
16 |
|
17 | ref = require('./utils'), srcToString = ref.srcToString, applyColors = ref.applyColors, dateToString = ref.dateToString, isString = ref.isString;
|
18 |
|
19 | LEVELS = (function() {
|
20 | var answer, o;
|
21 | answer = {};
|
22 | o = function(level, prefix, colors) {
|
23 | return answer[level] = {
|
24 | level: level,
|
25 | prefix: prefix,
|
26 | colors: colors
|
27 | };
|
28 | };
|
29 | o(bunyan.TRACE, 'TRACE:', ['grey']);
|
30 | o(bunyan.DEBUG, 'DEBUG:', ['cyan']);
|
31 | o(bunyan.INFO, 'INFO: ', ['green']);
|
32 | o(bunyan.WARN, 'WARN: ', ['yellow']);
|
33 | o(bunyan.ERROR, 'ERROR:', ['red']);
|
34 | o(bunyan.FATAL, 'FATAL:', ['magenta']);
|
35 | return answer;
|
36 | })();
|
37 |
|
38 | FIELDS_TO_IGNORE = ['src', 'msg', 'name', 'hostname', 'pid', 'level', 'time', 'v', 'err'];
|
39 |
|
40 | EXPRESS_BUNYAN_LOGGER_FIELDS = ['remote-address', 'ip', 'method', 'url', 'referer', 'user-agent', 'body', 'short-body', 'http-version', 'response-hrtime', 'status-code', 'req-headers', 'res-headers', 'incoming', 'req_id'];
|
41 |
|
42 | INDENT = " ";
|
43 |
|
44 | BunyanDebugStream = (function(superClass) {
|
45 | extend(BunyanDebugStream, superClass);
|
46 |
|
47 | function BunyanDebugStream(options1) {
|
48 | var c, key, level, levelName, levelValue, ref1, ref10, ref11, ref12, ref13, ref2, ref3, ref4, ref5, ref6, ref7, ref8, ref9, self, value;
|
49 | this.options = options1 != null ? options1 : {};
|
50 | BunyanDebugStream.__super__.constructor.call(this, {
|
51 | objectMode: true
|
52 | });
|
53 | if (this.options.forceColor) {
|
54 | colors.enabled = true;
|
55 | }
|
56 | this._colors = {};
|
57 | if (('colors' in this.options) && !this.options.colors) {
|
58 | this._useColor = false;
|
59 | for (levelValue in LEVELS) {
|
60 | level = LEVELS[levelValue];
|
61 | this._colors[levelValue] = [];
|
62 | }
|
63 | } else {
|
64 | this._useColor = true;
|
65 | for (levelValue in LEVELS) {
|
66 | level = LEVELS[levelValue];
|
67 | this._colors[levelValue] = level.colors;
|
68 | }
|
69 | ref2 = (ref1 = this.options.colors) != null ? ref1 : {};
|
70 | for (level in ref2) {
|
71 | c = ref2[level];
|
72 | if (isString(c)) {
|
73 | c = [c];
|
74 | }
|
75 | if (this._colors[level] != null) {
|
76 | this._colors[level] = c;
|
77 | } else {
|
78 | levelName = level;
|
79 | level = bunyan[levelName != null ? levelName.toUpperCase() : void 0];
|
80 | if (this._colors[level] != null) {
|
81 | this._colors[level] = c;
|
82 | } else {
|
83 |
|
84 | }
|
85 | }
|
86 | }
|
87 | }
|
88 | this._processName = (ref3 = (ref4 = (ref5 = this.options.processName) != null ? ref5 : (process.argv.length > 1 ? path.basename(process.argv[1], path.extname(process.argv[1])) : void 0)) != null ? ref4 : (process.argv.length > 0 ? path.basename(process.argv[0], path.extname(process.argv[0])) : void 0)) != null ? ref3 : '';
|
89 | self = this;
|
90 | this._stringifiers = {
|
91 | req: exports.stdStringifiers.req,
|
92 | err: exports.stdStringifiers.err
|
93 | };
|
94 | if (this.options.stringifiers != null) {
|
95 | ref6 = this.options.stringifiers;
|
96 | for (key in ref6) {
|
97 | value = ref6[key];
|
98 | this._stringifiers[key] = value;
|
99 | }
|
100 | }
|
101 | this._prefixers = (ref7 = this.options.prefixers) != null ? ref7 : {};
|
102 | this._out = (ref8 = this.options.out) != null ? ref8 : process.stdout;
|
103 | this._basepath = (ref9 = this.options.basepath) != null ? ref9 : process.cwd();
|
104 | this._showDate = (ref10 = this.options.showDate) != null ? ref10 : true;
|
105 | this._showLoggerName = (ref11 = this.options.showLoggerName) != null ? ref11 : true;
|
106 | this._showPid = (ref12 = this.options.showPid) != null ? ref12 : true;
|
107 | this._showLevel = (ref13 = this.options.showLevel) != null ? ref13 : true;
|
108 | }
|
109 |
|
110 | BunyanDebugStream.prototype._runStringifier = function(entry, key, stringifier, consumed, message) {
|
111 | var err, i, len, newMessage, ref1, ref2, result, value;
|
112 | consumed[key] = true;
|
113 | value = null;
|
114 | newMessage = message;
|
115 | try {
|
116 | if (stringifier == null) {
|
117 |
|
118 | } else {
|
119 | result = stringifier(entry[key], {
|
120 | entry: entry,
|
121 | useColor: this._useColor,
|
122 | debugStream: this
|
123 | });
|
124 | if (result == null) {
|
125 |
|
126 | } else if (isString(result)) {
|
127 | value = result;
|
128 | } else {
|
129 | ref2 = (ref1 = result.consumed) != null ? ref1 : [];
|
130 | for (i = 0, len = ref2.length; i < len; i++) {
|
131 | key = ref2[i];
|
132 | consumed[key] = true;
|
133 | }
|
134 | if (result.value != null) {
|
135 | if (result.replaceMessage) {
|
136 | newMessage = result.value;
|
137 | value = null;
|
138 | } else {
|
139 | value = result.value;
|
140 | }
|
141 | }
|
142 | }
|
143 | }
|
144 | } catch (_error) {
|
145 | err = _error;
|
146 | newMessage = message;
|
147 | value = "Error running stringifier:\n" + err.stack;
|
148 | }
|
149 | if (value != null) {
|
150 | value = value.replace(/\n/g, "\n" + INDENT);
|
151 | }
|
152 | return {
|
153 | message: newMessage,
|
154 | value: value
|
155 | };
|
156 | };
|
157 |
|
158 | BunyanDebugStream.prototype._entryToString = function(entry) {
|
159 | var colorsToApply, cols, consumed, date, field, i, key, len, levelPrefix, line, message, prefixer, prefixes, processStr, ref1, ref2, ref3, ref4, ref5, ref6, ref7, ref8, src, start, stringifier, value, valueString, values;
|
160 | if (typeof entry === 'string') {
|
161 | entry = JSON.parse(entry);
|
162 | }
|
163 | colorsToApply = this._colors[(ref1 = entry.level) != null ? ref1 : bunyan.INFO];
|
164 | src = srcToString(entry.src, this._basepath, this.options.basepathReplacement);
|
165 | if (src) {
|
166 | src += ': ';
|
167 | }
|
168 | message = entry.msg;
|
169 | consumed = {};
|
170 | for (i = 0, len = FIELDS_TO_IGNORE.length; i < len; i++) {
|
171 | field = FIELDS_TO_IGNORE[i];
|
172 | consumed[field] = true;
|
173 | }
|
174 | values = [];
|
175 | ref2 = this._stringifiers;
|
176 | for (key in ref2) {
|
177 | stringifier = ref2[key];
|
178 | if (entry[key] != null) {
|
179 | ref3 = message = this._runStringifier(entry, key, stringifier, consumed, message), message = ref3.message, value = ref3.value;
|
180 | if (value != null) {
|
181 | values.push("" + INDENT + key + ": " + value);
|
182 | }
|
183 | } else {
|
184 | consumed[key] = true;
|
185 | }
|
186 | }
|
187 | prefixes = [];
|
188 | ref4 = this._prefixers;
|
189 | for (key in ref4) {
|
190 | prefixer = ref4[key];
|
191 | if (entry[key] != null) {
|
192 | ref5 = this._runStringifier(entry, key, prefixer, consumed, message), message = ref5.message, value = ref5.value;
|
193 | if (value != null) {
|
194 | prefixes.push(value);
|
195 | }
|
196 | } else {
|
197 | consumed[key] = true;
|
198 | }
|
199 | }
|
200 | for (key in entry) {
|
201 | value = entry[key];
|
202 | if (consumed[key]) {
|
203 | continue;
|
204 | }
|
205 | valueString = JSON.stringify(value);
|
206 | if (valueString != null) {
|
207 | cols = process.stdout.columns;
|
208 | start = "" + INDENT + key + ": ";
|
209 | if (cols && (valueString.length + start.length) >= cols) {
|
210 | valueString = valueString.slice(0, cols - 3 - start.length) + "...";
|
211 | }
|
212 | values.push("" + start + valueString);
|
213 | }
|
214 | }
|
215 | prefixes = prefixes.length > 0 ? "[" + (prefixes.join(',')) + "] " : '';
|
216 | date = this._showDate ? (dateToString((ref6 = entry.time) != null ? ref6 : new Date())) + " " : '';
|
217 | processStr = "";
|
218 | if (this.options.showProcess) {
|
219 | processStr += this._processName;
|
220 | }
|
221 | if (this._showLoggerName) {
|
222 | processStr += entry.name;
|
223 | }
|
224 | if (this._showPid) {
|
225 | processStr += "[" + entry.pid + "]";
|
226 | }
|
227 | if (processStr.length > 0) {
|
228 | processStr += " ";
|
229 | }
|
230 | levelPrefix = this._showLevel ? ((ref7 = (ref8 = LEVELS[entry.level]) != null ? ref8.prefix : void 0) != null ? ref7 : ' ') + ' ' : '';
|
231 | line = "" + date + processStr + levelPrefix + src + prefixes + (applyColors(message, colorsToApply));
|
232 | if (typeof request !== "undefined" && request !== null) {
|
233 | line += "\n" + INDENT + request;
|
234 | }
|
235 | if (values.length > 0) {
|
236 | line += "\n" + applyColors(values.join('\n'), colorsToApply);
|
237 | }
|
238 | return line;
|
239 | };
|
240 |
|
241 | BunyanDebugStream.prototype._write = function(entry, encoding, done) {
|
242 | this._out.write(this._entryToString(entry) + "\n");
|
243 | return done();
|
244 | };
|
245 |
|
246 | return BunyanDebugStream;
|
247 |
|
248 | })(Writable);
|
249 |
|
250 | module.exports = exports = function(options) {
|
251 | return new BunyanDebugStream(options);
|
252 | };
|
253 |
|
254 | serializers = module.exports.serializers = {};
|
255 |
|
256 | ref1 = bunyan.stdSerializers;
|
257 | for (serializerName in ref1) {
|
258 | serializer = ref1[serializerName];
|
259 | serializers[serializerName] = serializer;
|
260 | }
|
261 |
|
262 | serializers.req = function(req) {
|
263 | var answer;
|
264 | answer = bunyan.stdSerializers.req(req);
|
265 | if (answer != null) {
|
266 | if (req.user != null) {
|
267 | answer.user = req != null ? req.user : void 0;
|
268 | }
|
269 | }
|
270 | return answer;
|
271 | };
|
272 |
|
273 | serializers.res = function(res) {
|
274 | var answer;
|
275 | answer = bunyan.stdSerializers.res(res);
|
276 | if (answer != null) {
|
277 | answer.headers = res._headers;
|
278 | if (res.responseTime != null) {
|
279 | answer.responseTime = res.responseTime;
|
280 | }
|
281 | }
|
282 | return answer;
|
283 | };
|
284 |
|
285 | exports.stdStringifiers = {
|
286 | req: function(req, arg) {
|
287 | var consumed, contentLength, entry, fields, host, ref10, ref11, ref12, ref13, ref14, ref2, ref3, ref4, ref5, ref6, ref7, ref8, ref9, replaceMessage, request, res, responseTime, status, statusCode, statusColor, url, useColor, user;
|
288 | entry = arg.entry, useColor = arg.useColor;
|
289 | consumed = ['req', 'res'];
|
290 | res = entry.res;
|
291 | if ((entry['status-code'] != null) && (entry['method'] != null) && (entry['url'] != null) && (entry['res-headers'] != null)) {
|
292 | consumed = consumed.concat(EXPRESS_BUNYAN_LOGGER_FIELDS);
|
293 | }
|
294 | statusCode = (ref2 = res != null ? res.statusCode : void 0) != null ? ref2 : entry['status-code'];
|
295 | if (statusCode != null) {
|
296 | status = "" + statusCode;
|
297 | if (useColor) {
|
298 | statusColor = statusCode < 200 ? colors.grey : statusCode < 400 ? colors.green : colors.red;
|
299 | status = colors.bold(statusColor(status));
|
300 | }
|
301 | } else {
|
302 | status = "";
|
303 | }
|
304 | responseTime = (res != null ? res.responseTime : void 0) != null ? res.responseTime : entry.duration != null ? (consumed.push('duration'), entry.duration) : entry["response-time"] != null ? (consumed.push("response-time"), entry["response-time"]) : null;
|
305 | if (responseTime != null) {
|
306 | responseTime = responseTime + "ms";
|
307 | } else {
|
308 | responseTime = "";
|
309 | }
|
310 | user = req.user != null ? ((ref3 = (ref4 = (ref5 = req.user) != null ? ref5.username : void 0) != null ? ref4 : (ref6 = req.user) != null ? ref6.name : void 0) != null ? ref3 : req.user) + "@" : entry.user != null ? (consumed.push("user"), ((ref7 = (ref8 = (ref9 = entry.user) != null ? ref9.username : void 0) != null ? ref8 : (ref10 = entry.user) != null ? ref10.name : void 0) != null ? ref7 : entry.user) + "@") : "";
|
311 | contentLength = (ref11 = res != null ? (ref12 = res.headers) != null ? ref12['content-length'] : void 0 : void 0) != null ? ref11 : (ref13 = entry['res-headers']) != null ? ref13['content-length'] : void 0;
|
312 | contentLength = contentLength != null ? "- " + contentLength + " bytes" : "";
|
313 | host = ((ref14 = req.headers) != null ? ref14.host : void 0) || null;
|
314 | url = host != null ? "" + host + req.url : "" + req.url;
|
315 | fields = [req.method, user + url, status, responseTime, contentLength];
|
316 | fields = fields.filter(function(f) {
|
317 | return !!f;
|
318 | });
|
319 | request = fields.join(' ');
|
320 | replaceMessage = !entry.msg || entry.msg === 'request finish';
|
321 | return {
|
322 | consumed: consumed,
|
323 | value: request,
|
324 | replaceMessage: replaceMessage
|
325 | };
|
326 | },
|
327 | err: function(err, arg) {
|
328 | var debugStream, ref2, ref3, ref4, useColor;
|
329 | useColor = arg.useColor, debugStream = arg.debugStream;
|
330 | return exceptionFormatter(err, {
|
331 | format: useColor ? 'ansi' : 'ascii',
|
332 | colors: false,
|
333 | maxLines: (ref2 = (ref3 = debugStream.options) != null ? ref3.maxExceptionLines : void 0) != null ? ref2 : null,
|
334 | basepath: debugStream._basepath,
|
335 | basepathReplacement: (ref4 = debugStream.options) != null ? ref4.basepathReplacement : void 0
|
336 | });
|
337 | }
|
338 | };
|
339 |
|
340 | }).call(this);
|