netdata/collectors/node.d.plugin/node.d.plugin.in

304 lines
11 KiB
Bash
Executable File

#!/usr/bin/env bash
':' //; exec "$(command -v nodejs || command -v node || echo "ERROR node IS NOT AVAILABLE IN THIS SYSTEM")" "$0" "$@"
// shebang hack from:
// http://unix.stackexchange.com/questions/65235/universal-node-js-shebang
// Initially this is run as a shell script.
// Then, the second line, finds nodejs or node or js in the system path
// and executes it with the shell parameters.
// netdata
// real-time performance and health monitoring, done right!
// (C) 2017 Costa Tsaousis <costa@tsaousis.gr>
// SPDX-License-Identifier: GPL-3.0-or-later
// --------------------------------------------------------------------------------------------------------------------
'use strict';
// --------------------------------------------------------------------------------------------------------------------
// get NETDATA environment variables
var NETDATA_PLUGINS_DIR = process.env.NETDATA_PLUGINS_DIR || __dirname;
var NETDATA_USER_CONFIG_DIR = process.env.NETDATA_USER_CONFIG_DIR || '@configdir_POST@';
var NETDATA_STOCK_CONFIG_DIR = process.env.NETDATA_STOCK_CONFIG_DIR || '@libconfigdir_POST@';
var NETDATA_UPDATE_EVERY = process.env.NETDATA_UPDATE_EVERY || 1;
var NODE_D_DIR = NETDATA_PLUGINS_DIR + '/../node.d';
// make sure the modules are found
process.mainModule.paths.unshift(NODE_D_DIR + '/node_modules');
process.mainModule.paths.unshift(NODE_D_DIR);
// --------------------------------------------------------------------------------------------------------------------
// load required modules
var fs = require('fs');
var url = require('url');
var util = require('util');
var http = require('http');
var path = require('path');
var extend = require('extend');
var netdata = require('netdata');
// --------------------------------------------------------------------------------------------------------------------
// configuration
function netdata_read_json_config_file(module_filename) {
var f = path.basename(module_filename);
var ufilename, sfilename;
var m = f.match('.plugin' + '$');
if(m !== null) {
ufilename = netdata.options.paths.config + '/' + f.substring(0, m.index) + '.conf';
sfilename = netdata.options.paths.stock_config + '/' + f.substring(0, m.index) + '.conf';
}
m = f.match('.node.js' + '$');
if(m !== null) {
ufilename = netdata.options.paths.config + '/node.d/' + f.substring(0, m.index) + '.conf';
sfilename = netdata.options.paths.stock_config + '/node.d/' + f.substring(0, m.index) + '.conf';
}
try {
netdata.debug('loading module\'s ' + module_filename + ' user-config ' + ufilename);
return JSON.parse(fs.readFileSync(ufilename, 'utf8'));
}
catch(e) {
netdata.error('Cannot read user-configuration file ' + ufilename + ': ' + e.message + '.');
dumpError(e);
}
try {
netdata.debug('loading module\'s ' + module_filename + ' stock-config ' + sfilename);
return JSON.parse(fs.readFileSync(sfilename, 'utf8'));
}
catch(e) {
netdata.error('Cannot read stock-configuration file ' + sfilename + ': ' + e.message + ', using internal defaults.');
dumpError(e);
}
return {};
}
// internal defaults
extend(true, netdata.options, {
filename: path.basename(__filename),
update_every: NETDATA_UPDATE_EVERY,
paths: {
plugins: NETDATA_PLUGINS_DIR,
config: NETDATA_USER_CONFIG_DIR,
stock_config: NETDATA_STOCK_CONFIG_DIR,
modules: []
},
modules_enable_autodetect: true,
modules_enable_all: true,
modules: {}
});
// load configuration file
netdata.options_loaded = netdata_read_json_config_file(__filename);
extend(true, netdata.options, netdata.options_loaded);
if(!netdata.options.paths.plugins)
netdata.options.paths.plugins = NETDATA_PLUGINS_DIR;
if(!netdata.options.paths.config)
netdata.options.paths.config = NETDATA_USER_CONFIG_DIR;
if(!netdata.options.paths.stock_config)
netdata.options.paths.stock_config = NETDATA_STOCK_CONFIG_DIR;
// console.error('merged netdata object:');
// console.error(util.inspect(netdata, {depth: 10}));
// apply module paths to node.js process
function applyModulePaths() {
var len = netdata.options.paths.modules.length;
while(len--)
process.mainModule.paths.unshift(netdata.options.paths.modules[len]);
}
applyModulePaths();
// --------------------------------------------------------------------------------------------------------------------
// tracing
function dumpError(err) {
if (typeof err === 'object') {
if (err.stack) {
netdata.debug(err.stack);
}
}
}
// --------------------------------------------------------------------------------------------------------------------
// get command line arguments
{
var found_myself = false;
var found_number = false;
var found_modules = false;
process.argv.forEach(function (val, index, array) {
netdata.debug('PARAM: ' + val);
if(!found_myself) {
if(val === __filename)
found_myself = true;
}
else {
switch(val) {
case 'debug':
netdata.options.DEBUG = true;
netdata.debug('DEBUG enabled');
break;
default:
if(found_number === true) {
if(found_modules === false) {
for(var i in netdata.options.modules)
netdata.options.modules[i].enabled = false;
}
if(typeof netdata.options.modules[val] === 'undefined')
netdata.options.modules[val] = {};
netdata.options.modules[val].enabled = true;
netdata.options.modules_enable_all = false;
netdata.debug('enabled module ' + val);
}
else {
try {
var x = parseInt(val);
if(x > 0) {
netdata.options.update_every = x;
if(netdata.options.update_every < NETDATA_UPDATE_EVERY) {
netdata.options.update_every = NETDATA_UPDATE_EVERY;
netdata.debug('Update frequency ' + x + 's is too low');
}
found_number = true;
netdata.debug('Update frequency set to ' + netdata.options.update_every + ' seconds');
}
else netdata.error('Ignoring parameter: ' + val);
}
catch(e) {
netdata.error('Cannot get value of parameter: ' + val);
dumpError(e);
}
}
break;
}
}
});
}
if(netdata.options.update_every < 1) {
netdata.debug('Adjusting update frequency to 1 second');
netdata.options.update_every = 1;
}
// --------------------------------------------------------------------------------------------------------------------
// find modules
function findModules() {
var found = 0;
var files = fs.readdirSync(NODE_D_DIR);
var len = files.length;
while(len--) {
var m = files[len].match('.node.js' + '$');
if(m !== null) {
var n = files[len].substring(0, m.index);
if(typeof(netdata.options.modules[n]) === 'undefined')
netdata.options.modules[n] = { name: n, enabled: netdata.options.modules_enable_all };
if(netdata.options.modules[n].enabled === true) {
netdata.options.modules[n].name = n;
netdata.options.modules[n].filename = NODE_D_DIR + '/' + files[len];
netdata.options.modules[n].loaded = false;
// load the module
try {
netdata.debug('loading module ' + netdata.options.modules[n].filename);
netdata.options.modules[n].module = require(netdata.options.modules[n].filename);
netdata.options.modules[n].module.name = n;
netdata.debug('loaded module ' + netdata.options.modules[n].name + ' from ' + netdata.options.modules[n].filename);
}
catch(e) {
netdata.options.modules[n].enabled = false;
netdata.error('Cannot load module: ' + netdata.options.modules[n].filename + ' exception: ' + e);
dumpError(e);
continue;
}
// load its configuration
var c = {
enable_autodetect: netdata.options.modules_enable_autodetect,
update_every: netdata.options.update_every
};
var c2 = netdata_read_json_config_file(files[len]);
extend(true, c, c2);
// call module auto-detection / configuration
try {
netdata.modules_configuring++;
netdata.debug('Configuring module ' + netdata.options.modules[n].name);
var serv = netdata.configure(netdata.options.modules[n].module, c, function() {
netdata.debug('Configured module ' + netdata.options.modules[n].name);
netdata.modules_configuring--;
});
netdata.debug('Configuring module ' + netdata.options.modules[n].name + ' reports ' + serv + ' eligible services.');
}
catch(e) {
netdata.modules_configuring--;
netdata.options.modules[n].enabled = false;
netdata.error('Failed module auto-detection: ' + netdata.options.modules[n].name + ' exception: ' + e + ', disabling module.');
dumpError(e);
continue;
}
netdata.options.modules[n].loaded = true;
found++;
}
}
}
// netdata.debug(netdata.options.modules);
return found;
}
if(findModules() === 0) {
netdata.error('Cannot load any .node.js module from: ' + NODE_D_DIR);
netdata.disableNodePlugin();
process.exit(1);
}
// --------------------------------------------------------------------------------------------------------------------
// start
function start_when_configuring_ends() {
if(netdata.modules_configuring > 0) {
netdata.debug('Waiting modules configuration, still running ' + netdata.modules_configuring);
setTimeout(start_when_configuring_ends, 500);
return;
}
netdata.modules_configuring = 0;
netdata.start();
}
start_when_configuring_ends();
//netdata.debug('netdata object:')
//netdata.debug(netdata);