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 .= ""; for ($j=0;$j<$cols and $j<$count;$j++) { $k=$i*$cols+$j; if ($k>=$count) break; $snaptable .= "". "$names[$k]". "\n"; } $snaptable .= ""; for ($j=0;$j<$cols and $j<$count;$j++) { $k=$i*$cols+$j; if ($k>=$count) break; $name = $names[$k]; $nameurl=rawurlencode($name); $snaptable .= ""; if ($grids[$name]) { $snaptable .= ""; } else { $snaptable .= ""; } $snaptable .= "". "". "\n"; } $snaptable .= "\n"; } $tpl->assign("snapshot", $snaptable); } $tpl->printToScreen(); ?>