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