1
0

fluxpoller.pl 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456
  1. #!/usr/bin/perl
  2. ################################################################################
  3. # $Id: fluxpoller.pl 2651 2007-03-19 17:26:32Z b4rt $
  4. # $Revision: 2651 $
  5. # $Date: 2007-03-19 12:26:32 -0500 (Mon, 19 Mar 2007) $
  6. ################################################################################
  7. # #
  8. # LICENSE #
  9. # #
  10. # This program is free software; you can redistribute it and/or #
  11. # modify it under the terms of the GNU General Public License (GPL) #
  12. # as published by the Free Software Foundation; either version 2 #
  13. # of the License, or (at your option) any later version. #
  14. # #
  15. # This program is distributed in the hope that it will be useful, #
  16. # but WITHOUT ANY WARRANTY; without even the implied warranty of #
  17. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
  18. # GNU General Public License for more details. #
  19. # #
  20. # To read the license please visit http://www.gnu.org/copyleft/gpl.html #
  21. # #
  22. # #
  23. ################################################################################
  24. use strict;
  25. ################################################################################
  26. # load-average multiplier
  27. # CHANGEME
  28. my $AVGmultiplier = "100";
  29. # stat-file-dir (".transfers" in tf-b4rt and ".torrents" in TF 2.1 / 2.1-b4rt)
  30. my $STATFILEDIR=".transfers";
  31. # webserver-user
  32. # (only used on bsd)
  33. my $WEBUSER = "www";
  34. # define socket-bins. default : qw( python transmissionc wget )
  35. # (only used on bsd)
  36. my @BINS_SOCKET = qw( python transmissionc wget java );
  37. # should we try to find needed binaries ? (using "whereis" + "awk")
  38. # use 1 to activate, else "constants" are used (the faster + safer way)
  39. my $autoFindBinaries = 0;
  40. # Internal Vars
  41. my ($REVISION, $DIR, $PROG, $EXTENSION, $USAGE, $OSTYPE);
  42. # bin Vars
  43. my ($BIN_CAT, $BIN_HEAD, $BIN_TAIL, $BIN_NETSTAT, $BIN_SOCKSTAT, $BIN_GREP, $BIN_AWK);
  44. # check env
  45. checkEnv();
  46. # define common binaries
  47. $BIN_CAT = "/bin/cat";
  48. $BIN_HEAD = "/usr/bin/head";
  49. $BIN_TAIL = "/usr/bin/tail";
  50. $BIN_AWK = "/usr/bin/awk";
  51. if ($OSTYPE == 1) { # linux
  52. $BIN_GREP = "/bin/grep";
  53. $BIN_NETSTAT = "/bin/netstat";
  54. } elsif ($OSTYPE == 2) { # bsd
  55. $BIN_GREP = "/usr/bin/grep";
  56. $BIN_SOCKSTAT = "/usr/bin/sockstat";
  57. }
  58. #-------------------------------------------------------------------------------
  59. # Main
  60. #-------------------------------------------------------------------------------
  61. # find binaries
  62. if ($autoFindBinaries != 0) { findBinaries() };
  63. # init some vars
  64. $REVISION =
  65. do { my @r = (q$Revision: 2651 $ =~ /\d+/g); sprintf "%d"."%02d" x $#r, @r };
  66. ($DIR=$0) =~ s/([^\/\\]*)$//;
  67. ($PROG=$1) =~ s/\.([^\.]*)$//;
  68. $EXTENSION=$1;
  69. # main-"switch"
  70. SWITCH: {
  71. $_ = shift @ARGV;
  72. /^traffic/ && do { # --- traffic ---
  73. printTraffic(shift @ARGV, shift @ARGV);
  74. exit;
  75. };
  76. /^connections/ && do { # --- connections ---
  77. printConnections(shift @ARGV);
  78. exit;
  79. };
  80. /^loadavg/ && do { # --- LOAD AVG ---
  81. printLoadAVG(shift @ARGV);
  82. exit;
  83. };
  84. /.*(version|-v).*/ && do { # --- version ---
  85. printVersion();
  86. exit;
  87. };
  88. /.*(help|-h).*/ && do { # --- help ---
  89. printUsage();
  90. exit;
  91. };
  92. printUsage();
  93. exit;
  94. }
  95. #===============================================================================
  96. # Subs
  97. #===============================================================================
  98. #------------------------------------------------------------------------------#
  99. # Sub: printTraffic #
  100. # Parameters: string with path of flux-dir #
  101. # string with wanted output-format (mrtg|cacti) #
  102. # Return: null #
  103. #------------------------------------------------------------------------------#
  104. sub printTraffic {
  105. my $fluxDir = shift;
  106. if (!(defined $fluxDir)) {
  107. printUsage();
  108. exit;
  109. }
  110. $fluxDir .= "/".$STATFILEDIR;
  111. my $outputFormat = shift;
  112. if ($outputFormat eq "mrtg") {
  113. mrtgPrintTraffic($fluxDir);
  114. } elsif ($outputFormat eq "cacti") {
  115. cactiPrintTraffic($fluxDir);
  116. } else {
  117. # get traffic-vals
  118. my @traffic = fluxTraffic($fluxDir);
  119. # print traffic-vals
  120. print $traffic[0]." ".$traffic[1]."\n";
  121. }
  122. }
  123. #------------------------------------------------------------------------------#
  124. # Sub: mrtgPrintTraffic #
  125. # Parameters: string with path of flux-".stat-files"-dir #
  126. # Return: null #
  127. #------------------------------------------------------------------------------#
  128. sub mrtgPrintTraffic {
  129. my $fluxDir = shift;
  130. # get traffic-vals
  131. my @traffic = fluxTraffic($fluxDir);
  132. # print down-speed for mrtg
  133. print $traffic[0];
  134. print "\n";
  135. # print up-speed for mrtg
  136. print $traffic[1];
  137. print "\n";
  138. # print uptime for mrtg
  139. mrtgPrintUptime();
  140. # print target-name for mrtg
  141. mrtgPrintTargetname();
  142. }
  143. #------------------------------------------------------------------------------#
  144. # Sub: cactiPrintTraffic #
  145. # Parameters: string with path of flux-".stat-files"-dir #
  146. # Return: null #
  147. #------------------------------------------------------------------------------#
  148. sub cactiPrintTraffic {
  149. my $fluxDir = shift;
  150. # get traffic-vals
  151. my @traffic = fluxTraffic($fluxDir);
  152. # print traffic for cacti
  153. my $trafficLine = "";
  154. $trafficLine .= "bandwidth_in:";
  155. $trafficLine .= $traffic[0];
  156. $trafficLine .= " ";
  157. $trafficLine .= "bandwidth_out:";
  158. $trafficLine .= $traffic[1];
  159. print $trafficLine;
  160. }
  161. #------------------------------------------------------------------------------#
  162. # Sub: printConnections #
  163. # Parameters: string with wanted output-format (mrtg|cacti) #
  164. # Return: null #
  165. #------------------------------------------------------------------------------#
  166. sub printConnections {
  167. my $outputFormat = shift;
  168. if ($outputFormat eq "mrtg") {
  169. mrtgPrintConnections();
  170. } elsif ($outputFormat eq "cacti") {
  171. cactiPrintConnections();
  172. } else {
  173. print fluxConnections();
  174. print "\n";
  175. }
  176. }
  177. #------------------------------------------------------------------------------#
  178. # Sub: mrtgPrintConnections #
  179. # Parameters: null #
  180. # Return: null #
  181. #------------------------------------------------------------------------------#
  182. sub mrtgPrintConnections {
  183. # print down-"speed" for mrtg
  184. print fluxConnections();
  185. print "\n";
  186. # print up-"speed" for mrtg
  187. print "0";
  188. print "\n";
  189. # print uptime for mrtg
  190. mrtgPrintUptime();
  191. # print target-name for mrtg
  192. mrtgPrintTargetname();
  193. }
  194. #------------------------------------------------------------------------------#
  195. # Sub: cactiPrintConnections #
  196. # Parameters: null #
  197. # Return: null #
  198. #------------------------------------------------------------------------------#
  199. sub cactiPrintConnections {
  200. # print connections for cacti
  201. print fluxConnections();
  202. }
  203. #------------------------------------------------------------------------------#
  204. # Sub: printLoadAVG #
  205. # Parameters: string with wanted output-format (mrtg|cacti) #
  206. # Return: null #
  207. #------------------------------------------------------------------------------#
  208. sub printLoadAVG {
  209. my $outputFormat = shift;
  210. if ($outputFormat eq "mrtg") {
  211. mrtgPrintLoadAVG();
  212. } elsif ($outputFormat eq "cacti") {
  213. cactiPrintLoadAVG();
  214. } else {
  215. print LoadAVG();
  216. #print "\n";
  217. }
  218. }
  219. #------------------------------------------------------------------------------#
  220. # Sub: mrtgPrintLoadAVG #
  221. # Parameters: null #
  222. # Return: null #
  223. #------------------------------------------------------------------------------#
  224. sub mrtgPrintLoadAVG {
  225. # print Load AVG. for mrtg
  226. LoadAVG();
  227. # print uptime for mrtg
  228. mrtgPrintUptime();
  229. # print target-name for mrtg
  230. mrtgPrintTargetname();
  231. }
  232. #------------------------------------------------------------------------------#
  233. # Sub: cactiPrintLoadAVG #
  234. # Parameters: null #
  235. # Return: null #
  236. #------------------------------------------------------------------------------#
  237. sub cactiPrintLoadAVG {
  238. # print Load AVG. for cacti
  239. LoadAVG();
  240. }
  241. #------------------------------------------------------------------------------#
  242. # Sub: LoadAVG #
  243. # Parameters: null #
  244. # Return: null #
  245. #------------------------------------------------------------------------------#
  246. sub LoadAVG {
  247. # vars
  248. my ($AVG1min, $AVG5min, $AVG15min);
  249. #generate LOAD AVG.
  250. if ($OSTYPE == 1) { # linux
  251. my $loadAVG = `cat /proc/loadavg`;
  252. ($AVG1min, $AVG5min, $AVG15min) = split /\s/, $loadAVG, 3;
  253. } elsif ($OSTYPE == 2) { # bsd
  254. my $loadAVG = `uptime`;
  255. ($AVG1min, $AVG5min, $AVG15min) = $loadAVG=~/.*load averages: (\S+), (\S+), (\S+)/;
  256. }
  257. #1m AVG.
  258. print ($AVG1min * $AVGmultiplier);
  259. print "\n";
  260. #5m AVG.
  261. print ($AVG5min * $AVGmultiplier);
  262. print "\n";
  263. }
  264. #------------------------------------------------------------------------------#
  265. # Sub: mrtgPrintUptime #
  266. # Parameters: null #
  267. # Return: null #
  268. #------------------------------------------------------------------------------#
  269. sub mrtgPrintUptime {
  270. # uptime data for mrtg
  271. my $uptime = `uptime`;
  272. $uptime =~ /up (.*?), (.*?), /;
  273. print "$1, $2\n";
  274. }
  275. #------------------------------------------------------------------------------#
  276. # Sub: mrtgPrintTargetname #
  277. # Parameters: null #
  278. # Return: null #
  279. #------------------------------------------------------------------------------#
  280. sub mrtgPrintTargetname {
  281. # target-name for mrtg
  282. my $targetname = `hostname`;
  283. print $targetname;
  284. }
  285. #------------------------------------------------------------------------------#
  286. # Sub: fluxTraffic #
  287. # Parameters: string with path of flux-".stat-files"-dir #
  288. # Return: array with current down-traffic ([0]) and up-traffic ([1]) #
  289. #------------------------------------------------------------------------------#
  290. sub fluxTraffic {
  291. my $fluxDir = shift;
  292. # init speed-sum-vars
  293. my $downspeed = 0.0;
  294. my $upspeed = 0.0;
  295. # process stat-files
  296. opendir(DIR, $fluxDir);
  297. my @files = map { $_->[1] } # extract pathnames
  298. map { [ $_, "$fluxDir/$_" ] } # full paths
  299. grep { !/^\./ } # no dot-files
  300. grep { /.*\.stat$/ } # only .stat-files
  301. readdir(DIR);
  302. closedir(DIR);
  303. foreach my $statFile (@files) {
  304. if (-f $statFile) {
  305. my ($down, $up) = split(/\n/, `$BIN_CAT $statFile | $BIN_HEAD -n 5 | $BIN_TAIL -n 2`, 2);
  306. if ($down != "") {
  307. $down =~ s/(.*\d)(\s.*)/$1/;
  308. chomp $down;
  309. $downspeed += $down;
  310. }
  311. if ($up != "") {
  312. $up =~ s/(.*\d)(\s.*)/$1/;
  313. chomp $up;
  314. $upspeed += $up;
  315. }
  316. }
  317. }
  318. my @retVal;
  319. $retVal[0] = ($downspeed<<10);
  320. $retVal[1] = ($upspeed<<10);
  321. return @retVal;
  322. }
  323. #------------------------------------------------------------------------------#
  324. # Sub: fluxConnections #
  325. # Parameters: null #
  326. # Return: int with current flux-tcp-connections (python + transmission) #
  327. #------------------------------------------------------------------------------#
  328. sub fluxConnections {
  329. my $cons = 0;
  330. my $cons_temp = 0;
  331. if ($OSTYPE == 1) { # linux
  332. $cons_temp = `$BIN_NETSTAT -e -p --tcp -n 2> /dev/null | $BIN_GREP -v root | $BIN_GREP -v 127.0.0.1 | $BIN_GREP -cE '.*(python|transmissionc|wget).*'`;
  333. chomp $cons_temp;
  334. $cons = int $cons_temp;
  335. } elsif ($OSTYPE == 2) { # bsd
  336. foreach my $bin_socket (@BINS_SOCKET) {
  337. $cons_temp = `$BIN_SOCKSTAT | $BIN_GREP -cE $WEBUSER.+$bin_socket.+tcp`;
  338. chomp $cons_temp;
  339. $cons += $cons_temp;
  340. }
  341. }
  342. return $cons;
  343. }
  344. #------------------------------------------------------------------------------#
  345. # Sub: findBinaries #
  346. # Parameters: null #
  347. # Return: null #
  348. #------------------------------------------------------------------------------#
  349. sub findBinaries {
  350. $BIN_CAT = `whereis cat | awk '{print \$2}'`; chomp $BIN_CAT;
  351. $BIN_HEAD = `whereis head | awk '{print \$2}'`; chomp $BIN_HEAD;
  352. $BIN_TAIL = `whereis tail | awk '{print \$2}'`; chomp $BIN_TAIL;
  353. $BIN_NETSTAT = `whereis netstat | awk '{print \$2}'`; chomp $BIN_NETSTAT;
  354. $BIN_SOCKSTAT = `whereis sockstat | awk '{print \$2}'`; chomp $BIN_SOCKSTAT;
  355. $BIN_GREP = `whereis grep | awk '{print \$2}'`; chomp $BIN_GREP;
  356. $BIN_AWK = `whereis awk | awk '{print \$2}'`; chomp $BIN_AWK;
  357. }
  358. #------------------------------------------------------------------------------#
  359. # Sub: checkEnv #
  360. # Parameters: null #
  361. # Return: null #
  362. #------------------------------------------------------------------------------#
  363. sub checkEnv {
  364. ## win32 not supported ;)
  365. if ("$^O" =~ /win32/i) {
  366. print "\r\nWin32 not supported.\r\n";
  367. exit;
  368. } elsif ("$^O" =~ /linux/i) {
  369. $OSTYPE = 1;
  370. return;
  371. } elsif ("$^O" =~ /bsd$/i) {
  372. $OSTYPE = 2;
  373. return;
  374. }
  375. }
  376. #------------------------------------------------------------------------------#
  377. # Sub: printVersion #
  378. # Arguments: Null #
  379. # Returns: Version Information #
  380. #------------------------------------------------------------------------------#
  381. sub printVersion {
  382. print $PROG.".".$EXTENSION." Version ".$REVISION."\n";
  383. }
  384. #------------------------------------------------------------------------------#
  385. # Sub: printUsage #
  386. # Parameters: null #
  387. # Return: null #
  388. #------------------------------------------------------------------------------#
  389. sub printUsage {
  390. print <<"USAGE";
  391. $PROG.$EXTENSION (Revision $REVISION)
  392. Usage: $PROG.$EXTENSION type [extra-args]
  393. types:
  394. <traffic> : print current flux-traffic.
  395. extra-args : 1. flux-dir (aka "Path" inside flux-admin)
  396. 2. (optional) output-format (mrtg|cacti)
  397. <connections> : print current flux-tcp-connections.
  398. extra-args : 1. (optional) output-format (mrtg|cacti)
  399. <loadavg> : print current load-average.
  400. extra-args : 1. (optional) output-format (mrtg|cacti)
  401. Examples:
  402. $PROG.$EXTENSION traffic /usr/local/torrentflux
  403. $PROG.$EXTENSION traffic /usr/local/torrentflux mrtg
  404. $PROG.$EXTENSION traffic /usr/local/torrentflux cacti
  405. $PROG.$EXTENSION connections
  406. $PROG.$EXTENSION connections mrtg
  407. $PROG.$EXTENSION connections cacti
  408. $PROG.$EXTENSION loadavg
  409. $PROG.$EXTENSION loadavg mrtg
  410. $PROG.$EXTENSION loadavg cacti
  411. USAGE
  412. }
  413. # EOF