newOption.value = options[i].firstChild ? options[i].firstChild.data : '';
if (keepSelection && newOption.value == oldValue)
newOption.setAttribute('selected', 'selected');
- if (keepSelection && optCnt == 1 && newOption.value == '@') {
+ if (newOption.value[0] == '@') {
newOption.setAttribute('style', 'font-style: italic');
- newOption.appendChild(document.createTextNode('Meta graph'));
+ if (newOption.value == '@' || newOption.value == '@merge')
+ newOption.appendChild(document.createTextNode('Meta graph'));
+ else if (newOption.value == '@all')
+ newOption.appendChild(document.createTextNode('All entries'));
+ else if (newOption.value == '@merge_sum')
+ newOption.appendChild(document.createTextNode('Meta summed graph'));
+ else if (newOption.value == '@merge_avg')
+ newOption.appendChild(document.createTextNode('Meta averaged graph'));
+ else if (newOption.value == '@merge_stack')
+ newOption.appendChild(document.createTextNode('Meta stacked graph'));
+ else if (newOption.value == '@merge_line')
+ newOption.appendChild(document.createTextNode('Meta lines graph'));
+ else
+ newOption.appendChild(document.createTextNode(newOption.value));
} else
newOption.appendChild(document.createTextNode(newOption.value));
select.appendChild(newOption);
var time_list = document.getElementById('timespan');
var timespan = time_list.selectedIndex >= 0 ? time_list.options[time_list.selectedIndex].value : '';
var tinyLegend = document.getElementById('tinylegend').checked;
- var logarithmic = document.getElementById('logarithmic').checked
- GraphDoAppend(host, plugin, pinst, type, tinst, timespan, tinyLegend, logarithmic);
+ var logarithmic = document.getElementById('logarithmic').checked;
+ if (host[0] == '@' || plugin[0] == '@' || pinst[0] == '@' || type[0] == '@' || (tinst[0] == '@' && tinst.substr(0, 5) != '@merge')) {
+ var query = 'action=list_graphs&host='+encodeURIComponent(host)+'&plugin='+encodeURIComponent(plugin)+'&plugin_instance='+encodeURIComponent(pinst);
+ query = query+'&type='+encodeURIComponent(type)+'&type_instance='+encodeURIComponent(tinst)+'×pan='+encodeURIComponent(timespan);
+ query = query+(logarithmic ? '&logarithmic=1' : '')+(tinyLegend ? '&tinylegend=1' : '');
+ loadXMLDoc(dhtml_url, query);
+ } else
+ GraphDoAppend(host, plugin, pinst, type, tinst, timespan, tinyLegend, logarithmic);
+}
+
+function ListOfGraph(response) {
+ var graphs = response ? response.getElementsByTagName('graph') : null;
+ if (graphs && graphs.length > 0) {
+ for (i = 0; i < graphs.length; i++)
+ GraphDoAppend(graphs[i].getAttribute('host'), graphs[i].getAttribute('plugin'), graphs[i].getAttribute('plugin_instance'),
+ graphs[i].getAttribute('type'), graphs[i].getAttribute('type_instance'), graphs[i].getAttribute('timespan'),
+ graphs[i].getAttribute('tinyLegend') == '1', graphs[i].getAttribute('logarithmic') == '1');
+ } else
+ alert('No graph found for adding');
}
function GraphDoAppend(host, plugin, pinst, type, tinst, timespan, tinyLegend, logarithmic) {
return 0;
}
-/**
- * Fetch list of hosts found in collectd's datadirs.
- * @return Sorted list of hosts (sorted by label from rigth to left)
- */
-function collectd_list_hosts() {
+function collectd_walk(&$options) {
global $config;
- $hosts = array();
foreach($config['datadirs'] as $datadir)
- if ($d = @opendir($datadir)) {
- while (($dent = readdir($d)) !== false)
- if ($dent != '.' && $dent != '..' && is_dir($datadir.'/'.$dent) && preg_match(REGEXP_HOST, $dent))
- $hosts[] = $dent;
- closedir($d);
+ if ($dh = @opendir($datadir)) {
+ while (($hdent = readdir($dh)) !== false) {
+ if ($hdent == '.' || $hdent == '..' || !is_dir($datadir.'/'.$hdent))
+ continue;
+ if (!preg_match(REGEXP_HOST, $hdent))
+ continue;
+ if (isset($options['cb_host']) && ($options['cb_host'] === false || !$options['cb_host']($options, $hdent)))
+ continue;
+
+ if ($dp = @opendir($datadir.'/'.$hdent)) {
+ while (($pdent = readdir($dp)) !== false) {
+ if ($pdent == '.' || $pdent == '..' || !is_dir($datadir.'/'.$hdent.'/'.$pdent))
+ continue;
+ if ($i = strpos($pdent, '-')) {
+ $plugin = substr($pdent, 0, $i);
+ $pinst = substr($pdent, $i+1);
+ } else {
+ $plugin = $pdent;
+ $pinst = '';
+ }
+ if (isset($options['cb_plugin']) && ($options['cb_plugin'] === false || !$options['cb_plugin']($options, $hdent, $plugin)))
+ continue;
+ if (isset($options['cb_pinst']) && ($options['cb_pinst'] === false || !$options['cb_pinst']($options, $hdent, $plugin, $pinst)))
+ continue;
+
+ if ($dt = @opendir($datadir.'/'.$hdent.'/'.$pdent)) {
+ while (($tdent = readdir($dt)) !== false) {
+ if ($tdent == '.' || $tdent == '..' || !is_file($datadir.'/'.$hdent.'/'.$pdent.'/'.$tdent))
+ continue;
+ if (substr($tdent, strlen($tdent)-4) != '.rrd')
+ continue;
+ $tdent = substr($tdent, 0, strlen($tdent)-4);
+ if ($i = strpos($tdent, '-')) {
+ $type = substr($tdent, 0, $i);
+ $tinst = substr($tdent, $i+1);
+ } else {
+ $type = $tdent;
+ $tinst = '';
+ }
+ if (isset($options['cb_type']) && ($options['cb_type'] === false || !$options['cb_type']($options, $hdent, $plugin, $pinst, $type)))
+ continue;
+ if (isset($options['cb_tinst']) && ($options['cb_tinst'] === false || !$options['cb_tinst']($options, $hdent, $plugin, $pinst, $type, $tinst)))
+ continue;
+ }
+ closedir($dt);
+ }
+ }
+ closedir($dp);
+ }
+ }
+ closedir($dh);
} else
error_log('Failed to open datadir: '.$datadir);
- $hosts = array_unique($hosts);
+ return true;
+}
+
+function _collectd_list_cb_host(&$options, $host) {
+ if ($options['cb_plugin'] === false) {
+ $options['result'][] = $host;
+ return false;
+ } else if (isset($options['filter_host'])) {
+ if ($options['filter_host'] == '@all') {
+ return true; // We take anything
+ } else if (substr($options['filter_host'], 0, 2) == '@.') {
+ if ($host == substr($options['filter_host'], 2) || substr($host, 0, 1-strlen($options['filter_host'])) == substr($options['filter_host'], 1))
+ return true; // Host part of domain
+ else
+ return false;
+ } else if ($options['filter_host'] == $host) {
+ return true;
+ } else
+ return false;
+ } else
+ return true;
+}
+
+function _collectd_list_cb_plugin(&$options, $host, $plugin) {
+ if ($options['cb_pinst'] === false) {
+ $options['result'][] = $plugin;
+ return false;
+ } else if (isset($options['filter_plugin'])) {
+ if ($options['filter_plugin'] == '@all')
+ return true;
+ else if ($options['filter_plugin'] == $plugin)
+ return true;
+ else
+ return false;
+ } else
+ return true;
+}
+
+function _collectd_list_cb_pinst(&$options, $host, $plugin, $pinst) {
+ if ($options['cb_type'] === false) {
+ $options['result'][] = $pinst;
+ return false;
+ } else if (isset($options['filter_pinst'])) {
+ if ($options['filter_pinst'] == '@all')
+ return true;
+ else if (strncmp($options['filter_pinst'], '@merge_', 7) == 0)
+ return true;
+ else if ($options['filter_pinst'] == $pinst)
+ return true;
+ else
+ return false;
+ } else
+ return true;
+}
+
+function _collectd_list_cb_type(&$options, $host, $plugin, $pinst, $type) {
+ if ($options['cb_tinst'] === false) {
+ $options['result'][] = $type;
+ return false;
+ } else if (isset($options['filter_type'])) {
+ if ($options['filter_type'] == '@all')
+ return true;
+ else if ($options['filter_type'] == $type)
+ return true;
+ else
+ return false;
+ } else
+ return true;
+}
+
+function _collectd_list_cb_tinst(&$options, $host, $plugin, $pinst, $type, $tinst) {
+ $options['result'][] = $tinst;
+ return false;
+}
+
+function _collectd_list_cb_graph(&$options, $host, $plugin, $pinst, $type, $tinst) {
+ if (isset($options['filter_tinst'])) {
+ if ($options['filter_tinst'] == '@all') {
+ } else if ($options['filter_tinst'] == $tinst) {
+ } else if (strncmp($options['filter_tinst'], '@merge', 6) == 0) {
+ // Need to exclude @merge with non-existent meta graph
+ } else
+ return false;
+ }
+ if (isset($options['filter_pinst']) && strncmp($options['filter_pinst'], '@merge', 6) == 0)
+ $pinst = $options['filter_pinst'];
+ if (isset($options['filter_tinst']) && strncmp($options['filter_tinst'], '@merge', 6) == 0)
+ $tinst = $options['filter_tinst'];
+ $ident = collectd_identifier($host, $plugin, $pinst, $type, $tinst);
+ if (!in_array($ident, $options['ridentifiers'])) {
+ $options['ridentifiers'][] = $ident;
+ $options['result'][] = array('host'=>$host, 'plugin'=>$plugin, 'pinst'=>$pinst, 'type'=>$type, 'tinst'=>$tinst);
+ }
+}
+
+/**
+ * Fetch list of hosts found in collectd's datadirs.
+ * @return Sorted list of hosts (sorted by label from rigth to left)
+ */
+function collectd_list_hosts() {
+ $options = array(
+ 'result' => array(),
+ 'cb_host' => '_collectd_list_cb_host',
+ 'cb_plugin' => false,
+ 'cb_pinst' => false,
+ 'cb_type' => false,
+ 'cb_tinst' => false
+ );
+ collectd_walk($options);
+ $hosts = array_unique($options['result']);
usort($hosts, 'collectd_compare_host');
return $hosts;
}
* @arg_host Name of host for which to return plugins
* @return Sorted list of plugins (sorted alphabetically)
*/
-function collectd_list_plugins($arg_host) {
- global $config;
-
- $plugins = array();
- foreach ($config['datadirs'] as $datadir)
- if (preg_match(REGEXP_HOST, $arg_host) && ($d = @opendir($datadir.'/'.$arg_host))) {
- while (($dent = readdir($d)) !== false)
- if ($dent != '.' && $dent != '..' && is_dir($datadir.'/'.$arg_host.'/'.$dent)) {
- if ($i = strpos($dent, '-'))
- $plugins[] = substr($dent, 0, $i);
- else
- $plugins[] = $dent;
- }
- closedir($d);
- }
- $plugins = array_unique($plugins);
+function collectd_list_plugins($arg_host, $arg_plugin = null) {
+ $options = array(
+ 'result' => array(),
+ 'cb_host' => '_collectd_list_cb_host',
+ 'cb_plugin' => '_collectd_list_cb_plugin',
+ 'cb_pinst' => is_null($arg_plugin) ? false : '_collectd_list_cb_pinst',
+ 'cb_type' => false,
+ 'cb_tinst' => false,
+ 'filter_host' => $arg_host,
+ 'filter_plugin' => $arg_plugin
+ );
+ collectd_walk($options);
+ $plugins = array_unique($options['result']);
sort($plugins);
return $plugins;
}
/**
- * Fetch list of plugin instances found in collectd's datadirs for given host+plugin
- * @arg_host Name of host
- * @arg_plugin Name of plugin
- * @return Sorted list of plugin instances (sorted alphabetically)
- */
-function collectd_list_pinsts($arg_host, $arg_plugin) {
- global $config;
-
- $pinsts = array();
- foreach ($config['datadirs'] as $datadir)
- if (preg_match(REGEXP_HOST, $arg_host) && ($d = opendir($datadir.'/'.$arg_host))) {
- while (($dent = readdir($d)) !== false)
- if ($dent != '.' && $dent != '..' && is_dir($datadir.'/'.$arg_host.'/'.$dent)) {
- if ($i = strpos($dent, '-')) {
- $plugin = substr($dent, 0, $i);
- $pinst = substr($dent, $i+1);
- } else {
- $plugin = $dent;
- $pinst = '';
- }
- if ($plugin == $arg_plugin)
- $pinsts[] = $pinst;
- }
- closedir($d);
- }
- $pinsts = array_unique($pinsts);
- sort($pinsts);
- return $pinsts;
-}
-
-/**
* Fetch list of types found in collectd's datadirs for given host+plugin+instance
* @arg_host Name of host
* @arg_plugin Name of plugin
* @arg_pinst Plugin instance
* @return Sorted list of types (sorted alphabetically)
*/
-function collectd_list_types($arg_host, $arg_plugin, $arg_pinst) {
- global $config;
-
- $types = array();
- $my_plugin = $arg_plugin . (strlen($arg_pinst) ? '-'.$arg_pinst : '');
- if (!preg_match(REGEXP_PLUGIN, $my_plugin))
- return $types;
- foreach ($config['datadirs'] as $datadir)
- if (preg_match(REGEXP_HOST, $arg_host) && ($d = @opendir($datadir.'/'.$arg_host.'/'.$my_plugin))) {
- while (($dent = readdir($d)) !== false)
- if ($dent != '.' && $dent != '..' && is_file($datadir.'/'.$arg_host.'/'.$my_plugin.'/'.$dent) && substr($dent, strlen($dent)-4) == '.rrd') {
- $dent = substr($dent, 0, strlen($dent)-4);
- if ($i = strpos($dent, '-'))
- $types[] = substr($dent, 0, $i);
- else
- $types[] = $dent;
- }
- closedir($d);
- }
- $types = array_unique($types);
+function collectd_list_types($arg_host, $arg_plugin, $arg_pinst, $arg_type = null) {
+ $options = array(
+ 'result' => array(),
+ 'cb_host' => '_collectd_list_cb_host',
+ 'cb_plugin' => '_collectd_list_cb_plugin',
+ 'cb_pinst' => '_collectd_list_cb_pinst',
+ 'cb_type' => '_collectd_list_cb_type',
+ 'cb_tinst' => is_null($arg_type) ? false : '_collectd_list_cb_tinst',
+ 'filter_host' => $arg_host,
+ 'filter_plugin' => $arg_plugin,
+ 'filter_pinst' => $arg_pinst,
+ 'filter_type' => $arg_type
+ );
+ collectd_walk($options);
+ $types = array_unique($options['result']);
sort($types);
return $types;
}
-/**
- * Fetch list of type instances found in collectd's datadirs for given host+plugin+instance+type
- * @arg_host Name of host
- * @arg_plugin Name of plugin
- * @arg_pinst Plugin instance
- * @arg_type Type
- * @return Sorted list of type instances (sorted alphabetically)
- */
-function collectd_list_tinsts($arg_host, $arg_plugin, $arg_pinst, $arg_type) {
- global $config;
-
- $tinsts = array();
- $my_plugin = $arg_plugin . (strlen($arg_pinst) ? '-'.$arg_pinst : '');
- if (!preg_match(REGEXP_PLUGIN, $my_plugin))
- return $types;
- foreach ($config['datadirs'] as $datadir)
- if (preg_match(REGEXP_HOST, $arg_host) && ($d = @opendir($datadir.'/'.$arg_host.'/'.$my_plugin))) {
- while (($dent = readdir($d)) !== false)
- if ($dent != '.' && $dent != '..' && is_file($datadir.'/'.$arg_host.'/'.$my_plugin.'/'.$dent) && substr($dent, strlen($dent)-4) == '.rrd') {
- $dent = substr($dent, 0, strlen($dent)-4);
- if ($i = strpos($dent, '-')) {
- $type = substr($dent, 0, $i);
- $tinst = substr($dent, $i+1);
- } else {
- $type = $dent;
- $tinst = '';
- }
- if ($type == $arg_type)
- $tinsts[] = $tinst;
- }
- closedir($d);
- }
- $tinsts = array_unique($tinsts);
- sort($tinsts);
- return $tinsts;
+function collectd_list_graphs($arg_host, $arg_plugin, $arg_pinst, $arg_type, $arg_tinst) {
+ $options = array(
+ 'result' => array(),
+ 'ridentifiers' => array(),
+ 'cb_host' => '_collectd_list_cb_host',
+ 'cb_plugin' => '_collectd_list_cb_plugin',
+ 'cb_pinst' => '_collectd_list_cb_pinst',
+ 'cb_type' => '_collectd_list_cb_type',
+ 'cb_tinst' => '_collectd_list_cb_graph',
+ 'filter_host' => $arg_host,
+ 'filter_plugin' => $arg_plugin,
+ 'filter_pinst' => $arg_pinst,
+ 'filter_type' => $arg_type,
+ 'filter_tinst' => $arg_tinst == '@' ? '@merge' : $arg_tinst
+ );
+ collectd_walk($options);
+ return $options['result'];
}
/**
print("</response>");
}
+function dhtml_response_graphs(&$graphs, $method) {
+ header("Content-Type: text/xml");
+
+ print('<?xml version="1.0" encoding="utf-8" ?>'."\n");
+ print("<response>\n");
+ printf(" <method>%s</method>\n", htmlspecialchars($method));
+ print(" <result>\n");
+ foreach ($graphs as &$graph)
+ printf(' <graph host="%s" plugin="%s" plugin_instance="%s" type="%s" type_instance="%s" timespan="%s" logarithmic="%d" tinyLegend="%d" />'."\n",
+ htmlspecialchars($graph['host']), htmlspecialchars($graph['plugin']), htmlspecialchars($graph['pinst']),
+ htmlspecialchars($graph['type']), htmlspecialchars($graph['tinst']), htmlspecialchars($graph['timespan']),
+ htmlspecialchars($graph['logarithmic']), htmlspecialchars($graph['tinyLegend']));
+ print(" </result>\n");
+ print("</response>");
+}
+
/**
* Product page body with selection fields
*/
case 'list_hosts':
// Generate a list of hosts
$hosts = collectd_list_hosts();
+ if (count($hosts) > 1)
+ array_unshift($hosts, '@all');
return dhtml_response_list($hosts, 'ListOfHost');
case 'list_plugins':
// Generate list of plugins for selected hosts
- $arg_hosts = read_var('host', $_POST, array());
- if (!is_array($arg_hosts))
- $arg_hosts = array($arg_hosts);
- $plugins = collectd_list_plugins(reset($arg_hosts));
+ $arg_hosts = read_var('host', $_POST, '');
+ if (is_array($arg_hosts))
+ $arg_hosts = reset($arg_hosts);
+ $plugins = collectd_list_plugins($arg_hosts);
+ if (count($plugins) > 1)
+ array_unshift($plugins, '@all');
return dhtml_response_list($plugins, 'ListOfPlugin');
case 'list_pinsts':
// Generate list of plugin_instances for selected hosts and plugin
- $arg_hosts = read_var('host', $_POST, array());
- if (!is_array($arg_hosts))
- $arg_hosts = array($arg_hosts);
+ $arg_hosts = read_var('host', $_POST, '');
+ if (is_array($arg_hosts))
+ $arg_hosts = reset($arg_hosts);
$arg_plugin = read_var('plugin', $_POST, '');
- $pinsts = collectd_list_pinsts(reset($arg_hosts), $arg_plugin);
+ $pinsts = collectd_list_plugins($arg_hosts, $arg_plugin);
+ if (count($pinsts) > 1)
+ array_unshift($pinsts, '@all' /* , '@merge_sum', '@merge_avg', '@merge_stack', '@merge_line' */);
return dhtml_response_list($pinsts, 'ListOfPluginInstance');
case 'list_types':
// Generate list of types for selected hosts, plugin and plugin-instance
- $arg_hosts = read_var('host', $_POST, array());
- if (!is_array($arg_hosts))
- $arg_hosts = array($arg_hosts);
+ $arg_hosts = read_var('host', $_POST, '');
+ if (is_array($arg_hosts))
+ $arg_hosts = reset($arg_hosts);
$arg_plugin = read_var('plugin', $_POST, '');
$arg_pinst = read_var('plugin_instance', $_POST, '');
- $types = collectd_list_types(reset($arg_hosts), $arg_plugin, $arg_pinst);
+ $types = collectd_list_types($arg_hosts, $arg_plugin, $arg_pinst);
+ if (count($types) > 1)
+ array_unshift($types, '@all');
return dhtml_response_list($types, 'ListOfType');
case 'list_tinsts':
// Generate list of types for selected hosts, plugin and plugin-instance
- $arg_hosts = read_var('host', $_POST, array());
- if (!is_array($arg_hosts))
- $arg_hosts = array($arg_hosts);
+ $arg_hosts = read_var('host', $_POST, '');
+ if (is_array($arg_hosts))
+ $arg_hosts = reset($arg_hosts);
$arg_plugin = read_var('plugin', $_POST, '');
$arg_pinst = read_var('plugin_instance', $_POST, '');
$arg_type = read_var('type', $_POST, '');
- $tinsts = collectd_list_tinsts(reset($arg_hosts), $arg_plugin, $arg_pinst, $arg_type);
- if (count($tinsts)) {
- require('definitions.php');
- load_graph_definitions();
- if (isset($MetaGraphDefs[$arg_type])) {
- $meta_tinsts = array('@');
- return dhtml_response_list($meta_tinsts, 'ListOfTypeInstance');
+ $tinsts = collectd_list_types($arg_hosts, $arg_plugin, $arg_pinst, $arg_type);
+ if (count($tinsts))
+ if ($arg_type != '@all') {
+ require('definitions.php');
+ load_graph_definitions();
+ if (isset($MetaGraphDefs[$arg_type]))
+ array_unshift($tinsts, '@merge');
+ if (count($tinsts) > 1)
+ array_unshift($tinsts, '@all');
+ } else {
+ array_unshift($tinsts, /* '@merge_sum', '@merge_avg', '@merge_stack', '@merge_line', */ '@merge');
+ if (count($tinsts) > 1)
+ array_unshift($tinsts, '@all');
}
- }
return dhtml_response_list($tinsts, 'ListOfTypeInstance');
+ case 'list_graphs':
+ // Generate list of types for selected hosts, plugin and plugin-instance
+ $arg_hosts = read_var('host', $_POST, '');
+ if (is_array($arg_hosts))
+ $arg_hosts = reset($arg_hosts);
+ $arg_plugin = read_var('plugin', $_POST, '');
+ $arg_pinst = read_var('plugin_instance', $_POST, '');
+ $arg_type = read_var('type', $_POST, '');
+ $arg_tinst = read_var('type_instance', $_POST, '');
+ $arg_log = (int)read_var('logarithmic', $_POST, '0');
+ $arg_legend = (int)read_var('tinyLegend', $_POST, '0');
+ $arg_period = read_var('timespan', $_POST, '');
+ $graphs = collectd_list_graphs($arg_hosts, $arg_plugin, $arg_pinst, $arg_type, $arg_tinst);
+ foreach ($graphs as &$graph) {
+ $graph['logarithmic'] = $arg_log;
+ $graph['tinyLegend'] = $arg_legend;
+ $graph['timespan'] = $arg_period;
+ }
+ return dhtml_response_graphs($graphs, 'ListOfGraph');
+
case 'overview':
default:
return build_page();