Annotation of loncom/cgi/clusterstatus.pl, revision 1.25
1.1 www 1: #!/usr/bin/perl
2: $|=1;
1.25 ! raeburn 3: # Generates a html page showing various status reports about the domain or cluster
! 4: # $Id: clusterstatus.pl,v 1.24 2005/04/13 18:30:46 albertel Exp $
1.21 albertel 5: #
6: # Copyright Michigan State University Board of Trustees
7: #
8: # This file is part of the LearningOnline Network with CAPA (LON-CAPA).
9: #
10: # LON-CAPA is free software; you can redistribute it and/or modify
11: # it under the terms of the GNU General Public License as published by
12: # the Free Software Foundation; either version 2 of the License, or
13: # (at your option) any later version.
14: #
15: # LON-CAPA 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: # You should have received a copy of the GNU General Public License
21: # along with LON-CAPA; if not, write to the Free Software
22: # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23: #
24: # /home/httpd/html/adm/gpl.txt
25: #
26: # http://www.lon-capa.org/
1.9 www 27: #
1.3 harris41 28:
1.25 ! raeburn 29: use strict;
! 30:
1.3 harris41 31: use lib '/home/httpd/lib/perl/';
1.25 ! raeburn 32: use Apache::lonnet;
! 33: use Apache::lonlocal;
1.3 harris41 34: use LONCAPA::Configuration;
1.25 ! raeburn 35: use LONCAPA::loncgi;
1.1 www 36: use LWP::UserAgent();
37: use HTTP::Headers;
38: use IO::File;
39:
1.25 ! raeburn 40: my $perlvar=&LONCAPA::Configuration::read_conf('loncapa.conf');
! 41:
1.8 www 42: my %host=();
43: my $oneday=60*60*24;
44:
45: my %connectionstatus=();
1.9 www 46: my %perlvar=();
47:
48: my $mode;
1.14 www 49: my $concount=0;
1.16 www 50: my $fromcache;
51:
1.25 ! raeburn 52: my %domaininfo = &Apache::lonnet::domain_info();
! 53: my %allhostname = &Apache::lonnet::all_hostnames();
! 54: my (%hostname,%hostip);
! 55: my %hostdom = &Apache::lonnet::all_host_domain();
! 56: my %iphost = &Apache::lonnet::get_iphost();
! 57: my %libserv= &Apache::lonnet::all_library();
! 58:
! 59: foreach my $ip (keys(%iphost)) {
! 60: $hostip{$iphost{$ip}} = $ip;
! 61: }
1.16 www 62:
63: my $maxusers=0;
64: my $maxload=0;
65: my $totalusers=0;
66:
67: my %FORM=();
68:
69: my $stat_total=0;
70: my $stat_notyet=0;
71: my $stat_fromcache=0;
1.9 www 72:
73: sub select_form {
74: my ($def,$name,%hash) = @_;
75: my $selectform = "<select name=\"$name\" size=\"1\">\n";
1.25 ! raeburn 76: foreach my $key (sort(keys(%hash))) {
! 77: $selectform.="<option value=\"$key\" ".
! 78: ($key eq $def? 'selected' : '').
! 79: ">".$hash{$key}."</option>\n";
1.9 www 80: }
81: $selectform.="</select>";
82: return $selectform;
83: }
84:
1.8 www 85:
86: sub key {
87: my ($local,$url)=@_;
88: my $key=$local.'_'.$url;
89: $key=~s/\W/\_/gs;
90: return $key;
91: }
92:
93: sub hidden {
94: my ($name,$value)=@_;
1.25 ! raeburn 95: print("\n<input type='hidden' name='$name' value='$value' />");
1.8 www 96: }
97:
98: sub request {
99: my ($local,$url,$cachetime)=@_;
1.13 www 100: $cachetime*=(0.5+rand);
1.8 www 101: my $key=&key($local,$url);
102: my $reply='';
1.16 www 103: $stat_total++;
104: # if fromcache flag is set, only return cached values
105: if ($fromcache) {
106: if ($FORM{$key.'_time'}) {
1.25 ! raeburn 107: $stat_fromcache++;
1.16 www 108: return $FORM{$key};
109: } else {
1.25 ! raeburn 110: $stat_notyet++;
1.16 www 111: return 'not_yet';
112: }
113: }
114: # normal mode, refresh when expired or not yet present
1.8 www 115: if ($FORM{$key.'_time'}) {
116: if ((time-$FORM{$key.'_time'})<$cachetime) {
117: $reply=$FORM{$key};
118: &hidden($key.'_time',$FORM{$key.'_time'});
1.16 www 119: $stat_fromcache++;
1.8 www 120: }
121: }
122: unless ($reply) {
1.25 ! raeburn 123: if ($hostname{$local}) {
! 124: my $ua=new LWP::UserAgent(timeout => 20);
1.8 www 125: my $request=new HTTP::Request('GET',
126: "http://".$hostname{$local}.$url);
127: my $response=$ua->request($request);
1.25 ! raeburn 128: if ($response->is_success) {
! 129: $reply=$response->content;
! 130: chomp($reply);
! 131: } else {
1.8 www 132: $reply='local_error';
133: }
1.25 ! raeburn 134: } else {
! 135: $reply='local_unknown';
! 136: }
1.8 www 137: &hidden($key.'_time',time);
138: }
139: &hidden($key,$reply);
140: return $reply;
141: }
142:
143: # ============================================= Are local and remote connected?
1.1 www 144: sub connected {
145: my ($local,$remote)=@_;
146: $local=~s/\W//g;
147: $remote=~s/\W//g;
148:
149: unless ($hostname{$remote}) { return 'remote_unknown'; }
1.8 www 150: my $url='/cgi-bin/ping.pl?'.$remote;
151: #
1.14 www 152: # Slowly phase this in: if not cached, only do 5 percent of the cases,
153: # but always do the first five.
1.8 www 154: #
155: unless ($FORM{&key($local,$url)}) {
1.16 www 156: unless (($concount<=5) || (rand>0.95)) {
157: $stat_total++;
158: $stat_notyet++;
1.14 www 159: return 'not_yet';
160: } else {
161: $concount++;
162: }
1.8 www 163: }
164: #
165: # Actually do the query
166: #
167: &statuslist($local,'connecting '.$remote);
1.9 www 168: my $reply=&request($local,$url,3600);
1.8 www 169: $reply=(split("\n",$reply))[0];
170: $reply=~s/\W//g;
171: if ($reply ne $remote) { return $reply; }
172: return 'ok';
173: }
174: # ============================================================ Get a reply hash
175:
176: sub replyhash {
177: my %returnhash=();
178: foreach (split(/\&/,&request(@_))) {
179: my ($name,$value)=split(/\=/,$_);
180: if ($name) {
181: unless ($value) { $value=''; }
182: $returnhash{$name}=$value;
183: }
184: }
185: return %returnhash;
186: }
1.1 www 187:
1.9 www 188: # ================================================================ Link to host
1.1 www 189:
1.8 www 190: sub otherwindow {
191: my ($local,$url,$label)=@_;
192: return
1.9 www 193: " <a href='http://$hostname{$local}$url' target='newwin$local'>$label</a> ";
194: }
195:
196: sub login {
197: my $local=shift;
1.25 ! raeburn 198: print(&otherwindow($local,'/adm/login?domain='.$perlvar{'lonDefDomain'},
! 199: 'Login'));
1.9 www 200: }
201:
202: sub runloncron {
203: my $local=shift;
1.25 ! raeburn 204: print(&otherwindow($local,'/cgi-bin/loncron.pl',&Apache::lonlocal::mt('Run loncron')));
1.9 www 205: }
206:
207: sub loncron {
208: my $local=shift;
1.25 ! raeburn 209: print(&otherwindow($local,'/lon-status','loncron'));
1.9 www 210: }
211:
212: sub lonc {
213: my $local=shift;
1.25 ! raeburn 214: print(&otherwindow($local,'/lon-status/loncstatus.txt','lonc'));
1.9 www 215: }
216:
217: sub lond {
218: my $local=shift;
1.25 ! raeburn 219: print(&otherwindow($local,'/lon-status/londstatus.txt','lond'));
1.9 www 220: }
221:
222: sub users {
223: my $local=shift;
1.25 ! raeburn 224: print(&otherwindow($local,'/cgi-bin/userstatus.pl',&Apache::lonlocal::mt('Users')));
1.9 www 225: }
226:
227: sub versions {
228: my $local=shift;
1.25 ! raeburn 229: print(&otherwindow($local,'/cgi-bin/lonversions.pl',&Apache::lonlocal::mt('Versions')));
1.9 www 230: }
231:
232: sub server {
233: my $local=shift;
1.25 ! raeburn 234: print(&otherwindow($local,'/server-status',&Apache::lonlocal::mt('Server Status')));
1.8 www 235: }
1.1 www 236:
1.18 www 237: sub announcement {
238: my $local=shift;
1.25 ! raeburn 239: print(&otherwindow($local,'/announcement.txt',&Apache::lonlocal::mt('Announcement')));
1.18 www 240: }
241:
1.22 www 242: sub takeonline {
243: my $local=shift;
1.25 ! raeburn 244: print(&otherwindow($local,'/cgi-bin/takeonline.pl',&Apache::lonlocal::mt('Take online')));
1.22 www 245: }
246:
1.23 www 247: sub takeoffline {
248: my $local=shift;
1.25 ! raeburn 249: print(&otherwindow($local,'/cgi-bin/takeoffline.pl',&Apache::lonlocal::mt('Take offline')));
1.23 www 250: }
251:
252: sub reroute {
253: my ($local,$remote)=@_;
1.25 ! raeburn 254: print(&otherwindow($local,'/cgi-bin/takeoffline.pl?'.
1.23 www 255: $hostname{$remote}.'&'.$hostdom{$local}
1.25 ! raeburn 256: ,$remote)."\n");
1.23 www 257: }
258:
259: sub allreroutes {
260: my $local=shift;
261: &takeoffline($local);
1.25 ! raeburn 262: print(&Apache::lonlocal::mt('Reroute to:').' <font size="1">');
1.23 www 263: foreach my $remote (sort keys %hostname) {
264: unless ($local eq $remote) {
265: &reroute($local,$remote);
266: }
267: }
1.25 ! raeburn 268: print('</font>');
1.23 www 269: }
270:
1.11 www 271: # ========================================================= Produce a green bar
272: sub bar {
273: my $parm=shift;
274: my $number=int($parm+0.5);
1.25 ! raeburn 275: print('<table><tr><td bgcolor="#225522"><font color="#225522">');
1.11 www 276: for (my $i=0;$i<$number;$i++) {
277: print "+";
278: }
1.25 ! raeburn 279: print("</font></table>");
1.11 www 280: }
281:
1.9 www 282: # ========================================================== Show server status
283:
1.8 www 284: sub serverstatus {
1.11 www 285: my ($local,$trouble)=@_;
1.25 ! raeburn 286: my $hostrole;
! 287: if (exists($libserv{$local})) {
! 288: $hostrole = 'library';
! 289: } else {
! 290: $hostrole = 'access';
! 291: }
! 292: my %lt = &Apache::lonlocal::texthash(
! 293: rero => 'Reroute:',
! 294: vers => 'Version:',
! 295: load => 'Load:',
! 296: acti => 'Active Users:',
! 297: rpms => 'RPMs',
! 298: mysq => 'MySQL Database:',
! 299: notc => 'Not connected',
! 300: lonc => 'loncron errors',
! 301: );
! 302:
! 303: print(<<ENDHEADER);
1.11 www 304: <a name="$local" />
1.9 www 305: <table width="100%" bgcolor="#225522" cellspacing="2" cellpadding="2" border="0">
306: <tr><td bgcolor="#BBDDBB"><font color="#225522" face="arial"><b>
1.25 ! raeburn 307: $local $hostdom{$local}</b> <tt>($hostname{$local}); $hostrole</tt>
! 308: <br />$domaininfo{$hostdom{$local}}{'description'}
! 309: $domaininfo{$hostdom{$local}}{'city'}
1.10 www 310: </font></th></tr><tr><td bgcolor="#DDDDBB"><font color="#225522">
1.9 www 311: ENDHEADER
312: &login($local);&server($local);&users($local);&versions($local);
1.18 www 313: &announcement($local);
1.9 www 314: &loncron($local);&lond($local);&lonc($local);&runloncron($local);
1.25 ! raeburn 315: print("</font></td></tr>");
1.11 www 316: if ($trouble) {
1.25 ! raeburn 317: print("<tr><td bgcolor='#DDBBBB'><font color='#552222' size='+2'>$trouble</font></td></tr>");
1.11 www 318: }
1.25 ! raeburn 319: print("<tr><td bgcolor='#BBBBBB'>");
1.22 www 320: # re-routing
321: if ($host{$local.'_reroute'}) {
1.25 ! raeburn 322: print('<br />'.$lt{'rero'}.' '.$host{$local.'_reroute'});
1.22 www 323: &takeonline($local);
324: }
1.15 www 325: # version
326: if ($host{$local.'_version'}) {
1.25 ! raeburn 327: print('<br />'.$lt{'vers'}.' '.$host{$local.'_version'});
1.15 www 328: }
1.9 www 329: # load
330: if (($host{$local.'_load_doomed'}>0.5) || ($mode eq 'load_doomed')) {
1.25 ! raeburn 331: print('<br />'.$lt{'load'}.' '.$host{$local.'_load'});
1.9 www 332: }
333: # users
334: if (($host{$local.'_users_doomed'}>10) || ($mode eq 'users_doomed')) {
1.25 ! raeburn 335: print('<br />'.$lt{'acti'}.' '.$host{$local.'_users'});
1.9 www 336: }
337:
1.8 www 338: # checkrpms
339: if ($host{$local.'_checkrpms'}) {
1.25 ! raeburn 340: print('<br />'.$lt{'rpms'}.' '.$host{$local.'_checkrpms'});
1.8 www 341: }
342: # mysql
343: if ($host{$local.'_mysql'}) {
1.25 ! raeburn 344: print('<br />'.$lt{'mysq'}.' '.$host{$local.'_mysql'});
1.8 www 345: }
1.11 www 346: # connections
347: if ($host{$local.'_notconnected'}) {
1.25 ! raeburn 348: print('<br />'.$lt{'notc'}.' ');
! 349: foreach my $item (split(/ /,$host{$local.'_notconnected'})) {
! 350: if ($item) {
! 351: print(' <a href="#$item">'.$item.'</a>');
1.11 www 352: }
353: }
354: }
355: # errors
356: if ($host{$local.'_errors'}) {
1.25 ! raeburn 357: print('<br />'.$lt{'lonc'}.' '.$host{$local.'_errors'});
1.11 www 358: }
1.23 www 359: print "</td></tr><tr><td bgcolor='#DDDDDD'>";
360: &allreroutes($local);
1.9 www 361: print "</td></tr></table><br />";
362: }
363:
364: # =========================================================== Doomedness sorted
365:
366: sub doomedness {
367: my $crit=shift;
368: my %alldoomed=();
369: my @allhosts=();
370: foreach (keys %host) {
371: if ($_=~/^(\w+)\_$crit$/) {
372: if ($host{$_}) {
373: push (@allhosts,$1);
374: $alldoomed{$1}=$host{$_};
375: }
376: }
377: }
378: return sort { $alldoomed{$b} <=> $alldoomed{$a} } @allhosts;
1.8 www 379: }
1.1 www 380:
1.16 www 381: sub resetvars {
382: $maxusers=0;
383: $maxload=0;
384: $totalusers=0;
385: $stat_total=0;
386: $stat_notyet=0;
387: $stat_fromcache=0;
1.17 www 388: $concount=0;
1.16 www 389: undef %host;
390: %host=();
1.1 www 391: }
1.8 www 392:
1.16 www 393: sub mainloop {
394: &resetvars();
1.8 www 395: # ==================================================== Main Loop over all Hosts
396:
1.25 ! raeburn 397: foreach my $local (sort(keys(%hostname))) {
1.9 www 398: $host{$local.'_unresponsive_doomed'}=0;
1.8 www 399: # -- Check general status
400: &statuslist($local,'General');
401: my %loncron=&replyhash($local,'/lon-status/loncron_simple.txt',1200);
402: if (defined($loncron{'local_error'})) {
403: $host{$local.'_loncron'}='Could not determine.';
1.9 www 404: $host{$local.'_unresponsive_doomed'}++;
1.8 www 405: } else {
406: if ((time-$loncron{'time'})>$oneday) {
407: $host{$local.'_loncron'}='Stale.';
1.9 www 408: $host{$local.'_unresponsive_doomed'}++;
1.8 www 409: } else {
1.11 www 410: $host{$local.'_loncron_doomed'}=$loncron{'notices'}
411: +4*$loncron{'warnings'}
412: +100*$loncron{'errors'};
413: $host{$local.'_errors'}=$loncron{'errors'};
1.8 www 414: }
415: }
1.15 www 416: # -- Check version
417: &statuslist($local,'Version');
418: my $version=&request($local,'/lon-status/version.txt',7200);
419: if ($version eq 'local_error') {
420: $host{$local.'_version'}='Could not determine.';
421: $host{$local.'_unresponsive_doomed'}++;
422: } else {
423: $host{$local.'_version'}=$version;
424: }
1.8 www 425: # -- Check user status
426: &statuslist($local,'Users');
427: my %userstatus=&replyhash($local,'/cgi-bin/userstatus.pl?simple',600);
428: if (defined($userstatus{'local_error'})) {
429: $host{$local.'_userstatus'}='Could not determine.';
1.9 www 430: $host{$local.'_unresponsive_doomed'}++;
1.8 www 431: } else {
1.9 www 432: $host{$local.'_users_doomed'}=$userstatus{'Active'};
433: $host{$local.'_users'}=$userstatus{'Active'};
1.11 www 434: unless ($host{$local.'_users'}) { $host{$local.'_users'}=0; }
435: if ($host{$local.'_users'}>$maxusers) {
436: $maxusers=$host{$local.'_users'};
437: }
438: $totalusers+=$host{$local.'_users'};
1.9 www 439: my ($sload,$mload,$lload)=split(/ /,$userstatus{'loadavg'});
440: $host{$local.'_load_doomed'}=$mload;
1.11 www 441: if ($mload>$maxload) {
442: $maxload=$mload;
443: }
1.9 www 444: $host{$local.'_load'}=$userstatus{'loadavg'};
1.8 www 445: }
1.22 www 446: # -- Check reroute status
447: &statuslist($local,'Reroute');
448: my %reroute=&replyhash($local,'/lon-status/reroute.txt',1800);
449: if ($reroute{'status'} eq 'rerouting') {
450: if ($reroute{'server'}) {
451: $host{$local.'_reroute'}=
452: 'Rerouting to <tt>'.$reroute{'server'}.
453: '</tt>, domain: '.$reroute{'domain'}.
454: ' (since '.localtime($reroute{'time'}).')';
455: } else {
456: $host{$local.'_reroute'}='offline';
457: }
458: }
1.8 www 459: # -- Check mysql status
460: &statuslist($local,'Database');
1.9 www 461: my %mysql=&replyhash($local,'/lon-status/mysql.txt',3600);
1.8 www 462: if (defined($mysql{'local_error'})) {
463: $host{$local.'_mysql'}='Could not determine.';
1.9 www 464: $host{$local.'_unresponsive_doomed'}++;
1.8 www 465: } else {
466: if ((time-$mysql{'time'})>(7*$oneday)) {
1.25 ! raeburn 467: if (exists($libserv{$local})) {
1.8 www 468: $host{$local.'_mysql'}='Stale.';
469: $host{$local.'_mysql_doomed'}=1;
470: }
471: if ($mysql{'mysql'} eq 'defunct') {
472: $host{$local.'_mysql'}='Defunct (maybe stale).';
473: $host{$local.'_mysql_doomed'}=2;
474: }
475: } elsif ($mysql{'mysql'} eq 'defunct') {
476: $host{$local.'_mysql'}='Defunct.';
477: $host{$local.'_mysql_doomed'}=3;
478: }
479: }
480: # -- Check rpm status
481: &statuslist($local,'RPMs');
1.9 www 482: my %checkrpms=&replyhash($local,'/lon-status/checkrpms.txt',7200);
1.8 www 483: if (defined($checkrpms{'local_error'})) {
484: $host{$local.'_checkrpms'}='Could not determine.';
1.9 www 485: $host{$local.'_unresponsive_doomed'}++;
1.8 www 486: } else {
487: if ((time-$checkrpms{'time'})>(4*$oneday)) {
488: $host{$local.'_checkrpms'}='Stale.';
489: $host{$local.'_checkrpms_doomed'}=50;
1.9 www 490: $host{$local.'_unresponsive_doomed'}++;
1.8 www 491: } elsif ($checkrpms{'status'} eq 'fail') {
492: $host{$local.'_checkrpms'}='Could not checked RPMs.';
493: $host{$local.'_checkrpms_doomed'}=100;
494: } elsif ($checkrpms{'rpmcount'}) {
495: $host{$local.'_checkrpms'}='Outdated RPMs: '.
496: $checkrpms{'rpmcount'};
497: $host{$local.'_checkrpms_doomed'}=$checkrpms{'rpmcount'};
498: }
499: }
500: # -- Check connections
501: &statuslist($local,'Connections');
502: $host{$local.'_notconnected'}='';
503: $host{$local.'_notconnected_doomed'}=0;
1.16 www 504: foreach my $remote (sort keys %hostname) {
1.8 www 505: my $status=&connected($local,$remote);
506: $connectionstatus{$local.'_TO_'.$remote}=$status;
507: unless (($status eq 'ok') || ($status eq 'not_yet')) {
508: $host{$local.'_notconnected'}.=' '.$remote;
509: $host{$local.'_notconnected_doomed'}++;
510: }
511: }
1.16 www 512: # =============================================================== End Main Loop
513: }
514:
1.8 www 515: }
1.16 www 516:
517: sub reports {
1.9 www 518: # ====================================================================== Output
519: if ($mode=~/\_doomed$/) {
520: # Output by doomedness
521: foreach (&doomedness($mode)) {
522: &serverstatus($_);
523: }
1.10 www 524: } elsif ($mode eq 'connections') {
525: print
526: "<table cellspacing='3' cellpadding='3' border='0' bgcolor='#225522'>".
527: "<tr><td bgcolor='#225522'> </td>";
1.11 www 528: foreach my $remote (sort keys %hostname) {
1.17 www 529: print '<td bgcolor="#DDDDBB">'.$remote.'</td>';
1.10 www 530: }
531: print "</tr>\n";
532: # connection matrix
1.11 www 533: foreach my $local (sort keys %hostname) {
1.17 www 534: print '<tr><td bgcolor="#DDDDBB">'.$local.'</td>';
1.11 www 535: foreach my $remote (sort keys %hostname) {
1.10 www 536: if ($connectionstatus{$local.'_TO_'.$remote} eq 'not_yet') {
1.14 www 537: my $cellcolor='#FFFFFF';
538: if ($local eq $remote) { $cellcolor='#DDDDDD'; }
539: print '<td bgcolor="'.$cellcolor.'"><font color="#555522" size="-2">not yet tested</font></td>';
1.10 www 540: } elsif ($connectionstatus{$local.'_TO_'.$remote} eq 'ok') {
1.14 www 541: my $cellcolor='#BBDDBB';
542: if ($local eq $remote) { $cellcolor='#99DD99'; }
1.10 www 543: print
1.25 ! raeburn 544: '<td bgcolor="'.$cellcolor.'"><font color="#225522" face="arial"><b>'.&Apache::lonlocal::mt('ok').'</b></td>';
1.10 www 545: } else {
1.20 www 546: my $cellcolor='#DDCCAA';
1.14 www 547: if ($connectionstatus{$local.'_TO_'.$remote} eq 'local_error') {
548: if ($local eq $remote) {
549: $cellcolor='#DD88AA';
550: } else {
551: $cellcolor='#DDAACC';
552: }
553: } else {
1.20 www 554: if ($local eq $remote) { $cellcolor='#DDBB77'; }
1.14 www 555: }
1.10 www 556: print
1.14 www 557: '<td bgcolor="'.$cellcolor.'"><font color="#552222" size="-2">'.
1.10 www 558: $connectionstatus{$local.'_TO_'.$remote}.'<br />';
559: &lonc($local); &lond($remote);
560: print '</td>';
561: }
562: }
563: print "</tr>\n";
564: }
1.11 www 565: print "</table>";
566: } elsif ($mode eq 'users') {
567: # Users
568: if ($maxusers) {
569: my $factor=50/$maxusers;
1.25 ! raeburn 570: print '<h3>'.&Apache::lonlocal::mt('Total active user(s)').': '.$totalusers.'</h3>'.
! 571: '<table cellspacing="3" cellpadding="3" border="0" bgcolor="#225522">';
1.11 www 572:
1.16 www 573: foreach my $local (sort keys %hostname) {
1.11 www 574: if (defined($host{$local.'_users'})) {
575: print
1.16 www 576: '<tr><td bgcolor="#BBDDBB"><font face="arial" color="#225522" size="+1">'.$local.
577: '</font><br /><font size="-2">'.
1.25 ! raeburn 578: $domaininfo{$hostdom{$local}}{'description'}.
1.16 www 579: '</font></td><td bgcolor="#DDDDBB">';
1.12 www 580: &users($local);
1.11 www 581: print
582: '</td><td bgcolor="#DDDDBB"><font face="arial" color="#225522">'.
583: $host{$local.'_users'}.'</font></td><td bgcolor="#DDDDBB"';
584: &bar($factor*$host{$local.'_users'});
1.25 ! raeburn 585: print '</td></tr>'."\n";
1.11 www 586: }
587: }
1.25 ! raeburn 588: print '</table>';
1.11 www 589: } else {
1.25 ! raeburn 590: print &Apache::lonlocal::mt('No active users logged in.');
1.11 www 591: }
592: } elsif ($mode eq 'load') {
593: # Load
594: if ($maxload) {
595: my $factor=50/$maxload;
596: print
597: "<table cellspacing='3' cellpadding='3' border='0' bgcolor='#225522'>";
1.16 www 598: foreach my $local (sort keys %hostname) {
1.11 www 599: if (defined($host{$local.'_load_doomed'})) {
600: print
1.16 www 601: '<tr><td bgcolor="#BBDDBB"><font face="arial" color="#225522" size="+1">'.
1.11 www 602: $local.
1.16 www 603: '</font><br /><font size="-2">'.
1.25 ! raeburn 604: $Apache::lonnet::domain{$hostdom{$local}}{'description'}.
1.16 www 605: '</font></td><td bgcolor="#DDDDBB">';
1.12 www 606: &server($local);
1.11 www 607: print
608: '</td><td bgcolor="#DDDDBB"><font face="arial" color="#225522">'.
609: $host{$local.'_load_doomed'}.'</font></td><td bgcolor="#DDDDBB"';
610: &bar($factor*$host{$local.'_load_doomed'});
611: print "</td></tr>\n";
612: }
613: }
614: print "</table>";
615: } else {
1.25 ! raeburn 616: print &Apache::lonlocal::mt('No workload.');
1.11 www 617: }
618: } elsif ($mode eq 'trouble') {
619: my $count=0;
1.16 www 620: foreach my $local (sort keys %hostname) {
1.11 www 621: my $trouble='';
1.15 www 622: if ($host{$local.'_unresponsive_doomed'}>3) {
1.25 ! raeburn 623: $trouble=&Apache::lonlocal::mt('Does not respond to several queries.').
! 624: '<br />';
1.15 www 625: }
1.11 www 626: if ($host{$local.'_errors'}) {
1.25 ! raeburn 627: $trouble=&Apache::lonlocal::mt('Has loncron errors').'<br />';
1.24 albertel 628: } elsif ($host{$local.'_loncron_doomed'}>2500) {
1.25 ! raeburn 629: $trouble=&Apache::lonlocal::mt('High loncron count.').'<br />';
1.11 www 630: }
631: if ($host{$local.'_load_doomed'}>5) {
1.25 ! raeburn 632: $trouble=&Apache::lonlocal::mt('High load.').'<br />';
1.11 www 633: }
634: if ($host{$local.'_users_doomed'}>200) {
1.25 ! raeburn 635: $trouble=&Apache::lonlocal::mt('High user volume.').'<br />';
1.11 www 636: }
637: if ($host{$local.'_mysql_doomed'}>1) {
1.25 ! raeburn 638: $trouble=&Apache::lonlocal::mt('MySQL database apparently offline.').'<br />';
1.11 www 639: }
640: if ($host{$local.'_checkrpms_doomed'}>100) {
1.25 ! raeburn 641: $trouble=&Apache::lonlocal::mt('RPMs outdated.').'<br />';
1.22 www 642: }
643: if ($host{$local.'_reroute'}) {
1.25 ! raeburn 644: $trouble=&Apache::lonlocal::&mt('Rerouting').'<br >';
1.11 www 645: }
646: if ($trouble) { $count++; &serverstatus($local,$trouble); }
647: }
1.25 ! raeburn 648: unless ($count) { print &Apache::lonlocal::mt('No major trouble.'); }
1.9 www 649: }
1.16 www 650: }
651:
652: # ====================================================================== Status
653: sub statuslist {
654: my ($local,$what)=@_;
1.25 ! raeburn 655: my $displaylocal;
! 656: if (defined($local)) {
! 657: $displaylocal = " $local ($hostname{$local})";
! 658: }
! 659: print '<script>document.prgstat.progress.value="'.
! 660: &Apache::lonlocal::mt("Testing[_1]: $what",$displaylocal).'";</script>'."\n";
1.16 www 661: }
662:
663: # =============================================================================
664: # =============================================================================
665: # Main program
666: #
667: # ========================================================= Get form parameters
668: my $buffer;
669:
670: read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});
671: my @pairs=split(/&/,$buffer);
672: my $pair; my $name; my $value;
673: undef %FORM;
674: %FORM=();
675: foreach $pair (@pairs) {
676: ($name,$value) = split(/=/,$pair);
677: $value =~ tr/+/ /;
678: $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C",hex($1))/eg;
679: $FORM{$name}=$value;
680: }
681:
682: $buffer=$ENV{'QUERY_STRING'};
683: @pairs=split(/&/,$buffer);
684: foreach $pair (@pairs) {
685: ($name,$value) = split(/=/,$pair);
686: $value =~ tr/+/ /;
687: $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C",hex($1))/eg;
688: $FORM{$name}=$value;
689: }
690:
691: # ====================================================== Determine refresh rate
692:
693: my $refresh=(($FORM{'refresh'}=~/^\d+$/)?$FORM{'refresh'}:30);
694: if ($refresh<30) { $refresh=30; }
695: my $starttime=time;
696:
697: # ============================================================== Determine mode
698:
1.25 ! raeburn 699: my %modes= &Apache::lonlocal::texthash (
! 700: 'trouble' => 'Trouble',
! 701: 'users_doomed' => 'Doomed: Users',
! 702: 'loncron_doomed' => 'Doomed: General (loncron)',
! 703: 'mysql_doomed' => 'Doomed: Database (mysql)',
! 704: 'notconnected_doomed' => 'Doomed: Connections',
! 705: 'checkrpms_doomed' => 'Doomed: RPMs',
! 706: 'load_doomed' => 'Doomed: Load',
! 707: 'unresponsive_doomed' => 'Doomed: Status could not be determined',
! 708: 'users' => 'User Report',
! 709: 'load' => 'Load Report',
! 710: 'connections' => 'Connections Matrix');
1.16 www 711: $mode=$FORM{'mode'};
712: unless ($modes{$mode}) { $mode='trouble'; }
713: # ================================================================ Send Headers
1.25 ! raeburn 714: print("Content-type: text/html\n\n".
! 715: '<html><body bgcolor="#FFFFFF">'."\n");
1.16 www 716: # -------------------- Read loncapa.conf (and by default, loncapa_apache.conf).
717: my $perlvarref=LONCAPA::Configuration::read_conf('loncapa.conf');
718: %perlvar=%{$perlvarref};
719: undef $perlvarref; # remove since sensitive and not needed
720: delete $perlvar{'lonReceipt'}; # remove since sensitive and not needed
721: delete $perlvar{'lonSqlAccess'}; # remove since sensitive and not needed
722:
1.25 ! raeburn 723: if (!&LONCAPA::loncgi::check_cookie_and_load_env()) {
! 724: &Apache::lonlocal::get_language_handle();
! 725: print(&LONCAPA::loncgi::missing_cookie_msg());
! 726: exit;
! 727: }
! 728:
! 729: if (!&LONCAPA::loncgi::can_view('clusterstatus')) {
! 730: &Apache::lonlocal::get_language_handle();
! 731: print &LONCAPA::loncgi::unauthorized_msg('clusterstatus');
! 732: exit;
! 733: }
! 734:
! 735: &Apache::lonlocal::get_language_handle();
! 736:
! 737: my $scope = 'Domain';
! 738: if ($Apache::lonnet::env{'request.role'} =~ m{^su\./}) {
! 739: %hostname = %allhostname;
! 740: $scope = 'Cluster';
! 741: } else {
! 742: undef(%hostname);
! 743: my @poss_domains = &Apache::lonnet::current_machine_domains();
! 744: foreach my $host (keys(%allhostname)) {
! 745: if (grep(/^\Q$hostdom{$host}\E$/,@poss_domains)) {
! 746: $hostname{$host} = $allhostname{$host};
! 747: }
1.16 www 748: }
749: }
750:
1.25 ! raeburn 751: print '<img src="/adm/lonIcons/lonlogos.gif" align="right" /><h1>'.&Apache::lonlocal::mt("LON-CAPA $scope Status").' '.localtime()."</h1>";
1.16 www 752: print "<form name='prgstat'>\n".
1.25 ! raeburn 753: '<input type="text" name="progress" value="'."'".&Apache::lonlocal::mt('Starting ...')."'".'" size="100" /><br />'.
! 754: "</form>\n";
1.16 www 755: print "<form name='status' method='post'>\n";
1.25 ! raeburn 756: print &Apache::lonlocal::mt('Choose next report:').' '.&select_form($mode,'mode',%modes).'<input type="submit" name="getreport" value="'.&Apache::lonlocal::mt('Go').'" /><hr />';
1.16 www 757: &hidden('refresh',$refresh);
758:
759: if (!$FORM{'runonetime'}) {
1.25 ! raeburn 760: my $lcscope = lc($scope);
! 761: print '<h3>'.&Apache::lonlocal::mt("Gathering initial $lcscope data").'</h3>'.
! 762: &Apache::lonlocal::mt('This may take some time ..').'<br />';
1.16 www 763: $fromcache=0;
764: &mainloop();
1.25 ! raeburn 765: &statuslist(undef,'Done initial run.');
1.16 www 766: &reports();
767: } else {
768: $fromcache=1;
769: &mainloop();
1.25 ! raeburn 770: &statuslist(undef,'Done gathering cached data');
1.16 www 771: &reports();
772: $fromcache=0;
773: &mainloop();
774: }
775: &hidden('runonetime',1);
1.25 ! raeburn 776: print '<tt><br />'.&Apache::lonlocal::mt('Total number of queries: [_1]',$stat_total);
! 777: if ($stat_total != 0) {
! 778: print '<br />'.&Apache::lonlocal::mt('Percent complete:').''.
! 779: int(($stat_total-$stat_notyet)/$stat_total*100.).
! 780: '<br />'.&Apache::lonlocal::mt('Percent from cache:').' '.
! 781: int($stat_fromcache/$stat_total*100.).'</tt>';
! 782: }
1.16 www 783:
1.9 www 784: # ============================================================== Close, refresh
1.8 www 785: print "</form><script>";
1.16 www 786: my $runtime=time-$starttime;
787: if (($refresh-$runtime)<0) {
788: print "document.status.submit();";
1.8 www 789: } else {
1.16 www 790: my $refreshtime=int(1000*($refresh-$runtime));
1.25 ! raeburn 791: my $refreshmsg = &Apache::lonlocal::mt('Will automatically refresh ([_1] secs refresh cycle)',$refresh);
1.11 www 792: print "setTimeout('document.status.submit()',$refreshtime);\n".
1.25 ! raeburn 793: "document.prgstat.progress.value='$refreshmsg'";
1.2 www 794: }
1.8 www 795: print "</script></body></html>";
796: exit 0;
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>