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