Annotation of loncom/loncron, revision 1.67

1.1       albertel    1: #!/usr/bin/perl
                      2: 
1.47      albertel    3: # Housekeeping program, started by cron, loncontrol and loncron.pl
                      4: #
1.67    ! albertel    5: # $Id: loncron,v 1.66 2006/02/06 09:08:56 albertel Exp $
1.47      albertel    6: #
                      7: # Copyright Michigan State University Board of Trustees
                      8: #
                      9: # This file is part of the LearningOnline Network with CAPA (LON-CAPA).
                     10: #
                     11: # LON-CAPA is free software; you can redistribute it and/or modify
                     12: # it under the terms of the GNU General Public License as published by
                     13: # the Free Software Foundation; either version 2 of the License, or
                     14: # (at your option) any later version.
                     15: #
                     16: # LON-CAPA is distributed in the hope that it will be useful,
                     17: # but WITHOUT ANY WARRANTY; without even the implied warranty of
                     18: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                     19: # GNU General Public License for more details.
                     20: #
                     21: # You should have received a copy of the GNU General Public License
                     22: # along with LON-CAPA; if not, write to the Free Software
                     23: # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
                     24: #
                     25: # /home/httpd/html/adm/gpl.txt
                     26: #
                     27: # http://www.lon-capa.org/
1.1       albertel   28: #
1.24      www        29: 
                     30: $|=1;
1.48      albertel   31: use strict;
1.1       albertel   32: 
1.26      harris41   33: use lib '/home/httpd/lib/perl/';
                     34: use LONCAPA::Configuration;
                     35: 
1.1       albertel   36: use IO::File;
                     37: use IO::Socket;
1.48      albertel   38: use HTML::Entities;
1.49      albertel   39: use Getopt::Long;
1.46      albertel   40: #globals
                     41: use vars qw (%perlvar %simplestatus $errors $warnings $notices $totalcount);
                     42: 
                     43: my $statusdir="/home/httpd/html/lon-status";
                     44: 
1.1       albertel   45: 
                     46: # -------------------------------------------------- Non-critical communication
                     47: sub reply {
1.64      albertel   48:     my ($cmd,$server,$hostname)=@_;
                     49:     my $peerfile="$perlvar{'lonSockDir'}/".$hostname->{$server};
1.1       albertel   50:     my $client=IO::Socket::UNIX->new(Peer    =>"$peerfile",
                     51:                                      Type    => SOCK_STREAM,
                     52:                                      Timeout => 10)
                     53:        or return "con_lost";
1.64      albertel   54:     print $client "sethost:$server:$cmd\n";
1.1       albertel   55:     my $answer=<$client>;
                     56:     chomp($answer);
                     57:     if (!$answer) { $answer="con_lost"; }
                     58:     return $answer;
                     59: }
                     60: 
                     61: # --------------------------------------------------------- Output error status
                     62: 
1.46      albertel   63: sub log {
                     64:     my $fh=shift;
                     65:     if ($fh) {	print $fh @_  }
                     66: }
                     67: 
1.1       albertel   68: sub errout {
                     69:    my $fh=shift;
1.46      albertel   70:    &log($fh,(<<ENDERROUT));
1.48      albertel   71:      <table border="2" bgcolor="#CCCCCC">
1.1       albertel   72:      <tr><td>Notices</td><td>$notices</td></tr>
                     73:      <tr><td>Warnings</td><td>$warnings</td></tr>
                     74:      <tr><td>Errors</td><td>$errors</td></tr>
1.48      albertel   75:      </table><p><a href="#top">Top</a></p>
1.1       albertel   76: ENDERROUT
                     77: }
                     78: 
1.42      albertel   79: sub start_daemon {
1.50      albertel   80:     my ($fh,$daemon,$pidfile,$args) = @_;
1.44      albertel   81:     my $progname=$daemon;
1.50      albertel   82:     if ($daemon eq 'lonc' && $args eq 'new') {
1.44      albertel   83: 	$progname='loncnew'; 
                     84: 	print "new ";
                     85:     }
1.51      albertel   86:     my $error_fname="$perlvar{'lonDaemons'}/logs/${daemon}_errors";
                     87:     my $size=(stat($error_fname))[7];
                     88:     if ($size>40000) {
                     89: 	&log($fh,"<p>Rotating error logs ...</p>");
                     90: 	rename("$error_fname.2","$error_fname.3");
                     91: 	rename("$error_fname.1","$error_fname.2");
                     92: 	rename("$error_fname","$error_fname.1");
                     93:     }
                     94:     system("$perlvar{'lonDaemons'}/$progname 2>$perlvar{'lonDaemons'}/logs/${daemon}_errors");
1.60      albertel   95:     sleep 1;
1.42      albertel   96:     if (-e $pidfile) {
1.48      albertel   97: 	&log($fh,"<p>Seems like it started ...</p>");
1.42      albertel   98: 	my $lfh=IO::File->new("$pidfile");
                     99: 	my $daemonpid=<$lfh>;
                    100: 	chomp($daemonpid);
1.62      albertel  101: 	if ($daemonpid =~ /^\d+$/ && kill 0 => $daemonpid) {
1.42      albertel  102: 	    return 1;
                    103: 	} else {
                    104: 	    return 0;
                    105: 	}
                    106:     }
1.48      albertel  107:     &log($fh,"<p>Seems like that did not work!</p>");
1.42      albertel  108:     $errors++;
                    109:     return 0;
                    110: }
                    111: 
                    112: sub checkon_daemon {
1.59      albertel  113:     my ($fh,$daemon,$maxsize,$send,$args)=@_;
1.42      albertel  114: 
1.63      albertel  115:     my $result;
1.48      albertel  116:     &log($fh,'<hr /><a name="'.$daemon.'" /><h2>'.$daemon.'</h2><h3>Log</h3><p style="white-space: pre;"><tt>');
1.57      albertel  117:     printf("%-15s ",$daemon);
1.42      albertel  118:     if (-e "$perlvar{'lonDaemons'}/logs/$daemon.log"){
                    119: 	open (DFH,"tail -n25 $perlvar{'lonDaemons'}/logs/$daemon.log|");
1.46      albertel  120: 	while (my $line=<DFH>) { 
                    121: 	    &log($fh,"$line");
1.42      albertel  122: 	    if ($line=~/INFO/) { $notices++; }
                    123: 	    if ($line=~/WARNING/) { $notices++; }
                    124: 	    if ($line=~/CRITICAL/) { $warnings++; }
                    125: 	};
                    126: 	close (DFH);
                    127:     }
1.48      albertel  128:     &log($fh,"</tt></p>");
1.42      albertel  129:     
                    130:     my $pidfile="$perlvar{'lonDaemons'}/logs/$daemon.pid";
                    131:     
                    132:     my $restartflag=1;
1.46      albertel  133:     my $daemonpid;
1.42      albertel  134:     if (-e $pidfile) {
                    135: 	my $lfh=IO::File->new("$pidfile");
1.46      albertel  136: 	$daemonpid=<$lfh>;
1.42      albertel  137: 	chomp($daemonpid);
1.62      albertel  138: 	if ($daemonpid =~ /^\d+$/ && kill 0 => $daemonpid) {
1.46      albertel  139: 	    &log($fh,"<h3>$daemon at pid $daemonpid responding");
1.59      albertel  140: 	    if ($send) { &log($fh,", sending $send"); }
1.46      albertel  141: 	    &log($fh,"</h3>");
1.59      albertel  142: 	    if ($send eq 'USR1') { kill USR1 => $daemonpid; }
                    143: 	    if ($send eq 'USR2') { kill USR2 => $daemonpid; }
1.42      albertel  144: 	    $restartflag=0;
1.59      albertel  145: 	    if ($send eq 'USR2') {
1.63      albertel  146: 		$result = 'reloaded';
1.59      albertel  147: 		print "reloaded\n";
                    148: 	    } else {
1.63      albertel  149: 		$result = 'running';
1.59      albertel  150: 		print "running\n";
                    151: 	    }
1.42      albertel  152: 	} else {
                    153: 	    $errors++;
1.46      albertel  154: 	    &log($fh,"<h3>$daemon at pid $daemonpid not responding</h3>");
1.42      albertel  155: 	    $restartflag=1;
1.46      albertel  156: 	    &log($fh,"<h3>Decided to clean up stale .pid file and restart $daemon</h3>");
1.42      albertel  157: 	}
                    158:     }
                    159:     if ($restartflag==1) {
                    160: 	$simplestatus{$daemon}='off';
                    161: 	$errors++;
1.57      albertel  162: 	my $kadaemon=$daemon;
                    163: 	if ($kadaemon eq 'lonmemcached') { $kadaemon='memcached'; }
1.46      albertel  164: 	&log($fh,'<br><font color="red">Killall '.$daemon.': '.
1.57      albertel  165: 	    `killall $kadaemon 2>&1`.' - ');
1.60      albertel  166: 	sleep 1;
1.46      albertel  167: 	&log($fh,unlink($pidfile).' - '.
1.57      albertel  168: 	    `killall -9 $kadaemon 2>&1`.
1.46      albertel  169: 	    '</font><br>');
                    170: 	&log($fh,"<h3>$daemon not running, trying to start</h3>");
1.42      albertel  171: 	
1.50      albertel  172: 	if (&start_daemon($fh,$daemon,$pidfile,$args)) {
1.46      albertel  173: 	    &log($fh,"<h3>$daemon at pid $daemonpid responding</h3>");
1.42      albertel  174: 	    $simplestatus{$daemon}='restarted';
1.63      albertel  175: 	    $result = 'started';
1.42      albertel  176: 	    print "started\n";
                    177: 	} else {
                    178: 	    $errors++;
1.46      albertel  179: 	    &log($fh,"<h3>$daemon at pid $daemonpid not responding</h3>");
1.48      albertel  180: 	    &log($fh,"<p>Give it one more try ...</p>");
1.42      albertel  181: 	    print " ";
1.50      albertel  182: 	    if (&start_daemon($fh,$daemon,$pidfile,$args)) {
1.46      albertel  183: 		&log($fh,"<h3>$daemon at pid $daemonpid responding</h3>");
1.42      albertel  184: 		$simplestatus{$daemon}='restarted';
1.63      albertel  185: 		$result = 'started';
1.42      albertel  186: 		print "started\n";
                    187: 	    } else {
1.63      albertel  188: 		$result = 'failed';
1.42      albertel  189: 		print " failed\n";
                    190: 		$simplestatus{$daemon}='failed';
                    191: 		$errors++; $errors++;
1.46      albertel  192: 		&log($fh,"<h3>$daemon at pid $daemonpid not responding</h3>");
1.48      albertel  193: 		&log($fh,"<p>Unable to start $daemon</p>");
1.42      albertel  194: 	    }
                    195: 	}
                    196: 
                    197: 	if (-e "$perlvar{'lonDaemons'}/logs/$daemon.log"){
1.46      albertel  198: 	    &log($fh,"<p><pre>");
1.42      albertel  199: 	    open (DFH,"tail -n100 $perlvar{'lonDaemons'}/logs/$daemon.log|");
1.46      albertel  200: 	    while (my $line=<DFH>) { 
                    201: 		&log($fh,"$line");
1.42      albertel  202: 		if ($line=~/WARNING/) { $notices++; }
                    203: 		if ($line=~/CRITICAL/) { $notices++; }
                    204: 	    };
                    205: 	    close (DFH);
1.48      albertel  206: 	    &log($fh,"</pre></p>");
1.42      albertel  207: 	}
                    208:     }
                    209:     
1.46      albertel  210:     my $fname="$perlvar{'lonDaemons'}/logs/$daemon.log";
1.42      albertel  211:     
                    212:     my ($dev,$ino,$mode,$nlink,
                    213: 	$uid,$gid,$rdev,$size,
                    214: 	$atime,$mtime,$ctime,
                    215: 	$blksize,$blocks)=stat($fname);
                    216:     
                    217:     if ($size>$maxsize) {
1.48      albertel  218: 	&log($fh,"<p>Rotating logs ...</p>");
1.42      albertel  219: 	rename("$fname.2","$fname.3");
                    220: 	rename("$fname.1","$fname.2");
                    221: 	rename("$fname","$fname.1");
                    222:     }
                    223: 
                    224:     &errout($fh);
1.63      albertel  225:     return $result;
1.42      albertel  226: }
1.1       albertel  227: 
1.46      albertel  228: # --------------------------------------------------------------------- Machine
                    229: sub log_machine_info {
                    230:     my ($fh)=@_;
1.48      albertel  231:     &log($fh,'<hr /><a name="machine" /><h2>Machine Information</h2>');
1.46      albertel  232:     &log($fh,"<h3>loadavg</h3>");
                    233: 	
                    234:     open (LOADAVGH,"/proc/loadavg");
                    235:     my $loadavg=<LOADAVGH>;
                    236:     close (LOADAVGH);
                    237:     
                    238:     &log($fh,"<tt>$loadavg</tt>");
                    239:     
                    240:     my @parts=split(/\s+/,$loadavg);
                    241:     if ($parts[1]>4.0) {
                    242: 	$errors++;
                    243:     } elsif ($parts[1]>2.0) {
                    244: 	$warnings++;
                    245:     } elsif ($parts[1]>1.0) {
                    246: 	$notices++;
                    247:     }
1.13      harris41  248: 
1.46      albertel  249:     &log($fh,"<h3>df</h3>");
                    250:     &log($fh,"<pre>");
1.14      harris41  251: 
1.46      albertel  252:     open (DFH,"df|");
                    253:     while (my $line=<DFH>) { 
1.48      albertel  254: 	&log($fh,&encode_entities($line,'<>&"')); 
1.46      albertel  255: 	@parts=split(/\s+/,$line);
                    256: 	my $usage=$parts[4];
                    257: 	$usage=~s/\W//g;
                    258: 	if ($usage>90) { 
                    259: 	    $warnings++;
                    260: 	    $notices++; 
                    261: 	} elsif ($usage>80) {
                    262: 	    $warnings++;
                    263: 	} elsif ($usage>60) {
                    264: 	    $notices++;
1.31      albertel  265: 	}
1.46      albertel  266: 	if ($usage>95) { $warnings++; $warnings++; $simplestatus{'diskfull'}++; }
1.1       albertel  267:     }
1.46      albertel  268:     close (DFH);
                    269:     &log($fh,"</pre>");
1.1       albertel  270: 
                    271: 
1.46      albertel  272:     &log($fh,"<h3>ps</h3>");
                    273:     &log($fh,"<pre>");
                    274:     my $psproc=0;
1.1       albertel  275: 
1.53      albertel  276:     open (PSH,"ps aux --cols 140 |");
1.46      albertel  277:     while (my $line=<PSH>) { 
1.48      albertel  278: 	&log($fh,&encode_entities($line,'<>&"')); 
1.46      albertel  279: 	$psproc++;
                    280:     }
                    281:     close (PSH);
                    282:     &log($fh,"</pre>");
1.1       albertel  283: 
1.46      albertel  284:     if ($psproc>200) { $notices++; }
                    285:     if ($psproc>250) { $notices++; }
1.1       albertel  286: 
1.61      albertel  287:     &log($fh,"<h3>distprobe</h3>");
                    288:     &log($fh,"<pre>");
                    289:     open(DSH,"$perlvar{'lonDaemons'}/distprobe |");
                    290:     while (my $line=<DSH>) { 
                    291: 	&log($fh,&encode_entities($line,'<>&"')); 
                    292: 	$psproc++;
                    293:     }
                    294:     close(DSH);
                    295:     &log($fh,"</pre>");
                    296: 
1.46      albertel  297:     &errout($fh);
                    298: }
1.1       albertel  299: 
1.46      albertel  300: sub start_logging {
                    301:     my ($hostdom,$hostrole,$hostname,$spareid)=@_;
1.43      albertel  302:     my $fh=IO::File->new(">$statusdir/newstatus.html");
                    303:     my %simplestatus=();
1.46      albertel  304:     my $now=time;
                    305:     my $date=localtime($now);
1.43      albertel  306:     
1.46      albertel  307: 
                    308:     &log($fh,(<<ENDHEADERS));
1.1       albertel  309: <html>
                    310: <head>
                    311: <title>LON Status Report $perlvar{'lonHostID'}</title>
                    312: </head>
1.3       www       313: <body bgcolor="#AAAAAA">
1.48      albertel  314: <a name="top" />
1.1       albertel  315: <h1>LON Status Report $perlvar{'lonHostID'}</h1>
                    316: <h2>$date ($now)</h2>
                    317: <ol>
1.48      albertel  318: <li><a href="#configuration">Configuration</a></li>
                    319: <li><a href="#machine">Machine Information</a></li>
                    320: <li><a href="#tmp">Temporary Files</a></li>
                    321: <li><a href="#tokens">Session Tokens</a></li>
                    322: <li><a href="#httpd">httpd</a></li>
                    323: <li><a href="#lonsql">lonsql</a></li>
                    324: <li><a href="#lond">lond</a></li>
                    325: <li><a href="#lonc">lonc</a></li>
                    326: <li><a href="#lonhttpd">lonhttpd</a></li>
                    327: <li><a href="#lonnet">lonnet</a></li>
                    328: <li><a href="#connections">Connections</a></li>
                    329: <li><a href="#delayed">Delayed Messages</a></li>
                    330: <li><a href="#errcount">Error Count</a></li>
1.1       albertel  331: </ol>
1.48      albertel  332: <hr />
                    333: <a name="configuration" />
1.1       albertel  334: <h2>Configuration</h2>
                    335: <h3>PerlVars</h3>
1.48      albertel  336: <table border="2">
1.1       albertel  337: ENDHEADERS
                    338: 
1.46      albertel  339:     foreach my $varname (sort(keys(%perlvar))) {
1.48      albertel  340: 	&log($fh,"<tr><td>$varname</td><td>".
                    341: 	     &encode_entities($perlvar{$varname},'<>&"')."</td></tr>\n");
1.43      albertel  342:     }
1.48      albertel  343:     &log($fh,"</table><h3>Hosts</h3><table border='2'>");
1.46      albertel  344:     foreach my $id (sort(keys(%{$hostname}))) {
                    345: 	&log($fh,
                    346: 	    "<tr><td>$id</td><td>".$hostdom->{$id}.
                    347: 	    "</td><td>".$hostrole->{$id}.
                    348: 	    "</td><td>".$hostname->{$id}."</td></tr>\n");
                    349:     }
                    350:     &log($fh,"</table><h3>Spare Hosts</h3><ol>");
                    351:     foreach my $id (sort(keys(%{$spareid}))) {
1.48      albertel  352: 	&log($fh,"<li>$id\n</li>");
1.43      albertel  353:     }
1.46      albertel  354:     &log($fh,"</ol>\n");
                    355:     return $fh;
                    356: }
1.11      www       357: 
                    358: # --------------------------------------------------------------- clean out tmp
1.46      albertel  359: sub clean_tmp {
                    360:     my ($fh)=@_;
1.48      albertel  361:     &log($fh,'<hr /><a name="tmp" /><h2>Temporary Files</h2>');
1.46      albertel  362:     my $cleaned=0;
                    363:     my $old=0;
                    364:     while (my $fname=<$perlvar{'lonDaemons'}/tmp/*>) {
1.43      albertel  365: 	my ($dev,$ino,$mode,$nlink,
                    366: 	    $uid,$gid,$rdev,$size,
                    367: 	    $atime,$mtime,$ctime,
                    368: 	    $blksize,$blocks)=stat($fname);
1.46      albertel  369: 	my $now=time;
                    370: 	my $since=$now-$mtime;
1.43      albertel  371: 	if ($since>$perlvar{'lonExpire'}) {
1.46      albertel  372: 	    my $line='';
1.43      albertel  373: 	    if (open(PROBE,$fname)) {
                    374: 		$line=<PROBE>;
                    375: 		close(PROBE);
                    376: 	    }
                    377: 	    unless ($line=~/^CHECKOUTTOKEN\&/) {
                    378: 		$cleaned++;
                    379: 		unlink("$fname");
                    380: 	    } else {
                    381: 		if ($since>365*$perlvar{'lonExpire'}) {
                    382: 		    $cleaned++;
                    383: 		    unlink("$fname");
                    384: 		} else { $old++; }
                    385: 	    }
                    386: 	}
                    387:     }
1.46      albertel  388:     &log($fh,"Cleaned up ".$cleaned." files (".$old." old checkout tokens).");
                    389: }
1.11      www       390: 
                    391: # ------------------------------------------------------------ clean out lonIDs
1.46      albertel  392: sub clean_lonIDs {
                    393:     my ($fh)=@_;
1.48      albertel  394:     &log($fh,'<hr /><a name="tokens" /><h2>Session Tokens</h2>');
1.46      albertel  395:     my $cleaned=0;
                    396:     my $active=0;
                    397:     while (my $fname=<$perlvar{'lonIDsDir'}/*>) {
1.43      albertel  398: 	my ($dev,$ino,$mode,$nlink,
                    399: 	    $uid,$gid,$rdev,$size,
                    400: 	    $atime,$mtime,$ctime,
                    401: 	    $blksize,$blocks)=stat($fname);
1.46      albertel  402: 	my $now=time;
                    403: 	my $since=$now-$mtime;
1.43      albertel  404: 	if ($since>$perlvar{'lonExpire'}) {
                    405: 	    $cleaned++;
1.46      albertel  406: 	    &log($fh,"Unlinking $fname<br>");
1.43      albertel  407: 	    unlink("$fname");
                    408: 	} else {
                    409: 	    $active++;
                    410: 	}
1.46      albertel  411:     }
1.48      albertel  412:     &log($fh,"<p>Cleaned up ".$cleaned." stale session token(s).</p>");
1.46      albertel  413:     &log($fh,"<h3>$active open session(s)</h3>");
                    414: }
1.43      albertel  415: 
1.11      www       416: 
1.1       albertel  417: # ----------------------------------------------------------------------- httpd
1.46      albertel  418: sub check_httpd_logs {
                    419:     my ($fh)=@_;
1.48      albertel  420:     &log($fh,'<hr /><a name="httpd" /><h2>httpd</h2><h3>Access Log</h3><pre>');
1.43      albertel  421:     
                    422:     open (DFH,"tail -n25 /etc/httpd/logs/access_log|");
1.48      albertel  423:     while (my $line=<DFH>) { &log($fh,&encode_entities($line,'<>&"')) };
1.43      albertel  424:     close (DFH);
1.46      albertel  425: 	
                    426:     &log($fh,"</pre><h3>Error Log</h3><pre>");
                    427: 	
1.43      albertel  428:     open (DFH,"tail -n25 /etc/httpd/logs/error_log|");
1.46      albertel  429:     while (my $line=<DFH>) { 
                    430: 	&log($fh,"$line");
1.43      albertel  431: 	if ($line=~/\[error\]/) { $notices++; } 
1.46      albertel  432:     }
1.43      albertel  433:     close (DFH);
1.46      albertel  434:     &log($fh,"</pre>");
1.43      albertel  435:     &errout($fh);
1.46      albertel  436: }
1.1       albertel  437: 
                    438: # ---------------------------------------------------------------------- lonnet
                    439: 
1.48      albertel  440: sub rotate_lonnet_logs {
1.46      albertel  441:     my ($fh)=@_;
1.48      albertel  442:     &log($fh,'<hr /><a name="lonnet" /><h2>lonnet</h2><h3>Temp Log</h3><pre>');
1.43      albertel  443:     print "checking logs\n";
                    444:     if (-e "$perlvar{'lonDaemons'}/logs/lonnet.log"){
                    445: 	open (DFH,"tail -n50 $perlvar{'lonDaemons'}/logs/lonnet.log|");
1.46      albertel  446: 	while (my $line=<DFH>) { 
1.48      albertel  447: 	    &log($fh,&encode_entities($line,'<>&"'));
1.46      albertel  448: 	}
1.43      albertel  449: 	close (DFH);
                    450:     }
1.46      albertel  451:     &log($fh,"</pre><h3>Perm Log</h3><pre>");
1.43      albertel  452:     
                    453:     if (-e "$perlvar{'lonDaemons'}/logs/lonnet.perm.log") {
                    454: 	open(DFH,"tail -n10 $perlvar{'lonDaemons'}/logs/lonnet.perm.log|");
1.46      albertel  455: 	while (my $line=<DFH>) { 
1.48      albertel  456: 	    &log($fh,&encode_entities($line,'<>&"'));
1.46      albertel  457: 	}
1.43      albertel  458: 	close (DFH);
1.46      albertel  459:     } else { &log($fh,"No perm log\n") }
1.43      albertel  460: 
1.46      albertel  461:     my $fname="$perlvar{'lonDaemons'}/logs/lonnet.log";
1.43      albertel  462: 
                    463:     my ($dev,$ino,$mode,$nlink,
                    464: 	$uid,$gid,$rdev,$size,
                    465: 	$atime,$mtime,$ctime,
                    466: 	$blksize,$blocks)=stat($fname);
                    467: 
                    468:     if ($size>40000) {
1.48      albertel  469: 	&log($fh,"<p>Rotating logs ...</p>");
1.43      albertel  470: 	rename("$fname.2","$fname.3");
                    471: 	rename("$fname.1","$fname.2");
                    472: 	rename("$fname","$fname.1");
                    473:     }
1.1       albertel  474: 
1.46      albertel  475:     &log($fh,"</pre>");
1.43      albertel  476:     &errout($fh);
1.46      albertel  477: }
                    478: 
1.43      albertel  479: # ----------------------------------------------------------------- Connections
1.46      albertel  480: sub test_connections {
                    481:     my ($fh,$hostname)=@_;
1.48      albertel  482:     &log($fh,'<hr /><a name="connections" /><h2>Connections</h2>');
1.43      albertel  483:     print "testing connections\n";
1.48      albertel  484:     &log($fh,"<table border='2'>");
1.49      albertel  485:     my ($good,$bad)=(0,0);
1.46      albertel  486:     foreach my $tryserver (sort(keys(%{$hostname}))) {
1.43      albertel  487: 	print(".");
1.46      albertel  488: 	my $result;
1.64      albertel  489: 	my $answer=reply("ping",$tryserver,$hostname);
1.43      albertel  490: 	if ($answer eq "$tryserver:$perlvar{'lonHostID'}") {
                    491: 	    $result="<b>ok</b>";
1.49      albertel  492: 	    $good++;
1.43      albertel  493: 	} else {
                    494: 	    $result=$answer;
                    495: 	    $warnings++;
1.49      albertel  496: 	    if ($answer eq 'con_lost') {
                    497: 		$bad++;
                    498: 		$warnings++;
1.50      albertel  499: 	    } else {
                    500: 		$good++; #self connection
1.49      albertel  501: 	    }
1.43      albertel  502: 	}
                    503: 	if ($answer =~ /con_lost/) { print(" $tryserver down\n"); }
1.46      albertel  504: 	&log($fh,"<tr><td>$tryserver</td><td>$result</td></tr>\n");
1.1       albertel  505:     }
1.46      albertel  506:     &log($fh,"</table>");
1.49      albertel  507:     print "\n$good good, $bad bad connections\n";
1.43      albertel  508:     &errout($fh);
1.46      albertel  509: }
                    510: 
                    511: 
1.1       albertel  512: # ------------------------------------------------------------ Delayed messages
1.46      albertel  513: sub check_delayed_msg {
                    514:     my ($fh)=@_;
1.48      albertel  515:     &log($fh,'<hr /><a name="delayed" /><h2>Delayed Messages</h2>');
1.43      albertel  516:     print "checking buffers\n";
1.46      albertel  517:     
                    518:     &log($fh,'<h3>Scanning Permanent Log</h3>');
1.1       albertel  519: 
1.46      albertel  520:     my $unsend=0;
1.1       albertel  521: 
1.46      albertel  522:     my $dfh=IO::File->new("$perlvar{'lonDaemons'}/logs/lonnet.perm.log");
                    523:     while (my $line=<$dfh>) {
                    524: 	my ($time,$sdf,$dserv,$dcmd)=split(/:/,$line);
                    525: 	if ($sdf eq 'F') { 
                    526: 	    my $local=localtime($time);
                    527: 	    &log($fh,"<b>Failed: $time, $dserv, $dcmd</b><br>");
                    528: 	    $warnings++;
1.43      albertel  529: 	}
1.46      albertel  530: 	if ($sdf eq 'S') { $unsend--; }
                    531: 	if ($sdf eq 'D') { $unsend++; }
1.1       albertel  532:     }
1.46      albertel  533: 
1.48      albertel  534:     &log($fh,"<p>Total unsend messages: <b>$unsend</b></p>\n");
1.43      albertel  535:     $warnings=$warnings+5*$unsend;
1.1       albertel  536: 
1.43      albertel  537:     if ($unsend) { $simplestatus{'unsend'}=$unsend; }
1.48      albertel  538:     &log($fh,"<h3>Outgoing Buffer</h3>\n<pre>");
1.1       albertel  539: 
1.43      albertel  540:     open (DFH,"ls -lF $perlvar{'lonSockDir'}/delayed|");
1.46      albertel  541:     while (my $line=<DFH>) { 
1.48      albertel  542: 	&log($fh,&encode_entities($line,'<>&"'));
1.46      albertel  543:     }
1.48      albertel  544:     &log($fh,"</pre>\n");
1.43      albertel  545:     close (DFH);
1.46      albertel  546: }
1.1       albertel  547: 
1.46      albertel  548: sub finish_logging {
                    549:     my ($fh)=@_;
1.48      albertel  550:     &log($fh,"<a name='errcount' />\n");
1.43      albertel  551:     $totalcount=$notices+4*$warnings+100*$errors;
                    552:     &errout($fh);
1.46      albertel  553:     &log($fh,"<h1>Total Error Count: $totalcount</h1>");
                    554:     my $now=time;
                    555:     my $date=localtime($now);
1.48      albertel  556:     &log($fh,"<hr />$date ($now)</body></html>\n");
1.43      albertel  557:     print "lon-status webpage updated\n";
                    558:     $fh->close();
1.46      albertel  559: 
                    560:     if ($errors) { $simplestatus{'errors'}=$errors; }
                    561:     if ($warnings) { $simplestatus{'warnings'}=$warnings; }
                    562:     if ($notices) { $simplestatus{'notices'}=$notices; }
                    563:     $simplestatus{'time'}=time;
1.1       albertel  564: }
                    565: 
1.46      albertel  566: sub log_simplestatus {
                    567:     rename ("$statusdir/newstatus.html","$statusdir/index.html");
                    568:     
1.43      albertel  569:     my $sfh=IO::File->new(">$statusdir/loncron_simple.txt");
                    570:     foreach (keys %simplestatus) {
                    571: 	print $sfh $_.'='.$simplestatus{$_}.'&';
                    572:     }
                    573:     print $sfh "\n";
                    574:     $sfh->close();
1.41      www       575: }
1.46      albertel  576: 
                    577: sub send_mail {
1.43      albertel  578:     print "sending mail\n";
1.46      albertel  579:     my $emailto="$perlvar{'lonAdmEMail'}";
1.54      www       580:     if ($totalcount>2500) {
1.43      albertel  581: 	$emailto.=",$perlvar{'lonSysEMail'}";
                    582:     }
1.46      albertel  583:     my $subj="LON: $perlvar{'lonHostID'} E:$errors W:$warnings N:$notices"; 
1.52      albertel  584: 
1.58      albertel  585:     my $result=system("metasend -b -S 4000000 -t $emailto -s '$subj' -f $statusdir/index.html -m text/html >& /dev/null");
1.52      albertel  586:     if ($result != 0) {
                    587: 	$result=system("mail -s '$subj' $emailto < $statusdir/index.html");
                    588:     }
1.1       albertel  589: }
1.46      albertel  590: 
1.49      albertel  591: sub usage {
                    592:     print(<<USAGE);
                    593: loncron - housekeeping program that checks up on various parts of Lon-CAPA
                    594: 
                    595: Options:
                    596:    --help     Display help
                    597:    --oldlonc  When starting the lonc daemon use 'lonc' not 'loncnew'
                    598:    --noemail  Do not send the status email
                    599:    --justcheckconnections  Only check the current status of the lonc/d
                    600:                                 connections, do not send emails do not
                    601:                                 check if the daemons are running, do not
                    602:                                 generate lon-status
                    603:    --justcheckdaemons      Only check that all of the Lon-CAPA daemons are
                    604:                                 running, do not send emails do not
                    605:                                 check the lonc/d connections, do not
                    606:                                 generate lon-status
1.59      albertel  607:    --justreload            Only tell the daemons to reload the config files,
                    608: 				do not send emails do not
                    609:                                 check if the daemons are running, do not
                    610:                                 generate lon-status
1.49      albertel  611:                            
                    612: USAGE
                    613: }
                    614: 
1.46      albertel  615: # ================================================================ Main Program
                    616: sub main () {
1.59      albertel  617:     my ($oldlonc,$help,$justcheckdaemons,$noemail,$justcheckconnections,
                    618: 	$justreload);
1.49      albertel  619:     &GetOptions("help"                 => \$help,
                    620: 		"oldlonc"              => \$oldlonc,
                    621: 		"justcheckdaemons"     => \$justcheckdaemons,
                    622: 		"noemail"              => \$noemail,
1.59      albertel  623: 		"justcheckconnections" => \$justcheckconnections,
                    624: 		"justreload"           => \$justreload
1.49      albertel  625: 		);
                    626:     if ($help) { &usage(); return; }
1.46      albertel  627: # --------------------------------- Read loncapa_apache.conf and loncapa.conf
                    628:     my $perlvarref=LONCAPA::Configuration::read_conf('loncapa.conf');
                    629:     %perlvar=%{$perlvarref};
                    630:     undef $perlvarref;
                    631:     delete $perlvar{'lonReceipt'}; # remove since sensitive and not needed
                    632:     delete $perlvar{'lonSqlAccess'}; # remove since sensitive and not needed
                    633: 
                    634: # --------------------------------------- Make sure that LON-CAPA is configured
                    635: # I only test for one thing here (lonHostID).  This is just a safeguard.
                    636:     if ('{[[[[lonHostID]]]]}' eq $perlvar{'lonHostID'}) {
                    637: 	print("Unconfigured machine.\n");
                    638: 	my $emailto=$perlvar{'lonSysEMail'};
                    639: 	my $hostname=`/bin/hostname`;
                    640: 	chop $hostname;
                    641: 	$hostname=~s/[^\w\.]//g; # make sure is safe to pass through shell
                    642: 	my $subj="LON: Unconfigured machine $hostname";
                    643: 	system("echo 'Unconfigured machine $hostname.' |\
                    644:  mailto $emailto -s '$subj' > /dev/null");
                    645: 	exit 1;
                    646:     }
                    647: 
                    648: # ----------------------------- Make sure this process is running from user=www
                    649:     my $wwwid=getpwnam('www');
                    650:     if ($wwwid!=$<) {
                    651: 	print("User ID mismatch.  This program must be run as user 'www'\n");
                    652: 	my $emailto="$perlvar{'lonAdmEMail'},$perlvar{'lonSysEMail'}";
                    653: 	my $subj="LON: $perlvar{'lonHostID'} User ID mismatch";
                    654: 	system("echo 'User ID mismatch.  loncron must be run as user www.' |\
                    655:  mailto $emailto -s '$subj' > /dev/null");
                    656: 	exit 1;
                    657:     }
                    658: 
                    659: # ------------------------------------------------------------- Read hosts file
                    660:     my $config=IO::File->new("$perlvar{'lonTabDir'}/hosts.tab");
                    661:     
                    662:     my (%hostname,%hostdom,%hostrole,%spareid);
                    663:     while (my $configline=<$config>) {
1.49      albertel  664: 	next if ($configline =~ /^(\#|\s*\$)/);
1.56      albertel  665: 	my ($id,$domain,$role,$name)=split(/:/,$configline);
                    666: 	if ($id && $domain && $role && $name) {
                    667: 	    $name=~s/\s//g;
1.46      albertel  668: 	    $hostname{$id}=$name;
                    669: 	    $hostdom{$id}=$domain;
                    670: 	    $hostrole{$id}=$role;
                    671: 	}
                    672:     }
                    673:     undef $config;
                    674: 
                    675: # ------------------------------------------------------ Read spare server file
                    676:     $config=IO::File->new("$perlvar{'lonTabDir'}/spare.tab");
                    677:     
                    678:     while (my $configline=<$config>) {
                    679: 	chomp($configline);
                    680: 	if (($configline) && ($configline ne $perlvar{'lonHostID'})) {
                    681: 	    $spareid{$configline}=1;
                    682: 	}
                    683:     }
                    684:     undef $config;
                    685: 
                    686: # ---------------------------------------------------------------- Start report
                    687: 
                    688:     $errors=0;
                    689:     $warnings=0;
                    690:     $notices=0;
                    691: 
                    692: 	
1.49      albertel  693:     my $fh;
1.59      albertel  694:     if (!$justcheckdaemons && !$justcheckconnections && !$justreload) {
1.49      albertel  695: 	$fh=&start_logging(\%hostdom,\%hostrole,\%hostname,\%spareid);
                    696: 
                    697: 	&log_machine_info($fh);
                    698: 	&clean_tmp($fh);
                    699: 	&clean_lonIDs($fh);
                    700: 	&check_httpd_logs($fh);
                    701: 	&rotate_lonnet_logs($fh);
                    702:     }
1.59      albertel  703:     if (!$justcheckconnections && !$justreload) {
1.49      albertel  704: 	&checkon_daemon($fh,'lonsql',200000);
1.63      albertel  705: 	if ( &checkon_daemon($fh,'lond',40000,'USR1') eq 'running') {
                    706: 	    &checkon_daemon($fh,'lond',40000,'USR2');
                    707: 	}
1.50      albertel  708: 	my $args='new';
                    709: 	if ($oldlonc) { $args = ''; }
1.67    ! albertel  710: 	&checkon_daemon($fh,'lonc',40000,'USR1',$args);
1.49      albertel  711: 	&checkon_daemon($fh,'lonhttpd',40000);
1.57      albertel  712: 	&checkon_daemon($fh,'lonmemcached',40000);
1.49      albertel  713:     }
1.59      albertel  714:     if ($justreload) {
                    715: 	&checkon_daemon($fh,'lond',40000,'USR2');
                    716: 	my $args='new';
                    717: 	if ($oldlonc) { $args = ''; }
                    718: 	&checkon_daemon($fh,'lonc',40000,'USR2',$args);
                    719:     }
1.63      albertel  720:     if ($justcheckconnections) {
1.49      albertel  721: 	&test_connections($fh,\%hostname);
                    722:     }
1.59      albertel  723:     if (!$justcheckdaemons && !$justcheckconnections && !$justreload) {
1.49      albertel  724: 	&check_delayed_msg($fh);
                    725: 	&finish_logging($fh);
                    726: 	&log_simplestatus();
                    727: 	
                    728: 	if ($totalcount>200 && !$noemail) { &send_mail(); }
                    729:     }
1.46      albertel  730: }
                    731: 
                    732: &main();
1.1       albertel  733: 1;
                    734: 
                    735: 
                    736: 
                    737: 
                    738: 
                    739: 
                    740: 
                    741: 

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>
500 Internal Server Error

Internal Server Error

The server encountered an internal error or misconfiguration and was unable to complete your request.

Please contact the server administrator at root@localhost to inform them of the time this error occurred, and the actions you performed just before this error.

More information about this error may be available in the server error log.