node.d.plugin.in 11 KB

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