This repository has been archived by the owner on Jan 13, 2018. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 72
/
logger.js
173 lines (146 loc) · 5.07 KB
/
logger.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
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
/* jshint undef:false */
'use strict';
var color = require('coa/lib/color').Color,
W = require('winston'),
UTIL = require('util'),
BEMUTIL = require('./util'),
propertiesFilter = [
'__self'
];
for(var i in W) exports[i] = W[i];
init();
/**
* Sets the max logging level
* @param level
*/
exports.setLevel = function(level) {
init(level);
};
/**
* Log formatted message
*
* @param {String} level
* @param {String} message
* @param {*} ...args
*/
exports.flog = function(level) {
W[level](UTIL.format.apply(this, Array.prototype.slice.call(arguments, 1)));
};
exports.fatal = function() {
this.error.apply(this, arguments);
process.exit();
};
var times = {};
exports.time = function(label) {
label = UTIL.format.apply(UTIL, arguments);
times[label] = Date.now();
};
exports.timeEnd = function(label) {
label = UTIL.format.apply(UTIL, arguments);
var duration = Date.now() - times[label];
exports.flog('info', '%s: ' + color('red', '%dms'), label, duration);
delete times[label];
};
exports.timeEndLevel = function(level, label) {
label = UTIL.format.apply(UTIL, Array.prototype.slice.call(arguments, 1));
var duration = Date.now() - times[label];
exports.flog(level, '%s: ' + color('red', '%dms'), label, duration);
delete times[label];
};
/**
* Adds tracing before and after executing specified function or specified object's methods
* @param {Object} options The object with properties:
* @param {Function} options.object pass object the methods of which you want to trace
* @param {Function} options.func pass function you want to trace (the method will return wrapper function in this case)
* @param {String} [options.objectName] this value is used in the traces to identify what object method is being executed
* @param {String[]} [options.whiteList] in case object was specified only methods in the whiteList will be wrapped
* @param {String[]} [options.blackList] in case object was specified the methods in blackList hash won't be wrapped
* @return {Function} The wrapped function in case options.func was specified or nothing otherwise
*/
exports.trace = function (options) {
return attach(
options,
function(f) {
exports.fsilly('>>> %s.%s', f.objectName || '?', f.functionName || '?');
},
function(f) {
exports.fsilly('<<< %s.%s', f.objectName || '?', f.functionName || '?');
}
);
};
/**
* The same as {@link trace} but uses specified callbacks to do tracing
*
* @param {Object} options
* @param {Function} [callbackBefore]
* @param {Function} [callbackAfter]
* @return {Function} The wrapped function in case options.func was specified or nothing otherwise
*/
var attach = exports.attach = function(options, callbackBefore, callbackAfter) {
if (options.object) {
var c = options.object.prototype || options.object;
if (!c) throw new Error('object has no prototype');
Object.keys(c)
.filter(function(prop) {
if (typeof c[prop] === 'function' && propertiesFilter.indexOf(prop) === -1) {
if (options.whiteList) return (options.whiteList.indexOf(prop) !== -1);
if (options.blackList) return (options.blackList.indexOf(prop) === -1);
return true;
}
return false;
})
.map(function(f) {
c[f] = wrapFunction(
{
objectName: options.objectName,
functionName: f,
func: c[f],
object: options.object
},
callbackBefore,
callbackAfter);
});
} else if (options.func) {
return wrapFunction(options.func, callbackBefore, callbackAfter);
}
};
function wrapFunction(options, callbackBefore, callbackAfter) {
var f = (typeof options === 'function')? options: options.func;
return function() {
callbackBefore && callbackBefore(options);
var res = f.apply(this, arguments);
callbackAfter && callbackAfter(options);
return res;
};
}
function init(level) {
W.remove(W.transports.Console);
W.add(W.transports.Console,
{
timestamp: function() {
var d = new Date();
return UTIL.format(
'%s:%s:%s.%s',
BEMUTIL.pad(d.getHours(), 2, '0'),
BEMUTIL.pad(d.getMinutes(), 2, '0'),
BEMUTIL.pad(d.getSeconds(), 2, '0'),
BEMUTIL.pad(d.getMilliseconds(), 3, '0'));
},
colorize: true,
level: level
});
W.setLevels({
silly: 0,
debug: 1,
verbose: 2,
info: 3,
warn: 4,
error: 5
});
Object.keys(W.levels).forEach(function (level) {
exports[level] = W[level];
exports['f' + level] = function() {
W[level](UTIL.format.apply(this, arguments));
};
});
}