PageRenderTime 25ms CodeModel.GetById 37ms RepoModel.GetById 1ms app.codeStats 0ms

/statgraph.pl

https://github.com/bcc/statgraph
Perl | 201 lines | 139 code | 28 blank | 34 comment | 23 complexity | 8ca94be3c3a789db6211a0e9a6a6af35 MD5 | raw file
  1. #!/usr/bin/perl
  2. # statgraph: A simple host resource graphing tool
  3. # Copyright (C) 2004-2011 Ben Charlton <ben@spod.cx>
  4. #
  5. # This program is free software; you can redistribute it and/or modify
  6. # it under the terms of the GNU General Public License as published by
  7. # the Free Software Foundation; either version 2 of the License, or
  8. # (at your option) any later version.
  9. #
  10. # This program is distributed in the hope that it will be useful,
  11. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. # GNU General Public License for more details.
  14. #
  15. # You should have received a copy of the GNU General Public License along
  16. # with this program; see the file COPYING. If not, write to the Free
  17. # Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
  18. # MA 02110-1301 USA, or see http://www.gnu.org
  19. use strict;
  20. use StatGraph;
  21. ## TODO: configure with getopt
  22. my $config = "statgraph.conf";
  23. ## Get configuration
  24. open CONFIG, $config || die "Cannot open $config: $!";
  25. my @CONFIG = (<CONFIG>);
  26. close CONFIG;
  27. my %CONFIG = confparse(\@CONFIG);
  28. my %HOSTS = %{$CONFIG{hosts}};
  29. %CONFIG = %{$CONFIG{config}};
  30. ## Set default configuration options if they've not been specified
  31. my $defaultport = $CONFIG{defaultport} || 27001;
  32. my $rrdlocation = $CONFIG{rrdlocation} || "rrd/";
  33. my $pid = $$;
  34. my $parent = 0;
  35. my @kids = ();
  36. my $host;
  37. ## Main loop - run once for each host
  38. FORK: foreach my $currhost (keys %HOSTS) {
  39. my $newpid = fork();
  40. if ( not defined $newpid ) {
  41. # if return value of fork() is undef, something went wrong
  42. die "fork didn't work: $!\n";
  43. }
  44. elsif ( $newpid == 0 ) {
  45. # if return value is 0, this is the child process
  46. $parent = $pid; # which has a parent called $pid
  47. $pid = $$; # and which will have a process ID of its very own
  48. @kids = (); # the child doesn't want this baggage from the parent
  49. $host = $currhost;
  50. last FORK; # and we don't want the child making babies either
  51. }
  52. else {
  53. # the parent process is returned the PID of the newborn by fork()
  54. push @kids, $newpid;
  55. }
  56. }
  57. if ( $parent ) {
  58. # if I have a parent, i.e. if I'm the child process
  59. my %results;
  60. my %ignore;
  61. foreach (split(/\s+/, $HOSTS{$host}{ignore})) {
  62. $ignore{$_} = 1;
  63. }
  64. ## exec method
  65. if ($HOSTS{$host}{method} eq 'exec') {
  66. unless (defined $HOSTS{$host}{execcommand}) {
  67. die "execcommand not specified for $host, skipping...";
  68. }
  69. %results = get_exec_results($HOSTS{$host}{execcommand}, "$rrdlocation$host.txt");
  70. ## Network socket connection method
  71. } elsif ($HOSTS{$host}{method} eq 'connect') {
  72. unless (defined $HOSTS{$host}{hostname}) {
  73. die "hostname not specified for $host, skipping...";
  74. }
  75. my $port = $HOSTS{$host}{port} || $defaultport;
  76. %results = get_net_results($HOSTS{$host}{hostname}, $port, "$rrdlocation$host.txt");
  77. ## Unknown method
  78. } else {
  79. die "Unknown method specified for $host, skipping...";
  80. }
  81. ## Simple check that we've got reasonable statgrab data
  82. unless ($results{const}{0} eq '0') {
  83. die "Bad statgrab results";
  84. } else {
  85. print "got result for $host\n";
  86. }
  87. ## Update RRDs
  88. foreach ('cpu', 'load', 'mem', 'page', 'proc', 'user', 'swap') {
  89. unless (-e "$rrdlocation$host.$_.rrd") {
  90. create_rrd($rrdlocation, $_, $host, '');
  91. }
  92. }
  93. update_rrd("$rrdlocation$host.cpu.rrd", sprintf("N:%s:%s:%s:%s:%s:%s:%s",
  94. $results{cpu}{idle},
  95. $results{cpu}{iowait},
  96. $results{cpu}{kernel},
  97. $results{cpu}{nice},
  98. $results{cpu}{swap},
  99. $results{cpu}{total},
  100. $results{cpu}{user}));
  101. update_rrd("$rrdlocation$host.load.rrd", sprintf("N:%s:%s:%s",
  102. $results{load}{min1},
  103. $results{load}{min5},
  104. $results{load}{min15}));
  105. update_rrd("$rrdlocation$host.mem.rrd", sprintf("N:%s:%s:%s:%s",
  106. $results{mem}{cache},
  107. $results{mem}{free},
  108. $results{mem}{total},
  109. $results{mem}{used}));
  110. update_rrd("$rrdlocation$host.page.rrd", sprintf("N:%s:%s",
  111. $results{page}{in},
  112. $results{page}{out}));
  113. update_rrd("$rrdlocation$host.proc.rrd", sprintf("N:%s:%s:%s:%s:%s",
  114. $results{proc}{running},
  115. $results{proc}{sleeping},
  116. $results{proc}{stopped},
  117. $results{proc}{total},
  118. $results{proc}{zombie}));
  119. update_rrd("$rrdlocation$host.user.rrd", sprintf("N:%s",
  120. $results{user}{num}));
  121. update_rrd("$rrdlocation$host.swap.rrd", sprintf("N:%s:%s:%s",
  122. $results{swap}{free},
  123. $results{swap}{total},
  124. $results{swap}{used}));
  125. ## net device RRDs
  126. foreach my $dev (keys %{ $results{net} }) {
  127. unless (defined $ignore{"net.$dev"}) {
  128. unless (-e "$rrdlocation$host.net.$dev.rrd") {
  129. create_rrd($rrdlocation, 'net', $host, $dev);
  130. }
  131. update_rrd("$rrdlocation$host.net.$dev.rrd", sprintf("N:%s:%s:%s:%s:%s:%s",
  132. $results{net}{$dev}{rx} || 0,
  133. $results{net}{$dev}{tx} || 0,
  134. $results{net}{$dev}{ipackets} || 0,
  135. $results{net}{$dev}{opackets} || 0,
  136. $results{net}{$dev}{ierrors} || 0,
  137. $results{net}{$dev}{oerrors} || 0));
  138. }
  139. }
  140. ## disk device RRDs
  141. foreach my $dev (keys %{ $results{disk} }) {
  142. unless (defined $ignore{"disk.$dev"}) {
  143. unless (-e "$rrdlocation$host.disk.$dev.rrd") {
  144. create_rrd($rrdlocation, 'disk', $host, $dev);
  145. }
  146. update_rrd("$rrdlocation$host.disk.$dev.rrd", sprintf("N:%s:%s",
  147. $results{disk}{$dev}{read_bytes},
  148. $results{disk}{$dev}{write_bytes}));
  149. }
  150. }
  151. ## fs device RRDs
  152. foreach my $dev (keys %{ $results{fs} }) {
  153. unless (defined $ignore{"fs.$dev"}) {
  154. unless (-e "$rrdlocation$host.fs.$dev.rrd") {
  155. create_rrd($rrdlocation, 'fs', $host, $dev);
  156. }
  157. update_rrd("$rrdlocation$host.fs.$dev.rrd", sprintf("N:%s:%s:%s:%s",
  158. $results{fs}{$dev}{used},
  159. $results{fs}{$dev}{size},
  160. $results{fs}{$dev}{used_inodes},
  161. $results{fs}{$dev}{total_inodes}));
  162. }
  163. }
  164. }
  165. else {
  166. # parent process needs to preside over the death of its kids
  167. while ( my $kid = shift @kids ) {
  168. my $reaped = waitpid( $kid, 0 );
  169. unless ( $reaped == $kid ) {
  170. warn "Something's up: $?\n";
  171. }
  172. }
  173. }