[1030] | 1 | #!/usr/bin/perl -w #-d
|
---|
| 2 | #
|
---|
| 3 | # sar/iostat graphing tool based on rrdtool
|
---|
| 4 | # (c) 2004 B. Cornec HP <bruno.cornec@hp.com>
|
---|
| 5 | # Licensed under the GPL or Artistic License
|
---|
| 6 | #
|
---|
| 7 | # Original Charter: Monitor CPU/Load/Net_eth0|2 (io/s)/Disk (io/s)
|
---|
| 8 | # 1 mesure par 20 seconde
|
---|
| 9 | # So the script has been developped first with that context in mind
|
---|
| 10 | # trying to be generic enough to be expandable later on
|
---|
| 11 | # More work needs to be done, some code factorized, ...
|
---|
| 12 | #
|
---|
| 13 | #
|
---|
| 14 | use strict; # Always :-)
|
---|
| 15 | use RRDs; # for data management and graphing
|
---|
| 16 | use Data::Dumper; # for debug
|
---|
| 17 | use HTML::AsSubs; # for HTML generation
|
---|
| 18 | use Storable; # for data exchange
|
---|
| 19 | use Date::Manip; # for timestamp
|
---|
| 20 | use Config::Auto; # for config file
|
---|
| 21 | use sario2rrd qw(from_epoch);
|
---|
| 22 | # local common functions
|
---|
| 23 |
|
---|
| 24 | # Avoid localisation problems in sar
|
---|
| 25 | $ENV{LANG}="C";
|
---|
| 26 |
|
---|
| 27 | #
|
---|
| 28 | # Begin of configuration options
|
---|
| 29 | #
|
---|
| 30 | my $dir = "sar2rrd"; # Place under the html dir of user apache
|
---|
| 31 | # Under that directory you should have one
|
---|
| 32 | # directory per machine and in it all the
|
---|
| 33 | # files resulting form the sar and iostat
|
---|
| 34 | # commands (saxx and ioxx). Look at the
|
---|
| 35 | # cron file and related script
|
---|
| 36 |
|
---|
| 37 | my ($l,$p,$uid,$gid,$q,$c,$gc,$apache,$empty) = getpwnam("apache") or die "apache not in passwd file";
|
---|
| 38 | my $base = "$apache/html/$dir";
|
---|
| 39 | my $config = Config::Auto::parse("$base/$dir.conf");
|
---|
| 40 | my @machines = @{$config->{machines}};
|
---|
| 41 | my @shots = @{$config->{shots}};
|
---|
| 42 | my $lgshot = $config->{lgshot};
|
---|
| 43 |
|
---|
| 44 | my $debug = 0;
|
---|
| 45 | foreach my $a (@ARGV) {
|
---|
| 46 | $debug++ if ($a =~ /-v/);
|
---|
| 47 | $| = 1; # Flush STDOUT
|
---|
| 48 | }
|
---|
| 49 | my $m;
|
---|
| 50 | my %t;
|
---|
| 51 | my %attrio = %{ retrieve("$base/$config->{svgio}") };
|
---|
| 52 | my %attrsar = %{ retrieve("$base/$config->{svgsar}") };
|
---|
| 53 |
|
---|
| 54 | my $h = "$base/dgi.html";
|
---|
| 55 | open (MAIN, "> $h") || die "Unable to create $h : $!";
|
---|
| 56 | my @hm = (h1("sar2rrd - sar/iostats monitoring via rrdtool"),
|
---|
| 57 | p("List of systems to monitor:"));
|
---|
| 58 | my @index;
|
---|
| 59 | my @tmp1;
|
---|
| 60 | my @tmp2;
|
---|
| 61 |
|
---|
| 62 | print Dumper($config) if ($debug > 1);
|
---|
| 63 |
|
---|
| 64 | foreach $m (@machines) {
|
---|
| 65 | #
|
---|
| 66 | # The graphs/HTML generation
|
---|
| 67 | #
|
---|
| 68 | push @index,li(a({href=>"$m/dgi.html"}, "$m"));
|
---|
| 69 | my $hm = "$base/$m/dgi.html";
|
---|
| 70 | open (MACHINE, "> $hm") || die "Unable to create $hm : $!";
|
---|
| 71 | my @hhm = (h1("sar2rrd - Monitoring $m"));
|
---|
| 72 | my $img="$base/$m/img";
|
---|
| 73 | print "Graphing rrd base for $m under $img\n" if ($debug > 0);
|
---|
| 74 | my $cpt = 1;
|
---|
| 75 | foreach my $t (@shots) {
|
---|
| 76 | @tmp1 = ();
|
---|
| 77 | @tmp2 = ();
|
---|
| 78 | my $ht = "$base/$m/tir-$cpt.html";
|
---|
| 79 | open (TIR, "> $ht") || die "Unable to create $ht : $!";
|
---|
| 80 | my @hht = (h1("sar2rrd - Monitoring $m - Shot $cpt"));
|
---|
| 81 | my $sdt = UnixDate($t,"%s");
|
---|
| 82 | my $edt = $sdt + $lgshot;
|
---|
| 83 | my $sdtiso = from_epoch($sdt);
|
---|
| 84 | my $edtiso = from_epoch($edt);
|
---|
| 85 | printf "Shot #$cpt - Machine $m (Between $sdt/$sdtiso et $edt/$edtiso)\n" if ($debug > 0);
|
---|
| 86 | print "Generating " if ($debug > 0);
|
---|
| 87 | mkdir "$img",0755 if (not (-d "$img"));
|
---|
| 88 | unlink <$img/*-tir$cpt.png>;
|
---|
| 89 | print "mem-tir$cpt.png " if ($debug > 0);
|
---|
| 90 | RRDs::graph("$img/mem-tir$cpt.png","-s $sdt","-e $edt","-v KiloBytes","-aPNG","-t Memory Report - $m","DEF:s1=$base/$m/$config->{rrdsar}:memoryfree:AVERAGE","AREA:s1#00ee22:Free Memory");
|
---|
| 91 | my $rrderror = RRDs::error;
|
---|
| 92 | die "Problem while generating graph: $rrderror\n" if ($rrderror);
|
---|
| 93 | print "load-tir$cpt.png " if ($debug > 0);
|
---|
| 94 | RRDs::graph("$img/load-tir$cpt.png","-s $sdt","-e $edt","-S",$config->{step},"-aPNG","-t","Load Report - $m","DEF:s1=$base/$m/$config->{rrdsar}:load1:AVERAGE","DEF:s2=$base/$m/$config->{rrdsar}:load5:AVERAGE","DEF:s3=$base/$m/$config->{rrdsar}:runq:AVERAGE","LINE2:s1#00b6e4:Load 1m","LINE2:s2#00ee22:Load 5m","LINE2:s3#ff0000:Run Queue");
|
---|
| 95 | $rrderror = RRDs::error;
|
---|
| 96 | die "Problem while generating graph: $rrderror\n" if ($rrderror);
|
---|
| 97 | push @tmp1,td(img({src=>"$config->{http}/$dir/$m/img/mem-tir$cpt.png"}));
|
---|
| 98 | push @tmp1,td(img({src=>"$config->{http}/$dir/$m/img/load-tir$cpt.png"}));
|
---|
| 99 | push @tmp1,HTML::AsSubs::tr(@tmp1);
|
---|
| 100 |
|
---|
| 101 | my $col = 0;
|
---|
| 102 | foreach my $i (@{$attrsar{$m}{measures}},@{$attrio{$m}{measures}}) {
|
---|
| 103 | if ($i =~ /^eth/) {
|
---|
| 104 | $i =~ s/-[inout]+//;
|
---|
| 105 | next if (-f "$img/$i-tir$cpt.png");
|
---|
| 106 | print "$i-tir$cpt.png " if ($debug > 0);
|
---|
| 107 | RRDs::graph("$img/$i-tir$cpt.png","-s",$sdt,"-e",$edt,"-v packets/s","-S",$config->{step},"-aPNG","-t","Network Report $i - $m","DEF:s1=$base/$m/$config->{rrdsar}:$i-in:AVERAGE","DEF:s2=$base/$m/$config->{rrdsar}:$i-out:AVERAGE","LINE2:s1#ff0000:$i (in)","LINE2:s2#00ee22:$i (out)");
|
---|
| 108 | push @tmp2,td(img({src=>"$config->{http}/$dir/$m/img/$i-tir$cpt.png"}));
|
---|
| 109 | $col++;
|
---|
| 110 | if ($col == 2) {
|
---|
| 111 | push @tmp1,HTML::AsSubs::tr(@tmp2);
|
---|
| 112 | @tmp2 = ();
|
---|
| 113 | $col = 0;
|
---|
| 114 | }
|
---|
| 115 |
|
---|
| 116 | }
|
---|
| 117 | if (($i =~ /^sd/) || ($i =~ /^hd/) || ($i =~ /^cciss/)) {
|
---|
| 118 | $i =~ s/-[inout]+//;
|
---|
| 119 | next if (-f "$img/$i-tir$cpt.png");
|
---|
| 120 | print "$i-tir$cpt.png " if ($debug > 0);
|
---|
| 121 | RRDs::graph("$img/$i-tir$cpt.png","-s",$sdt,"-e",$edt,"-v Op/s","-S",$config->{step},"-aPNG","-t","Disk Report $i - $m","DEF:s1=$base/$m/$config->{rrdio}:$i-in:AVERAGE","DEF:s2=$base/$m/$config->{rrdio}:$i-out:AVERAGE","LINE2:s1#ff0000:$i (in)","LINE2:s2#00ee22:$i (out)");
|
---|
| 122 | push @tmp2,td(img({src=>"$config->{http}/$dir/$m/img/$i-tir$cpt.png"}));
|
---|
| 123 | $col++;
|
---|
| 124 | if ($col == 2) {
|
---|
| 125 | push @tmp1,HTML::AsSubs::tr(@tmp2);
|
---|
| 126 | @tmp2 = ();
|
---|
| 127 | $col = 0;
|
---|
| 128 | }
|
---|
| 129 | }
|
---|
| 130 | if (($i =~ /^cpu/) || ($i =~ /^all/)) {
|
---|
| 131 | $i =~ s/-[a-z]+//;
|
---|
| 132 | next if (-f "$img/$i-tir$cpt.png");
|
---|
| 133 | print "$i-tir$cpt.png " if ($debug > 0);
|
---|
| 134 | RRDs::graph("$img/$i-tir$cpt.png","-s",$sdt,"-e",$edt,"-S",$config->{step},"-aPNG","-t","CPU Report $i - $m","DEF:s1=$base/$m/$config->{rrdsar}:$i-idle:AVERAGE","DEF:s2=$base/$m/$config->{rrdsar}:$i-nice:AVERAGE","DEF:s3=$base/$m/$config->{rrdsar}:$i-system:AVERAGE","DEF:s4=$base/$m/$config->{rrdsar}:$i-user:AVERAGE","AREA:s1#00b6e4:$i (idle)","STACK:s2#00ee22:$i (nice)","STACK:s3#ff0000:$i (system)","STACK:s4#000000:$i (user)");
|
---|
| 135 | push @tmp2,td(img({src=>"$config->{http}/$dir/$m/img/$i-tir$cpt.png"}));
|
---|
| 136 | $col++;
|
---|
| 137 | if ($col == 2) {
|
---|
| 138 | push @tmp1,HTML::AsSubs::tr(@tmp2);
|
---|
| 139 | @tmp2 = ();
|
---|
| 140 | $col = 0;
|
---|
| 141 | }
|
---|
| 142 | }
|
---|
| 143 | }
|
---|
| 144 | $rrderror = RRDs::error;
|
---|
| 145 | die "Problem while generating graph: $rrderror\n" if ($rrderror);
|
---|
| 146 | print "\n" if ($debug > 0);
|
---|
| 147 | push @hht,table(@tmp1);
|
---|
| 148 | my $hht = body(@hht);
|
---|
| 149 | print TIR $hht->as_HTML;
|
---|
| 150 | close(TIR);
|
---|
| 151 | push @hhm,li(a({href=>"tir-$cpt.html"}, "Tir $cpt"));
|
---|
| 152 | $cpt++;
|
---|
| 153 | }
|
---|
| 154 | my $hhm = body(@hhm);
|
---|
| 155 | print MACHINE $hhm->as_HTML;
|
---|
| 156 | close(MACHINE);
|
---|
| 157 | }
|
---|
| 158 | push @hm,ul(@index);
|
---|
| 159 | my $hm = body(@hm);
|
---|
| 160 | print MAIN $hm->as_HTML;
|
---|
| 161 | close MAIN;
|
---|
| 162 | print "Point your browser to $config->{http}/$dir/dgi.html\n" if ($debug > 0);
|
---|
| 163 |
|
---|
| 164 | #
|
---|
| 165 | # Second pass
|
---|
| 166 | #
|
---|
| 167 | $h = "$base/dgi-tirs.html";
|
---|
| 168 | open (MAIN, "> $h") || die "Unable to create $h : $!";
|
---|
| 169 | @hm = (h1("sar2rrd - sar/iostats monitoring via rrdtool"),
|
---|
| 170 | p("List of shots:"));
|
---|
| 171 | @index = ();
|
---|
| 172 | my $cpt = 1;
|
---|
| 173 | my %attrs;
|
---|
| 174 | foreach $m (@machines) {
|
---|
| 175 | foreach my $attr (@{$attrsar{$m}{measures}},@{$attrio{$m}{measures}}) {
|
---|
| 176 | next if ($attr =~ /^load/);
|
---|
| 177 | next if ($attr =~ /^runq/);
|
---|
| 178 | $attr = "mem" if ($attr =~ /^memory/);
|
---|
| 179 | $attr = "load" if ($attr =~ /^plist/);
|
---|
| 180 | $attrs{$attr}++;
|
---|
| 181 | }
|
---|
| 182 | }
|
---|
| 183 |
|
---|
| 184 | foreach my $t (@shots) {
|
---|
| 185 | #
|
---|
| 186 | # The graphs/HTML generation
|
---|
| 187 | #
|
---|
| 188 | push @index,li(a({href=>"dgi-tir-$cpt.html"}, "Tir $cpt"));
|
---|
| 189 | my $hm = "$base/dgi-tir-$cpt.html";
|
---|
| 190 | open (SHOT, "> $hm") || die "Unable to create $hm : $!";
|
---|
| 191 | my @hhm = (h1("sar2rrd - Monitoring Shots"));
|
---|
| 192 | print "Graphing rrd base for Shot $cpt\n" if ($debug > 0);
|
---|
| 193 | foreach my $i (sort keys %attrs) {
|
---|
| 194 | @tmp1 = ();
|
---|
| 195 | @tmp2 = ();
|
---|
| 196 | my $ht = "$base/attr-$cpt-$i.html";
|
---|
| 197 | open (ATTR, "> $ht") || die "Unable to create $ht : $!";
|
---|
| 198 | my @hht = (h1("sar2rrd - Monitoring $i - Tir $cpt"));
|
---|
| 199 | my $col = 0;
|
---|
| 200 | foreach $m (@machines) {
|
---|
| 201 | my $img="$base/$m/img";
|
---|
| 202 | #push @tmp1,td(img({src=>"$config->{http}/$dir/$m/img/load-tir$cpt.png"}));
|
---|
| 203 | #push @tmp1,td(img({src=>"$config->{http}/$dir/$m/img/load-tir$cpt.png"}));
|
---|
| 204 | #push @tmp1,HTML::AsSubs::tr(@tmp1);
|
---|
| 205 |
|
---|
| 206 | push @tmp2,td(img({src=>"$config->{http}/$dir/$m/img/$i-tir$cpt.png"}));
|
---|
| 207 | $col++;
|
---|
| 208 | if ($col == 2) {
|
---|
| 209 | push @tmp1,HTML::AsSubs::tr(@tmp2);
|
---|
| 210 | @tmp2 = ();
|
---|
| 211 | $col = 0;
|
---|
| 212 | }
|
---|
| 213 | }
|
---|
| 214 | push @hht,table(@tmp1);
|
---|
| 215 | my $hht = body(@hht);
|
---|
| 216 | print ATTR $hht->as_HTML;
|
---|
| 217 | close(ATTR);
|
---|
| 218 | push @hhm,li(a({href=>"attr-$cpt-$i.html"}, "$i"));
|
---|
| 219 | }
|
---|
| 220 | my $hhm = body(@hhm);
|
---|
| 221 | print SHOT $hhm->as_HTML;
|
---|
| 222 | close(SHOT);
|
---|
| 223 | $cpt++;
|
---|
| 224 | }
|
---|
| 225 | push @hm,ul(@index);
|
---|
| 226 | $hm = body(@hm);
|
---|
| 227 | print MAIN $hm->as_HTML;
|
---|
| 228 | close MAIN;
|
---|
| 229 | print "Point your browser to $config->{http}/$dir/dgi-tirs.html\n" if ($debug > 0);
|
---|