Diff for /loncom/loncron between versions 1.22 and 1.103.2.1

version 1.22, 2001/08/27 13:54:50 version 1.103.2.1, 2017/10/20 13:38:34
Line 1 Line 1
 #!/usr/bin/perl  #!/usr/bin/perl
   
 # The LearningOnline Network  # Housekeeping program, started by cron, loncontrol and loncron.pl
 # Housekeeping program, started by cron  
 #  #
 # (TCP networking package  # $Id$
 # 6/1/99,6/2,6/10,6/11,6/12,6/14,6/26,6/28,6/29,6/30,  
 # 7/1,7/2,7/9,7/10,7/12 Gerd Kortemeyer)  
 #  #
 # 7/14,7/15,7/19,7/21,7/22,11/18,  # Copyright Michigan State University Board of Trustees
 # 2/8 Gerd Kortemeyer  #
 # 12/6/2000,12/8 Scott Harrison  # This file is part of the LearningOnline Network with CAPA (LON-CAPA).
 # 12/23 Gerd Kortemeyer  #
 # YEAR=2001  # LON-CAPA is free software; you can redistribute it and/or modify
 # 1/10/2001, 2/12/, 2/26, 3/15, 04/11, 04/21,8/27 Scott Harrison  # it under the terms of the GNU General Public License as published by
   # the Free Software Foundation; either version 2 of the License, or
   # (at your option) any later version.
   #
   # LON-CAPA is distributed in the hope that it will be useful,
   # but WITHOUT ANY WARRANTY; without even the implied warranty of
   # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   # GNU General Public License for more details.
   #
   # You should have received a copy of the GNU General Public License
   # along with LON-CAPA; if not, write to the Free Software
   # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   #
   # /home/httpd/html/adm/gpl.txt
   #
   # http://www.lon-capa.org/
   #
   
   $|=1;
   use strict;
   
   use lib '/home/httpd/lib/perl/';
   use LONCAPA::Configuration;
   use LONCAPA::Checksumming;
   use LONCAPA;
   use Apache::lonnet;
   use Apache::loncommon;
   
 use IO::File;  use IO::File;
 use IO::Socket;  use IO::Socket;
   use HTML::Entities;
   use Getopt::Long;
   #globals
   use vars qw (%perlvar %simplestatus $errors $warnings $notices $totalcount);
   
   my $statusdir="/home/httpd/html/lon-status";
   
 my $qflag=0;  
 if (@ARGV) {  
     my $arg=shift @ARGV;  
     $qflag=1 if $arg eq 'quick';  
 }  
   
 # -------------------------------------------------- Non-critical communication  
 sub reply {  
     my ($cmd,$server)=@_;  
     my $peerfile="$perlvar{'lonSockDir'}/$server";  
     my $client=IO::Socket::UNIX->new(Peer    =>"$peerfile",  
                                      Type    => SOCK_STREAM,  
                                      Timeout => 10)  
        or return "con_lost";  
     print $client "$cmd\n";  
     my $answer=<$client>;  
     chomp($answer);  
     if (!$answer) { $answer="con_lost"; }  
     return $answer;  
 }  
   
 # --------------------------------------------------------- Output error status  # --------------------------------------------------------- Output error status
   
   sub log {
       my $fh=shift;
       if ($fh) { print $fh @_  }
   }
   
 sub errout {  sub errout {
    my $fh=shift;     my $fh=shift;
    print $fh (<<ENDERROUT);     &log($fh,(<<ENDERROUT));
      <p><table border=2 bgcolor="#CCCCCC">       <table border="2" bgcolor="#CCCCCC">
      <tr><td>Notices</td><td>$notices</td></tr>       <tr><td>Notices</td><td>$notices</td></tr>
      <tr><td>Warnings</td><td>$warnings</td></tr>       <tr><td>Warnings</td><td>$warnings</td></tr>
      <tr><td>Errors</td><td>$errors</td></tr>       <tr><td>Errors</td><td>$errors</td></tr>
      </table><p><a href="#top">Top</a><p>       </table><p><a href="#top">Top</a></p>
 ENDERROUT  ENDERROUT
 }  }
   
 # ================================================================ Main Program  sub rotate_logfile {
       my ($file,$fh,$description) = @_;
       my $size=(stat($file))[7];
       if ($size>40000) {
    &log($fh,"<p>Rotating $description ...</p>");
    rename("$file.2","$file.3");
    rename("$file.1","$file.2");
    rename("$file","$file.1");
       } 
   }
   
 # ------------------------------------------------------------ Read access.conf  sub start_daemon {
 {      my ($fh,$daemon,$pidfile,$args) = @_;
     my $config=IO::File->new("/etc/httpd/conf/access.conf");      my $progname=$daemon;
       if ($daemon eq 'lonc') {
     while (my $configline=<$config>) {   $progname='loncnew'; 
         if ($configline =~ /PerlSetVar/) {  
    my ($dummy,$varname,$varvalue)=split(/\s+/,$configline);  
            $perlvar{$varname}=$varvalue;  
         }  
     }      }
     delete $perlvar{'lonReceipt'}; # remove since sensitive and not needed      my $error_fname="$perlvar{'lonDaemons'}/logs/${daemon}_errors";
     delete $perlvar{'lonSqlAccess'}; # remove since sensitive and not needed      &rotate_logfile($error_fname,$fh,'error logs');
       if ($daemon eq 'lonc') {
    &clean_sockets($fh);
       }
       system("$perlvar{'lonDaemons'}/$progname 2>$perlvar{'lonDaemons'}/logs/${daemon}_errors");
       sleep 1;
       if (-e $pidfile) {
    &log($fh,"<p>Seems like it started ...</p>");
    my $lfh=IO::File->new("$pidfile");
    my $daemonpid=<$lfh>;
    chomp($daemonpid);
    if ($daemonpid =~ /^\d+$/ && kill 0 => $daemonpid) {
       return 1;
    } else {
       return 0;
    }
       }
       &log($fh,"<p>Seems like that did not work!</p>");
       $errors++;
       return 0;
 }  }
   
 # --------------------------------------- Make sure that LON-CAPA is configured  sub checkon_daemon {
 # I only test for one thing here (lonHostID).  This is just a safeguard.      my ($fh,$daemon,$maxsize,$send,$args)=@_;
 if ('{[[[[lonHostID]]]]}' eq $perlvar{'lonHostID'}) {  
    print("Unconfigured machine.\n");  
    $emailto=$perlvar{'lonSysEMail'};  
    $hostname=`/bin/hostname`;  
    chop $hostname;  
    $hostname=~s/[^\w\.]//g; # make sure is safe to pass through shell  
    $subj="LON: Unconfigured machine $hostname";  
    system("echo 'Unconfigured machine $hostname.' |\  
  mailto $emailto -s '$subj' > /dev/null");  
     exit 1;  
 }  
   
 # ----------------------------- Make sure this process is running from user=www      my $result;
 my $wwwid=getpwnam('www');      &log($fh,'<hr /><a name="'.$daemon.'" /><h2>'.$daemon.'</h2><h3>Log</h3><p style="white-space: pre;"><tt>');
 if ($wwwid!=$<) {      printf("%-15s ",$daemon);
    print("User ID mismatch.  This program must be run as user 'www'\n");      if (-e "$perlvar{'lonDaemons'}/logs/$daemon.log"){
    $emailto="$perlvar{'lonAdmEMail'},$perlvar{'lonSysEMail'}";   open (DFH,"tail -n25 $perlvar{'lonDaemons'}/logs/$daemon.log|");
    $subj="LON: $perlvar{'lonHostID'} User ID mismatch";   while (my $line=<DFH>) { 
    system("echo 'User ID mismatch.  loncron must be run as user www.' |\      &log($fh,"$line");
  mailto $emailto -s '$subj' > /dev/null");      if ($line=~/INFO/) { $notices++; }
    exit 1;      if ($line=~/WARNING/) { $notices++; }
 }      if ($line=~/CRITICAL/) { $warnings++; }
    };
    close (DFH);
       }
       &log($fh,"</tt></p>");
       
       my $pidfile="$perlvar{'lonDaemons'}/logs/$daemon.pid";
       
       my $restartflag=1;
       my $daemonpid;
       if (-e $pidfile) {
    my $lfh=IO::File->new("$pidfile");
    $daemonpid=<$lfh>;
    chomp($daemonpid);
    if ($daemonpid =~ /^\d+$/ && kill 0 => $daemonpid) {
       &log($fh,"<h3>$daemon at pid $daemonpid responding");
       if ($send) { &log($fh,", sending $send"); }
       &log($fh,"</h3>");
       if ($send eq 'USR1') { kill USR1 => $daemonpid; }
       if ($send eq 'USR2') { kill USR2 => $daemonpid; }
       $restartflag=0;
       if ($send eq 'USR2') {
    $result = 'reloaded';
    print "reloaded\n";
       } else {
    $result = 'running';
    print "running\n";
       }
    } else {
       $errors++;
       &log($fh,"<h3>$daemon at pid $daemonpid not responding</h3>");
       $restartflag=1;
       &log($fh,"<h3>Decided to clean up stale .pid file and restart $daemon</h3>");
    }
       }
       if ($restartflag==1) {
    $simplestatus{$daemon}='off';
    $errors++;
    my $kadaemon=$daemon;
    if ($kadaemon eq 'lonmemcached') { $kadaemon='memcached'; }
    &log($fh,'<br /><font color="red">Killall '.$daemon.': '.
       `killall $kadaemon 2>&1`.' - ');
    sleep 1;
    &log($fh,unlink($pidfile).' - '.
       `killall -9 $kadaemon 2>&1`.
       '</font><br />');
    &log($fh,"<h3>$daemon not running, trying to start</h3>");
   
    if (&start_daemon($fh,$daemon,$pidfile,$args)) {
       &log($fh,"<h3>$daemon at pid $daemonpid responding</h3>");
       $simplestatus{$daemon}='restarted';
       $result = 'started';
       print "started\n";
    } else {
       $errors++;
       &log($fh,"<h3>$daemon at pid $daemonpid not responding</h3>");
       &log($fh,"<p>Give it one more try ...</p>");
       print " ";
       if (&start_daemon($fh,$daemon,$pidfile,$args)) {
    &log($fh,"<h3>$daemon at pid $daemonpid responding</h3>");
    $simplestatus{$daemon}='restarted';
    $result = 'started';
    print "started\n";
       } else {
    $result = 'failed';
    print " failed\n";
    $simplestatus{$daemon}='failed';
    $errors++; $errors++;
    &log($fh,"<h3>$daemon at pid $daemonpid not responding</h3>");
    &log($fh,"<p>Unable to start $daemon</p>");
       }
    }
   
 # ------------------------------------------------------------- Read hosts file   if (-e "$perlvar{'lonDaemons'}/logs/$daemon.log"){
 {      &log($fh,"<p><pre>");
     my $config=IO::File->new("$perlvar{'lonTabDir'}/hosts.tab");      open (DFH,"tail -n100 $perlvar{'lonDaemons'}/logs/$daemon.log|");
       while (my $line=<DFH>) { 
     while (my $configline=<$config>) {   &log($fh,"$line");
        my ($id,$domain,$role,$name,$ip)=split(/:/,$configline);   if ($line=~/WARNING/) { $notices++; }
        $hostname{$id}=$name;   if ($line=~/CRITICAL/) { $notices++; }
        $hostdom{$id}=$domain;      };
        $hostrole{$id}=$role;      close (DFH);
        $hostip{$id}=$ip;      &log($fh,"</pre></p>");
        if (($role eq 'library') && ($id ne $perlvar{'lonHostID'})) {   }
    $libserv{$id}=$name;  
        }  
     }      }
       
       my $fname="$perlvar{'lonDaemons'}/logs/$daemon.log";
       &rotate_logfile($fname,$fh,'logs');
   
       &errout($fh);
       return $result;
 }  }
   
 # ------------------------------------------------------ Read spare server file  # --------------------------------------------------------------------- Machine
 {  sub log_machine_info {
     my $config=IO::File->new("$perlvar{'lonTabDir'}/spare.tab");      my ($fh)=@_;
       &log($fh,'<hr /><a name="machine" /><h2>Machine Information</h2>');
     while (my $configline=<$config>) {      &log($fh,"<h3>loadavg</h3>");
        chomp($configline);  
        if (($configline) && ($configline ne $perlvar{'lonHostID'})) {      open (LOADAVGH,"/proc/loadavg");
           $spareid{$configline}=1;      my $loadavg=<LOADAVGH>;
        }      close (LOADAVGH);
       
       &log($fh,"<tt>$loadavg</tt>");
       
       my @parts=split(/\s+/,$loadavg);
       if ($parts[1]>4.0) {
    $errors++;
       } elsif ($parts[1]>2.0) {
    $warnings++;
       } elsif ($parts[1]>1.0) {
    $notices++;
     }      }
 }  
   
 # ---------------------------------------------------------------- Start report      &log($fh,"<h3>df</h3>");
       &log($fh,"<pre>");
   
       open (DFH,"df|");
       while (my $line=<DFH>) { 
    &log($fh,&encode_entities($line,'<>&"')); 
    @parts=split(/\s+/,$line);
    my $usage=$parts[4];
    $usage=~s/\W//g;
    if ($usage>90) { 
       $warnings++;
       $notices++; 
    } elsif ($usage>80) {
       $warnings++;
    } elsif ($usage>60) {
       $notices++;
    }
    if ($usage>95) { $warnings++; $warnings++; $simplestatus{'diskfull'}++; }
       }
       close (DFH);
       &log($fh,"</pre>");
   
 $statusdir="/home/httpd/html/lon-status";  
   
 $errors=0;      &log($fh,"<h3>ps</h3>");
 $warnings=0;      &log($fh,"<pre>");
 $notices=0;      my $psproc=0;
   
 $now=time;      open (PSH,"ps aux --cols 140 |");
 $date=localtime($now);      while (my $line=<PSH>) { 
    &log($fh,&encode_entities($line,'<>&"')); 
    $psproc++;
       }
       close (PSH);
       &log($fh,"</pre>");
   
 {      if ($psproc>200) { $notices++; }
 my $fh=IO::File->new(">$statusdir/newstatus.html");      if ($psproc>250) { $notices++; }
   
 print $fh (<<ENDHEADERS);      &log($fh,"<h3>distprobe</h3>");
 <html>      &log($fh,"<pre>");
       &log($fh,&encode_entities(&LONCAPA::distro(),'<>&"'));
       &log($fh,"</pre>");
   
       &errout($fh);
   }
   
   sub start_logging {
       my $fh=IO::File->new(">$statusdir/newstatus.html");
       my %simplestatus=();
       my $now=time;
       my $date=localtime($now);
       
   
       &log($fh,(<<ENDHEADERS));
   <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
   <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
 <head>  <head>
 <title>LON Status Report $perlvar{'lonHostID'}</title>  <title>LON Status Report $perlvar{'lonHostID'}</title>
   <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
 </head>  </head>
 <body bgcolor="#AAAAAA">  <body bgcolor="#AAAAAA">
 <a name="top">  <a name="top" />
 <h1>LON Status Report $perlvar{'lonHostID'}</h1>  <h1>LON Status Report $perlvar{'lonHostID'}</h1>
 <h2>$date ($now)</h2>  <h2>$date ($now)</h2>
 <ol>  <ol>
 <li><a href="#configuration">Configuration</a>  <li><a href="#configuration">Configuration</a></li>
 <li><a href="#machine">Machine Information</a>  <li><a href="#machine">Machine Information</a></li>
 <li><a href="#tmp">Temporary Files</a>  <li><a href="#tmp">Temporary Files</a></li>
 <li><a href="#tokens">Session Tokens</a>  <li><a href="#tokens">Session Tokens</a></li>
 <li><a href="#httpd">httpd</a>  <li><a href="#webdav">WebDAV Session Tokens</a></li>
 <li><a href="#lonsql">lonsql</a>  <li><a href="#httpd">httpd</a></li>
 <li><a href="#lond">lond</a>  <li><a href="#lonsql">lonsql</a></li>
 <li><a href="#lonc">lonc</a>  <li><a href="#lond">lond</a></li>
 <li><a href="#lonnet">lonnet</a>  <li><a href="#lonc">lonc</a></li>
 <li><a href="#connections">Connections</a>  <li><a href="#lonnet">lonnet</a></li>
 <li><a href="#delayed">Delayed Messages</a>  <li><a href="#connections">Connections</a></li>
 <li><a href="#errcount">Error Count</a>  <li><a href="#delayed">Delayed Messages</a></li>
   <li><a href="#errcount">Error Count</a></li>
 </ol>  </ol>
 <hr>  <hr />
 <a name="configuration">  <a name="configuration" />
 <h2>Configuration</h2>  <h2>Configuration</h2>
 <h3>PerlVars</h3>  <h3>PerlVars</h3>
 <table border=2>  <table border="2">
 ENDHEADERS  ENDHEADERS
   
 foreach $varname (keys %perlvar) {      foreach my $varname (sort(keys(%perlvar))) {
     print $fh "<tr><td>$varname</td><td>$perlvar{$varname}</td></tr>\n";   &log($fh,"<tr><td>$varname</td><td>".
 }       &encode_entities($perlvar{$varname},'<>&"')."</td></tr>\n");
 print $fh "</table><h3>Hosts</h3><table border=2>";      }
 foreach $id (keys %hostname) {      &log($fh,"</table><h3>Hosts</h3><table border='2'>");
 print $fh       my %hostname = &Apache::lonnet::all_hostnames();
     "<tr><td>$id</td><td>$hostdom{$id}</td><td>$hostrole{$id}</td>";      foreach my $id (sort(keys(%hostname))) {
 print $fh "<td>$hostname{$id}</td><td>$hostip{$id}</td></tr>\n";   my $role = (&Apache::lonnet::is_library($id) ? 'library'
 }                                       : 'access');
 print $fh "</table><h3>Spare Hosts</h3><ol>";   &log($fh,
 foreach $id (keys %spareid) {      "<tr><td>$id</td><td>".&Apache::lonnet::host_domain($id).
     print $fh "<li>$id\n";      "</td><td>".$role.
       "</td><td>".&Apache::lonnet::hostname($id)."</td></tr>\n");
       }
       &log($fh,"</table><h3>Spare Hosts</h3>");
       if (keys(%Apache::lonnet::spareid) > 0) {
           &log($fh,"<ul>");
           foreach my $type (sort(keys(%Apache::lonnet::spareid))) {
       &log($fh,"<li>$type\n<ol>");
       foreach my $id (@{ $Apache::lonnet::spareid{$type} }) {
           &log($fh,"<li>$id</li>\n");
       }
       &log($fh,"</ol>\n</li>\n");
           }
           &log($fh,"</ul>\n");
       } else {
           &log($fh,"No spare hosts specified<br />\n");
       }
       return $fh;
 }  }
   
 print $fh "</ol>\n";  
   
 # --------------------------------------------------------------------- Machine  
   
 print $fh '<hr><a name="machine"><h2>Machine Information</h2>';  
 print $fh "<h3>loadavg</h3>";  
   
 open (LOADAVGH,"/proc/loadavg");  
 $loadavg=<LOADAVGH>;  
 close (LOADAVGH);  
   
 print $fh "<tt>$loadavg</tt>";  
   
 @parts=split(/\s+/,$loadavg);  
 if ($parts[1]>4.0) {  
     $errors++;  
 } elsif ($parts[1]>2.0) {  
     $warnings++;  
 } elsif ($parts[1]>1.0) {  
     $notices++;  
 }  
   
 print $fh "<h3>df</h3>";  
 print $fh "<pre>";  
   
 open (DFH,"df|");  
 while ($line=<DFH>) {   
    print $fh "$line";   
    @parts=split(/\s+/,$line);  
    $usage=$parts[4];  
    $usage=~s/\W//g;  
    if ($usage>90) {   
       $warnings++;   
    } elsif ($usage>80) {  
       $warnings++;  
    } elsif ($usage>60) {  
       $notices++;  
    }  
    if ($usage>95) { $warnings++; $warnings++ }  
 }  
 close (DFH);  
 print $fh "</pre>";  
 &errout($fh);  
   
 # --------------------------------------------------------------- clean out tmp  # --------------------------------------------------------------- clean out tmp
 print $fh '<hr><a name="tmp"><h2>Temporary Files</h2>';  sub clean_tmp {
 $cleaned=0;      my ($fh)=@_;
 while ($fname=<$perlvar{'lonDaemons'}/tmp/*>) {      &log($fh,'<hr /><a name="tmp" /><h2>Temporary Files</h2>');
                           my ($dev,$ino,$mode,$nlink,      my ($cleaned,$old,$removed) = (0,0,0);
                               $uid,$gid,$rdev,$size,      my %errors = (
                               $atime,$mtime,$ctime,                       dir       => [],
                               $blksize,$blocks)=stat($fname);                       file      => [],
                           $now=time;                       failopen  => [],
                           $since=$now-$mtime;                   );
                           if ($since>$perlvar{'lonExpire'}) {      my %error_titles = (
                               $cleaned++;                           dir       => 'failed to remove empty directory:',
                               unlink("$fname");                           file      => 'failed to unlike stale file',
                           }                           failopen  => 'failed to open file or directory'
                              );
       ($cleaned,$old,$removed) = &recursive_clean_tmp('',$cleaned,$old,$removed,\%errors);
       &log($fh,"Cleaned up: ".$cleaned." files; removed: $removed empty directories; (found: $old old checkout tokens)");
       foreach my $key (sort(keys(%errors))) {
           if (ref($errors{$key}) eq 'ARRAY') {
               if (@{$errors{$key}} > 0) {
                   &log($fh,"Error during cleanup ($error_titles{$key}):<ul><li>".
                        join('</li><li><tt>',@{$errors{$key}}).'</tt></li></ul><br />');
               }
           }
       }
 }  }
 print $fh "Cleaned up ".$cleaned." files.";  
   
 # ------------------------------------------------------------ clean out lonIDs  sub recursive_clean_tmp {
 print $fh '<hr><a name="tokens"><h2>Session Tokens</h2>';      my ($subdir,$cleaned,$old,$removed,$errors) = @_;
 $cleaned=0;      my $base = "$perlvar{'lonDaemons'}/tmp";
 $active=0;      my $path = $base;
 while ($fname=<$perlvar{'lonIDsDir'}/*>) {      next if ($subdir =~ m{\.\./});
                           my ($dev,$ino,$mode,$nlink,      next unless (ref($errors) eq 'HASH');
                               $uid,$gid,$rdev,$size,      unless ($subdir eq '') {
                               $atime,$mtime,$ctime,          $path .= '/'.$subdir;
                               $blksize,$blocks)=stat($fname);      }
                           $now=time;      if (opendir(my $dh,"$path")) {
                           $since=$now-$mtime;          while (my $file = readdir($dh)) {
                           if ($since>$perlvar{'lonExpire'}) {              next if ($file =~ /^\.\.?$/);
                               $cleaned++;              my $fname = "$path/$file";
                               print $fh "Unlinking $fname<br>";              if (-d $fname) {
                               unlink("$fname");                  my $innerdir;
                           } else {                  if ($subdir eq '') {
                               $active++;                      $innerdir = $file;
                           }                  } else {
                           $innerdir = $subdir.'/'.$file;
                   }
                   ($cleaned,$old,$removed) = 
                        &recursive_clean_tmp($innerdir,$cleaned,$old,$removed,$errors);
                   my @doms = &Apache::lonnet::current_machine_domains();
                   
                   if (open(my $dirhandle,$fname)) {
                       unless (($innerdir eq 'helprequests') ||
                               (($innerdir =~ /^addcourse/) && ($innerdir !~ m{/\d+$}))) {
                           my @contents = grep {!/^\.\.?$/} readdir($dirhandle);
                                         join('&&',@contents)."\n";    
                           if (scalar(grep {!/^\.\.?$/} readdir($dirhandle)) == 0) {
                               closedir($dirhandle);
                               if ($fname =~ m{^\Q$perlvar{'lonDaemons'}\E/tmp/}) {
                                   if (rmdir($fname)) {
                                       $removed ++;
                                   } elsif (ref($errors->{dir}) eq 'ARRAY') {
                                       push(@{$errors->{dir}},$fname);
                                   }
                               }
                           }
                       } else {
                           closedir($dirhandle);
                       }
                   }
               } else {
                   my ($dev,$ino,$mode,$nlink,
                       $uid,$gid,$rdev,$size,
                       $atime,$mtime,$ctime,
                       $blksize,$blocks)=stat($fname);
                   my $now=time;
                   my $since=$now-$mtime;
                   if ($since>$perlvar{'lonExpire'}) {
                       if ($subdir eq '') {
                           my $line='';
                           if ($fname =~ /\.db$/) {
                               if (unlink($fname)) {
                                   $cleaned++;
                               } elsif (ref($errors->{file}) eq 'ARRAY') {
                                   push(@{$errors->{file}},$fname);
                               }
                           } elsif (open(PROBE,$fname)) {
                               my $line='';
                               $line=<PROBE>;
                               close(PROBE);
                               if ($line=~/^CHECKOUTTOKEN\&/) {
                                   if ($since>365*$perlvar{'lonExpire'}) {
                                       if (unlink($fname)) {
                                           $cleaned++; 
                                       } elsif (ref($errors->{file}) eq 'ARRAY') {
                                           push(@{$errors->{file}},$fname);
                                       }
                                   } else {
                                       $old++;
                                   }
                               } else {
                                   if (unlink($fname)) {
                                       $cleaned++;
                                   } elsif (ref($errors->{file}) eq 'ARRAY') {
                                       push(@{$errors->{file}},$fname);
                                   }
                               }
                           } elsif (ref($errors->{failopen}) eq 'ARRAY') {
                               push(@{$errors->{failopen}},$fname); 
                           }
                       } else {
                           if (unlink($fname)) {
                               $cleaned++;
                           } elsif (ref($errors->{file}) eq 'ARRAY') {
                               push(@{$errors->{file}},$fname);
                           }
                       }
                   }
               }
           }
           closedir($dh);
       } elsif (ref($errors->{failopen}) eq 'ARRAY') {
           push(@{$errors->{failopen}},$path);
       }
       return ($cleaned,$old,$removed);
 }  }
 print $fh "<p>Cleaned up ".$cleaned." stale session token(s).";  
 print $fh "<h3>$active open session(s)</h3>";  
   
 # ----------------------------------------------------------------------- httpd  
   
 print $fh '<hr><a name="httpd"><h2>httpd</h2><h3>Access Log</h3><pre>';  
   
 open (DFH,"tail -n40 /etc/httpd/logs/access_log|");  # ------------------------------------------------------------ clean out lonIDs
 while ($line=<DFH>) { print $fh "$line" };  sub clean_lonIDs {
 close (DFH);      my ($fh)=@_;
       &log($fh,'<hr /><a name="tokens" /><h2>Session Tokens</h2>');
       my $cleaned=0;
       my $active=0;
       while (my $fname=<$perlvar{'lonIDsDir'}/*>) {
    my ($dev,$ino,$mode,$nlink,
       $uid,$gid,$rdev,$size,
       $atime,$mtime,$ctime,
       $blksize,$blocks)=stat($fname);
    my $now=time;
    my $since=$now-$mtime;
    if ($since>$perlvar{'lonExpire'}) {
       $cleaned++;
       &log($fh,"Unlinking $fname<br />");
       unlink("$fname");
    } else {
       $active++;
    }
       }
       &log($fh,"<p>Cleaned up ".$cleaned." stale session token(s).</p>");
       &log($fh,"<h3>$active open session(s)</h3>");
   }
   
 print $fh "</pre><h3>Error Log</h3><pre>";  # ------------------------------------------------ clean out webDAV Session IDs
   sub clean_webDAV_sessionIDs {
       my ($fh)=@_;
       if ($perlvar{'lonRole'} eq 'library') {
           &log($fh,'<hr /><a name="webdav" /><h2>WebDAV Session Tokens</h2>');
           my $cleaned=0;
           my $active=0;
           my $now = time;
           if (-d $perlvar{'lonDAVsessDir'}) {
               while (my $fname=<$perlvar{'lonDAVsessDir'}/*>) {
                   my @stats = stat($fname);
                   my $since=$now-$stats[9];
                   if ($since>$perlvar{'lonExpire'}) {
                       $cleaned++;
                       &log($fh,"Unlinking $fname<br />");
                       unlink("$fname");
                   } else {
                       $active++;
                   }
               }
               &log($fh,"<p>Cleaned up ".$cleaned." stale webDAV session token(s).</p>");
               &log($fh,"<h3>$active open webDAV session(s)</h3>");
           }
       }
   }
   
 open (DFH,"tail -n50 /etc/httpd/logs/error_log|");  # ----------------------------------------------------------- clean out sockets
 while ($line=<DFH>) {   sub clean_sockets {
    print $fh "$line";      my ($fh)=@_;
    if ($line=~/\[error\]/) { $notices++; }       my $cleaned=0;
 };      opendir(SOCKETS,$perlvar{'lonSockDir'});
 close (DFH);      while (my $fname=readdir(SOCKETS)) {
 print $fh "</pre>";   next if (-d $fname 
 &errout($fh);   || $fname=~/(mysqlsock|maximasock|rsock|\Q$perlvar{'lonSockDir'}\E)/);
    $cleaned++;
    &log($fh,"Unlinking $fname<br />");
    unlink("/home/httpd/sockets/$fname");
       }
       &log($fh,"<p>Cleaned up ".$cleaned." stale sockets.</p>");
   }
   
   
 # ---------------------------------------------------------------------- lonsql  # ----------------------------------------------------------------------- httpd
   sub check_httpd_logs {
       my ($fh)=@_;
       if (open(PIPE,"./lchttpdlogs|")) {
           while (my $line=<PIPE>) {
               &log($fh,$line);
               if ($line=~/\[error\]/) { $notices++; }
           }
           close(PIPE);
       }
       &errout($fh);
   }
   
 my $restartflag=1;  # ---------------------------------------------------------------------- lonnet
 if ($perlvar{'lonRole'} eq "library") {  
   
     print $fh '<hr><a name="lonsql"><h2>lonsql</h2><h3>Log</h3><pre>';  sub rotate_lonnet_logs {
           my ($fh)=@_;
     if (-e "$perlvar{'lonDaemons'}/logs/lonsql.log"){      &log($fh,'<hr /><a name="lonnet" /><h2>lonnet</h2><h3>Temp Log</h3><pre>');
  open (DFH,"tail -n100 $perlvar{'lonDaemons'}/logs/lonsql.log|");      print "Checking logs.\n";
  while ($line=<DFH>) {       if (-e "$perlvar{'lonDaemons'}/logs/lonnet.log"){
     print $fh "$line";   open (DFH,"tail -n50 $perlvar{'lonDaemons'}/logs/lonnet.log|");
     if ($line=~/INFO/) { $notices++; }   while (my $line=<DFH>) { 
     if ($line=~/WARNING/) { $notices++; }      &log($fh,&encode_entities($line,'<>&"'));
     if ($line=~/CRITICAL/) { $warnings++; }   }
  };  
  close (DFH);   close (DFH);
     }      }
     print $fh "</pre>";      &log($fh,"</pre><h3>Perm Log</h3><pre>");
           
     my $lonsqlfile="$perlvar{'lonDaemons'}/logs/lonsql.pid";      if (-e "$perlvar{'lonDaemons'}/logs/lonnet.perm.log") {
        open(DFH,"tail -n10 $perlvar{'lonDaemons'}/logs/lonnet.perm.log|");
     if (-e $lonsqlfile) {   while (my $line=<DFH>) { 
  my $lfh=IO::File->new("$lonsqlfile");      &log($fh,&encode_entities($line,'<>&"'));
  my $lonsqlpid=<$lfh>;  
  chomp($lonsqlpid);  
  if (kill 0 => $lonsqlpid) {  
     print $fh "<h3>lonsql at pid $lonsqlpid responding</h3>";  
     $restartflag=0;  
  } else {  
     $errors++; $errors++;  
     print $fh "<h3>lonsql at pid $lonsqlpid not responding</h3>";  
     # Intelligently handle this.  
     # Possibility #1: there is no process  
     # Solution: remove .pid file and restart  
     if (getpgrp($lonsqlpid)==-1) {  
  unlink($lonsqlfile);  
  $restartflag=1;  
     }  
     else {  
  # Possibility #2: there is a live process that is not  
  # responding for an unknown reason  
  # Solution: kill parent and children processes, remove .pid  
  # and restart  
  `killall -9 lonsql`;  
  unlink($lonsqlfile);  
  $restartflag=1;  
     }  
  }  
  print $fh   
     "<h3>Deciding to clean up stale .pid file and restart lonsql</h3>";  
     }  
     if ($restartflag==1) {  
  $errors++;  
  print $fh "<h3>lonsql not running, trying to start</h3>";  
  system(  
  "$perlvar{'lonDaemons'}/lonsql 2>>$perlvar{'lonDaemons'}/logs/lonsql_errors");  
  sleep 120 unless $qflag;  
  if (-e $lonsqlfile) {  
     print $fh "Seems like it started ...<p>";  
     my $lfh=IO::File->new("$lonsqlfile");  
     my $lonsqlpid=<$lfh>;  
     chomp($lonsqlpid);  
     sleep 30 unless $qflag;  
     if (kill 0 => $lonsqlpid) {  
  print $fh "<h3>lonsql at pid $lonsqlpid responding</h3>";  
     } else {  
  $errors++; $errors++;  
  print $fh "<h3>lonsql at pid $lonsqlpid not responding</h3>";  
  print $fh "Give it one more try ...<p>";  
  system(  
  "$perlvar{'lonDaemons'}/lonsql 2>>$perlvar{'lonDaemons'}/logs/lonsql_errors");  
  sleep 120 unless $qflag;  
     }  
  } else {  
     print $fh "Seems like that did not work!<p>";  
     $errors++;  
  }  
  if (-e "$perlvar{'lonDaemons'}/logs/lonsql.log"){  
     print $fh "<p><pre>";  
     open (DFH,"tail -n100 $perlvar{'lonDaemons'}/logs/lonsql.log|");  
     while ($line=<DFH>) {   
  print $fh "$line";  
  if ($line=~/WARNING/) { $notices++; }  
  if ($line=~/CRITICAL/) { $notices++; }  
     };  
     close (DFH);  
     print $fh "</pre>";  
  }   }
     }   close (DFH);
       } else { &log($fh,"No perm log\n") }
   
     $fname="$perlvar{'lonDaemons'}/logs/lonsql.log";      my $fname="$perlvar{'lonDaemons'}/logs/lonnet.log";
       &rotate_logfile($fname,$fh,'lonnet log');
   
     my ($dev,$ino,$mode,$nlink,      &log($fh,"</pre>");
  $uid,$gid,$rdev,$size,      &errout($fh);
  $atime,$mtime,$ctime,  }
  $blksize,$blocks)=stat($fname);  
   
     if ($size>40000) {  sub rotate_other_logs {
  print $fh "Rotating logs ...<p>";      my ($fh) = @_;
  rename("$fname.2","$fname.3");      my %logs = (
  rename("$fname.1","$fname.2");                    autoenroll          => 'Auto Enroll log',
  rename("$fname","$fname.1");                    autocreate          => 'Create Course log',
                     searchcat           => 'Search Cataloguing log',
                     autoupdate          => 'Auto Update log',
                     refreshcourseids_db => 'Refresh CourseIDs db log',
                  );
       foreach my $item (keys(%logs)) {
           my $fname=$perlvar{'lonDaemons'}.'/logs/'.$item.'.log';
           &rotate_logfile($fname,$fh,$logs{$item});
     }      }
   }
   
   # ----------------------------------------------------------------- Connections
   sub test_connections {
       my ($fh)=@_;
       &log($fh,'<hr /><a name="connections" /><h2>Connections</h2>');
       print "Testing connections.\n";
       &log($fh,"<table border='2'>");
       my ($good,$bad)=(0,0);
       my %hostname = &Apache::lonnet::all_hostnames();
       foreach my $tryserver (sort(keys(%hostname))) {
    print(".");
    my $result;
    my $answer=&Apache::lonnet::reply("ping",$tryserver);
    if ($answer eq "$tryserver:$perlvar{'lonHostID'}") {
       $result="<b>ok</b>";
       $good++;
    } else {
       $result=$answer;
       $warnings++;
       if ($answer eq 'con_lost') {
    $bad++;
    $warnings++;
       } else {
    $good++; #self connection
       }
    }
    if ($answer =~ /con_lost/) { print(" $tryserver down\n"); }
    &log($fh,"<tr><td>$tryserver</td><td>$result</td></tr>\n");
       }
       &log($fh,"</table>");
       print "\n$good good, $bad bad connections\n";
     &errout($fh);      &errout($fh);
 }  }
 # ------------------------------------------------------------------------ lond  
   
 print $fh '<hr><a name="lond"><h2>lond</h2><h3>Log</h3><pre>';  
   
 if (-e "$perlvar{'lonDaemons'}/logs/lond.log"){  # ------------------------------------------------------------ Delayed messages
 open (DFH,"tail -n100 $perlvar{'lonDaemons'}/logs/lond.log|");  sub check_delayed_msg {
 while ($line=<DFH>) {       my ($fh)=@_;
    print $fh "$line";      &log($fh,'<hr /><a name="delayed" /><h2>Delayed Messages</h2>');
    if ($line=~/INFO/) { $notices++; }      print "Checking buffers.\n";
    if ($line=~/WARNING/) { $notices++; }      
    if ($line=~/CRITICAL/) { $warnings++; }      &log($fh,'<h3>Scanning Permanent Log</h3>');
 };  
 close (DFH);  
 }  
 print $fh "</pre>";  
   
 my $londfile="$perlvar{'lonDaemons'}/logs/lond.pid";  
   
 $restartflag=1;  
 if (-e $londfile) {      
    my $lfh=IO::File->new("$londfile");  
    my $londpid=<$lfh>;  
    chomp($londpid);  
    if (kill 0 => $londpid) {  
       print $fh "<h3>lond at pid $londpid responding</h3>";  
       $restartflag=0;  
    } else {  
       $errors++;  
       print $fh "<h3>lond at pid $londpid not responding</h3>";  
       # Intelligently handle this.  
       # Possibility #1: there is no process  
       # Solution: remove .pid file and restart  
       if (getpgrp($londpid)==-1) {  
   unlink($londfile);  
   $restartflag=1;  
       }  
       else {  
       # Possibility #2: there is a live process that is not responding  
       #                 for an unknown reason  
       # Solution: kill parent and children processes, remove .pid and restart  
   `killall -9 lond`;  
   unlink($londfile);  
   $restartflag=1;  
       }  
       print $fh   
   "<h3>Deciding to clean up stale .pid file and restart lond</h3>";  
    }  
 }   
 if ($restartflag==1) {  
    $errors++;  
    print $fh "<h3>lond not running, trying to start</h3>";  
    system(  
      "$perlvar{'lonDaemons'}/lond 2>>$perlvar{'lonDaemons'}/logs/lond_errors");  
    sleep 120 unless $qflag;  
    if (-e $londfile) {  
        print $fh "Seems like it started ...<p>";  
        my $lfh=IO::File->new("$londfile");  
        my $londpid=<$lfh>;  
        chomp($londpid);  
        sleep 30 unless $qflag;  
        if (kill 0 => $londpid) {  
           print $fh "<h3>lond at pid $londpid responding</h3>";  
        } else {  
           $errors++; $errors++;  
           print $fh "<h3>lond at pid $londpid not responding</h3>";  
           print $fh "Give it one more try ...<p>";  
   system(  
  "$perlvar{'lonDaemons'}/lond 2>>$perlvar{'lonDaemons'}/logs/lond_errors");  
           sleep 120 unless $qflag;  
        }  
    } else {  
        print $fh "Seems like that did not work!<p>";  
        $errors++;  
    }  
    if (-e "$perlvar{'lonDaemons'}/logs/lond.log"){  
     print $fh "<p><pre>";  
     open (DFH,"tail -n100 $perlvar{'lonDaemons'}/logs/lond.log|");  
     while ($line=<DFH>) {   
       print $fh "$line";  
       if ($line=~/WARNING/) { $notices++; }  
       if ($line=~/CRITICAL/) { $notices++; }  
     };  
     close (DFH);  
     print $fh "</pre>";  
    }  
 }  
   
 $fname="$perlvar{'lonDaemons'}/logs/lond.log";      my $unsend=0;
   
                           my ($dev,$ino,$mode,$nlink,      my %hostname = &Apache::lonnet::all_hostnames();
                               $uid,$gid,$rdev,$size,      my $numhosts = scalar(keys(%hostname));
                               $atime,$mtime,$ctime,  
                               $blksize,$blocks)=stat($fname);  
   
 if ($size>40000) {  
     print $fh "Rotating logs ...<p>";  
     rename("$fname.2","$fname.3");  
     rename("$fname.1","$fname.2");  
     rename("$fname","$fname.1");  
 }  
   
 &errout($fh);  
 # ------------------------------------------------------------------------ lonc  
   
 print $fh '<hr><a name="lonc"><h2>lonc</h2><h3>Log</h3><pre>';  
   
 if (-e "$perlvar{'lonDaemons'}/logs/lonc.log"){  
 open (DFH,"tail -n100 $perlvar{'lonDaemons'}/logs/lonc.log|");  
 while ($line=<DFH>) {   
    print $fh "$line";  
    if ($line=~/INFO/) { $notices++; }  
    if ($line=~/WARNING/) { $notices++; }  
    if ($line=~/CRITICAL/) { $warnings++; }  
 };  
 close (DFH);  
 }  
 print $fh "</pre>";  
   
 my $loncfile="$perlvar{'lonDaemons'}/logs/lonc.pid";  
   
 $restartflag=1;  
 if (-e $loncfile) {  
    my $lfh=IO::File->new("$loncfile");  
    my $loncpid=<$lfh>;  
    chomp($loncpid);  
    if (kill 0 => $loncpid) {  
       print $fh "<h3>lonc at pid $loncpid responding, sending USR1</h3>";  
       kill USR1 => $loncpid;  
       $restartflag=0;  
    } else {  
       $errors++;  
       print $fh "<h3>lonc at pid $loncpid not responding</h3>";  
       # Intelligently handle this.  
       # Possibility #1: there is no process  
       # Solution: remove .pid file and restart  
       if (getpgrp($loncpid)==-1) {  
   unlink($loncfile);  
   $restartflag=1;  
       }  
       else {  
       # Possibility #2: there is a live process that is not responding  
       #                 for an unknown reason  
       # Solution: kill parent and children processes, remove .pid and restart  
   `killall -9 lonc`;  
   unlink($loncfile);  
   $restartflag=1;  
       }  
       print $fh   
   "<h3>Deciding to clean up stale .pid file and restart lonc</h3>";  
    }  
 }   
 if ($restartflag==1) {  
    $errors++;  
    print $fh "<h3>lonc not running, trying to start</h3>";  
  system(  
  "$perlvar{'lonDaemons'}/lonc 2>>$perlvar{'lonDaemons'}/logs/lonc_errors");  
    sleep 120 unless $qflag;  
    if (-e $loncfile) {  
        print $fh "Seems like it started ...<p>";  
        my $lfh=IO::File->new("$loncfile");  
        my $loncpid=<$lfh>;  
        chomp($loncpid);  
        sleep 30 unless $qflag;  
        if (kill 0 => $loncpid) {  
           print $fh "<h3>lonc at pid $loncpid responding</h3>";  
        } else {  
           $errors++; $errors++;  
           print $fh "<h3>lonc at pid $loncpid not responding</h3>";  
           print $fh "Give it one more try ...<p>";  
    system(  
  "$perlvar{'lonDaemons'}/lonc 2>>$perlvar{'lonDaemons'}/logs/lonc_errors");  
           sleep 120 unless $qflag;  
        }  
    } else {  
        print $fh "Seems like that did not work!<p>";  
        $errors++;  
    }  
    if (-e "$perlvar{'lonDaemons'}/logs/lonc.log") {  
     print $fh "<p><pre>";  
     open (DFH,"tail -n100 $perlvar{'lonDaemons'}/logs/lonc.log|");  
     while ($line=<DFH>) {   
       print $fh "$line";  
       if ($line=~/WARNING/) { $notices++; }  
       if ($line=~/CRITICAL/) { $notices++; }  
     };  
     close (DFH);  
     print $fh "</pre>";  
    }  
 }  
   
 $fname="$perlvar{'lonDaemons'}/logs/lonc.log";      my $dfh=IO::File->new("$perlvar{'lonDaemons'}/logs/lonnet.perm.log");
       while (my $line=<$dfh>) {
    my ($time,$sdf,$dserv,$dcmd)=split(/:/,$line);
           if ($numhosts) {
               next unless ($hostname{$dserv});
           }
    if ($sdf eq 'F') { 
       my $local=localtime($time);
       &log($fh,"<b>Failed: $time, $dserv, $dcmd</b><br />");
       $warnings++;
    }
    if ($sdf eq 'S') { $unsend--; }
    if ($sdf eq 'D') { $unsend++; }
       }
   
                           my ($dev,$ino,$mode,$nlink,      &log($fh,"<p>Total unsend messages: <b>$unsend</b></p>\n");
                               $uid,$gid,$rdev,$size,      if ($unsend > 0) {
                               $atime,$mtime,$ctime,          $warnings=$warnings+5*$unsend;
                               $blksize,$blocks)=stat($fname);      }
   
 if ($size>40000) {      if ($unsend) { $simplestatus{'unsend'}=$unsend; }
     print $fh "Rotating logs ...<p>";      &log($fh,"<h3>Outgoing Buffer</h3>\n<pre>");
     rename("$fname.2","$fname.3");  # list directory with delayed messages and remember offline servers
     rename("$fname.1","$fname.2");      my %servers=();
     rename("$fname","$fname.1");      open (DFH,"ls -lF $perlvar{'lonSockDir'}/delayed|");
       while (my $line=<DFH>) {
           my ($server)=($line=~/\.(\w+)$/);
           if ($server) { $servers{$server}=1; }
    &log($fh,&encode_entities($line,'<>&"'));
       }
       &log($fh,"</pre>\n");
       close (DFH);
   # pong to all servers that have delayed messages
   # this will trigger a reverse connection, which should flush the buffers
       foreach my $tryserver (sort(keys(%servers))) {
           if ($hostname{$tryserver} || !$numhosts) {
               my $answer;
               eval {
                   local $SIG{ ALRM } = sub { die "TIMEOUT" };
                   alarm(20);
                   $answer = &Apache::lonnet::reply("pong",$tryserver);
                   alarm(0);
               };
               if ($@ && $@ =~ m/TIMEOUT/) {
                   &log($fh,"Attempted pong to $tryserver timed out<br />");
                   print "Time out while contacting: $tryserver for pong.\n";
               } else {
                   &log($fh,"Pong to $tryserver: $answer<br />");
               }
           } else {
               &log($fh,"$tryserver has delayed messages, but is not part of the cluster -- skipping 'Pong'.<br />");
           }
       }
 }  }
   
      sub finish_logging {
 &errout($fh);      my ($fh)=@_;
 # ---------------------------------------------------------------------- lonnet      &log($fh,"<a name='errcount' />\n");
       $totalcount=$notices+4*$warnings+100*$errors;
 print $fh '<hr><a name="lonnet"><h2>lonnet</h2><h3>Temp Log</h3><pre>';      &errout($fh);
 if (-e "$perlvar{'lonDaemons'}/logs/lonnet.log"){      &log($fh,"<h1>Total Error Count: $totalcount</h1>");
 open (DFH,"tail -n50 $perlvar{'lonDaemons'}/logs/lonnet.log|");      my $now=time;
 while ($line=<DFH>) {       my $date=localtime($now);
     print $fh "$line";      &log($fh,"<hr />$date ($now)</body></html>\n");
 };      print "lon-status webpage updated.\n";
 close (DFH);      $fh->close();
 }  
 print $fh "</pre><h3>Perm Log</h3><pre>";      if ($errors) { $simplestatus{'errors'}=$errors; }
       if ($warnings) { $simplestatus{'warnings'}=$warnings; }
 if (-e "$perlvar{'lonDaemons'}/logs/lonnet.perm.log") {      if ($notices) { $simplestatus{'notices'}=$notices; }
     open(DFH,"tail -n10 $perlvar{'lonDaemons'}/logs/lonnet.perm.log|");      $simplestatus{'time'}=time;
 while ($line=<DFH>) {   
    print $fh "$line";  
 };  
 close (DFH);  
 } else { print $fh "No perm log\n" }  
   
 $fname="$perlvar{'lonDaemons'}/logs/lonnet.log";  
   
                           my ($dev,$ino,$mode,$nlink,  
                               $uid,$gid,$rdev,$size,  
                               $atime,$mtime,$ctime,  
                               $blksize,$blocks)=stat($fname);  
   
 if ($size>40000) {  
     print $fh "Rotating logs ...<p>";  
     rename("$fname.2","$fname.3");  
     rename("$fname.1","$fname.2");  
     rename("$fname","$fname.1");  
 }  }
   
 print $fh "</pre>";  sub log_simplestatus {
 &errout($fh);      rename("$statusdir/newstatus.html","$statusdir/index.html");
 # ----------------------------------------------------------------- Connections      
       my $sfh=IO::File->new(">$statusdir/loncron_simple.txt");
       foreach (keys %simplestatus) {
    print $sfh $_.'='.$simplestatus{$_}.'&';
       }
       print $sfh "\n";
       $sfh->close();
   }
   
 print $fh '<hr><a name="connections"><h2>Connections</h2>';  sub write_loncaparevs {
       print "Retrieving LON-CAPA version information.\n";
       my %hostname = &Apache::lonnet::all_hostnames();
       my $output;
       foreach my $id (sort(keys(%hostname))) {
           if ($id ne '') {
               my $loncaparev;
               eval {
                   local $SIG{ ALRM } = sub { die "TIMEOUT" };
                   alarm(10);
                   $loncaparev =
                       &Apache::lonnet::get_server_loncaparev('',$id,1,'loncron');
                   alarm(0);
               };
               if ($@ && $@ =~ m/TIMEOUT/) {
                   print "Time out while contacting lonHost: $id for version.\n";   
               }
               if ($loncaparev =~ /^[\w.\-]+$/) {
                   $output .= $id.':'.$loncaparev."\n";
               }
           }
       }
       if ($output) {
           if (open(my $fh,">$perlvar{'lonTabDir'}/loncaparevs.tab")) {
               print $fh $output;
               close($fh);
               &Apache::lonnet::load_loncaparevs();
           }
       }
       return;
   }
   
 print $fh "<table border=2>";  sub write_serverhomeIDs {
 foreach $tryserver (keys %hostname) {      print "Retrieving LON-CAPA lonHostID information.\n";
       my %name_to_host = &Apache::lonnet::all_names();
       my $output;
       foreach my $name (sort(keys(%name_to_host))) {
           if ($name ne '') {
               if (ref($name_to_host{$name}) eq 'ARRAY') {
                   my $serverhomeID;
                   eval {
                       local $SIG{ ALRM } = sub { die "TIMEOUT" };
                       alarm(10);
                       $serverhomeID = 
                           &Apache::lonnet::get_server_homeID($name,1,'loncron');
                       alarm(0);
                   };
                   if ($@ && $@ =~ m/TIMEOUT/) {
                       print "Time out while contacting server: $name\n"; 
                   }
                   if ($serverhomeID ne '') {
                       $output .= $name.':'.$serverhomeID."\n";
                   } else {
                       $output .= $name.':'.$name_to_host{$name}->[0]."\n";
                   }
               }
           }
       }
       if ($output) {
           if (open(my $fh,">$perlvar{'lonTabDir'}/serverhomeIDs.tab")) {
               print $fh $output;
               close($fh);
               &Apache::lonnet::load_serverhomeIDs();
           }
       }
       return;
   }
   
     $answer=reply("pong",$tryserver);  sub write_checksums {
     if ($answer eq "$tryserver:$perlvar{'lonHostID'}") {      my $distro = &LONCAPA::distro();
  $result="<b>ok</b>";      if ($distro) {
           print "Retrieving file version and checksumming.\n";
           my $numchksums = 0;
           my ($chksumsref,$versionsref) =
               &LONCAPA::Checksumming::get_checksums($distro,$perlvar{'lonDaemons'},
                                                     $perlvar{'lonLib'},
                                                     $perlvar{'lonIncludes'},
                                                     $perlvar{'lonTabDir'});
           if (ref($chksumsref) eq 'HASH') {
               $numchksums = scalar(keys(%{$chksumsref}));
           }
           print "File version retrieved and checksumming completed for $numchksums files.\n";
     } else {      } else {
         $result=$answer;          print "File version retrieval and checksumming skipped - could not determine Linux distro.\n"; 
         $warnings++;  
         if ($answer eq 'con_lost') { $warnings++; }  
     }      }
     print $fh "<tr><td>$tryserver</td><td>$result</td></tr>\n";      return;
   
 }  }
 print $fh "</table>";  
   
 &errout($fh);  
 # ------------------------------------------------------------ Delayed messages  
   
 print $fh '<hr><a name="delayed"><h2>Delayed Messages</h2>';  
   
 print $fh '<h3>Scanning Permanent Log</h3>';  
   
 $unsend=0;  
 {  
     my $dfh=IO::File->new("$perlvar{'lonDaemons'}/logs/lonnet.perm.log");  
     while ($line=<$dfh>) {  
  ($time,$sdf,$dserv,$dcmd)=split(/:/,$line);  
         if ($sdf eq 'F') {   
     $local=localtime($time);  
             print "<b>Failed: $time, $dserv, $dcmd</b><br>";  
             $warnings++;  
         }  
         if ($sdf eq 'S') { $unsend--; }  
         if ($sdf eq 'D') { $unsend++; }  
     }  
 }  
 print $fh "Total unsend messages: <b>$unsend</b><p>\n";  
 $warnings=$warnings+5*$unsend;  
   
 print $fh "<h3>Outgoing Buffer</h3>";  
   
 open (DFH,"ls -lF $perlvar{'lonSockDir'}/delayed|");  
 while ($line=<DFH>) {   
     print $fh "$line<br>";  
 };  
 close (DFH);  
   
 # ------------------------------------------------------------------------- End  
 print $fh "<a name=errcount>\n";  
 $totalcount=$notices+4*$warnings+100*$errors;  
 &errout($fh);  
 print $fh "<h1>Total Error Count: $totalcount</h1>";  
 $now=time;  
 $date=localtime($now);  
 print $fh "<hr>$date ($now)</body></html>\n";  
   
   sub send_mail {
       my $defdom = $perlvar{'lonDefDomain'};
       my $origmail = $perlvar{'lonAdmEMail'};
       my $emailto = &Apache::loncommon::build_recipient_list(undef,
                                      'lonstatusmail',$defdom,$origmail);
       if ($totalcount>2500) {
    $emailto.=",$perlvar{'lonSysEMail'}";
       }
       my $from;
       my $hostname=`/bin/hostname`;
       chop($hostname);
       $hostname=~s/[^\w\.]//g;
       if ($hostname) {
           $from = 'www@'.$hostname;
       }
       my $subj="LON: $perlvar{'lonHostID'} E:$errors W:$warnings N:$notices";
       my $loncronmail = "To: $emailto\n".
                         "From: $from\n".
                         "Subject: ".$subj."\n".
                         "Content-type: text/html\; charset=UTF-8\n".
                         "MIME-Version: 1.0\n\n";
       if (open(my $fh,"<$statusdir/index.html")) {
           while (<$fh>) {
               $loncronmail .= $_;
           }
           close($fh);
       } else {
           $loncronmail .= "Failed to read from http://$hostname/lon-status/index.html\n";
       }
       $loncronmail .= "\n\n";
       if (open(my $mailh, "|/usr/lib/sendmail -oi -t -odb")) {
           print $mailh $loncronmail;
           close($mailh);
           print "Sending mail.\n";
       } else {
           print "Sending mail failed.\n";
       }
 }  }
   
 rename ("$statusdir/newstatus.html","$statusdir/index.html");  sub usage {
       print(<<USAGE);
 if ($totalcount>200) {  loncron - housekeeping program that checks up on various parts of LON-CAPA
    $emailto="$perlvar{'lonAdmEMail'},$perlvar{'lonSysEMail'}";  
    $subj="LON: $perlvar{'lonHostID'} E:$errors W:$warnings N:$notices";   Options:
    system(     --help     Display 
  "metasend -b -t $emailto -s '$subj' -f $statusdir/index.html -m text/html")     --noemail  Do not send the status email
     unless $qflag;     --justcheckconnections  Only check the current status of the lonc/d
                                   connections, do not send emails do not
                                   check if the daemons are running, do not
                                   generate lon-status
      --justcheckdaemons      Only check that all of the Lon-CAPA daemons are
                                   running, do not send emails do not
                                   check the lonc/d connections, do not
                                   generate lon-status
      --justreload            Only tell the daemons to reload the config files,
    do not send emails do not
                                   check if the daemons are running, do not
                                   generate lon-status
                              
   USAGE
 }  }
 1;  
   
   
   # ================================================================ Main Program
   sub main () {
       my ($help,$justcheckdaemons,$noemail,$justcheckconnections,
    $justreload);
       &GetOptions("help"                 => \$help,
    "justcheckdaemons"     => \$justcheckdaemons,
    "noemail"              => \$noemail,
    "justcheckconnections" => \$justcheckconnections,
    "justreload"           => \$justreload
    );
       if ($help) { &usage(); return; }
   # --------------------------------- Read loncapa_apache.conf and loncapa.conf
       my $perlvarref=LONCAPA::Configuration::read_conf('loncapa.conf');
       %perlvar=%{$perlvarref};
       undef $perlvarref;
       delete $perlvar{'lonReceipt'}; # remove since sensitive and not needed
       delete $perlvar{'lonSqlAccess'}; # remove since sensitive and not needed
       chdir($perlvar{'lonDaemons'});
   # --------------------------------------- Make sure that LON-CAPA is configured
   # I only test for one thing here (lonHostID).  This is just a safeguard.
       if ('{[[[[lonHostID]]]]}' eq $perlvar{'lonHostID'}) {
    print("Unconfigured machine.\n");
    my $emailto=$perlvar{'lonSysEMail'};
    my $hostname=`/bin/hostname`;
    chop $hostname;
    $hostname=~s/[^\w\.]//g; # make sure is safe to pass through shell
    my $subj="LON: Unconfigured machine $hostname";
    system("echo 'Unconfigured machine $hostname.' |\
    mailto $emailto -s '$subj' > /dev/null");
    exit 1;
       }
   
   # ----------------------------- Make sure this process is running from user=www
       my $wwwid=getpwnam('www');
       if ($wwwid!=$<) {
    print("User ID mismatch. This program must be run as user 'www'.\n");
    my $emailto="$perlvar{'lonAdmEMail'},$perlvar{'lonSysEMail'}";
    my $subj="LON: $perlvar{'lonHostID'} User ID mismatch";
    system("echo 'User ID mismatch. loncron must be run as user www.' |\
    mailto $emailto -s '$subj' > /dev/null");
    exit 1;
       }
   
   # -------------------------------------------- Force reload of host information
       my $nomemcache;
       if ($justcheckdaemons) {
           $nomemcache=1;
           my $memcachepidfile="$perlvar{'lonDaemons'}/logs/memcached.pid";
           my $memcachepid;
           if (-e $memcachepidfile) {
               my $memfh=IO::File->new($memcachepidfile);
               $memcachepid=<$memfh>;
               chomp($memcachepid);
               if ($memcachepid =~ /^\d+$/ && kill 0 => $memcachepid) {
                   undef($nomemcache);
               }
           }
       }
       &Apache::lonnet::load_hosts_tab(1,$nomemcache);
       &Apache::lonnet::load_domain_tab(1,$nomemcache);
       &Apache::lonnet::get_iphost(1,$nomemcache);
   
   # ----------------------------------------- Force firewall update for lond port  
   
       if ((!$justcheckdaemons) && (!$justreload)) {
           my $now = time;
           my $tmpfile = $perlvar{'lonDaemons'}.'/tmp/lciptables_iphost_'.
                         $now.$$.int(rand(10000));
           if (open(my $fh,">$tmpfile")) {
               my %iphosts = &Apache::lonnet::get_iphost();
               foreach my $key (keys(%iphosts)) {
                   print $fh "$key\n";
               }
               close($fh);
               if (&LONCAPA::try_to_lock('/tmp/lock_lciptables')) {
                   my $execpath = $perlvar{'lonDaemons'}.'/lciptables';
                   system("$execpath $tmpfile");
                   unlink('/tmp/lock_lciptables');  # Remove the lock file. 
               }
               unlink($tmpfile);
           }
       }
   
   # ---------------------------------------------------------------- Start report
   
       $errors=0;
       $warnings=0;
       $notices=0;
   
   
       my $fh;
       if (!$justcheckdaemons && !$justcheckconnections && !$justreload) {
    $fh=&start_logging();
   
    &log_machine_info($fh);
    &clean_tmp($fh);
    &clean_lonIDs($fh);
           &clean_webDAV_sessionIDs($fh);
    &check_httpd_logs($fh);
    &rotate_lonnet_logs($fh);
    &rotate_other_logs($fh);
       }
       if (!$justcheckconnections && !$justreload) {
    &checkon_daemon($fh,'lonmemcached',40000);
    &checkon_daemon($fh,'lonsql',200000);
    if ( &checkon_daemon($fh,'lond',40000,'USR1') eq 'running') {
       &checkon_daemon($fh,'lond',40000,'USR2');
    }
    &checkon_daemon($fh,'lonc',40000,'USR1');
           &checkon_daemon($fh,'lonmaxima',40000);
           &checkon_daemon($fh,'lonr',40000);
       }
       if ($justreload) {
    &checkon_daemon($fh,'lond',40000,'USR2');
    &checkon_daemon($fh,'lonc',40000,'USR2');
       }
       if ($justcheckconnections) {
    &test_connections($fh);
       }
       if (!$justcheckdaemons && !$justcheckconnections && !$justreload) {
    &check_delayed_msg($fh);
    &finish_logging($fh);
    &log_simplestatus();
           &write_loncaparevs();
           &write_serverhomeIDs();
    &write_checksums();
    if ($totalcount>200 && !$noemail) { &send_mail(); }
       }
   }
   
   &main();
   1;
   

Removed from v.1.22  
changed lines
  Added in v.1.103.2.1


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.