diff options
Diffstat (limited to 'collectors/node.d.plugin/node.d.plugin.in')
-rwxr-xr-x | collectors/node.d.plugin/node.d.plugin.in | 303 |
1 files changed, 303 insertions, 0 deletions
diff --git a/collectors/node.d.plugin/node.d.plugin.in b/collectors/node.d.plugin/node.d.plugin.in new file mode 100755 index 0000000..05c126e --- /dev/null +++ b/collectors/node.d.plugin/node.d.plugin.in @@ -0,0 +1,303 @@ +#!/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); |