1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 | var util = require('util');
|
7 | var _ = require('lodash');
|
8 |
|
9 | var properties = require('./properties');
|
10 | var uuid = require('./utils/uuid');
|
11 |
|
12 | const levels = {trace: 0, debug: 1, info: 2, warn: 3, err: 4, error: 4};
|
13 | var loggers = {};
|
14 | var enabled = {};
|
15 |
|
16 |
|
17 |
|
18 |
|
19 |
|
20 |
|
21 | var manager = module.exports = function (namespace) {
|
22 | var logger = loggers[namespace];
|
23 | if (!logger) {
|
24 | logger = new Logger(namespace);
|
25 | loggers[namespace] = logger;
|
26 | _.forEach(_.keys(enabled), function (item) {
|
27 | if ((new RegExp(item)).test(namespace)) {
|
28 | logger.enabled = true;
|
29 | logger.level = enabled[item] || 'info';
|
30 | }
|
31 | });
|
32 | }
|
33 | return logger;
|
34 | };
|
35 | manager.getLogger = manager;
|
36 |
|
37 |
|
38 |
|
39 |
|
40 |
|
41 |
|
42 | manager.enable = function (namespace, level) {
|
43 | var regex = namespace2regex(namespace);
|
44 | enabled[regex] = level;
|
45 | var namespaces = matchingNamespaces(regex);
|
46 | _.forEach(namespaces, function (item) {
|
47 | var logger = loggers[item];
|
48 | if (logger) {
|
49 | logger.enabled = true;
|
50 | if (level) logger.level = level;
|
51 | }
|
52 | });
|
53 | };
|
54 |
|
55 |
|
56 |
|
57 |
|
58 |
|
59 | manager.disable = function (namespace) {
|
60 | var regex = namespace2regex(namespace);
|
61 | delete enabled[regex];
|
62 | var namespaces = matchingNamespaces(regex);
|
63 | _.forEach(namespaces, function (item) {
|
64 | var logger = loggers[item];
|
65 | if (logger) logger.enabled = false;
|
66 | });
|
67 | };
|
68 |
|
69 |
|
70 |
|
71 |
|
72 |
|
73 |
|
74 | manager.level = function (namespace, level) {
|
75 | var regex = namespace2regex(namespace);
|
76 | var namespaces = matchingNamespaces(regex);
|
77 | _.forEach(namespaces, function (item) {
|
78 | var logger = loggers[item];
|
79 | if (logger) logger.level = level;
|
80 | });
|
81 | };
|
82 |
|
83 |
|
84 |
|
85 |
|
86 |
|
87 |
|
88 | function namespace2regex(namespace) {
|
89 | return '^' + namespace.replace('*', '.*?') + '$';
|
90 | }
|
91 |
|
92 |
|
93 |
|
94 |
|
95 |
|
96 |
|
97 | function matchingNamespaces(regex) {
|
98 | var re = new RegExp(regex);
|
99 | return _.filter(_.keys(loggers), function (key) {
|
100 | return re.test(key);
|
101 | });
|
102 | }
|
103 |
|
104 |
|
105 |
|
106 |
|
107 |
|
108 |
|
109 | function Logger(namespace) {
|
110 | this.namespace = namespace;
|
111 | this.enabled = false;
|
112 | this.level = 'info';
|
113 | }
|
114 |
|
115 |
|
116 |
|
117 |
|
118 |
|
119 | _.forEach(_.keys(levels), function (level) {
|
120 | Logger.prototype[level] = function () {
|
121 | return internalLog(this, level, Array.prototype.slice.call(arguments));
|
122 | };
|
123 | });
|
124 |
|
125 |
|
126 |
|
127 |
|
128 |
|
129 |
|
130 |
|
131 |
|
132 |
|
133 | Logger.prototype.makeLog = function (level, code, message, techData, userData) {
|
134 | if (levels[level] < levels[this.level]) return {};
|
135 |
|
136 | var messages = [];
|
137 | messages.push('[' + code + '] ' + message);
|
138 | if (techData) messages.push({techData: techData});
|
139 | if (userData) messages.push({userData: userData});
|
140 |
|
141 | var errid = internalLog(this, level, messages);
|
142 | return {errid: errid, code: code, data: userData};
|
143 | };
|
144 |
|
145 |
|
146 |
|
147 |
|
148 |
|
149 |
|
150 |
|
151 |
|
152 | var internalLog = function (logger, level, messages) {
|
153 | var errors = [];
|
154 | if (level === 'error' || level === 'err' || level === 'warn') {
|
155 | errors.push(formatError(new Error('Current Stack')));
|
156 | }
|
157 | _.forEach(messages, function (message) {
|
158 | if (util.isError(message)) {
|
159 | errors.push(message);
|
160 | } else if (_.isObject(message) || _.isArray(message)) {
|
161 | var extractedErrors = extractErrors(message, 3);
|
162 | if (!_.isEmpty(extractedErrors)) {
|
163 | errors = errors.concat(extractedErrors);
|
164 | }
|
165 | }
|
166 | });
|
167 | if (!_.isEmpty(errors)) messages.push({errors: errors});
|
168 | messages.push({container: {ID: properties.ID, name: properties.name, netInfo: properties.netInfo}});
|
169 |
|
170 | var errid = uuid();
|
171 | if (logger.enabled && levels[level] >= levels[logger.level]) {
|
172 | try {
|
173 | manager.log(logger.namespace, level, messages);
|
174 | } catch (err) {
|
175 | console.error('hubiquitus log processing error', err, err.stack);
|
176 | }
|
177 | }
|
178 | return errid;
|
179 | };
|
180 |
|
181 |
|
182 |
|
183 |
|
184 |
|
185 |
|
186 |
|
187 | manager.log = function (namespace, level, messages) {
|
188 | var log = '[' + namespace + '][' + level + '][' + new Date() + ']';
|
189 | _.forEach(messages, function (message) {
|
190 | log += '\n';
|
191 | if (_.isObject(message) || _.isArray(message)) {
|
192 | log += util.inspect(message, {depth: 10});
|
193 | } else {
|
194 | log += message;
|
195 | }
|
196 | });
|
197 | console.log(log + '\n');
|
198 | };
|
199 |
|
200 |
|
201 |
|
202 |
|
203 |
|
204 |
|
205 | function formatError(err) {
|
206 | return {err: ('Error ' + err.message), stack: err.stack};
|
207 | }
|
208 |
|
209 |
|
210 |
|
211 |
|
212 |
|
213 |
|
214 |
|
215 | function extractErrors(data, depth) {
|
216 | depth = depth || 1;
|
217 | var currentDepth = 0;
|
218 |
|
219 | return (function extract(data) {
|
220 | currentDepth++;
|
221 | var errors = [];
|
222 | _.forEach(data, function (item, name) {
|
223 | if (util.isError(item)) {
|
224 | errors.push(formatError(item));
|
225 | } else if (currentDepth < depth && (_.isObject(data) || _.isArray(data))) {
|
226 | var extractedErrors = extract(item);
|
227 | if (!_.isEmpty(extractedErrors)) {
|
228 | errors = errors.concat(extractedErrors);
|
229 | }
|
230 | }
|
231 | });
|
232 | return errors;
|
233 | })(data);
|
234 | }
|