dumperrorlog.in 5.5 KB
Newer Older
1 2
#!/usr/bin/perl -w
#
3
# Copyright (c) 2005-2011 University of Utah and the Flux Group.
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
# 
# {{{EMULAB-LICENSE
# 
# This file is part of the Emulab network testbed software.
# 
# This file is free software: you can redistribute it and/or modify it
# under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or (at
# your option) any later version.
# 
# This file 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 Affero General Public
# License for more details.
# 
# You should have received a copy of the GNU Affero General Public License
# along with this file.  If not, see <http://www.gnu.org/licenses/>.
# 
# }}}
23
#
24
use strict;
25 26 27 28 29 30 31 32 33 34
use English;
use Getopt::Std;

#
# Check DB consistency.
#
sub usage() {
    print STDOUT "Usage: dumperrorlog [-d]\n";
    exit(-1);
}
35
my $optlist  = "df";
36
my $debug    = 0;
37
my $force    = 0;
38 39
my $tempfile = "/var/tmp/testbed_dumperrorlog_tempfile";

40 41
my $keep_important = 4 * 24 * 60 * 60;
my $keep_any       = 2 * 24 * 60 * 60;
42 43
my $max_rows       = 300000;

44 45 46
#
# Configure variables
#
47 48 49 50 51 52 53 54
my $TB		 = "@prefix@";
my $TBOPS        = "@TBOPSEMAIL@";
my $ISUTAHEMULAB = "@OURDOMAIN@" eq 'emulab.net';
my $USERNODE	 = "@USERNODE@";
my $PROXY        = "$TB/sbin/dumperrorlog.proxy";
my $SCP          = "/usr/bin/scp";
my $SSHTB	 = "$TB/bin/sshtb";
my $ERRORLOGDB   = "@TBERRORLOGDBNAME@";
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80

# un-taint path
$ENV{'PATH'} = '/bin:/usr/bin:/usr/local/bin:/usr/site/bin';
delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'};

#
# Turn off line buffering on output
#
$| = 1; 

# Load the Testbed support stuff.
use lib "@prefix@/lib";
use libdb;
use libtestbed;

# Protos
sub fatal($);

#
# Only real root can call this.
# 
if ($UID != 0) {
    print STDERR "You must be root to run this script!\n";
    exit(-1);
}

81 82 83 84 85 86 87
#
# Only one script can run at a time, for now just
# abort instead of waiting
#
my $lock_res = TBScriptLock("dumperrorlog", 1, 0);
exit(-1) if $lock_res != TBSCRIPTLOCK_OKAY();

88 89 90 91 92 93 94 95 96
#
# Form a temp name.
#
my $logname = TBMakeLogname("dumperrorlog");

#
# Parse command arguments. Once we return from getopts, all that should
# left are the required arguments.
#
97
my %options = ();
98 99 100 101 102 103 104 105 106
if (! getopts($optlist, \%options)) {
    usage();
}
if (@ARGV) {
    usage();
}
if (defined($options{"d"})) {
    $debug++;
}
107 108 109
if (defined($options{"f"})) {
    $force++;
}
110 111 112 113 114 115 116 117 118 119 120

#
# Reopen both stdout and stderr so that we can record all the output for
# later mailing.
#
if (! $debug) {
    open(STDERR, ">> $logname") or die("opening $logname for STDERR: $!");
    open(STDOUT, ">> $logname") or die("opening $logname for STDOUT: $!");
}

#
121
# Get the last log index we archived out.
122 123 124 125
#
my $query_result =
    DBQueryFatal("select idx from emulab_indicies ".
		 "where name='lastlog_seqnum'");
126 127
my ($minseq) = $query_result->fetchrow_array();
if (!defined($minseq)) {
128 129
    DBQueryFatal("insert into emulab_indicies (name, idx) ".
		 "values ('lastlog_seqnum', 0)");
130
    $minseq = 0;
131 132 133 134 135 136
}

#
# Grab the index number for the NOTICE priority.
#
$query_result =
137 138
    DBQueryFatal("select priority from priorities ".
		 "where priority_name='NOTICE'");
139 140 141 142 143
my ($NOTICE) = $query_result->fetchrow_array();
if (!defined($NOTICE)) {
    fatal("No priority named 'NOTICE' in the priorities table!");
}

144 145 146 147 148 149 150 151 152 153 154
#
# Now get the largest log index to copy
# 
$query_result =
    DBQueryFatal("select MAX(seq) from log ".
		 "where seq > $minseq " .
		 "  and seq <= $minseq + $max_rows ");
my $maxseq = $query_result->fetchrow_array();
$maxseq = $minseq unless defined $maxseq;

print "Copying log entries ($minseq,$maxseq]\n";
155

156
#
157 158 159
# Might not be any new entries ...
# 
if ($minseq != $maxseq) {
160 161 162 163 164 165
    #
    # Backup old outfile
    #
    if (-e "${tempfile}.log") {
	unlink("${tempfile}.log.save")
	    if (-e "${tempfile}.log.save");
166

167 168 169
	system("/bin/mv -f ${tempfile}.log ${tempfile}.log.save");
    }

170 171 172 173
    #
    # Grab all of the new entries and store to the file
    #
    DBQueryFatal("select * from log ".
174
		 "where seq > $minseq " .
175
		 "and seq <= $maxseq " .
176 177
		 "into outfile '${tempfile}.log' ");

178 179 180 181
    system("echo \"load data infile '${tempfile}.log' replace into table log\" ".
	   "     | mysql $ERRORLOGDB");
    fatal("Could not load into archive DB!")
	if ($?);
182

183
    if ($ISUTAHEMULAB) {
184 185 186 187 188 189 190 191
	# XXX This awful hack will go away when Kevin is happy with
	# the error logging code.
	#

	#
	# Copy the file over to ops and load it into the DB over there.
	#
	system("$SCP -p ${tempfile}.log ".
192 193
	       "     ${USERNODE}:/var/db/mysql/$ERRORLOGDB") == 0
		   or fatal("Could not copy $tempfile to $USERNODE!");
194 195 196 197

	system("$SSHTB -host $USERNODE $PROXY log") == 0
	    or fatal("Could not load log entries into ops DB!");
    }
198
}
199

200 201
# Okay, now that we have really archived them away, update the
# seq number.
202
DBQueryFatal("update emulab_indicies set idx='$maxseq' ".
203 204
	     "where name='lastlog_seqnum'");

205
#
206
# And then age out entries.
207 208
#
DBQueryFatal("delete from log ".
209 210
	     "where stamp < (UNIX_TIMESTAMP(now()) - $keep_important)".
	     "  and seq <= $maxseq");
211 212

#
213
# And age out non critical data.
214 215 216
#
DBQueryFatal("delete from log ".
	     "where priority > $NOTICE and ".
217 218
	     "      stamp < (UNIX_TIMESTAMP(now()) - $keep_any)".
	     "        and seq <= $maxseq");
219

220 221 222
unlink("$logname")
    if (-e $logname);

223 224
TBScriptUnlock();

225 226 227 228 229 230 231 232 233 234 235 236 237 238
exit(0);

sub fatal($)
{
    my ($msg) = @_;

    SENDMAIL($TBOPS, "DumpErrorLog Failed", $msg, undef, undef, ($logname));
   
    unlink("$logname")
	if (-e $logname);

    die("*** $0:\n".
	"    $msg\n");
}
239