node.d.plugin 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294
  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. // shebang hack from:
  4. // http://unix.stackexchange.com/questions/65235/universal-node-js-shebang
  5. // Initially this is run as a shell script.
  6. // Then, the second line, finds nodejs or node or js in the system path
  7. // and executes it with the shell parameters.
  8. // netdata
  9. // real-time performance and health monitoring, done right!
  10. // (C) 2017 Costa Tsaousis <costa@tsaousis.gr>
  11. // SPDX-License-Identifier: GPL-3.0+
  12. // --------------------------------------------------------------------------------------------------------------------
  13. 'use strict';
  14. // --------------------------------------------------------------------------------------------------------------------
  15. // get NETDATA environment variables
  16. var NETDATA_PLUGINS_DIR = process.env.NETDATA_PLUGINS_DIR || __dirname;
  17. var NETDATA_CONFIG_DIR = process.env.NETDATA_CONFIG_DIR || __dirname + '/../../../../etc/netdata';
  18. var NETDATA_UPDATE_EVERY = process.env.NETDATA_UPDATE_EVERY || 1;
  19. var NODE_D_DIR = NETDATA_PLUGINS_DIR + '/../node.d';
  20. // make sure the modules are found
  21. process.mainModule.paths.unshift(NODE_D_DIR + '/node_modules');
  22. process.mainModule.paths.unshift(NODE_D_DIR);
  23. // --------------------------------------------------------------------------------------------------------------------
  24. // load required modules
  25. var fs = require('fs');
  26. var url = require('url');
  27. var util = require('util');
  28. var http = require('http');
  29. var path = require('path');
  30. var extend = require('extend');
  31. var netdata = require('netdata');
  32. // --------------------------------------------------------------------------------------------------------------------
  33. // configuration
  34. function pluginConfig(filename) {
  35. var f = path.basename(filename);
  36. // node.d.plugin configuration
  37. var m = f.match('.plugin' + '$');
  38. if(m !== null)
  39. return netdata.options.paths.config + '/' + f.substring(0, m.index) + '.conf';
  40. // node.d modules configuration
  41. m = f.match('.node.js' + '$');
  42. if(m !== null)
  43. return netdata.options.paths.config + '/node.d/' + f.substring(0, m.index) + '.conf';
  44. return netdata.options.paths.config + '/node.d/' + f + '.conf';
  45. }
  46. // internal defaults
  47. extend(true, netdata.options, {
  48. filename: path.basename(__filename),
  49. update_every: NETDATA_UPDATE_EVERY,
  50. paths: {
  51. plugins: NETDATA_PLUGINS_DIR,
  52. config: NETDATA_CONFIG_DIR,
  53. modules: [],
  54. },
  55. modules_enable_autodetect: true,
  56. modules_enable_all: true,
  57. modules: {},
  58. });
  59. netdata.options.config_filename = pluginConfig(__filename);
  60. // load configuration file
  61. try {
  62. netdata.options_loaded = JSON.parse(fs.readFileSync(netdata.options.config_filename, 'utf8'));
  63. extend(true, netdata.options, netdata.options_loaded);
  64. if(!netdata.options.paths.plugins)
  65. netdata.options.paths.plugins = NETDATA_PLUGINS_DIR;
  66. if(!netdata.options.paths.config)
  67. netdata.options.paths.config = NETDATA_CONFIG_DIR;
  68. // console.error('merged netdata object:');
  69. // console.error(util.inspect(netdata, {depth: 10}));
  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. // apply module paths to node.js process
  77. function applyModulePaths() {
  78. var len = netdata.options.paths.modules.length;
  79. while(len--)
  80. process.mainModule.paths.unshift(netdata.options.paths.modules[len]);
  81. }
  82. applyModulePaths();
  83. // --------------------------------------------------------------------------------------------------------------------
  84. // tracing
  85. function dumpError(err) {
  86. if (typeof err === 'object') {
  87. if (err.stack) {
  88. netdata.debug(err.stack);
  89. }
  90. }
  91. }
  92. // --------------------------------------------------------------------------------------------------------------------
  93. // get command line arguments
  94. {
  95. var found_myself = false;
  96. var found_number = false;
  97. var found_modules = false;
  98. process.argv.forEach(function (val, index, array) {
  99. netdata.debug('PARAM: ' + val);
  100. if(!found_myself) {
  101. if(val === __filename)
  102. found_myself = true;
  103. }
  104. else {
  105. switch(val) {
  106. case 'debug':
  107. netdata.options.DEBUG = true;
  108. netdata.debug('DEBUG enabled');
  109. break;
  110. default:
  111. if(found_number === true) {
  112. if(found_modules === false) {
  113. for(var i in netdata.options.modules)
  114. netdata.options.modules[i].enabled = false;
  115. }
  116. if(typeof netdata.options.modules[val] === 'undefined')
  117. netdata.options.modules[val] = {};
  118. netdata.options.modules[val].enabled = true;
  119. netdata.options.modules_enable_all = false;
  120. netdata.debug('enabled module ' + val);
  121. }
  122. else {
  123. try {
  124. var x = parseInt(val);
  125. if(x > 0) {
  126. netdata.options.update_every = x;
  127. if(netdata.options.update_every < NETDATA_UPDATE_EVERY) {
  128. netdata.options.update_every = NETDATA_UPDATE_EVERY;
  129. netdata.debug('Update frequency ' + x + 's is too low');
  130. }
  131. found_number = true;
  132. netdata.debug('Update frequency set to ' + netdata.options.update_every + ' seconds');
  133. }
  134. else netdata.error('Ignoring parameter: ' + val);
  135. }
  136. catch(e) {
  137. netdata.error('Cannot get value of parameter: ' + val);
  138. dumpError(e);
  139. }
  140. }
  141. break;
  142. }
  143. }
  144. });
  145. }
  146. if(netdata.options.update_every < 1) {
  147. netdata.debug('Adjusting update frequency to 1 second');
  148. netdata.options.update_every = 1;
  149. }
  150. // --------------------------------------------------------------------------------------------------------------------
  151. // find modules
  152. function findModules() {
  153. var found = 0;
  154. var files = fs.readdirSync(NODE_D_DIR);
  155. var len = files.length;
  156. while(len--) {
  157. var m = files[len].match('.node.js' + '$');
  158. if(m !== null) {
  159. var n = files[len].substring(0, m.index);
  160. if(typeof(netdata.options.modules[n]) === 'undefined')
  161. netdata.options.modules[n] = { name: n, enabled: netdata.options.modules_enable_all };
  162. if(netdata.options.modules[n].enabled === true) {
  163. netdata.options.modules[n].name = n;
  164. netdata.options.modules[n].filename = NODE_D_DIR + '/' + files[len];
  165. netdata.options.modules[n].loaded = false;
  166. if(typeof(netdata.options.modules[n].config_filename) !== 'string')
  167. netdata.options.modules[n].config_filename = pluginConfig(files[len]);
  168. // load the module
  169. try {
  170. netdata.debug('loading module ' + netdata.options.modules[n].filename);
  171. netdata.options.modules[n].module = require(netdata.options.modules[n].filename);
  172. netdata.options.modules[n].module.name = n;
  173. netdata.debug('loaded module ' + netdata.options.modules[n].name + ' from ' + netdata.options.modules[n].filename);
  174. }
  175. catch(e) {
  176. netdata.options.modules[n].enabled = false;
  177. netdata.error('Cannot load module: ' + netdata.options.modules[n].filename + ' exception: ' + e);
  178. dumpError(e);
  179. continue;
  180. }
  181. // load its configuration
  182. var c = {
  183. enable_autodetect: netdata.options.modules_enable_autodetect,
  184. update_every: netdata.options.update_every
  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. // call module auto-detection / configuration
  197. try {
  198. netdata.modules_configuring++;
  199. netdata.debug('Configuring module ' + netdata.options.modules[n].name);
  200. var serv = netdata.configure(netdata.options.modules[n].module, c, function() {
  201. netdata.debug('Configured module ' + netdata.options.modules[n].name);
  202. netdata.modules_configuring--;
  203. });
  204. netdata.debug('Configuring module ' + netdata.options.modules[n].name + ' reports ' + serv + ' eligible services.');
  205. }
  206. catch(e) {
  207. netdata.modules_configuring--;
  208. netdata.options.modules[n].enabled = false;
  209. netdata.error('Failed module auto-detection: ' + netdata.options.modules[n].name + ' exception: ' + e + ', disabling module.');
  210. dumpError(e);
  211. continue;
  212. }
  213. netdata.options.modules[n].loaded = true;
  214. found++;
  215. }
  216. }
  217. }
  218. // netdata.debug(netdata.options.modules);
  219. return found;
  220. }
  221. if(findModules() === 0) {
  222. netdata.error('Cannot load any .node.js module from: ' + NODE_D_DIR);
  223. netdata.disableNodePlugin();
  224. process.exit(1);
  225. }
  226. // --------------------------------------------------------------------------------------------------------------------
  227. // start
  228. function start_when_configuring_ends() {
  229. if(netdata.modules_configuring > 0) {
  230. netdata.debug('Waiting modules configuration, still running ' + netdata.modules_configuring);
  231. setTimeout(start_when_configuring_ends, 500);
  232. return;
  233. }
  234. netdata.modules_configuring = 0;
  235. netdata.start();
  236. }
  237. start_when_configuring_ends();
  238. //netdata.debug('netdata object:')
  239. //netdata.debug(netdata);