]> arthur.barton.de Git - netdata.git/blob - plugins.d/node.d.plugin
96e00694e463b602995436218cf1193ab97e3023
[netdata.git] / plugins.d / node.d.plugin
1 #!/usr/bin/env node
2
3 'use strict';
4
5 // --------------------------------------------------------------------------------------------------------------------
6 // get NETDATA environment variables
7
8 var NETDATA_PLUGINS_DIR = process.env.NETDATA_PLUGINS_DIR || __dirname;
9 var NETDATA_CONFIG_DIR = process.env.NETDATA_CONFIG_DIR || '/etc/netdata';
10 var NETDATA_UPDATE_EVERY = process.env.NETDATA_UPDATE_EVERY || 1;
11 var NODE_D_DIR = NETDATA_PLUGINS_DIR + '/../node.d';
12
13 // make sure the modules are found
14 process.mainModule.paths.unshift(NODE_D_DIR + '/node_modules');
15 process.mainModule.paths.unshift(NODE_D_DIR);
16
17
18 // --------------------------------------------------------------------------------------------------------------------
19 // load required modules
20
21 var fs = require('fs');
22 var url = require('url');
23 var http = require('http');
24 var path = require('path');
25 var extend = require('extend');
26 var netdata = require('netdata');
27
28
29 // --------------------------------------------------------------------------------------------------------------------
30 // configuration
31
32 function pluginConfig(filename) {
33         var f = path.basename(filename);
34
35         var m = f.match('.plugin' + '$');
36         if(m === null) m = f.match('.node.js' + '$');
37         if(m !== null)
38                 return netdata.options.paths.config + '/' + f.substring(0, m.index) + '.conf';
39
40         return netdata.options.paths.config + '/' + f + '.conf';
41 }
42
43 // internal defaults
44 extend(true, netdata.options, {
45         filename: path.basename(__filename),
46
47         update_every: NETDATA_UPDATE_EVERY,
48
49         exit_after_ms: 3600 * 4 * 1000,
50
51         paths: {
52                 plugins: NETDATA_PLUGINS_DIR,
53                 config: NETDATA_CONFIG_DIR,
54                 modules: [],
55         },
56
57         modules_enable_autodetect: true,
58         modules_enable_all: true,
59         modules: {},
60 });
61 netdata.options.config_filename = pluginConfig(__filename);
62
63 // load configuration file
64 try {
65         netdata.options_loaded = JSON.parse(fs.readFileSync(netdata.options.config_filename, 'utf8'));
66         extend(true, netdata.options, netdata.options_loaded);
67         console.error('merged netdata object:');
68         console.error(netdata);
69 }
70 catch(e) {
71         netdata.error('Cannot read configuration file ' + netdata.options.config_filename + ': ' + e.message + ', using internal defaults.');
72         netdata.options_loaded = undefined;
73         dumpError(e);
74 }
75
76
77 // apply module paths to node.js process
78 function applyModulePaths() {
79         var len = netdata.options.paths.modules.length;
80         while(len--)
81                 process.mainModule.paths.unshift(netdata.options.paths.modules[len]);
82 }
83 applyModulePaths();
84
85
86 // --------------------------------------------------------------------------------------------------------------------
87 // tracing
88
89 function dumpError(err) {
90         if (typeof err === 'object') {
91                 if (err.stack) {
92                         netdata.debug(err.stack);
93                 }
94         }
95 }
96
97 // --------------------------------------------------------------------------------------------------------------------
98 // get command line arguments
99 {
100         var found_myself = false;
101         var found_number = false;
102         var found_modules = false;
103         process.argv.forEach(function (val, index, array) {
104                 netdata.debug('PARAM: ' + val);
105
106                 if(!found_myself) {
107                         if(val === __filename)
108                                 found_myself = true;
109                 }
110                 else {
111                         switch(val) {
112                                 case 'debug':
113                                         netdata.options.DEBUG = true;
114                                         netdata.debug('DEBUG enabled');
115                                         break;
116
117                                 default:
118                                         if(found_number === true) {
119                                                 if(found_modules === false) {
120                                                         for(var i in netdata.options.modules)
121                                                                 netdata.options.modules[i].enabled = false;
122                                                 }
123
124                                                 if(typeof netdata.options.modules[val] === 'undefined')
125                                                         netdata.options.modules[val] = {};
126
127                                                 netdata.options.modules[val].enabled = true;
128                                                 netdata.options.modules_enable_all = false;
129                                                 netdata.debug('enabled module ' + val);
130                                         }
131                                         else {
132                                                 try {
133                                                         var x = parseInt(val);
134                                                         if(x > 0) {
135                                                                 netdata.options.update_every = x;
136                                                                 if(netdata.options.update_every < NETDATA_UPDATE_EVERY) {
137                                                                         netdata.options.update_every = NETDATA_UPDATE_EVERY;
138                                                                         netdata.debug('Update frequency ' + x + 's is too low');
139                                                                 }
140
141                                                                 found_number = true;
142                                                                 netdata.debug('Update frequency set to ' + netdata.options.update_every + ' seconds');
143                                                         }
144                                                         else netdata.error('Ignoring parameter: ' + val);
145                                                 }
146                                                 catch(e) {
147                                                         netdata.error('Cannot get value of parameter: ' + val);
148                                                         dumpError(e);
149                                                 }
150                                         }
151                                         break;
152                         }
153                 }
154         });
155 }
156
157 if(netdata.options.update_every < 1) {
158         netdata.debug('Adjusting update frequency to 1 second');
159         netdata.options.update_every = 1;
160 }
161
162 // --------------------------------------------------------------------------------------------------------------------
163 // find modules
164
165 function findModules() {
166         var found = 0;
167
168         var files = fs.readdirSync(NODE_D_DIR);
169         var len = files.length;
170         while(len--) {
171                 var m = files[len].match('.node.js' + '$');
172                 if(m !== null) {
173                         var n = files[len].substring(0, m.index);
174
175                         if(typeof(netdata.options.modules[n]) === 'undefined')
176                                 netdata.options.modules[n] = { name: n, enabled: netdata.options.modules_enable_all };
177
178                         if(netdata.options.modules[n].enabled === true) {
179                                 netdata.options.modules[n].name = n;
180                                 netdata.options.modules[n].filename = NODE_D_DIR + '/' + files[len];
181                                 netdata.options.modules[n].loaded = false;
182
183                                 if(typeof(netdata.options.modules[n].config_filename) !== 'string')
184                                         netdata.options.modules[n].config_filename = pluginConfig(files[len]);
185
186                                 // load the module
187                                 try {
188                                         netdata.debug('loading module ' + netdata.options.modules[n].filename);
189                                         netdata.options.modules[n].module = require(netdata.options.modules[n].filename);
190                                         netdata.options.modules[n].module.name = n;
191                                         netdata.debug('loaded module ' + netdata.options.modules[n].name + ' from ' + netdata.options.modules[n].filename);
192                                 }
193                                 catch(e) {
194                                         netdata.options.modules[n].enabled = false;
195                                         netdata.error('Cannot load module: ' + netdata.options.modules[n].filename + ' exception: ' + e);
196                                         dumpError(e);
197                                         continue;
198                                 }
199
200                                 // load its configuration
201                                 var c = {
202                                         enable_autodetect: netdata.options.modules_enable_autodetect,
203                                         update_every: netdata.options.update_every
204                                 };
205                                 try {
206                                         netdata.debug('loading module\'s ' + netdata.options.modules[n].name + ' config ' + netdata.options.modules[n].config_filename);
207                                         var c2 = JSON.parse(fs.readFileSync(netdata.options.modules[n].config_filename, 'utf8'));
208                                         extend(true, c, c2);
209                                         netdata.debug('loaded module\'s ' + netdata.options.modules[n].name + ' config ' + netdata.options.modules[n].config_filename);
210                                 }
211                                 catch(e) {
212                                         netdata.error('Cannot load module\'s ' + netdata.options.modules[n].name + ' config from ' + netdata.options.modules[n].config_filename + ' exception: ' + e + ', using internal defaults.');
213                                         dumpError(e);
214                                 }
215
216                                 // call module auto-detection / configuration
217                                 try {
218                                         netdata.modules_configuring++;
219                                         netdata.debug('Configuring module ' + netdata.options.modules[n].name);
220                                         var serv = netdata.configure(netdata.options.modules[n].module, c, function() {
221                                                 netdata.debug('Configured module ' + netdata.options.modules[n].name);
222                                                 netdata.modules_configuring--;
223                                         });
224
225                                         netdata.debug('Configuring module ' + netdata.options.modules[n].name + ' reports ' + serv + ' eligible services.');
226                                 }
227                                 catch(e) {
228                                         netdata.modules_configuring--;
229                                         netdata.options.modules[n].enabled = false;
230                                         netdata.error('Failed module auto-detection: ' + netdata.options.modules[n].name + ' exception: ' + e + ', disabling module.');
231                                         dumpError(e);
232                                         continue;
233                                 }
234
235                                 netdata.options.modules[n].loaded = true;
236                                 found++;
237                         }
238                 }
239         }
240
241         // netdata.debug(netdata.options.modules);
242         return found;
243 }
244
245 if(findModules() === 0) {
246         netdata.error('Cannot load any .node.js module from: ' + NODE_D_DIR);
247         netdata.disableNodePlugin();
248         process.exit(1);
249 }
250
251
252 // --------------------------------------------------------------------------------------------------------------------
253 // start
254
255 function start_when_configuring_ends() {
256         if(netdata.modules_configuring > 0) {
257                 netdata.debug('Waiting modules configuration, still running ' + netdata.modules_configuring);
258                 setTimeout(start_when_configuring_ends, 500);
259                 return;
260         }
261
262         netdata.modules_configuring = 0;
263         netdata.start();
264 }
265 start_when_configuring_ends();
266
267 //netdata.debug('netdata object:')
268 //netdata.debug(netdata);