]> arthur.barton.de Git - netdata.git/blob - node.d/node_modules/netdata.js
added SNMP node.js data collector; node.d.plugin now supports multiple processors...
[netdata.git] / node.d / node_modules / netdata.js
1 'use strict';\r
2 \r
3 var url = require('url');\r
4 var http = require('http');\r
5 var util = require('util');\r
6 \r
7 /*\r
8 var netdata = require('netdata');\r
9 \r
10 var example_chart = {\r
11         id: 'id',                                               // the unique id of the chart\r
12         name: 'name',                                   // the name of the chart\r
13         title: 'title',                                 // the title of the chart\r
14         units: 'units',                                 // the units of the chart dimensions\r
15         family: 'family',                               // the family of the chart\r
16         category: 'category',                   // the category of the chart\r
17         type: netdata.chartTypes.line,  // the type of the chart\r
18         priority: 0,                                    // the priority relative to others in the same family and category\r
19         update_every: 1,                                // the expected update frequency of the chart\r
20         dimensions: {\r
21                 'dim1': {\r
22                         id: 'dim1',                             // the unique id of the dimension\r
23                         name: 'name',                   // the name of the dimension\r
24                         algorithm: netdata.chartAlgorithms.absolute,    // the id of the netdata algorithm\r
25                         multiplier: 1,                  // the multiplier\r
26                         divisor: 1,                             // the divisor\r
27                         hidden: false,                  // is hidden (boolean)\r
28                 },\r
29                 'dim2': {\r
30                         id: 'dim2',                             // the unique id of the dimension\r
31                         name: 'name',                   // the name of the dimension\r
32                         algorithm: 'absolute',  // the id of the netdata algorithm\r
33                         multiplier: 1,                  // the multiplier\r
34                         divisor: 1,                             // the divisor\r
35                         hidden: false,                  // is hidden (boolean)\r
36                 }\r
37                 // add as many dimensions as needed\r
38         }\r
39 };\r
40 */\r
41 \r
42 var netdata = {\r
43         options: {\r
44                 filename: __filename,\r
45                 DEBUG: false,\r
46                 update_every: 1,\r
47         },\r
48 \r
49         chartAlgorithms: {\r
50                 incremental: 'incremental',\r
51                 absolute: 'absolute',\r
52                 percentage_of_absolute_row: 'percentage-of-absolute-row',\r
53                 percentage_of_incremental_row: 'percentage-of-incremental-row'\r
54         },\r
55 \r
56         chartTypes: {\r
57                 line: 'line',\r
58                 area: 'area',\r
59                 stacked: 'stacked'\r
60         },\r
61 \r
62         services: new Array(),\r
63         modules_configuring: 0,\r
64         charts: {},\r
65 \r
66 \r
67         processors: {\r
68                 http: {\r
69                         name: 'http',\r
70 \r
71                         process: function(service, callback) {\r
72                                 if(netdata.options.DEBUG === true) netdata.debug(service.module.name + ': ' + service.name + ': making ' + this.name + ' request: ' + netdata.stringify(service.request));\r
73 \r
74                                 var req = http.request(service.request, function(response) {\r
75                                         if(netdata.options.DEBUG === true) netdata.debug(service.module.name + ': ' + service.name + ': got server response...');\r
76 \r
77                                         var end = false;\r
78                                         var data = '';\r
79                                         response.setEncoding('utf8');\r
80 \r
81                                         if(response.statusCode !== 200) {\r
82                                                 if(end === false) {\r
83                                                         service.error('Got HTTP code ' + response.statusCode + ', failed to get data.');\r
84                                                         end = true;\r
85                                                         callback(null);\r
86                                                 }\r
87                                         }\r
88 \r
89                                         response.on('data', function(chunk) {\r
90                                                 if(end === false) data += chunk;\r
91                                         });\r
92 \r
93                                         response.on('error', function() {\r
94                                                 if(end === false) {\r
95                                                         service.error(': Read error, failed to get data.');\r
96                                                         end = true;\r
97                                                         callback(null);\r
98                                                 }\r
99                                         });\r
100 \r
101                                         response.on('end', function() {\r
102                                                 if(end === false) {\r
103                                                         if(netdata.options.DEBUG === true) netdata.debug(service.module.name + ': ' + service.name + ': read completed.');\r
104                                                         end = true;\r
105                                                         callback(data);\r
106                                                 }\r
107                                         });\r
108                                 });\r
109 \r
110                                 req.on('error', function(e) {\r
111                                         service.error('Failed to make request: ' + netdata.stringify(service.request) + ', message: ' + e.message);\r
112                                         callback(null);\r
113                                 });\r
114 \r
115                                 // write data to request body\r
116                                 if(typeof service.postData !== 'undefined' && service.request.method === 'POST') {\r
117                                         if(netdata.options.DEBUG === true) netdata.debug(service.module.name + ': ' + service.name + ': posting data: ' + service.postData);\r
118                                         req.write(service.postData);\r
119                                 }\r
120 \r
121                                 req.end();\r
122                         }\r
123                 }\r
124         },\r
125 \r
126         stringify: function(obj) {\r
127                 return util.inspect(obj, {depth: 10});\r
128         },\r
129 \r
130         // show debug info, if debug is enabled\r
131         debug: function(msg) {\r
132                 if(this.options.DEBUG === true) {\r
133                         var now = new Date();\r
134                         console.error(now.toString() + ': ' + netdata.options.filename + ': DEBUG: ' + ((typeof(msg) === 'object')?netdata.stringify(msg):msg).toString());\r
135                 }\r
136         },\r
137 \r
138         // log an error\r
139         error: function(msg) {\r
140                 var now = new Date();\r
141                 console.error(now.toString() + ': ' + netdata.options.filename + ': ERROR: ' + ((typeof(msg) === 'object')?netdata.stringify(msg):msg).toString());\r
142         },\r
143 \r
144         // send data to netdata\r
145         send: function(msg) {\r
146                 console.log(msg.toString());\r
147         },\r
148 \r
149         service: function(service) {\r
150                 if(typeof service === 'undefined')\r
151                         service = {};\r
152 \r
153                 service._current_chart = null;  // the current chart we work on\r
154                 service._queue = '';                    // data to be sent to netdata\r
155 \r
156                 service.error_reported = false; // error log flood control\r
157 \r
158                 service.added = false;                  // added to netdata.services\r
159                 service.enabled = true;\r
160                 service.updates = 0;\r
161                 service.running = false;\r
162                 service.started = 0;\r
163                 service.ended = 0;\r
164                 service.next_run = new Date().getTime();\r
165 \r
166                 if(typeof service.update_every === 'undefined')\r
167                         service.update_every = service.module.update_every;\r
168 \r
169                 if(typeof service.update_every === 'undefined')\r
170                         service.update_every = netdata.options.update_every;\r
171 \r
172                 if(typeof service.processor === 'undefined')\r
173                         service.processor = netdata.processors.http;\r
174 \r
175                 if(service.update_every < netdata.options.update_every)\r
176                         service.update_every = netdata.options.update_every;\r
177 \r
178                 service.commit = function() {\r
179                         if(this.added !== true) {\r
180                                 this.added = true;\r
181                                 \r
182                                 var now = new Date().getTime();\r
183                                 while( this.next_run < now )\r
184                                         this.next_run += (this.update_every * 1000);\r
185 \r
186                                 netdata.services.push(this);\r
187                                 if(netdata.options.DEBUG === true) netdata.debug(this.module.name + ': ' + this.name + ': service committed.');\r
188                         }\r
189                 };\r
190 \r
191                 service.execute = function(callback) {\r
192                         this.module.active++;\r
193                         this.running = true;\r
194                         this.started = new Date().getTime();\r
195                         this.updates++;\r
196 \r
197                         if(netdata.options.DEBUG === true)\r
198                                 netdata.debug(this.module.name + ': ' + this.name + ': making ' + this.processor.name + ' request: ' + netdata.stringify(this));\r
199 \r
200                         this.processor.process(this, function(response) {\r
201                                 service.ended = new Date().getTime();\r
202                                 service.duration = service.ended - service.started;\r
203 \r
204                                 if(typeof response === 'undefined')\r
205                                         response = null;\r
206 \r
207                                 if(response !== null)\r
208                                         service.errorClear();\r
209 \r
210                                 if(netdata.options.DEBUG === true)\r
211                                         netdata.debug(service.module.name + ': ' + service.name + ': processing ' + service.processor.name + ' response (received in ' + (service.ended - service.started).toString() + ' ms)');\r
212 \r
213                                 callback(service, response);\r
214 \r
215                                 service.running = false;\r
216                                 service.module.active--;\r
217                                 if(service.module.active < 0) {\r
218                                         service.module.active = 0;\r
219                                         if(netdata.options.DEBUG === true) netdata.debug(service.module.name + ': active module counter below zero.');\r
220                                 }\r
221 \r
222                                 if(service.module.active === 0) {\r
223                                         // check if we run under configure\r
224                                         if(service.module.configure_callback !== null) {\r
225                                                 if(netdata.options.DEBUG === true) netdata.debug(service.module.name + ': configuration finish callback called from processResponse().');\r
226                                                 var ccallback = service.module.configure_callback;\r
227                                                 service.module.configure_callback = null;\r
228                                                 ccallback();\r
229                                         }\r
230                                 }\r
231                         });\r
232                 };\r
233 \r
234                 service.update = function() {\r
235                         if(netdata.options.DEBUG === true) netdata.debug(this.module.name + ': ' + this.name + ': starting data collection...');\r
236 \r
237                         this.module.update(this, function() {\r
238                                 if(netdata.options.DEBUG === true) netdata.debug(service.module.name + ': ' + service.name + ': data collection ended in ' + service.duration.toString() + ' ms.');\r
239                         });\r
240                 };\r
241 \r
242                 service.error = function(message) {\r
243                         if(this.error_reported === false) {\r
244                                 netdata.error(this.module.name + ': ' + this.name + ': ' + message);\r
245                                 this.error_reported = true;\r
246                         }\r
247                         else if(netdata.options.DEBUG === true)\r
248                                 netdata.debug(this.module.name + ': ' + this.name + ': ' + message);\r
249                 };\r
250 \r
251                 service.errorClear = function() {\r
252                         this.error_reported = false;\r
253                 };\r
254 \r
255                 service.queue = function(txt) {\r
256                         this._queue += txt + '\n';\r
257                 };\r
258 \r
259                 service._send_chart_to_netdata = function(chart) {\r
260                         // internal function to send a chart to netdata\r
261                         this.queue('CHART "' + chart.id + '" "' + chart.name + '" "' + chart.title + '" "' + chart.units + '" "' + chart.family + '" "' + chart.category + '" "' + chart.type + '" ' + chart.priority.toString() + ' ' + chart.update_every.toString());\r
262                         \r
263                         for(var dim in chart.dimensions) {\r
264                                 var d = chart.dimensions[dim];\r
265 \r
266                                 this.queue('DIMENSION "' + d.id + '" "' + d.name + '" "' + d.algorithm + '" ' + d.multiplier.toString() + ' ' + d.divisor.toString() + ' ' + ((d.hidden === true)?'hidden':'').toString());\r
267                                 d._created = true;\r
268                                 d._updated = false;\r
269                         }\r
270 \r
271                         chart._created = true;\r
272                         chart._updated = false;\r
273                 };\r
274 \r
275                 // begin data collection for a chart\r
276                 service.begin = function(chart) {\r
277                         if(this._current_chart !== null && this._current_chart !== chart) {\r
278                                 this.error('Called begin() for chart ' + chart.id + ' while chart ' + this._current_chart.id + ' is still open. Closing it.');\r
279                                 this.end();\r
280                         }\r
281 \r
282                         if(typeof(chart.id) === 'undefined' || netdata.charts[chart.id] != chart) {\r
283                                 this.error('Called begin() for chart ' + chart.id + ' that is not mine. Where did you find it? Ignoring it.');\r
284                                 return false;\r
285                         }\r
286 \r
287                         if(netdata.options.DEBUG === true) netdata.debug('setting current chart to ' + chart.id);\r
288                         this._current_chart = chart;\r
289                         this._current_chart._began = true;\r
290 \r
291                         if(this._current_chart._dimensions_count !== 0) {\r
292                                 if(this._current_chart._created === false || this._current_chart._updated === true)\r
293                                         this._send_chart_to_netdata(this._current_chart);\r
294 \r
295                                 var now = this.ended;\r
296                                 this.queue('BEGIN ' + this._current_chart.id + ' ' + ((this._current_chart._last_updated > 0)?((now - this._current_chart._last_updated) * 1000):'').toString());\r
297                         }\r
298                         // else this.error('Called begin() for chart ' + chart.id + ' which is empty.');\r
299 \r
300                         this._current_chart._last_updated = now;\r
301                         this._current_chart._began = true;\r
302                         this._current_chart._counter++;\r
303 \r
304                         return true;\r
305                 };\r
306 \r
307                 // set a collected value for a chart\r
308                 // we do most things on the first value we attempt to set\r
309                 service.set = function(dimension, value) {\r
310                         if(this._current_chart === null) {\r
311                                 this.error('Called set(' + dimension + ', ' + value + ') without an open chart.');\r
312                                 return false;\r
313                         }\r
314 \r
315                         if(typeof(this._current_chart.dimensions[dimension]) === 'undefined') {\r
316                                 this.error('Called set(' + dimension + ', ' + value + ') but dimension "' + dimension + '" does not exist in chart "' + this._current_chart.id + '".');\r
317                                 return false;\r
318                         }\r
319 \r
320                         if(typeof value === 'undefined' || value === null)\r
321                                 return false;\r
322 \r
323                         if(this._current_chart._dimensions_count !== 0)\r
324                                 this.queue('SET ' + dimension + ' = ' + value);\r
325 \r
326                         return true;\r
327                 };\r
328 \r
329                 // end data collection for the current chart - after calling begin()\r
330                 service.end = function() {\r
331                         if(this._current_chart !== null && this._current_chart._began === false) {\r
332                                 this.error('Called end() without an open chart.');\r
333                                 return false;\r
334                         }\r
335 \r
336                         if(this._current_chart._dimensions_count !== 0) {\r
337                                 this.queue('END');\r
338                                 netdata.send(this._queue);\r
339                         }\r
340 \r
341                         this._queue = '';\r
342                         this._current_chart._began = false;\r
343                         if(netdata.options.DEBUG === true) netdata.debug('sent chart ' + this._current_chart.id);\r
344                         this._current_chart = null;\r
345                         return true;\r
346                 };\r
347 \r
348                 // discard the collected values for the current chart - after calling begin()\r
349                 service.flush = function() {\r
350                         if(this._current_chart === null || this._current_chart._began === false) {\r
351                                 this.error('Called flush() without an open chart.');\r
352                                 return false;\r
353                         }\r
354 \r
355                         this._queue = '';\r
356                         this._current_chart._began = false;\r
357                         this._current_chart = null;\r
358                         return true;\r
359                 };\r
360 \r
361                 // create a netdata chart\r
362                 service.chart = function(id, chart) {\r
363                         if(typeof(netdata.charts[id]) === 'undefined') {\r
364                                 netdata.charts[id] = {\r
365                                         _created: false,\r
366                                         _updated: true,\r
367                                         _began: false,\r
368                                         _counter: 0,\r
369                                         _last_updated: 0,\r
370                                         _dimensions_count: 0,\r
371                                         id: id,\r
372                                         name: id,\r
373                                         title: 'untitled chart',\r
374                                         units: 'a unit',\r
375                                         family: '',\r
376                                         category: '',\r
377                                         type: netdata.chartTypes.line,\r
378                                         priority: 0,\r
379                                         update_every: netdata.options.update_every,\r
380                                         dimensions: {}\r
381                                 };\r
382                         }\r
383 \r
384                         var c = netdata.charts[id];\r
385 \r
386                         if(typeof(chart.name) !== 'undefined' && chart.name !== c.name) {\r
387                                 if(netdata.options.DEBUG === true) netdata.debug('chart ' + id + ' updated its name');\r
388                                 c.name = chart.name;\r
389                                 c._updated = true;\r
390                         }\r
391 \r
392                         if(typeof(chart.title) !== 'undefined' && chart.title !== c.title) {\r
393                                 if(netdata.options.DEBUG === true) netdata.debug('chart ' + id + ' updated its title');\r
394                                 c.title = chart.title;\r
395                                 c._updated = true;\r
396                         }\r
397 \r
398                         if(typeof(chart.units) !== 'undefined' && chart.units !== c.units) {\r
399                                 if(netdata.options.DEBUG === true) netdata.debug('chart ' + id + ' updated its units');\r
400                                 c.units = chart.units;\r
401                                 c._updated = true;\r
402                         }\r
403 \r
404                         if(typeof(chart.family) !== 'undefined' && chart.family !== c.family) {\r
405                                 if(netdata.options.DEBUG === true) netdata.debug('chart ' + id + ' updated its family');\r
406                                 c.family = chart.family;\r
407                                 c._updated = true;\r
408                         }\r
409 \r
410                         if(typeof(chart.category) !== 'undefined' && chart.category !== c.category) {\r
411                                 if(netdata.options.DEBUG === true) netdata.debug('chart ' + id + ' updated its category');\r
412                                 c.category = chart.category;\r
413                                 c._updated = true;\r
414                         }\r
415 \r
416                         if(typeof(chart.type) !== 'undefined' && chart.type !== c.type) {\r
417                                 if(netdata.options.DEBUG === true) netdata.debug('chart ' + id + ' updated its type');\r
418                                 c.type = chart.type;\r
419                                 c._updated = true;\r
420                         }\r
421 \r
422                         if(typeof(chart.priority) !== 'undefined' && chart.priority !== c.priority) {\r
423                                 if(netdata.options.DEBUG === true) netdata.debug('chart ' + id + ' updated its priority');\r
424                                 c.priority = chart.priority;\r
425                                 c._updated = true;\r
426                         }\r
427 \r
428                         if(typeof(chart.update_every) !== 'undefined' && chart.update_every !== c.update_every) {\r
429                                 if(netdata.options.DEBUG === true) netdata.debug('chart ' + id + ' updated its update_every from ' + c.update_every + ' to ' + chart.update_every);\r
430                                 c.update_every = chart.update_every;\r
431                                 c._updated = true;\r
432                         }\r
433 \r
434                         if(typeof(chart.dimensions) !== 'undefined') {\r
435                                 for(var x in chart.dimensions) {\r
436                                         if(typeof(c.dimensions[x]) === 'undefined') {\r
437                                                 c._dimensions_count++;\r
438 \r
439                                                 c.dimensions[x] = {\r
440                                                         _created: false,\r
441                                                         _updated: false,\r
442                                                         id: x,                                  // the unique id of the dimension\r
443                                                         name: x,                                // the name of the dimension\r
444                                                         algorithm: netdata.chartAlgorithms.absolute,    // the id of the netdata algorithm\r
445                                                         multiplier: 1,                  // the multiplier\r
446                                                         divisor: 1,                             // the divisor\r
447                                                         hidden: false,                  // is hidden (boolean)\r
448                                                 };\r
449 \r
450                                                 if(netdata.options.DEBUG === true) netdata.debug('chart ' + id + ' created dimension ' + x);\r
451                                                 c._updated = true;\r
452                                         }\r
453 \r
454                                         var dim = chart.dimensions[x];\r
455                                         var d = c.dimensions[x];\r
456 \r
457                                         if(typeof(dim.name) !== 'undefined' && d.name !== dim.name) {\r
458                                                 if(netdata.options.DEBUG === true) netdata.debug('chart ' + id + ', dimension ' + x + ' updated its name');\r
459                                                 d.name = dim.name;\r
460                                                 d._updated = true;\r
461                                         }\r
462 \r
463                                         if(typeof(dim.algorithm) !== 'undefined' && d.algorithm !== dim.algorithm) {\r
464                                                 if(netdata.options.DEBUG === true) netdata.debug('chart ' + id + ', dimension ' + x + ' updated its algorithm from ' + d.algorithm + ' to ' + dim.algorithm);\r
465                                                 d.algorithm = dim.algorithm;\r
466                                                 d._updated = true;\r
467                                         }\r
468 \r
469                                         if(typeof(dim.multiplier) !== 'undefined' && d.multiplier !== dim.multiplier) {\r
470                                                 if(netdata.options.DEBUG === true) netdata.debug('chart ' + id + ', dimension ' + x + ' updated its multiplier');\r
471                                                 d.multiplier = dim.multiplier;\r
472                                                 d._updated = true;\r
473                                         }\r
474 \r
475                                         if(typeof(dim.divisor) !== 'undefined' && d.divisor !== dim.divisor) {\r
476                                                 if(netdata.options.DEBUG === true) netdata.debug('chart ' + id + ', dimension ' + x + ' updated its divisor');\r
477                                                 d.divisor = dim.divisor;\r
478                                                 d._updated = true;\r
479                                         }\r
480 \r
481                                         if(typeof(dim.hidden) !== 'undefined' && d.hidden !== dim.hidden) {\r
482                                                 if(netdata.options.DEBUG === true) netdata.debug('chart ' + id + ', dimension ' + x + ' updated its hidden status');\r
483                                                 d.hidden = dim.hidden;\r
484                                                 d._updated = true;\r
485                                         }\r
486 \r
487                                         if(d._updated) c._updated = true;\r
488                                 }\r
489                         }\r
490 \r
491                         //if(netdata.options.DEBUG === true) netdata.debug(netdata.charts);\r
492                         return netdata.charts[id];\r
493                 };\r
494 \r
495                 return service;\r
496         },\r
497 \r
498         runAllServices: function() {\r
499                 if(netdata.options.DEBUG === true) netdata.debug('runAllServices()');\r
500 \r
501                 var now = new Date().getTime();\r
502                 var len = netdata.services.length;\r
503                 while(len--) {\r
504                         var service = netdata.services[len];\r
505 \r
506                         if(service.enabled === false || service.running === true) continue;\r
507                         if(now <= service.next_run) continue;\r
508 \r
509                         service.update();\r
510 \r
511                         now = new Date().getTime();\r
512                         while(service.next_run < now)\r
513                                 service.next_run += (service.update_every * 1000);\r
514                 }\r
515 \r
516                 // 1/10th of update_every in pause\r
517                 setTimeout(netdata.runAllServices, netdata.options.update_every * 100);\r
518         },\r
519 \r
520         start: function() {\r
521                 if(netdata.options.DEBUG === true) this.debug('started, services: ' + netdata.stringify(this.services));\r
522 \r
523                 if(this.services.length === 0) {\r
524                         this.disableNodePlugin();\r
525                         process.exit(1);\r
526                 }\r
527                 else this.runAllServices();\r
528         },\r
529 \r
530         // disable the whole node.js plugin\r
531         disableNodePlugin: function() {\r
532                 this.send('DISABLE');\r
533                 process.exit(1);\r
534         },\r
535 \r
536         requestFromParams: function(protocol, hostname, port, path, method) {\r
537                 return {\r
538                         protocol: protocol,\r
539                         hostname: hostname,\r
540                         port: port,\r
541                         path: path,\r
542                         //family: 4,\r
543                         method: method,\r
544                         headers: {\r
545                                 'Content-Type': 'application/x-www-form-urlencoded',\r
546                                 'Connection': 'keep-alive'\r
547                         },\r
548                         agent: new http.Agent({\r
549                                 keepAlive: true,\r
550                                 keepAliveMsecs: netdata.options.update_every * 1000,\r
551                                 maxSockets: 2, // it must be 2 to work\r
552                                 maxFreeSockets: 1\r
553                         })\r
554                 };\r
555         },\r
556 \r
557         requestFromURL: function(a_url) {\r
558                 var u = url.parse(a_url);\r
559                 return netdata.requestFromParams(u.protocol, u.hostname, u.port, u.path, 'GET');\r
560         },\r
561 \r
562         configure: function(module, config, callback) {\r
563                 if(netdata.options.DEBUG === true) this.debug(module.name + ': configuring (update_every: ' + this.options.update_every + ')...');\r
564 \r
565                 module.active = 0;\r
566                 module.update_every = this.options.update_every;\r
567 \r
568                 if(typeof config.update_every !== 'undefined')\r
569                         module.update_every = config.update_every;\r
570 \r
571                 module.enable_autodetect = (config.enable_autodetect)?true:false;\r
572 \r
573                 if(typeof(callback) === 'function')\r
574                         module.configure_callback = callback;\r
575                 else\r
576                         module.configure_callback = null;\r
577 \r
578                 var added = module.configure(config);\r
579 \r
580                 if(netdata.options.DEBUG === true) this.debug(module.name + ': configured, reporting ' + added + ' eligible services.');\r
581 \r
582                 if(module.configure_callback !== null && added === 0) {\r
583                         if(netdata.options.DEBUG === true) this.debug(module.name + ': configuration finish callback called from configure().');\r
584                         module.configure_callback = null;\r
585                         callback();\r
586                 }\r
587 \r
588                 return added;\r
589         }\r
590 };\r
591 \r
592 if(netdata.options.DEBUG === true) netdata.debug('loaded netdata from: ' + __filename);\r
593 module.exports = netdata;\r