Commit d034c0fb authored by Timothy Stack's avatar Timothy Stack
Browse files

Automatically scroll and highlight the activity log file:

	* www/Sajax.php: Remove automatic include of json.js, it didn't
	always work, need to do it manually now.  Use the fvlogger stuff
	when debugging is turned on.

	* www/mungelog.js: Javascript functions for dealing with log
	output.

	* www/showlogfile.php3: Automatically scroll the window when new
	output comes in and do some light highlighting.
parent 8b54529e
......@@ -107,22 +107,15 @@ if (!isset($SAJAX_INCLUDED)) {
var sajax_debug_mode = <?php echo $sajax_debug_mode ? "true" : "false"; ?>;
var sajax_request_type = "<?php echo $t; ?>";
// http://www.phpied.com/javascript-include/
function include_dom(script_filename) {
var html_doc = document.getElementsByTagName('head').item(0);
var js = document.createElement('script');
js.setAttribute('language', 'javascript');
js.setAttribute('type', 'text/javascript');
js.setAttribute('src', script_filename);
html_doc.appendChild(js);
return false;
}
include_dom("json.js");
function sajax_debug(text) {
if (sajax_debug_mode)
alert("RSD: " + text)
if (sajax_debug_mode) {
if (debug) {
debug("RSD: " + text);
}
else {
alert("RSD: " + text);
}
}
}
function sajax_init_object() {
sajax_debug("sajax_init_object() called..")
......@@ -183,8 +176,14 @@ if (!isset($SAJAX_INCLUDED)) {
alert("Error: " + data);
else if (status == "+")
args[args.length-1](data);
else if (status == "$")
args[args.length-1](JSON.parse(data));
else if (status == "$") {
try {
args[args.length-1](JSON.parse(data));
}
catch(error) {
sajax_debug("callback error " + error);
}
}
}
x.send(post_data);
sajax_debug(func_name + " uri = " + uri + "/post = " + post_data);
......
var LOG_STATE_LOADING = 1;
var LOG_STATE_LOADED = 2;
/* The experiment pid/eid used when getting the pnode list. */
var exp_pid = "";
var exp_eid = "";
var pnodes = new Array(); // List of pnode names in longest to shortest order.
var lastLength = 0; // The length of the download text at the last check.
var lastLine = ""; // The last line of the download text.
/*
* The progress of the GetPNodes() call.
* 0 - Not called yet.
* 1 - Request sent, waiting for the reply.
* 2 - Reply received.
*/
var getPNodeProgress = 0;
var nextState = LOG_STATE_LOADING; // The state of the log download.
var docTriesLeft = 2; // Tries before giving up on getting the document.
/*
* True for the first line of the log. Used to counteract the hack that sends
* 1024 spaces to flush the log.
*/
var firstLine = true;
/*
* Start the interval that will read from the download iframe and update the
* main body of the document.
*/
var upInterval = setInterval('ml_handleReadyState(nextState)', 1000);
/* Callback for the GetPNodes ajax function. */
function GetPNodes_cb(data) {
pnodes = data;
getPNodeProgress = 2;
ml_handleReadyState(nextState);
}
/* Clear the various 'loading' indicators. */
function ml_loadFinished() {
clearInterval(upInterval);
var busyimg = document.getElementById('busy');
var loadingspan = document.getElementById('loading');
loadingspan.innerHTML = "";
busyimg.style.display = "none";
busyimg.src = "1px.gif";
nextState = LOG_STATE_LOADED;
}
/*
* @param ifr The iframe to retrieve the text from.
* @return The text in the given iframe. If the text is surrounded by '<pre>'
* tags (mozilla, IE), they will be stripped.
*/
function ml_getBodyText(ifr) {
var retval = null;
try {
var oDoc = (ifr.contentWindow || ifr.contentDocument);
if (oDoc.document) {
oDoc = oDoc.document;
}
retval = oDoc.body.innerHTML;
if (retval.indexOf("<pre>") != -1 || retval.indexOf("<PRE>") != -1) {
retval = retval.substring(5, retval.length - 6);
}
}
catch (error) {
}
return retval;
}
/* @return The innerHeight of the window. */
function ml_getInnerHeight() {
var retval;
if (self.innerHeight) // all except Explorer
retval = self.innerHeight;
else if (document.documentElement && document.documentElement.clientHeight)
// Explorer 6 Strict Mode
retval = document.documentElement.clientHeight;
else if (document.body) // other Explorers
retval = document.body.clientHeight;
return retval;
}
/* @return The scrollTop of the window. */
function ml_getScrollTop() {
var retval;
if (self.pageYOffset) // all except Explorer
retval = self.pageYOffset;
else if (document.documentElement && document.documentElement.scrollTop) // Explorer 6 Strict
retval = document.documentElement.scrollTop;
else if (document.body) // all other Explorers
retval = document.body.scrollTop;
return retval;
}
/* @return The height of the document. */
function ml_getScrollHeight() {
var retval;
var test1 = document.body.scrollHeight;
var test2 = document.body.offsetHeight;
if (test1 > test2) // all but Explorer Mac
retval = document.body.scrollHeight;
else // Explorer Mac;
//would also work in Explorer 6 Strict, Mozilla and Safari
retval = document.body.offsetHeight;
return retval;
}
/*
* Main function used to copy data from the download iframe to the body of the
* document.
*
* @param state The state of the download.
*/
function ml_handleReadyState(state) {
var oa = document.getElementById('outputarea');
var dl = document.getElementById('downloader');
if ((rt = ml_getBodyText(dl)) == null) {
/*
* Browsers that do not support DOMs for text/plain files or are a
* little slow in getting it setup will end up here. If we fail to
* get the document after a couple of tries, we bail out and just
* make the iframe visible.
*/
docTriesLeft -= 1;
if (docTriesLeft < 0) {
/* Give up, turn off the spinner and */
ml_loadFinished();
/* ... try to make the iframe visible. */
dl.border = 1;
dl.width = "90%";
dl.height = 500;
dl.style.width = "90%";
dl.style.height = 500;
dl.style.border = 1;
}
return;
}
if (state == LOG_STATE_LOADED) {
ml_loadFinished();
}
if (state == LOG_STATE_LOADING || state == LOG_STATE_LOADED) {
/*
* Get any new data and append it to the last line from the previous
* iteration (in case the line was only partially downloaded).
*/
var newData = lastLine + rt.substring(lastLength);
/* Look for assigns "signal" that the pnode list is available. */
if (newData.indexOf('Mapped to physical reality!') != -1) {
if (getPNodeProgress == 1) {
/* Still waiting for the reply. */
return;
}
else if (getPNodeProgress == 0) {
/* Send the request. */
getPNodeProgress = 1;
x_GetPNodes(exp_pid, exp_eid, GetPNodes_cb);
return;
}
}
lastLength = rt.length;
lastLine = "";
/*
* Record the size of the document before modifying it so we can see
* if we can automatically do the scroll.
*/
var ih = ml_getInnerHeight();
var y = ml_getScrollTop();
var h = ml_getScrollHeight();
var lines = newData.split("\n");
var plain = "";
/* Iterate over whatever lines we get. */
for (i = 0; i < lines.length - 1; i++) {
var line = lines[i];
var matches = new Array();
var lengths = new Array();
var hasError = 0;
/* Check for errors. */
if (line.indexOf('***') != -1) {
if (plain != "") {
tn = document.createTextNode(plain);
oa.appendChild(tn);
}
plain = "";
hasError = 1;
}
/*
* Look for pnodes to turn into links. The list is sorted by the
* length of the name so longer names will match before shorter
* (e.g. 'pc201' before 'pc2').
*/
for (lpc = 0; lpc < pnodes.length; lpc++) {
var pnode = pnodes[lpc];
var index = 0;
while ((index = line.indexOf(pnode, index)) != -1) {
/* Make sure a longer name was not already matched. */
if (!(index in lengths)) {
matches.push(index);
lengths[index] = pnode;
}
index += pnode.length;
}
}
/* Sort the indexes so we do them in order. */
matches.sort(function(a, b) { return a - b; });
var lastIndex = 0;
if (matches.length > 0) {
for (var j in matches) {
if (j == '______array') // js idiocy
continue;
index = matches[j];
pnode = lengths[index];
plain += line.substring(lastIndex, index);
tn = document.createTextNode(plain);
if (hasError) {
fn = document.createElement("font");
fn.setAttribute("color", "red");
fn.appendChild(tn);
oa.appendChild(fn);
}
else {
oa.appendChild(tn);
}
plain = "";
/* Create the link. */
var linktext = line.substring(index, index + pnode.length);
var nlink = document.createElement("A");
nlink.setAttribute('href',
'shownode.php3?node_id=' + pnode);
tn = document.createTextNode(linktext);
nlink.appendChild(tn);
oa.appendChild(nlink);
lastIndex = index + pnode.length;
}
}
else if (hasError) {
/* It is an error line, turn it red. */
tn = document.createTextNode(line);
fn = document.createElement("font");
fn.setAttribute("color", "red");
fn.appendChild(tn);
oa.appendChild(fn);
lastIndex = line.length;
}
if (!firstLine || line.search(/[^ \t\n]/) != -1) {
plain += line.substring(lastIndex) + "\n";
}
firstLine = false;
}
lastLine = lines[lines.length - 1];
if (state == LOG_STATE_LOADED)
plain += lastLine;
tn = document.createTextNode(plain);
oa.appendChild(tn);
var nh = ml_getScrollHeight();
/* See if we should scroll the window down. */
if ((h - (y + ih)) < (y == 0 ? 200 : 10)) {
document.documentElement.scrollTop = nh;
document.body.scrollTop = nh;
}
}
}
......@@ -7,44 +7,80 @@
include("defs.php3");
include("showstuff.php3");
#
# Standard Testbed Header
#
PAGEHEADER("Experiment Activity Log");
require("Sajax.php");
sajax_init();
sajax_export("GetPNodes");
# If this call is to client request function, then turn off interactive mode.
# All errors will go to above function and get reported back through the
# Sajax interface.
if (sajax_client_request()) {
$session_interactive = 0;
}
#
# Only known and logged in users can end experiments.
# Only known and logged in users can look at experiments.
#
$uid = GETLOGIN();
LOGGEDINORDIE($uid);
$isadmin = ISADMIN($uid);
#
# Verify page arguments.
#
if (!isset($pid) ||
strcmp($pid, "") == 0) {
USERERROR("You must provide a Project ID.", 1);
}
if (!isset($eid) ||
strcmp($eid, "") == 0) {
USERERROR("You must provide an Experiment ID.", 1);
function CHECKPAGEARGS($pid, $eid) {
global $uid, $TB_EXPT_READINFO;
#
# Verify page arguments.
#
if (!isset($pid) ||
strcmp($pid, "") == 0) {
USERERROR("You must provide a Project ID.", 1);
}
if (!isset($eid) ||
strcmp($eid, "") == 0) {
USERERROR("You must provide an Experiment ID.", 1);
}
#
# Check to make sure this is a valid PID/EID tuple.
#
if (! TBValidExperiment($pid, $eid)) {
USERERROR("The experiment $pid/$eid is not a valid experiment!", 1);
}
#
# Verify permission.
#
if (! TBExptAccessCheck($uid, $pid, $eid, $TB_EXPT_READINFO)) {
USERERROR("You do not have permission to view the log for $pid/$eid!", 1);
}
}
#
# Check to make sure this is a valid PID/EID tuple.
function GetPNodes($pid, $eid) {
CHECKPAGEARGS($pid, $eid);
$retval = array();
$query_result = DBQueryFatal(
"select r.node_id from reserved as r ".
"where r.eid='$eid' and r.pid='$pid' order by LENGTH(node_id) desc");
while ($row = mysql_fetch_array($query_result)) {
$retval[] = $row[node_id];
}
if (! TBValidExperiment($pid, $eid)) {
USERERROR("The experiment $pid/$eid is not a valid experiment!", 1);
return $retval;
}
# See if this request is to one of the above functions. Does not return
# if it is. Otherwise return and continue on.
sajax_handle_client_request();
CHECKPAGEARGS($pid, $eid);
#
# Verify permission.
# Standard Testbed Header
#
if (! TBExptAccessCheck($uid, $pid, $eid, $TB_EXPT_READINFO)) {
USERERROR("You do not have permission to view the log for $pid/$eid!", 1);
}
PAGEHEADER("Experiment Activity Log");
#
# Check for a logfile. This file is transient, so it could be gone by
......@@ -59,13 +95,29 @@ echo "<font size=+2>Experiment <b>".
"<a href='showexp.php3?pid=$pid&eid=$eid'>$eid</a></b></font>\n";
echo "<br /><br />\n";
echo "<center>
<iframe src=spewlogfile.php3?pid=$pid&eid=$eid
width=90% height=500 scrolling=auto frameborder=1>
Your user agent does not support frames or is currently configured
not to display frames. However, you may visit
<A href=spewlogfile.php3?pid=$pid&eid=$eid>the log file directly.</A>
</iframe></center>\n";
?>
<pre id='outputarea'>
</pre>
<br>
<img id='busy' src='busy.gif'><span id='loading'> Loading...</span>
<?php
echo "
<script type='text/javascript' language='javascript' src='json.js'></script>
<script type='text/javascript' language='javascript' src='mungelog.js'></script>\n";
echo "
<script type='text/javascript' language='javascript'>\n";
sajax_show_javascript();
echo "
exp_pid = \"$pid\";
exp_eid = \"$eid\";
</script>
<iframe id='downloader' name='downloader' width=0 height=0 src='spewlogfile.php3?pid=$pid&eid=$eid' onload='ml_handleReadyState(LOG_STATE_LOADED);' border=0 style='width:0px; height:0px; border: 0px'>
</iframe>\n";
#
# Standard Testbed Footer
......
Supports Markdown
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