prepare();
# Find the private clusters. But no one is emabarrassed in the
# control room (public only!).
if ( $context != "control" ) {
$private=embarrassed();
}
# Build a list of cluster names and randomly pick a smaller subset to
# display for control room mode. This allows a dedicated host to
# eventually cycle through all the graphs w/o scrolling the mouse. A bunch
# of these stations could monitor a large grid.
#
# For the standard meta view still display all the hosts.
# Returns the sum of a given metric accross a source.
function source_reduce ($source, $metric)
{
global $grids;
if ($grids[$source]) {
return $grids[$source][$metric];
}
else {
return __reduce($metric, __sum, $source);
}
}
# Returns the number of nodes in a source. $metric = "HOSTS_UP | HOSTS_DOWN".
function source_count ($source, $metric)
{
global $grids, $clusters;
if ($grids[$source]) {
$val = $grids[$source][$metric];
}
else {
$val = $clusters[$source][$metric];
}
if (!$val) return 0;
else return $val;
}
foreach ( $grids as $key => $val ) {
if ($key!=$self and $grids[$key]["HOSTS_UP"]>0)
$source_names[] = $key;
}
foreach ( $clusters as $key => $val ) {
# Show all clusters, even ones with no alive hosts.
# Important for forensic analysis.
$source_names[] = $key;
}
if ( $context == "control" ) {
srand((double)microtime()*1000000);
shuffle($source_names);
$subset = array_slice($source_names, 0, abs($controlroom));
$source_names = $subset;
}
foreach( $source_names as $c) {
$cpucount = source_reduce($c, "cpu_num");
if (!$cpucount) $cpucount=1;
$load_one = source_reduce($c, "load_one");
$value = ((float) $load_one)/$cpucount;
$sorted_sources[$c] = $value;
}
if ($sort == "descending") {
arsort($sorted_sources);
}
else {
asort($sorted_sources);
}
# Add our self grid to beginning of array if needed. Cleaner than before,
# where we treated the first grid (MetaCluster) separately.
if ($context != "control" or $controlroom > 0)
$sorted_sources = array_merge(array($self=>"0"), $sorted_sources);
$num_sources = count($sorted_sources) - 1;
# Display the sources. The first is ourself, the rest are our children.
foreach ( $sorted_sources as $key => $val ) {
$num_nodes = source_count($key, "HOSTS_UP");
# This value is used as a divisor, and cannot be zero.
if (!$num_nodes) $num_nodes=1;
$num_dead_nodes = source_count($key, "HOSTS_DOWN");
$sourceURL = rawurlencode($key);
if ($grids[$key]) {
# Is this the our own grid?
if ($key==$self) {
$name = "$self $meta_designator ($num_sources sources)";
# Set meta context.
$graph_url = "me=$sourceURL&$get_metric_string";
$url = "./?$get_metric_string";
}
else {
# Set grid context.
$name = "$key $meta_designator";
$graph_url = "G=$sourceURL&$get_metric_string";
$authority = $grids[$key][AUTHORITY];
$url = "$authority?gw=fwd&gs=$GridstackURL";
}
$localtime = "";
$alt_url = "(tree view)";
$class = "grid";
}
else {
# Set cluster context.
$name = $key;
$graph_url = "c=$sourceURL&$get_metric_string";
$url = "./?$graph_url";
$alt_url = "(physical view)";
$localtime = "Cluster Localtime:
" . date("F j, Y, g:i a", $clusters[$key][LOCALTIME]) .
"
";
$class = "cluster";
}
$tpl->newBlock ("cluster_info");
$tpl->assign("name", $name );
$tpl->assign("cpu_num", source_reduce($key, "cpu_num"));
$tpl->assign("url", $url);
$tpl->assign("class", $class);
$tpl->assign("localtime", $localtime);
# I dont like this either, but we need to have private clusters because some
# users are skittish about publishing the load info.
if (!$private[$key]) {
$tpl->assign("alt_view", "$alt_url");
$tpl->assign("load_one", sprintf("%.2f", source_reduce($key, "load_one")));
$tpl->assign("load_five", sprintf("%.2f", source_reduce($key, "load_five")));
$tpl->assign("load_fifteen", sprintf("%.2f",source_reduce($key, "load_fifteen")));
$tpl->assign("cpu_user", sprintf("%.1f", source_reduce($key, "cpu_user")/$num_nodes));
$tpl->assign("cpu_nice", sprintf("%.1f", source_reduce($key, "cpu_nice")/$num_nodes));
$tpl->assign("cpu_system", sprintf("%.1f", source_reduce($key, "cpu_system")/$num_nodes));
$tpl->assign("cpu_idle", sprintf("%.1f", source_reduce($key, "cpu_idle")/$num_nodes));
# Each block has a different namespace, so we need to redefine variables.
$tpl->newBlock("public");
$tpl->assign("cpu_num", source_reduce($key, "cpu_num"));
# The next value should be true (0 if necessary). It is not a divisor.
$tpl->assign("num_nodes", source_count($key, "HOSTS_UP") );
$tpl->assign("num_dead_nodes", $num_dead_nodes );
$tpl->assign("range", $range);
$tpl->assign("name", $name );
$tpl->assign("url", $url);
$tpl->assign("graph_url", $graph_url);
}
else {
$tpl->newBlock("private");
$tpl->assign("num_nodes", source_count($key, "HOSTS_UP") + $num_dead_nodes);
$tpl->assign("cpu_num", source_reduce($key, "cpu_num"));
}
}
# Show load images.
if ($show_meta_snapshot=="yes") {
$tpl->newBlock("show_snapshot");
$tpl->assign("self", "$self $meta_designator");
foreach ($sorted_sources as $c=>$value) {
if ($c==$self)
continue;
if ($private[$c]) {
$Private[$c] = template("images/cluster_private.jpg");
continue;
}
if ($grids[$c])
$image = load_image("grid", $value);
else
$image = load_image("cluster", $value);
$names[]=$c;
$Images[]=$image;
}
# Add private cluster pictures to the end.
if (is_array($Private)) {
foreach ($Private as $c=>$image) {
$names[]=$c;
$Images[]=$image;
}
}
# All this fancyness is to get the Cluster names
# above the image. Not easy with template blocks.
$cols=5;
$count=count($names);
$rows=ceil($count/$cols);
$snaptable="";
for ($i=0; $i<$rows; $i++) {
$snaptable .= "