Ejemplo n.º 1
0
 * @copyright  (C) 2006-2014 Adam Armstrong
 *
 */
echo " Adding MIN RRA to very old RRD files:" . PHP_EOL;
$graphdata['hr_processes'] = 'hr_processes.rrd';
$graphdata['hr_users'] = 'hr_users.rrd';
$graphdata['ucd_contexts'] = 'ucd_ssRawContexts.rrd';
$graphdata['ucd_load'] = 'ucd_load.rrd';
$graphdata['ucd_interrupts'] = 'ucd_ssRawInterrupts.rrd';
foreach ($graphdata as $graph => $graphfile) {
    echo "  * {$graph}: ";
    foreach (dbFetchRows("SELECT DISTINCT hostname FROM `device_graphs`,`devices` WHERE `devices`.device_id=`device_graphs`.device_id AND graph='{$graph}'") as $entry) {
        // get_rrd_path expects a $device array, but it only uses the 'hostname' index, so we get away with this.
        $filename = get_rrd_path($entry, $graphfile);
        if (file_exists($filename)) {
            $info = rrdtool_file_info($filename);
            $has_min = FALSE;
            foreach ($info['RRA'] as $rra) {
                if ($rra['cf'] == 'MIN') {
                    $has_min = TRUE;
                    break;
                }
            }
            if (!$has_min) {
                shell_exec("scripts/rrdtoolx.py addrra {$filename} {$filename}.new RRA:MIN:0.5:6:1440 RRA:MIN:0.5:96:360 RRA:MIN:0.5:288:1440");
                rename("{$filename}.new", $filename);
                echo "U";
            } else {
                echo '.';
            }
        }
Ejemplo n.º 2
0
/**
 * Poll a table or oids from SNMP and build an RRD based on an array of arguments.
 *
 * Current limitations:
 *  - single MIB and RRD file for all graphs
 *  - single table per MIB
 *  - if set definition 'call_function', than poll used specific function for snmp walk/get,
 *    else by default used snmpwalk_cache_oid()
 *  - allowed oids only with simple numeric index (oid.0, oid.33), NOT allowed (oid.1.2.23)
 *  - only numeric data
 *
 * Example of (full) args array:
 *  array(
 *   'file'          => 'someTable.rrd',              // [MANDATORY] RRD filename, but if not set used MIB_table.rrd as filename
 *   'call_function' => 'snmpwalk_cache_oid'          // [OPTIONAL] Which function to use for snmp poll, bu default snmpwalk_cache_oid()
 *   'mib'           => 'SOMETHING-MIB',              // [OPTIONAL] MIB or list of MIBs separated by a colon
 *   'mib_dir'       => 'something',                  // [OPTIONAL] OS MIB directory or array of directories
 *   'graphs'        => array('one','two'),           // [OPTIONAL] List of graph_types that this table provides
 *   'table'         => 'someTable',                  // [RECOMENDED] Table name for OIDs
 *   'numeric'       => '.1.3.6.1.4.1.555.4.1.1.48',  // [OPTIONAL] Numeric table OID
 *   'ds_rename'     => array('http' => ''),          // [OPTIONAL] Array for renaming OIDs to DSes
 *   'oids'          => array(                        // List of OIDs you can use as key: full OID name
 *     'someOid' => array(                                 // OID name (You can use OID name, like 'cpvIKECurrSAs')
 *       'descr'     => 'Current IKE SAs',                 // [OPTIONAL] Description of the OID contents
 *       'numeric'   => '.1.3.6.1.4.1.555.4.1.1.48.45',    // [OPTIONAL] Numeric OID
 *       'index'     => '0',                               // [OPTIONAL] OID index, if not set equals '0'
 *       'ds_name'   => 'IKECurrSAs',                      // [OPTIONAL] DS name, if not set used OID name truncated to 19 chars
 *       'ds_type'   => 'GAUGE',                           // [OPTIONAL] DS type, if not set equals 'COUNTER'
 *       'ds_min'    => '0',                               // [OPTIONAL] Min value for DS, if not set equals 'U'
 *       'ds_max'    => '30000'                            // [OPTIONAL] Max value for DS, if not set equals '100000000000'
 *    )
 *  )
 *
 */
function collect_table($device, $oids_def, &$graphs)
{
    $rrd = array();
    $mib = NULL;
    $mib_dirs = NULL;
    $use_walk = isset($oids_def['table']) && $oids_def['table'];
    // Use snmpwalk by default
    $call_function = strtolower($oids_def['call_function']);
    switch ($call_function) {
        case 'snmp_get_multi':
            $use_walk = FALSE;
            break;
        case 'snmpwalk_cache_oid':
        default:
            $call_function = 'snmpwalk_cache_oid';
            if (!$use_walk) {
                // Break because we should use snmpwalk, but walking table not set
                return FALSE;
            }
    }
    if (isset($oids_def['numeric'])) {
        $oids_def['numeric'] = '.' . trim($oids_def['numeric'], '. ');
    }
    // Remove trailing dot
    if (isset($oids_def['mib'])) {
        $mib = $oids_def['mib'];
    }
    if (isset($oids_def['mib_dir'])) {
        $mib_dirs = mib_dirs($oids_def['mib_dir']);
    }
    if (isset($oids_def['file'])) {
        $rrd_file = $oids_def['file'];
    } else {
        if ($mib && isset($oids_def['table'])) {
            // Try to use MIB & tableName as rrd_file
            $rrd_file = strtolower(safename($mib . '_' . $oids_def['table'])) . '.rrd';
        } else {
            print_debug("  WARNING, not have rrd filename.");
            return FALSE;
            // Not have RRD filename
        }
    }
    // Get MIBS/Tables/OIDs permissions
    if ($use_walk) {
        // if use table walk, than check only this table permission (not oids)
        if (dbFetchCell("SELECT COUNT(*) FROM `devices_mibs` WHERE `device_id` = ? AND `mib` = ? AND `table_name` = ?\n                    AND (`oid` = '' OR `oid` IS NULL) AND `disabled` = '1'", array($device['device_id'], $mib, $oids_def['table']))) {
            print_debug("  WARNING, table '" . $oids_def['table'] . "' for '{$mib}' disabled and skipped.");
            return FALSE;
            // table disabled, exit
        }
        $oids_ok = TRUE;
    } else {
        // if use multi_get, than get all disabled oids
        $oids_disabled = dbFetchColumn("SELECT `oid` FROM `devices_mibs` WHERE `device_id` = ? AND `mib` = ?\n                                   AND (`oid` != '' AND `oid` IS NOT NULL) AND `disabled` = '1'", array($device['device_id'], $mib));
        $oids_ok = empty($oids_disabled);
        // if empty disabled, than set to TRUE
    }
    $search = array();
    $replace = array();
    if (is_array($oids_def['ds_rename'])) {
        foreach ($oids_def['ds_rename'] as $s => $r) {
            $search[] = $s;
            $replace[] = $r;
        }
    }
    // rrd DS limit is 20 bytes (19 chars + NULL terminator)
    $ds_len = 19;
    $oids = array();
    $oids_index = array();
    foreach ($oids_def['oids'] as $oid => $entry) {
        if (is_numeric($entry['numeric']) && isset($oids_def['numeric'])) {
            $entry['numeric'] = $oids_def['numeric'] . '.' . $entry['numeric'];
            // Numeric oid, for future using
        }
        if (!isset($entry['index'])) {
            $entry['index'] = '0';
        }
        if (!isset($entry['ds_type'])) {
            $entry['ds_type'] = 'COUNTER';
        }
        if (!isset($entry['ds_min'])) {
            $entry['ds_min'] = 'U';
        }
        if (!isset($entry['ds_max'])) {
            $entry['ds_max'] = '100000000000';
        }
        if (!isset($entry['ds_name'])) {
            // Convert OID name to DS name
            $ds_name = $oid;
            if (is_array($oids_def['ds_rename'])) {
                $ds_name = str_replace($search, $replace, $ds_name);
            }
        } else {
            $ds_name = $entry['ds_name'];
        }
        if (strlen($ds_name) > $ds_len) {
            $ds_name = truncate($ds_name, $ds_len, '');
        }
        if (isset($oids_def['no_index']) && $oids_def['no_index'] == TRUE) {
            $oids[] = $oid;
        } else {
            $oids[] = $oid . '.' . $entry['index'];
        }
        $oids_index[] = array('index' => $entry['index'], 'oid' => $oid);
        if (!$use_walk) {
            // Check permissions for snmp_get_multi _ONLY_
            // if at least one oid missing in $oids_disabled than TRUE
            $oids_ok = $oids_ok || !in_array($oid, $oids_disabled);
        }
        $rrd['rrd_create'][] = ' DS:' . $ds_name . ':' . $entry['ds_type'] . ':600:' . $entry['ds_min'] . ':' . $entry['ds_max'];
        if ($GLOBALS['debug']) {
            $rrd['ds_list'][] = $ds_name;
        }
        // Make DS lists for compare with RRD file in debug
    }
    if (!$use_walk && !$oids_ok) {
        print_debug("  WARNING, oids '" . implode("', '", array_keys($oids_def['oids'])) . "' for '{$mib}' disabled and skipped.");
        return FALSE;
        // All oids disabled, exit
    }
    switch ($call_function) {
        case 'snmpwalk_cache_oid':
            $data = snmpwalk_cache_oid($device, $oids_def['table'], array(), $mib, $mib_dirs);
            break;
        case 'snmp_get_multi':
            $data = snmp_get_multi($device, $oids, "-OQUs", $mib, $mib_dirs);
            break;
    }
    if (isset($GLOBALS['exec_status']['exitcode']) && $GLOBALS['exec_status']['exitcode'] !== 0) {
        // Break because latest snmp walk/get return not good exitstatus (wrong mib/timeout/error/etc)
        print_debug("  WARNING, latest snmp walk/get return not good exitstatus for '{$mib}', RRD update skipped.");
        return FALSE;
    }
    if (isset($oids_def['no_index']) && $oids_def['no_index'] == TRUE) {
        $data[0] = $data[''];
    }
    foreach ($oids_index as $entry) {
        $index = $entry['index'];
        $oid = $entry['oid'];
        if (is_numeric($data[$index][$oid])) {
            $rrd['ok'] = TRUE;
            // We have any data for current rrd_file
            $rrd['rrd_update'][] = $data[$index][$oid];
        } else {
            $rrd['rrd_update'][] = 'U';
        }
    }
    // Ok, all previous checks done, update RRD, table/oids permissions, $graphs
    if (isset($rrd['ok']) && $rrd['ok']) {
        // Create/update RRD file
        $rrd_create = implode('', $rrd['rrd_create']);
        $rrd_update = 'N:' . implode(':', $rrd['rrd_update']);
        rrdtool_create($device, $rrd_file, $rrd_create);
        rrdtool_update($device, $rrd_file, $rrd_update);
        foreach ($oids_def['graphs'] as $graph) {
            $graphs[$graph] = TRUE;
            // Set all graphs to TRUE
        }
        // Compare DSes form RRD file with DSes from array
        if (OBS_DEBUG) {
            $graph_template = "\$config['graph_types']['device']['GRAPH_CHANGE_ME'] = array(\n";
            $graph_template .= "  'file'      => '{$rrd_file}',\n";
            $graph_template .= "  'ds'        => array(\n";
            $rrd_file_info = rrdtool_file_info(get_rrd_path($device, $rrd_file));
            foreach ($rrd_file_info['DS'] as $ds => $nothing) {
                $ds_list[] = $ds;
                $graph_template .= "    '{$ds}' => array('label' => '{$ds}'),\n";
            }
            $graph_template .= "  )\n);";
            $in_args = array_diff($rrd['ds_list'], $ds_list);
            if ($in_args) {
                print_message("%rWARNING%n, in file '%W" . $rrd_file_info['filename'] . "%n' different DS lists. NOT have: " . implode(', ', $in_args));
            }
            $in_file = array_diff($ds_list, $rrd['ds_list']);
            if ($in_file) {
                print_message("%rWARNING%n, in file '%W" . $rrd_file_info['filename'] . "%n' different DS lists. Excess: " . implode(', ', $in_file));
            }
            // Print example for graph template using rrd_file and ds list
            print_message($graph_template);
        }
    } else {
        if ($use_walk) {
            // Table NOT exist on device!
            // Disable polling table (only if table not enabled manually in DB)
            if (!dbFetchCell("SELECT COUNT(*) FROM `devices_mibs` WHERE `device_id` = ? AND `mib` = ?\n                     AND `table_name` = ? AND (`oid` = '' OR `oid` IS NULL)", array($device['device_id'], $mib, $oids_def['table']))) {
                dbInsert(array('device_id' => $device['device_id'], 'mib' => $mib, 'table_name' => $oids_def['table'], 'disabled' => '1'), 'devices_mibs');
            }
            print_debug("  WARNING, table '" . $oids_def['table'] . "' for '{$mib}' disabled.");
        } else {
            // OIDs NOT exist on device!
            // Disable polling oids (only if table not enabled manually in DB)
            foreach (array_keys($oids_def['oids']) as $oid) {
                if (!dbFetchCell("SELECT COUNT(*) FROM `devices_mibs` WHERE `device_id` = ? AND `mib` = ?\n                       AND `oid` = ?", array($device['device_id'], $mib, $oid))) {
                    dbInsert(array('device_id' => $device['device_id'], 'mib' => $mib, 'oid' => $oid, 'disabled' => '1'), 'devices_mibs');
                }
            }
            print_debug("  WARNING, oids '" . implode("', '", array_keys($oids_def['oids'])) . "' for '{$mib}' disabled.");
        }
    }
    // Return obtained snmp data
    return $data;
}
Ejemplo n.º 3
0
/**
 * Draw RRD file based on it's structure
 * @host
 * @plugin
 * @pinst
 * @type
 * @tinst
 * @opts
 * @return Commandline to call RRDGraph in order to generate the final graph
 */
function collectd_draw_rrd($host, $plugin, $pinst = null, $type, $tinst = null, $opts = array())
{
    global $config;
    $timespan_def = null;
    if (!isset($opts['timespan'])) {
        $timespan_def = reset($config['timespan']);
    } else {
        foreach ($config['timespan'] as &$ts) {
            if ($ts['name'] == $opts['timespan']) {
                $timespan_def = $ts;
            }
        }
    }
    if (!isset($opts['rrd_opts'])) {
        $opts['rrd_opts'] = array();
    }
    if (isset($opts['logarithmic']) && $opts['logarithmic']) {
        array_unshift($opts['rrd_opts'], '-o');
    }
    $rrdinfo = null;
    $rrdfile = sprintf('%s/%s%s%s/%s%s%s', $host, $plugin, is_null($pinst) ? '' : '-', $pinst, $type, is_null($tinst) ? '' : '-', $tinst);
    foreach ($config['datadirs'] as $datadir) {
        if (is_file($datadir . '/' . $rrdfile . '.rrd')) {
            $rrdinfo = rrdtool_file_info($datadir . '/' . $rrdfile . '.rrd');
            if (isset($rrdinfo['RRA']) && is_array($rrdinfo['RRA'])) {
                break;
            } else {
                $rrdinfo = null;
            }
        }
    }
    if (is_null($rrdinfo)) {
        return false;
    }
    $graph = array();
    $has_avg = false;
    $has_max = false;
    $has_min = false;
    reset($rrdinfo['RRA']);
    $l_max = 0;
    while (list($k, $v) = each($rrdinfo['RRA'])) {
        if ($v['cf'] == 'MAX') {
            $has_max = true;
        } else {
            if ($v['cf'] == 'AVERAGE') {
                $has_avg = true;
            } else {
                if ($v['cf'] == 'MIN') {
                    $has_min = true;
                }
            }
        }
    }
    // Build legend. This may not work for all RRDs, i don't know :)
    if ($has_avg) {
        $graph[] = "COMMENT:           Last";
    }
    if ($has_min) {
        $graph[] = "COMMENT:   Min";
    }
    if ($has_max) {
        $graph[] = "COMMENT:   Max";
    }
    if ($has_avg) {
        $graph[] = "COMMENT:   Avg\\n";
    }
    reset($rrdinfo['DS']);
    while (list($k, $v) = each($rrdinfo['DS'])) {
        if (strlen($k) > $l_max) {
            $l_max = strlen($k);
        }
        if ($has_min) {
            $graph[] = sprintf('DEF:%s_min=%s:%s:MIN', $k, $rrdinfo['filename'], $k);
        }
        if ($has_avg) {
            $graph[] = sprintf('DEF:%s_avg=%s:%s:AVERAGE', $k, $rrdinfo['filename'], $k);
        }
        if ($has_max) {
            $graph[] = sprintf('DEF:%s_max=%s:%s:MAX', $k, $rrdinfo['filename'], $k);
        }
    }
    if ($has_min && $has_max || $has_min && $has_avg || $has_avg && $has_max) {
        $n = 1;
        reset($rrdinfo['DS']);
        while (list($k, $v) = each($rrdinfo['DS'])) {
            $graph[] = sprintf('LINE:%s_%s', $k, $has_min ? 'min' : 'avg');
            $graph[] = sprintf('CDEF:%s_var=%s_%s,%s_%s,-', $k, $k, $has_max ? 'max' : 'avg', $k, $has_min ? 'min' : 'avg');
            $graph[] = sprintf('AREA:%s_var#%s::STACK', $k, rrd_get_color($n++, false));
        }
    }
    reset($rrdinfo['DS']);
    $n = 1;
    while (list($k, $v) = each($rrdinfo['DS'])) {
        $graph[] = sprintf('LINE1:%s_avg#%s:%s ', $k, rrd_get_color($n++, true), $k . substr('                  ', 0, $l_max - strlen($k)));
        if (isset($opts['tinylegend']) && $opts['tinylegend']) {
            continue;
        }
        if ($has_avg) {
            $graph[] = sprintf('GPRINT:%s_avg:AVERAGE:%%5.1lf%%s', $k, $has_max || $has_min || $has_avg ? ',' : "\\l");
        }
        if ($has_min) {
            $graph[] = sprintf('GPRINT:%s_min:MIN:%%5.1lf%%s', $k, $has_max || $has_avg ? ',' : "\\l");
        }
        if ($has_max) {
            $graph[] = sprintf('GPRINT:%s_max:MAX:%%5.1lf%%s', $k, $has_avg ? ',' : "\\l");
        }
        if ($has_avg) {
            $graph[] = sprintf('GPRINT:%s_avg:LAST:%%5.1lf%%s\\l', $k);
        }
    }
    #$rrd_cmd = array(RRDTOOL, 'graph', '-', '-E', '-a', 'PNG', '-w', $config['rrd_width'], '-h', $config['rrd_height'], '-t', $rrdfile);
    #$rrd_cmd = array(RRDTOOL, 'graph', '-', '-E', '-a', 'PNG', '-w', $config['rrd_width'], '-h', $config['rrd_height']);
    $rrd_cmd = array('-', '-E', '-a', 'PNG', '-w', $config['rrd_width'], '-h', $config['rrd_height']);
    if ($config['rrd_width'] <= "300") {
        $small_opts = array('--font', "LEGEND:7:mono", '--font', "AXIS:6:mono", "--font-render-mode", "normal");
        $rrd_cmd = array_merge($rrd_cmd, $small_opts);
    }
    $rrd_cmd = array_merge($rrd_cmd, $config['rrd_opts_array'], $opts['rrd_opts'], $graph);
    $cmd = RRDTOOL;
    $cmd = '';
    for ($i = 1; $i < count($rrd_cmd); $i++) {
        $cmd .= ' ' . escapeshellarg($rrd_cmd[$i]);
    }
    return $cmd;
}