![]() ![]() | ![]() |
Saving my work: comprehensive clusterstatus
1: #!/usr/bin/perl 2: $|=1; 3: # The LearningOnline Network with CAPA 4: # Cluster Status 5: # (Versions 6: # (Running loncron 7: # 09/06/01 Gerd Kortemeyer) 8: # 02/18/02,02/19/02 Gerd Kortemeyer) 9: 10: use lib '/home/httpd/lib/perl/'; 11: use LONCAPA::Configuration; 12: 13: use LWP::UserAgent(); 14: use HTTP::Headers; 15: use IO::File; 16: 17: my %host=(); 18: my $oneday=60*60*24; 19: 20: my %connectionstatus=(); 21: 22: sub key { 23: my ($local,$url)=@_; 24: my $key=$local.'_'.$url; 25: $key=~s/\W/\_/gs; 26: return $key; 27: } 28: 29: sub hidden { 30: my ($name,$value)=@_; 31: print "\n<input type='hidden' name='$name' value='$value' />"; 32: } 33: 34: sub request { 35: my ($local,$url,$cachetime)=@_; 36: my $key=&key($local,$url); 37: my $reply=''; 38: if ($FORM{$key.'_time'}) { 39: if ((time-$FORM{$key.'_time'})<$cachetime) { 40: $reply=$FORM{$key}; 41: &hidden($key.'_time',$FORM{$key.'_time'}); 42: &hidden($key.'_fromcache',1); 43: } 44: } 45: unless ($reply) { 46: unless ($hostname{$local}) { 47: $reply='local_unknown'; 48: } else { 49: 50: my $ua=new LWP::UserAgent(timeout => 20); 51: 52: my $request=new HTTP::Request('GET', 53: "http://".$hostname{$local}.$url); 54: $request->authorization_basic('lonadm','litelite'); 55: 56: my $response=$ua->request($request); 57: 58: unless ($response->is_success) { 59: $reply='local_error'; 60: } else { 61: $reply=$response->content; 62: chomp($reply); 63: } 64: } 65: &hidden($key.'_time',time); 66: } 67: &hidden($key,$reply); 68: return $reply; 69: } 70: 71: # ============================================= Are local and remote connected? 72: sub connected { 73: my ($local,$remote)=@_; 74: $local=~s/\W//g; 75: $remote=~s/\W//g; 76: 77: unless ($hostname{$remote}) { return 'remote_unknown'; } 78: my $url='/cgi-bin/ping.pl?'.$remote; 79: # 80: # Slowly phase this in: if not cached, only do 10 percent of the cases 81: # 82: unless ($FORM{&key($local,$url)}) { 83: unless (rand>0.9) { return 'not_yet'; } 84: } 85: # 86: # Actually do the query 87: # 88: &statuslist($local,'connecting '.$remote); 89: my $reply=&request($local,$url,1800); 90: $reply=(split("\n",$reply))[0]; 91: $reply=~s/\W//g; 92: if ($reply ne $remote) { return $reply; } 93: return 'ok'; 94: } 95: # ============================================================ Get a reply hash 96: 97: sub replyhash { 98: my %returnhash=(); 99: foreach (split(/\&/,&request(@_))) { 100: my ($name,$value)=split(/\=/,$_); 101: if ($name) { 102: unless ($value) { $value=''; } 103: $returnhash{$name}=$value; 104: } 105: } 106: return %returnhash; 107: } 108: 109: # ========================================================== Show server status 110: 111: sub otherwindow { 112: my ($local,$url,$label)=@_; 113: return 114: "<a href='http://$hostname{$local}$url' target='newwin$local'>$label</a>"; 115: } 116: 117: sub serverstatus { 118: my $local=shift; 119: print "\n<hr /><h3>$local $hostdom{$local} ($hostname{$local}; $hostrole{$local})</h3>\n"; 120: # checkrpms 121: if ($host{$local.'_checkrpms'}) { 122: print "<br />RPMs: ".$host{$local.'_checkrpms'} 123: } 124: # mysql 125: if ($host{$local.'_mysql'}) { 126: print "<br />MySQL Database: ".$host{$local.'_mysql'} 127: } 128: } 129: 130: # ====================================================================== Status 131: sub statuslist { 132: my ($local,$what)=@_; 133: print 134: "<script>document.prgstat.progress.value='Testing $local ($hostname{$local}): $what';</script>\n"; 135: } 136: 137: # 138: # Main program 139: # 140: # ========================================================= Get form parameters 141: my $buffer; 142: 143: read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'}); 144: my @pairs=split(/&/,$buffer); 145: my $pair; my $name; my $value; 146: undef %FORM; 147: %FORM=(); 148: foreach $pair (@pairs) { 149: ($name,$value) = split(/=/,$pair); 150: $value =~ tr/+/ /; 151: $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C",hex($1))/eg; 152: $FORM{$name}=$value; 153: } 154: 155: $buffer=$ENV{'QUERY_STRING'}; 156: @pairs=split(/&/,$buffer); 157: foreach $pair (@pairs) { 158: ($name,$value) = split(/=/,$pair); 159: $value =~ tr/+/ /; 160: $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C",hex($1))/eg; 161: $FORM{$name}=$value; 162: } 163: 164: # ====================================================== Determine refresh rate 165: 166: my $refresh=(($FORM{'refresh'}=~/^\d+$/)?$FORM{'refresh'}:60); 167: if ($refresh<30) { $refresh=30; } 168: my $starttime=time; 169: # ================================================================ Send Headers 170: print "Content-type: text/html\n\n". 171: "<html><body bgcolor=#FFFFFF>\n"; 172: # -------------------- Read loncapa.conf (and by default, loncapa_apache.conf). 173: my $perlvarref=LONCAPA::Configuration::read_conf('loncapa.conf'); 174: my %perlvar=%{$perlvarref}; 175: undef $perlvarref; # remove since sensitive and not needed 176: delete $perlvar{'lonReceipt'}; # remove since sensitive and not needed 177: delete $perlvar{'lonSqlAccess'}; # remove since sensitive and not needed 178: 179: # ------------------------------------------------------------- Read hosts file 180: { 181: my $config=IO::File->new("$perlvar{'lonTabDir'}/hosts.tab"); 182: 183: $total=0; 184: while (my $configline=<$config>) { 185: $configline=~s/#.*$//; 186: unless ($configline=~/\w/) { next; } 187: my ($id,$domain,$role,$name,$ip)=split(/:/,$configline); 188: $hostname{$id}=$name; 189: $hostdom{$id}=$domain; 190: $hostrole{$id}=$role; 191: $hostip{$id}=$ip; 192: $total++; 193: if (($role eq 'library') && ($id ne $perlvar{'lonHostID'})) { 194: $libserv{$id}=$name; 195: } 196: } 197: } 198: 199: print "<h1>Cluster Status ".localtime()."</h1>"; 200: print "<form name='prgstat'>\n". 201: "<input type='text' name='progress' value='Starting ...' size='100' /><br />". 202: "</form>\n";; 203: print "<form name='status' method='post'>\n"; 204: &hidden('refresh',$refresh); 205: 206: # ==================================================== Main Loop over all Hosts 207: 208: foreach $local (sort keys %hostname) { 209: # -- Check general status 210: &statuslist($local,'General'); 211: my %loncron=&replyhash($local,'/lon-status/loncron_simple.txt',1200); 212: if (defined($loncron{'local_error'})) { 213: $host{$local.'_loncron'}='Could not determine.'; 214: } else { 215: if ((time-$loncron{'time'})>$oneday) { 216: $host{$local.'_loncron'}='Stale.'; 217: } else { 218: } 219: } 220: # -- Check user status 221: &statuslist($local,'Users'); 222: my %userstatus=&replyhash($local,'/cgi-bin/userstatus.pl?simple',600); 223: if (defined($userstatus{'local_error'})) { 224: $host{$local.'_userstatus'}='Could not determine.'; 225: } else { 226: } 227: # -- Check mysql status 228: &statuslist($local,'Database'); 229: my %mysql=&replyhash($local,'/lon-status/mysql.txt',1200); 230: if (defined($mysql{'local_error'})) { 231: $host{$local.'_mysql'}='Could not determine.'; 232: } else { 233: if ((time-$mysql{'time'})>(7*$oneday)) { 234: if ($hostrole{$local} eq 'library') { 235: $host{$local.'_mysql'}='Stale.'; 236: $host{$local.'_mysql_doomed'}=1; 237: } 238: if ($mysql{'mysql'} eq 'defunct') { 239: $host{$local.'_mysql'}='Defunct (maybe stale).'; 240: $host{$local.'_mysql_doomed'}=2; 241: } 242: } elsif ($mysql{'mysql'} eq 'defunct') { 243: $host{$local.'_mysql'}='Defunct.'; 244: $host{$local.'_mysql_doomed'}=3; 245: } 246: } 247: # -- Check rpm status 248: &statuslist($local,'RPMs'); 249: my %checkrpms=&replyhash($local,'/lon-status/checkrpms.txt',2400); 250: if (defined($checkrpms{'local_error'})) { 251: $host{$local.'_checkrpms'}='Could not determine.'; 252: } else { 253: if ((time-$checkrpms{'time'})>(4*$oneday)) { 254: $host{$local.'_checkrpms'}='Stale.'; 255: $host{$local.'_checkrpms_doomed'}=50; 256: } elsif ($checkrpms{'status'} eq 'fail') { 257: $host{$local.'_checkrpms'}='Could not checked RPMs.'; 258: $host{$local.'_checkrpms_doomed'}=100; 259: } elsif ($checkrpms{'rpmcount'}) { 260: $host{$local.'_checkrpms'}='Outdated RPMs: '. 261: $checkrpms{'rpmcount'}; 262: $host{$local.'_checkrpms_doomed'}=$checkrpms{'rpmcount'}; 263: } 264: } 265: # -- Check connections 266: &statuslist($local,'Connections'); 267: $host{$local.'_notconnected'}=''; 268: $host{$local.'_notconnected_doomed'}=0; 269: foreach $remote (sort keys %hostname) { 270: my $status=&connected($local,$remote); 271: $connectionstatus{$local.'_TO_'.$remote}=$status; 272: unless (($status eq 'ok') || ($status eq 'not_yet')) { 273: $host{$local.'_notconnected'}.=' '.$remote; 274: $host{$local.'_notconnected_doomed'}++; 275: } 276: } 277: # Eventually, use doomed count 278: &serverstatus($local); 279: } 280: 281: # =============================================================== End Mail Loop 282: print "</form><script>"; 283: $runtime=time-$starttime; 284: if ($runtime>=$refresh) { 285: print 'document.status.submit();'; 286: } else { 287: $refreshtime=int(1000*($refresh-$runtime)); 288: print "setTimeout('document.status.submit()',$refreshtime);"; 289: } 290: print "</script></body></html>"; 291: exit 0;