UNPKG

5.79 kBJavaScriptView Raw
1/*
2 * https://github.com/intesso/debug-trace
3 */
4
5/**
6 * Module dependencies.
7 */
8
9var callsite = require('callsite')
10 , tty = require('tty')
11 , moment = require('moment')
12 , isatty = Boolean(tty.isatty(2) && process.stdout.getWindowSize)
13 , defaultColors = { log: '90', error: '91', warn: '93', info: '96', trace: '90' };
14
15// change stack index
16const stackIndex = 7;
17
18/**
19 * Store custom options
20 *
21 * @param {Object} options
22 * @api public
23 */
24
25module.exports = function debugTrace(options) {
26 options = options || {};
27 console.traceOptions = console.traceOptions || {};
28 console.traceOptions.cwd = options.cwd || process.cwd() + '/';
29 console.traceOptions.colors = typeof options.colors !== 'undefined' ? options.colors : true;
30 console.traceOptions.always = typeof options.always !== 'undefined' ? options.always : true;
31 console.traceOptions.right = typeof options.right !== 'undefined' ? options.right : false;
32 // if (typeof options.overwriteDebugLog === 'undefined' || options.overwriteDebugLog) overwriteDebugLog(options.overwriteDebugLog);
33 // if (typeof options.patchOutput === 'undefined' || options.patchOutput) patchOutput();
34};
35
36// function overwriteDebugLog(debugLog) {
37// debugLog = typeof debugLog === 'function' ? debugLog : console.log;
38// try {
39// var Debug = require('debug');
40// Debug.log = function log() {
41// return debugLog.apply(debugLog, arguments);
42// };
43// } catch (error) {
44// console.log('debug module is not installed');
45// }
46// }
47//
48// function patchOutput() {
49// var stdout = process.stdout.write;
50// var stderr = process.stderr.write;
51// process.stdout.write = function write() {
52// var stack = callsite();
53// var trace = stack[1];
54// if (trace.getFunctionName() === 'log') {
55// var args = [].slice.call(arguments);
56// if (typeof args[args.length - 1] === 'string') args[args.length - 1] = args[args.length - 1].replace(/\n$/g, '');
57// return console.log.apply(console.log, args);
58// }
59// return stdout.apply(process.stdout, arguments);
60// };
61// process.stderr.write = function write() {
62// var stack = callsite();
63// var trace = stack[1];
64// if (trace.getFunctionName() === 'log') {
65// var args = [].slice.call(arguments);
66// if (typeof args[args.length - 1] === 'string') args[args.length - 1] = args[args.length - 1].replace(/\n$/g, '');
67// return console.error.apply(console.error, args);
68// }
69// return stderr.apply(process.stderr, arguments);
70// };
71// }
72
73/**
74 * Overrides the console methods.
75 */
76
77;['error', 'log', 'info', 'warn', 'trace'].forEach(function(name) {
78 var fn = console[name];
79 console[name] = function() {
80 var args = arguments;
81 if (console._trace || (console.traceOptions && console.traceOptions.always)) {
82 if (args.length === 1) args = ['', args[0]];
83 if (Buffer.isBuffer(args[0])) {
84 args[0] = args[0].inspect();
85 } else if (typeof args[0] === 'object') {
86 args[0] = JSON.stringify(args[0], null, ' ');
87 }
88 var pad = (args[0] && !console.traceOptions.right || !isatty ? ' ' : '');
89 // when using the debug module: dig one level deeper in the stack
90 var stack = callsite();
91 var trace = stack[stackIndex];
92 // if (stack.length > 2 && trace.getFunctionName() === 'log') {
93 // trace = stack[3];
94 // trace.debug = true;
95 // }
96 // if (stack.length > 3 && trace.getFunctionName() === 'write') {
97 // trace = stack[4];
98 // trace.debug = true;
99 // }
100 // trace.debug = trace.debug || false;
101 args[0] = console.traceFormat(trace, name) + pad + args[0];
102 }
103 console._trace = false;
104 return fn.apply(this, args);
105 };
106});
107
108/**
109 * Overridable formatting function.
110 *
111 * @param {CallSite}
112 * @param {String} calling method
113 * @api public
114 */
115
116console.traceFormat = function(call, method) {
117 call.filename = call.getFileName().replace(console.traceOptions.cwd, '');
118 call.method = method;
119 call.functionName = call.getFunctionName() || 'anonymous';
120 call.getDate = function getDate() {
121 return moment().format('YYYY-MM-DD HH:mm:ss');
122 };
123
124 var str = console.format(call);
125 var color = '99';
126
127 if (!isatty) {
128 return str;
129 }
130
131 if (console.traceOptions.colors !== false) {
132 if (console.traceOptions.colors === undefined || console.traceOptions.colors[method] === undefined) {
133 color = defaultColors[method];
134 } else {
135 color = console.traceOptions.colors[method];
136 }
137 }
138
139 if (console.traceOptions.right) {
140 var rowWidth = process.stdout.getWindowSize()[0];
141 return '\033[s' + // save current position
142 '\033[' + rowWidth + 'D' + // move to the start of the line
143 '\033[' + (rowWidth - str.length) + 'C' + // align right
144 '\033[' + color + 'm' + str + '\033[39m' +
145 '\033[u'; // restore current position
146 } else {
147 return '\033[' + color + 'm' + str + '\033[39m';
148 }
149};
150
151
152/**
153 * Overridable string formatting function.
154 *
155 * @param {CallSite} CallSite Object pimped with additional properties.
156 * @api public
157 */
158console.format = function(c) {
159 // skip libs
160 if (c.getFileName().indexOf('node_modules') !== -1 || c.getFileName() === 'internal/process/next_tick.js') {
161 return c.getDate();
162 }
163 // can not get the proxied method, omit it
164 if (c.filename.startsWith('log-invoke.decorator') && c.functionName === 'anonymous') {
165 return c.getDate();
166 }
167 return c.getDate() + ' [' + c.filename + ':' + c.getLineNumber() + '] ' + c.functionName;
168};
169
170/**
171 * Adds trace getter to the `console` object.
172 *
173 * @api public
174 */
175
176// function getter() {
177// this._trace = true;
178// return this;
179// }
180//
181// Object.defineProperty(console, 't', { get: getter });
182// Object.defineProperty(console, 'traced', { get: getter });