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