--- loncom/loncron 2002/06/08 14:59:04 1.30
+++ loncom/loncron 2010/07/17 20:01:56 1.84
@@ -1,716 +1,860 @@
#!/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.84 2010/07/17 20:01:56 raeburn Exp $
+#
+# 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/
#
-# 7/14,7/15,7/19,7/21,7/22,11/18,
-# 2/8 Gerd Kortemeyer
-# 12/6/2000,12/8 Scott Harrison
-# 12/23 Gerd Kortemeyer
-# YEAR=2001
-# 1/10/2001, 2/12/, 2/26, 3/15, 04/11, 04/21,8/27 Scott Harrison
-# 09/04,09/06,11/26 Gerd Kortemeyer
-# YEAR=2002
-# 5/11/2002 Scott Harrison
$|=1;
+use strict;
use lib '/home/httpd/lib/perl/';
use LONCAPA::Configuration;
+use Apache::lonnet;
+use Apache::loncommon;
use IO::File;
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";
-# -------------------------------------------------- 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 (-e "$perlvar{'lonDaemons'}/logs/$daemon.log"){
+ 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 '.$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`.
+ '
');
+ &log($fh,"$daemon not running, trying to start
");
+
+ 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,"");
+ open (DFH,"tail -n100 $perlvar{'lonDaemons'}/logs/$daemon.log|");
+ while (my $line=
"); + + open (DFH,"df|"); + while (my $line="); + + + &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="); -$statusdir="/home/httpd/html/lon-status"; + if ($psproc>200) { $notices++; } + if ($psproc>250) { $notices++; } -$errors=0; -$warnings=0; -$notices=0; + &log($fh,") { + &log($fh,&encode_entities($line,'<>&"')); + $psproc++; + } + close (PSH); + &log($fh,"
"); + open(DSH,"$perlvar{'lonDaemons'}/distprobe |"); + while (my $line="); -$now=time; -$date=localtime($now); + &errout($fh); +} -{ -my $fh=IO::File->new(">$statusdir/newstatus.html"); +sub start_logging { + my $fh=IO::File->new(">$statusdir/newstatus.html"); + my %simplestatus=(); + my $now=time; + my $date=localtime($now); + -print $fh (<) { + &log($fh,&encode_entities($line,'<>&"')); + $psproc++; + } + close(DSH); + &log($fh,"
$varname | $perlvar{$varname} |
$id | $hostdom{$id} | $hostrole{$id} | "; -print $fh "$hostname{$id} | $hostip{$id} |
$id | ".&Apache::lonnet::host_domain($id). + " | ".$role. + " | ".&Apache::lonnet::hostname($id)." |
"; - -open (DFH,"df|"); -while ($line="; - - -print $fh ") { - print $fh "$line"; - @parts=split(/\s+/,$line); - $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++ } -} -close (DFH); -print $fh "
"; -$psproc=0; - -open (PSH,"ps -aux|"); -while ($line="; -if ($psproc>200) { $notices++; } -if ($psproc>250) { $notices++; } - -&errout($fh); - -# --------------------------------------------------------------- clean out tmp -print $fh ') { - print $fh "$line"; - $psproc++; +# --------------------------------------------------------------- clean out tmp +sub clean_tmp { + my ($fh)=@_; + &log($fh,' Temporary Files
'); + my ($cleaned,$old,$removed) = (0,0,0); + my %errors = ( + dir => [], + file => [], + failopen => [], + ); + my %error_titles = ( + dir => 'failed to remove empty directory:', + 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}):
- ". + join('
- ',@{$errors{$key}}).'
'); + } + } + } } -close (PSH); -print $fh "
Cleaned up ".$cleaned." stale session token(s).
"); + &log($fh,"Cleaned up ".$cleaned." stale sockets.
"); } -print $fh "Cleaned up ".$cleaned." stale session token(s)."; -print $fh "
'); + + open (DFH,"tail -n25 /etc/httpd/logs/access_log|"); + while (my $line=) { &log($fh,&encode_entities($line,'<>&"')) }; + close (DFH); + + &log($fh,"
"); + + open (DFH,"tail -n25 /etc/httpd/logs/error_log|"); + while (my $line="); + &errout($fh); +} -print $fh ') { + &log($fh,"$line"); + if ($line=~/\[error\]/) { $notices++; } + } + close (DFH); + &log($fh,"
'; +# ---------------------------------------------------------------------- lonnet -open (DFH,"tail -n25 /etc/httpd/logs/access_log|"); -while ($line=) { print $fh "$line" }; -close (DFH); - -print $fh "
"; - -open (DFH,"tail -n25 /etc/httpd/logs/error_log|"); -while ($line="; -&errout($fh); - - -# ---------------------------------------------------------------------- lonsql - -my $restartflag=1; -if ($perlvar{'lonRole'} eq "library") { - - print $fh ') { - print $fh "$line"; - if ($line=~/\[error\]/) { $notices++; } -}; -close (DFH); -print $fh "
'; - print "lonsql\n"; - if (-e "$perlvar{'lonDaemons'}/logs/lonsql.log"){ - open (DFH,"tail -n100 $perlvar{'lonDaemons'}/logs/lonsql.log|"); - while ($line=) { - print $fh "$line"; - if ($line=~/INFO/) { $notices++; } - if ($line=~/WARNING/) { $notices++; } - if ($line=~/CRITICAL/) { $warnings++; } - }; +sub rotate_lonnet_logs { + my ($fh)=@_; + &log($fh,' 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="; + &log($fh,") { + &log($fh,&encode_entities($line,'<>&"')); + } close (DFH); } - print $fh "
"); - my $lonsqlfile="$perlvar{'lonDaemons'}/logs/lonsql.pid"; - - $restartflag=1; - - if (-e $lonsqlfile) { - my $lfh=IO::File->new("$lonsqlfile"); - my $lonsqlpid=<$lfh>; - chomp($lonsqlpid); - if (kill 0 => $lonsqlpid) { - print $fh ""); + &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}); } - if ($restartflag==1) { - $errors++; - print $fh 'lonsql at pid $lonsqlpid responding
"; - $restartflag=0; - } else { - $errors++; $errors++; - print $fh "lonsql at pid $lonsqlpid not responding
"; - $restartflag=1; - print $fh - "Decided to clean up stale .pid file and restart lonsql
"; + if (-e "$perlvar{'lonDaemons'}/logs/lonnet.perm.log") { + open(DFH,"tail -n10 $perlvar{'lonDaemons'}/logs/lonnet.perm.log|"); + while (my $line=) { + &log($fh,&encode_entities($line,'<>&"')); } + close (DFH); + } else { &log($fh,"No perm log\n") } + + my $fname="$perlvar{'lonDaemons'}/logs/lonnet.log"; + &rotate_logfile($fname,$fh,'lonnet log'); + + &log($fh,"
"; - my $lfh=IO::File->new("$lonsqlfile"); - my $lonsqlpid=<$lfh>; - chomp($lonsqlpid); - sleep 2; - if (kill 0 => $lonsqlpid) { - print $fh "
$tryserver | $result |
";
- rename("$fname.2","$fname.3");
- rename("$fname.1","$fname.2");
- rename("$fname","$fname.1");
- }
+ my $unsend=0;
- &errout($fh);
-}
-# ------------------------------------------------------------------------ lond
+ my $dfh=IO::File->new("$perlvar{'lonDaemons'}/logs/lonnet.perm.log");
+ while (my $line=<$dfh>) {
+ my ($time,$sdf,$dserv,$dcmd)=split(/:/,$line);
+ if ($sdf eq 'F') {
+ my $local=localtime($time);
+ &log($fh,"Failed: $time, $dserv, $dcmd
");
+ $warnings++;
+ }
+ if ($sdf eq 'S') { $unsend--; }
+ if ($sdf eq 'D') { $unsend++; }
+ }
-print $fh '
'; -print "lond\n"; + &log($fh,""; - -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 "Total unsend messages: $unsend
\n"); + $warnings=$warnings+5*$unsend; -if (-e "$perlvar{'lonDaemons'}/logs/lond.log"){ -open (DFH,"tail -n25 $perlvar{'lonDaemons'}/logs/lond.log|"); -while ($line=) { - print $fh "$line"; - if ($line=~/INFO/) { $notices++; } - if ($line=~/WARNING/) { $notices++; } - if ($line=~/CRITICAL/) { $warnings++; } -}; -close (DFH); -} -print $fh "
"; - my $lfh=IO::File->new("$londfile"); - my $londpid=<$lfh>; - chomp($londpid); - sleep 2; - if (kill 0 => $londpid) { - print $fh "
"; - system( - "$perlvar{'lonDaemons'}/lond 2>>$perlvar{'lonDaemons'}/logs/lond_errors"); - sleep 2; - } - } else { - print $fh "Seems like that did not work!
"; - $errors++; - } - if (-e "$perlvar{'lonDaemons'}/logs/lond.log"){ - print $fh "
"; - open (DFH,"tail -n100 $perlvar{'lonDaemons'}/logs/lond.log|"); - while ($line="; - } +# pong to all servers that have delayed messages +# this will trigger a reverse connection, which should flush the buffers + foreach my $tryserver (keys %servers) { + my $answer=&Apache::lonnet::reply("pong",$tryserver); + &log($fh,"Pong to $tryserver: $answer) { - print $fh "$line"; - if ($line=~/WARNING/) { $notices++; } - if ($line=~/CRITICAL/) { $notices++; } - }; + if ($unsend) { $simplestatus{'unsend'}=$unsend; } + &log($fh," Outgoing Buffer
\n"); +# list directory with delayed messages and remember offline servers + my %servers=(); + open (DFH,"ls -lF $perlvar{'lonSockDir'}/delayed|"); + while (my $line=\n"); close (DFH); - print $fh ") { + my ($server)=($line=~/\.(\w+)$/); + if ($server) { $servers{$server}=1; } + &log($fh,&encode_entities($line,'<>&"')); + } + &log($fh,"
"; - rename("$fname.2","$fname.3"); - rename("$fname.1","$fname.2"); - rename("$fname","$fname.1"); -} - -&errout($fh); -# ------------------------------------------------------------------------ lonc - -print $fh '
'; -print "lonc\n"; - -if (-e "$perlvar{'lonDaemons'}/logs/lonc.log"){ -open (DFH,"tail -n25 $perlvar{'lonDaemons'}/logs/lonc.log|"); -while ($line="; - -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 ") { - print $fh "$line"; - if ($line=~/INFO/) { $notices++; } - if ($line=~/WARNING/) { $notices++; } - if ($line=~/CRITICAL/) { $warnings++; } -}; -close (DFH); -} -print $fh "
"; - my $lfh=IO::File->new("$loncfile"); - my $loncpid=<$lfh>; - chomp($loncpid); - sleep 2; - if (kill 0 => $loncpid) { - print $fh "
"; - system( - "$perlvar{'lonDaemons'}/lonc 2>>$perlvar{'lonDaemons'}/logs/lonc_errors"); - sleep 2; - } - } else { - print $fh "Seems like that did not work!
"; - $errors++; - } - if (-e "$perlvar{'lonDaemons'}/logs/lonc.log") { - print $fh "
"; - open (DFH,"tail -n100 $perlvar{'lonDaemons'}/logs/lonc.log|"); - while ($line="; - } +sub finish_logging { + my ($fh)=@_; + &log($fh,"\n"); + $totalcount=$notices+4*$warnings+100*$errors; + &errout($fh); + &log($fh,") { - print $fh "$line"; - if ($line=~/WARNING/) { $notices++; } - if ($line=~/CRITICAL/) { $notices++; } - }; - close (DFH); - print $fh "