Commit 27558935 authored by Leigh B. Stoller's avatar Leigh B. Stoller

Add several minor experiment_stats fields; swap_errors (a count),

swap_exitcode (last error), idle_swaps (a count), batch (a flag to
indicate a batch experiment).

Add a operational log. Okay, its not actually a log, but a table that
will grow forever until it consumes the earth. Its a small table
though, so it will take a few years. Its cross indexed with the
experiment_stats table, so by massaging this table along with the
stats table, we can get a good picture of what was running on the
testbed when, and how many resources it was using. Sorry, not a log
file, but we can easily generate a log file from tbe table if the Boss
really wants one. The table entry averages 28 bytes.

Move stats to their own main menu item (admin mode only). Remove from
the showexp_list page since that was bogus.
parent d445ad87
......@@ -2942,7 +2942,7 @@ sub TBActivityReport($)
# char *mode, int code, int flags)
# Mode is one of preload, start, in, out, modify, end.
#
sub GatherSwapStats($$$$;$$)
sub GatherSwapStats($$$$$;$)
{
my ($pid, $eid, $uid, $mode, $ecode, $flags) = @_;
my ($pnodes,$vnodes,$duration);
......@@ -2950,8 +2950,6 @@ sub GatherSwapStats($$$$;$$)
# Optional argument to modify the stats gathering.
$flags = 0
if (!defined($flags));
$ecode = 0
if (!defined($ecode));
local $DBQUERY_MAXTRIES = 5;
......@@ -2969,7 +2967,7 @@ sub GatherSwapStats($$$$;$$)
# since the results are not well defined. swapout,terminate
# errors do normal processing.
#
if (0 && $ecode) {
if ($ecode) {
DBQueryWarn("update experiment_stats set ".
" swap_errors=swap_errors+1, ".
" swap_exitcode=$ecode ".
......@@ -3018,13 +3016,11 @@ sub GatherSwapStats($$$$;$$)
#
# Increment idleswap indicator, but only valid on swapout.
#
if (0) {
if ($flags & $TBDB_STATS_FLAGS_IDLESWAP) {
DBQueryWarn("update experiment_stats ".
"set idle_swaps=idle_swaps+1 ".
"where pid='$pid' and eid='$eid' and idx=idx");
}
}
}
#
......@@ -3115,9 +3111,19 @@ sub GatherSwapStats($$$$;$$)
}
#
# Okay, to make Jay happy, append info to a log file.
# Okay, Jay wants a log file but I am not crazy about that. Instead we
# have a tiny table of testbed wide stats, which cross indexes with the
# experiment_stats table via the idx field (which comes from the
# experiments table of course). For each operation insert a record. We
# can then construct a complete record of what happened from this
# table, when correlated with experiment_stats. We could probably not
# have an errorcode in experiment_stats, but since its a tinyint, not
# worth worrying about.
#
logit:
DBQueryWarn("insert into testbed_stats ".
"(idx, tstamp, exptidx, action, exitcode) ".
"values (0, now(), $idx, '$mode', $ecode)");
}
# _Always_ make sure that this 1 is at the end of the file...
......
......@@ -183,6 +183,9 @@ CREATE TABLE experiment_stats (
swapout_last datetime default NULL,
swapmodify_count smallint(5) unsigned default '0',
swapmodify_last datetime default NULL,
swap_errors smallint(5) unsigned default '0',
swap_exitcode tinyint(3) unsigned default '0',
idle_swaps smallint(5) unsigned default '0',
swapin_duration int(10) unsigned default '0',
vnodes smallint(5) unsigned default '0',
pnodes smallint(5) unsigned default '0',
......@@ -198,6 +201,7 @@ CREATE TABLE experiment_stats (
shapedlans smallint(5) unsigned default '0',
minlinks tinyint(3) unsigned default '0',
maxlinks tinyint(3) unsigned default '0',
batch tinyint(3) unsigned default '0',
PRIMARY KEY (eid,pid,idx)
) TYPE=MyISAM;
......
......@@ -345,3 +345,39 @@ last_net_act,last_cpu_act,last_ext_act);
PRIMARY KEY (uid)
) TYPE=MyISAM;
1.135: Add exit codes. Obviously, we get just the last exit code, but
I still think this will be useful. Note that we do not track
front end parse errors or other very early errors that are
likely the result of system problems, not user problems. Also
note that we need to standardize the error codes so that these
are meaningful a year from now!
alter table experiment_stats add swap_errors smallint(5) \
unsigned default '0' after swapmodify_last;
alter table experiment_stats add swap_exitcode tinyint(3) \
unsigned default '0' after swap_errors;
alter table experiment_stats add idle_swaps smallint(5) \
unsigned default '0' after swap_exitcode;
alter table experiment_stats add batch tinyint(3) \
unsigned default '0' after maxlinks;
Also add testbed wide stats table.
CREATE TABLE testbed_stats (
idx int(10) unsigned NOT NULL auto_increment,
tstamp datetime default NULL,
exptidx int(10) unsigned NOT NULL default '0',
action varchar(16) NOT NULL default '',
exitcode tinyint(3) unsigned default '0',
PRIMARY KEY (idx)
) TYPE=MyISAM;
This table gets an entry for each experiment operation. By
cross indexing with experiment_stats via the exptidx field, we
can figure out what was running on the testbed and how many
nodes it was using, etc. We also get Jay's desire for a per
operation log, except its not in a file but in the DB, where
all such information belongs. Average size of an entry is 30
bytes. We can squeeze this down easily by making the "action"
a tinyint instead varchar, but not gonna worry until the table
is over 1MB.
\ No newline at end of file
......@@ -153,8 +153,9 @@ my ($idx) = $query_result->fetchrow_array;
# Insert stats record.
DBQueryWarn("INSERT INTO experiment_stats ".
"(eid, pid, creator, idx, gid, created) ".
"VALUES ('$eid', '$pid', '$dbuid', $idx, '$gid', now())");
"(eid, pid, creator, idx, gid, created, batch) ".
"VALUES ('$eid', '$pid', '$dbuid', $idx, '$gid', now(), ".
($immediate ? 0 : 1) . ")");
if (! DBQueryWarn("unlock tables")) {
fatal("Unexpected DB Error!");
......
......@@ -283,7 +283,7 @@ if ($estate eq EXPTSTATE_ACTIVE) {
#
# Gather statistics for the swapout.
#
GatherSwapStats($pid, $eid, $dbuid, TBDB_STATS_SWAPOUT);
GatherSwapStats($pid, $eid, $dbuid, TBDB_STATS_SWAPOUT, 0);
}
if ($estate eq EXPTSTATE_SWAPPED) {
......@@ -299,7 +299,7 @@ if ($estate eq EXPTSTATE_SWAPPED) {
#
# Gather statistics for the swapout.
#
GatherSwapStats($pid, $eid, $dbuid, TBDB_STATS_TERMINATE);
GatherSwapStats($pid, $eid, $dbuid, TBDB_STATS_TERMINATE, 0);
}
if ($estate ne EXPTSTATE_TERMINATED && $estate ne EXPTSTATE_NEW) {
......
......@@ -275,10 +275,10 @@ TBUnLockExp($pid, $eid);
# Gather statistics.
#
if ($frontend) {
GatherSwapStats($pid, $eid, $dbuid, TBDB_STATS_PRELOAD);
GatherSwapStats($pid, $eid, $dbuid, TBDB_STATS_PRELOAD, 0);
}
else {
GatherSwapStats($pid, $eid, $dbuid, TBDB_STATS_START);
GatherSwapStats($pid, $eid, $dbuid, TBDB_STATS_START, 0);
}
#
......@@ -369,6 +369,16 @@ sub fatal()
print STDOUT "$mesg\n";
print STDOUT "Cleaning up and exiting with status $errorstat ...\n";
#
# Gather statistics.
#
if ($frontend) {
GatherSwapStats($pid, $eid, $dbuid, TBDB_STATS_PRELOAD, $errorstat);
}
else {
GatherSwapStats($pid, $eid, $dbuid, TBDB_STATS_START, $errorstat);
}
#
# If we got far enough to allocate nodes, must run tbend.
#
......@@ -386,6 +396,11 @@ sub fatal()
exit($errorstat);
}
#
# Okay, we *are* going to terminate the experiment.
#
GatherSwapStats($pid, $eid, $dbuid, TBDB_STATS_TERMINATE, 0);
# Clear the logfile so the webpage stops.
TBExptClearLogFile($pid, $eid);
......
......@@ -41,6 +41,7 @@ my $tbdata = "tbdata";
my $batch = 0;
my $idleswap = 0;
my $reboot = 0;
my $errorstat= -1;
my $inout;
my $logname;
......@@ -318,6 +319,7 @@ if ($inout eq "modify") {
if ($inout eq "out") {
print STDOUT "Running 'tbswap out' with arguments: $pid $eid\n";
if (system("$tbdir/tbswap out $pid $eid") != 0) {
$errorstat = $? >> 8;
fatal("tbswap out failed!\n");
}
......@@ -329,6 +331,7 @@ if ($inout eq "out") {
elsif ($inout eq "in") {
print STDOUT "Running 'tbswap in' with arguments: $pid $eid\n";
if (system("$tbdir/tbswap in $pid $eid") != 0) {
$errorstat = $? >> 8;
fatal("tbswap in failed!\n");
}
......@@ -347,6 +350,7 @@ elsif ($inout eq "modify") {
if ($estate eq EXPTSTATE_ACTIVE) {
print STDOUT "Running 'tbswap update' with arguments: $pid $eid\n";
if (system("$tbdir/tbswap update $pid $eid") != 0) {
$errorstat = $? >> 8;
fatal("tbswap update failed!\n");
}
......@@ -392,13 +396,14 @@ TBUnLockExp($pid, $eid);
# Gather stats.
#
if ($inout eq "in") {
GatherSwapStats($pid, $eid, $dbuid, TBDB_STATS_SWAPIN);
GatherSwapStats($pid, $eid, $dbuid, TBDB_STATS_SWAPIN, 0);
}
elsif ($inout eq "out") {
GatherSwapStats($pid, $eid, $dbuid, TBDB_STATS_SWAPOUT);
GatherSwapStats($pid, $eid, $dbuid, TBDB_STATS_SWAPOUT, 0,
($idleswap ? $TBDB_STATS_FLAGS_IDLESWAP : 0));
}
elsif ($inout eq "modify") {
GatherSwapStats($pid, $eid, $dbuid, TBDB_STATS_SWAPMODIFY);
GatherSwapStats($pid, $eid, $dbuid, TBDB_STATS_SWAPMODIFY, 0);
}
print "Done!\n";
......@@ -469,6 +474,19 @@ sub fatal($)
print STDOUT $mesg;
#
# Gather stats.
#
if ($inout eq "in") {
GatherSwapStats($pid, $eid, $dbuid, TBDB_STATS_SWAPIN, $errorstat);
}
elsif ($inout eq "out") {
GatherSwapStats($pid, $eid, $dbuid, TBDB_STATS_SWAPOUT, $errorstat);
}
elsif ($inout eq "modify") {
GatherSwapStats($pid, $eid, $dbuid, TBDB_STATS_SWAPMODIFY, $errorstat);
}
#
# if $hosed == 1, we entirely terminate the experiment.
#
......
......@@ -275,6 +275,8 @@ function WRITESIDEBAR() {
if (ISADMIN($login_uid)) {
WRITESIDEBARBUTTON("Edit Site Variables",
$TBBASE, "editsitevars.php3");
WRITESIDEBARBUTTON("View Testbed Stats",
$TBBASE, "showstats.php3");
}
if ($login_status & CHECKLOGIN_CVSWEB) {
......
......@@ -52,7 +52,6 @@ if ($isadmin) {
} else {
echo "Idle, ";
}
echo "<a class='static' href='showexpstats.php3'>Stats</a>, ";
}
if ($showtype != "all") {
......
......@@ -236,9 +236,12 @@ if (isset($formfields[usr_key]) &&
$formfields[usr_key] = ereg_replace("[\n]", "", $formfields[usr_key]);
#
# Must parse it and construct a key for the DB.
# Must parse it and construct a key for the DB. Accept both version
# 6 and version 7 (, vs :).
#
if (! preg_match("/(\w*),([-\w\@\.]*)/",
$formfields[usr_key], $matches) &&
! preg_match("/(\w*):([-\w\@\.\#]*)/",
$formfields[usr_key], $matches)) {
$errors["SFSKey"] = "Invalid Key Format";
}
......
<?php
#
# EMULAB-COPYRIGHT
# Copyright (c) 2000-2003 University of Utah and the Flux Group.
# All rights reserved.
#
include("defs.php3");
include("showstuff.php3");
#
# Standard Testbed Header
#
PAGEHEADER("Testbed Wide Stats");
#
# Only known and logged in users can end experiments.
#
$uid = GETLOGIN();
LOGGEDINORDIE($uid);
$isadmin = ISADMIN($uid);
#
# Only admins
#
if (! $isadmin) {
USERERROR("You do not have permission to view this page!", 1);
}
echo "Show <a class='static' href='showexpstats.php3'>
Experiment Stats</a><br>\n";
#
# Right now we show just the last 200 records entered.
#
$query_result =
DBQueryFatal("select * from testbed_stats order by idx desc limit 200");
if (mysql_num_rows($query_result) == 0) {
USERERROR("No testbed stats records in the system!", 1);
}
#
# Use first row to get the column headers (no pretty printing yet).
#
$row = mysql_fetch_assoc($query_result);
echo "<table align=center border=1>\n";
echo "<tr>\n";
foreach($row as $key => $value) {
$key = str_replace("_", " ", $key);
echo "<th><font size=-1>$key</font></th>\n";
}
echo "</tr>\n";
mysql_data_seek($query_result, 0);
while ($row = mysql_fetch_assoc($query_result)) {
echo "<tr>\n";
foreach($row as $key => $value) {
echo "<td nowrap>$value</td>\n";
}
echo "</tr>\n";
}
echo "</table>\n";
#
# Standard Testbed Footer
#
PAGEFOOTER();
?>
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment