--- loncom/loncron 1999/10/13 17:48:51 1.1
+++ loncom/loncron 2018/10/25 03:27:22 1.110
@@ -1,495 +1,1297 @@
#!/usr/bin/perl
-# The LearningOnline Network
-# Housekeeping program, started by cron
+# Housekeeping program, started by cron, loncontrol and loncron.pl
#
-# (TCP networking package
-# 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)
+# $Id: loncron,v 1.110 2018/10/25 03:27:22 raeburn Exp $
#
-# 7/14,7/15,7/19,7/21,7/22 Gerd Kortemeyer
+# Copyright Michigan State University Board of Trustees
+#
+# This file is part of the LearningOnline Network with CAPA (LON-CAPA).
+#
+# LON-CAPA is free software; you can redistribute it and/or modify
+# 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::Socket;
+use HTML::Entities;
+use Getopt::Long;
+use GDBM_File;
+use Storable qw(thaw);
+#globals
+use vars qw (%perlvar %simplestatus $errors $warnings $notices $totalcount);
+
+my $statusdir="/home/httpd/html/lon-status";
-# -------------------------------------------------- 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
+sub log {
+ my $fh=shift;
+ if ($fh) { print $fh @_ }
+}
+
sub errout {
my $fh=shift;
- print $fh (<
+ Rotating $description ... Seems like it started ... Seems like that did not work! ');
+ printf("%-15s ",$daemon);
+ if ($fh) {
+ if (-e "$perlvar{'lonDaemons'}/logs/$daemon.log"){
+ if (open(DFH,"tail -n25 $perlvar{'lonDaemons'}/logs/$daemon.log|")) {
+ while (my $line= Give it one more try ... Unable to start $daemon
+ &log($fh,(<
Notices $notices Warnings $warnings
- Errors $errors Attempting to send delayed messages
";
- while ($dfname=<$path/*>) {
- my $wcmd;
- {
- my $dfh=IO::File->new($dfname);
- $wcmd=<$dfh>;
- }
- my ($server,$cmd)=split(/:/,$wcmd);
- chomp($cmd);
- my $answer=reply($cmd,$server);
- if ($answer ne 'con_lost') {
- unlink("$dfname");
- print $fh "Send $cmd to $server: $answer
\n";
- &logperm("S:$server:$cmd");
- } else {
- print $fh "Failed to deliver $cmd to $server
\n";
- $warnings++;
- }
+sub rotate_logfile {
+ my ($file,$fh,$description) = @_;
+ my $size=(stat($file))[7];
+ if ($size>40000) {
+ &log($fh,"'.$daemon.'
Log
$daemon at pid $daemonpid responding");
+ if ($send) { &log($fh,", sending $send"); }
+ &log($fh,"
");
+ 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,"$daemon at pid $daemonpid not responding
");
+ $restartflag=1;
+ &log($fh,"Decided to clean up stale .pid file and restart $daemon
");
+ }
+ }
+ if ($restartflag==1) {
+ $simplestatus{$daemon}='off';
+ $errors++;
+ my $kadaemon=$daemon;
+ if ($kadaemon eq 'lonmemcached') { $kadaemon='memcached'; }
+ &log($fh,'
Killall '.$daemon.': '.
+ `killall $kadaemon 2>&1`.' - ');
+ sleep 1;
+ &log($fh,unlink($pidfile).' - '.
+ `killall -9 $kadaemon 2>&1`.
+ '
');
+ if ($kadaemon eq 'loncnew') {
+ &clean_lonc_childpids();
+ }
+ &log($fh,"$daemon not running, trying to start
");
- while (my $configline=<$config>) {
- my ($id,$domain,$role,$name,$ip)=split(/:/,$configline);
- $hostname{$id}=$name;
- $hostdom{$id}=$domain;
- $hostrole{$id}=$role;
- $hostip{$id}=$ip;
- if (($role eq 'library') && ($id ne $perlvar{'lonHostID'})) {
- $libserv{$id}=$name;
- }
+ if (&start_daemon($fh,$daemon,$pidfile,$args)) {
+ &log($fh,"$daemon at pid $daemonpid responding
");
+ $simplestatus{$daemon}='restarted';
+ $result = 'started';
+ print "started\n";
+ } else {
+ $errors++;
+ &log($fh,"$daemon at pid $daemonpid not responding
");
+ &log($fh,"$daemon at pid $daemonpid responding
");
+ $simplestatus{$daemon}='restarted';
+ $result = 'started';
+ print "started\n";
+ } else {
+ $result = 'failed';
+ print " failed\n";
+ $simplestatus{$daemon}='failed';
+ $errors++; $errors++;
+ &log($fh,"$daemon at pid $daemonpid not responding
");
+ &log($fh,"");
+ if (open(DFH,"tail -n100 $perlvar{'lonDaemons'}/logs/$daemon.log|")) {
+ while (my $line=
"); - while (my $configline=<$config>) { - chomp($configline); - if (($configline) && ($configline ne $perlvar{'lonHostID'})) { - $spareid{$configline}=1; - } + open (DFH,"df|"); + while (my $line="); -# ---------------------------------------------------------------- Start report -$statusdir="/home/httpd/html/lon-status"; + &log($fh,") { + &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,"
"); + my $psproc=0; + + open (PSH,"ps aux --cols 140 |"); + while (my $line="); -$errors=0; -$warnings=0; -$notices=0; + if ($psproc>200) { $notices++; } + if ($psproc>250) { $notices++; } -$now=time; -$date=localtime($now); + &log($fh,") { + &log($fh,&encode_entities($line,'<>&"')); + $psproc++; + } + close (PSH); + &log($fh,"
"); + &log($fh,&encode_entities(&LONCAPA::distro(),'<>&"')); + &log($fh,""); -{ -my $fh=IO::File->new(">$statusdir/newstatus.html"); + &errout($fh); +} -print $fh (<
$varname | $perlvar{$varname} |
$id | $hostdom{$id} | $hostrole{$id} | "; -print $fh "$hostname{$id} | $hostip{$id} |
$varname | ". + &encode_entities($perlvar{$varname},'<>&"')." |
$id | ".&Apache::lonnet::host_domain($id). + " | ".$role. + " | ".&Apache::lonnet::hostname($id)." |
Cleaned up ".$cleaned." stale session token(s).
"); + &log($fh,"Cleaned up ".$cleaned." stale webDAV session token(s).
"); + &log($fh,"Cleaned up ".$cleaned." stale sockets.
"); +} -print $fh "$loadavg"; -@parts=split(/\s+/,$loadavg); -if ($parts[1]>3.0) { - $errors++; -} elsif ($parts[1]>2.0) { - $warnings++; -} elsif ($parts[1]>1.0) { - $notices++; -} - -print $fh ""; - -open (DFH,"df|"); -while ($line="; -&errout($fh); # ----------------------------------------------------------------------- httpd - -print $fh ') { - print $fh "$line"; - @parts=split(/\s+/,$line); - $usage=$parts[4]; - $usage=~s/\W//g; - if ($usage>90) { - $errors++; - } elsif ($usage>80) { - $warnings++; - } elsif ($usage>60) { - $notices++; - } - if ($usage>95) { $errors++; } -} -close (DFH); -print $fh "
'; - -open (DFH,"tail -n40 /etc/httpd/logs/access_log|"); -while ($line=) { print $fh "$line" }; -close (DFH); - -print $fh "
"; - -open (DFH,"tail -n50 /etc/httpd/logs/error_log|"); -while ($line="; -&errout($fh); -# ------------------------------------------------------------------------ lond - -print $fh ') { - print $fh "$line"; - if ($line=~/\[error\]/) { $notices++; } -}; -close (DFH); -print $fh "
'; - -if (-e "$perlvar{'lonDaemons'}/logs/lond.log"){ -open (DFH,"tail -n50 $perlvar{'lonDaemons'}/logs/lond.log|"); -while ($line="; - -my $londfile="$perlvar{'lonDaemons'}/logs/lond.pid"; - -if (-e $londfile) { - my $lfh=IO::File->new("$londfile"); - my $londpid=<$lfh>; - chomp($londpid); - if (kill 0 => $londpid) { - print $fh ") { - print $fh "$line"; - if ($line=~/giving up/) { $notices++; } -}; -close (DFH); -} -print $fh "
"; - my $lfh=IO::File->new("$londfile"); - my $londpid=<$lfh>; - chomp($londpid); - sleep 30; - if (kill 0 => $londpid) { - print $fh "
"; - system("$perlvar{'lonDaemons'}/lond"); - sleep 120; - } - } else { - print $fh "Seems like that did not work!
"; - $errors++; - } -} - -$fname="$perlvar{'lonDaemons'}/logs/lond.log"; - - my ($dev,$ino,$mode,$nlink, - $uid,$gid,$rdev,$size, - $atime,$mtime,$ctime, - $blksize,$blocks)=stat($fname); - -if ($size>40000) { - print $fh "Rotating logs ...
"; - rename("$fname.2","$fname.3"); - rename("$fname.1","$fname.2"); - rename("$fname","$fname.1"); -} - -&errout($fh); -# ------------------------------------------------------------------------ lonc - -print $fh '
'; - -if (-e "$perlvar{'lonDaemons'}/logs/lonc.log"){ -open (DFH,"tail -n50 $perlvar{'lonDaemons'}/logs/lonc.log|"); -while ($line="; - -my $loncfile="$perlvar{'lonDaemons'}/logs/lonc.pid"; - -if (-e $loncfile) { - my $lfh=IO::File->new("$loncfile"); - my $loncpid=<$lfh>; - chomp($loncpid); - if (kill 0 => $loncpid) { - print $fh ") { - print $fh "$line"; - if ($line=~/died/) { $notices++; } -}; -close (DFH); -} -print $fh "
"; - my $lfh=IO::File->new("$loncfile"); - my $loncpid=<$lfh>; - chomp($loncpid); - sleep 30; - if (kill 0 => $loncpid) { - print $fh "
"; - system("$perlvar{'lonDaemons'}/lonc"); - sleep 120; - } - } else { - print $fh "Seems like that did not work!
"; - $errors++; - } -} - -$fname="$perlvar{'lonDaemons'}/logs/lonc.log"; - - my ($dev,$ino,$mode,$nlink, - $uid,$gid,$rdev,$size, - $atime,$mtime,$ctime, - $blksize,$blocks)=stat($fname); - -if ($size>40000) { - print $fh "Rotating logs ...
";
- rename("$fname.2","$fname.3");
- rename("$fname.1","$fname.2");
- rename("$fname","$fname.1");
+sub check_httpd_logs {
+ my ($fh)=@_;
+ if (open(PIPE,"./lchttpdlogs|")) {
+ while (my $line= ";
- rename("$fname.2","$fname.3");
- rename("$fname.1","$fname.2");
- rename("$fname","$fname.1");
+sub rotate_lonnet_logs {
+ my ($fh)=@_;
+ &log($fh,' Removed ".scalar(keys(%unlinked))." nosslverify clients \n";
-$warnings=$warnings+5*$unsend;
-
-print $fh "lonnet
Temp Log
';
-if (-e "$perlvar{'lonDaemons'}/logs/lonnet.log"){
-open (DFH,"tail -n50 $perlvar{'lonDaemons'}/logs/lonnet.log|");
-while ($line=
Perm Log
";
-
-if (-e "$perlvar{'lonDaemons'}/logs/lonnet.perm.log") {
- open(DFH,"tail -n10 $perlvar{'lonDaemons'}/logs/lonnet.perm.log|");
-while ($line=lonnet
Temp Log
');
+ print "Checking logs.\n";
+ if (-e "$perlvar{'lonDaemons'}/logs/lonnet.log"){
+ open (DFH,"tail -n50 $perlvar{'lonDaemons'}/logs/lonnet.log|");
+ while (my $line=
Perm Log
");
+
+ if (-e "$perlvar{'lonDaemons'}/logs/lonnet.perm.log") {
+ open(DFH,"tail -n10 $perlvar{'lonDaemons'}/logs/lonnet.perm.log|");
+ while (my $line=
");
+ &errout($fh);
+}
+
+sub rotate_other_logs {
+ my ($fh) = @_;
+ my %logs = (
+ autoenroll => 'Auto Enroll log',
+ 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});
+ }
}
-print $fh "";
-&errout($fh);
# ----------------------------------------------------------------- Connections
+sub test_connections {
+ my ($fh)=@_;
+ &log($fh,'Connections
');
+ print "Testing connections.\n";
+ &log($fh,"");
+ 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="ok";
+ $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,"
");
+ print "\n$good good, $bad bad connections\n";
+ &errout($fh);
+}
-print $fh ' \n");
+ }
+ &log($fh,"$tryserver $result Connections
';
-print $fh "Delayed Messages
';
+sub write_serverhomeIDs {
+ 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;
+}
-&senddelayed($fh);
+sub write_checksums {
+ my $distro = &LONCAPA::distro();
+ 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 {
+ print "File version retrieval and checksumming skipped - could not determine Linux distro.\n";
+ }
+ return;
+}
-print $fh 'Scanning Permanent Log
';
+sub clean_nosslverify {
+ my ($fh) = @_;
+ my %unlinked;
+ if (-d "$perlvar{'lonSockDir'}/nosslverify") {
+ if (opendir(my $dh,"$perlvar{'lonSockDir'}/nosslverify")) {
+ while (my $fname=readdir($dh)) {
+ next if ($fname =~ /^\.+$/);
+ if (unlink("/home/httpd/sockets/nosslverify/$fname")) {
+ &log($fh,"Unlinking $fname
");
+ $unlinked{$fname} = 1;
+ }
+ }
+ closedir($dh);
+ }
+ }
+ &log($fh,"
";
- $warnings++;
- }
- if ($sdf eq 'S') { $unsend--; }
- if ($sdf eq 'D') { $unsend++; }
- }
-}
-print $fh "Total unsend messages: $unsendOutgoing Buffer
";
-
-open (DFH,"ls -lF $perlvar{'lonSockDir'}/delayed|");
-while ($line=
";
-};
-close (DFH);
-
-# ------------------------------------------------------------------------- End
-print $fh "\n";
-$totalcount=$notices+4*$warnings+100*$errors;
-&errout($fh);
-print $fh "Total Error Count: $totalcount
";
-$now=time;
-$date=localtime($now);
-print $fh "
$date ($now)