#!/usr/bin/env bash ':' //; exec "$(command -v nodejs || command -v node || command -v js || echo "ERROR node.js 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 (#!/bin/sh). // 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) 2016 Costa Tsaousis // GPL v3+ // -------------------------------------------------------------------------------------------------------------------- 'use strict'; // -------------------------------------------------------------------------------------------------------------------- // get NETDATA environment variables var NETDATA_PLUGINS_DIR = process.env.NETDATA_PLUGINS_DIR || __dirname; var NETDATA_CONFIG_DIR = process.env.NETDATA_CONFIG_DIR || '/etc/netdata'; 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 pluginConfig(filename) { var f = path.basename(filename); // node.d.plugin configuration var m = f.match('.plugin' + '$'); if(m !== null) return netdata.options.paths.config + '/' + f.substring(0, m.index) + '.conf'; // node.d modules configuration m = f.match('.node.js' + '$'); if(m !== null) return netdata.options.paths.config + '/node.d/' + f.substring(0, m.index) + '.conf'; return netdata.options.paths.config + '/node.d/' + f + '.conf'; } // internal defaults extend(true, netdata.options, { filename: path.basename(__filename), update_every: NETDATA_UPDATE_EVERY, paths: { plugins: NETDATA_PLUGINS_DIR, config: NETDATA_CONFIG_DIR, modules: [], }, modules_enable_autodetect: true, modules_enable_all: true, modules: {}, }); netdata.options.config_filename = pluginConfig(__filename); // load configuration file try { netdata.options_loaded = JSON.parse(fs.readFileSync(netdata.options.config_filename, 'utf8')); 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_CONFIG_DIR; // console.error('merged netdata object:'); // console.error(util.inspect(netdata, {depth: 10})); } catch(e) { netdata.error('Cannot read configuration file ' + netdata.options.config_filename + ': ' + e.message + ', using internal defaults.'); netdata.options_loaded = undefined; dumpError(e); } // 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; if(typeof(netdata.options.modules[n].config_filename) !== 'string') netdata.options.modules[n].config_filename = pluginConfig(files[len]); // 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 }; try { netdata.debug('loading module\'s ' + netdata.options.modules[n].name + ' config ' + netdata.options.modules[n].config_filename); var c2 = JSON.parse(fs.readFileSync(netdata.options.modules[n].config_filename, 'utf8')); extend(true, c, c2); netdata.debug('loaded module\'s ' + netdata.options.modules[n].name + ' config ' + netdata.options.modules[n].config_filename); } catch(e) { netdata.error('Cannot load module\'s ' + netdata.options.modules[n].name + ' config from ' + netdata.options.modules[n].config_filename + ' exception: ' + e + ', using internal defaults.'); dumpError(e); } // 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);