function discover_processor(&$valid, $device, $processor_oid, $processor_index, $processor_type, $processor_descr, $processor_precision = 1, $value = NULL, $entPhysicalIndex = NULL, $hrDeviceIndex = NULL, $processor_returns_idle = 0) { global $config; print_debug($device['device_id'] . " -> {$processor_oid}, {$processor_index}, {$processor_type}, {$processor_descr}, {$processor_precision}, {$value}, {$entPhysicalIndex}, {$hrDeviceIndex}"); // Check processor description if (!$processor_descr) { print_debug("Skipped by empty description: {$processor_descr} "); return FALSE; } else { $processor_descr = substr($processor_descr, 0, 64); // Limit descr to 64 chars accordingly as in DB } // Skip discovery processor if value not numeric or null(default) if ($value !== NULL) { $value = snmp_fix_numeric($value); } // Remove unnecessary spaces if (!(is_numeric($value) || $value === NULL)) { print_debug("Skipped by not numeric value: {$value}, {$processor_descr} "); return FALSE; } // Check processor ignore filters foreach ($config['ignore_processor'] as $bi) { if (strcasecmp($bi, $processor_descr) == 0) { print_debug("Skipped by equals: {$bi}, {$processor_descr} "); return FALSE; } } foreach ($config['ignore_processor_string'] as $bi) { if (stripos($processor_descr, $bi) !== FALSE) { print_debug("Skipped by strpos: {$bi}, {$processor_descr} "); return FALSE; } } foreach ($config['ignore_processor_regexp'] as $bi) { if (preg_match($bi, $processor_descr) > 0) { print_debug("Skipped by regexp: {$bi}, {$processor_descr} "); return FALSE; } } $params = array('processor_index', 'entPhysicalIndex', 'hrDeviceIndex', 'processor_oid', 'processor_type', 'processor_descr', 'processor_precision', 'processor_returns_idle'); //$params_state = array('processor_usage'); $processor_db = dbFetchRow("SELECT * FROM `processors` WHERE `device_id` = ? AND `processor_index` = ? AND `processor_type` = ?", array($device['device_id'], $processor_index, $processor_type)); if (!isset($processor_db['processor_id'])) { $update = array('device_id' => $device['device_id']); if (!$processor_precision) { $processor_precision = 1; } foreach ($params as $param) { $update[$param] = ${$param} === NULL ? array('NULL') : ${$param}; } $id = dbInsert($update, 'processors'); if ($processor_precision != 1) { $value = round($value / $processor_precision, 2); } // The OID returns idle value, so we subtract it from 100. if ($processor_returns_idle) { $value = 100 - $value; } $update_state = array('processor_id' => $id, 'processor_usage' => $value); //foreach ($params_state as $param) { $update_state[$param] = $$param; } dbInsert($update_state, 'processors-state'); $GLOBALS['module_stats']['processors']['added']++; //echo('+'); log_event("Processor added: index {$processor_index}, type {$processor_type}, descr {$processor_descr}", $device, 'processor', $id); } else { $update = array(); foreach ($params as $param) { if (${$param} != $processor_db[$param]) { $update[$param] = ${$param} === NULL ? array('NULL') : ${$param}; } } if (count($update)) { dbUpdate($update, 'processors', '`processor_id` = ?', array($processor_db['processor_id'])); $GLOBALS['module_stats']['processors']['updated']++; //echo('U'); log_event("Processor updated: index {$processor_index}, mib {$processor_type}, descr {$processor_descr}", $device, 'processor', $processor_db['processor_id']); } else { $GLOBALS['module_stats']['processors']['unchanged']++; //echo('.'); } } $valid[$processor_type][$processor_index] = 1; }
function poll_status($device) { global $config, $agent_sensors, $ipmi_sensors, $graphs, $oid_cache; $sql = "SELECT * FROM `status`"; $sql .= " LEFT JOIN `status-state` USING(`status_id`)"; $sql .= " WHERE `device_id` = ?"; foreach (dbFetchRows($sql, array($device['device_id'])) as $status_db) { //print_cli_heading("Status: ".$status_db['status_descr']. "(".$status_db['poller_type'].")", 3); print_debug("Checking (" . $status_db['poller_type'] . ") " . $status_db['status_descr'] . " "); // $status_poll = $status_db; // Cache non-humanized status array for use as new status state if ($status_db['poller_type'] == "snmp") { // Check if a specific poller file exists for this status, else collect via SNMP. $file = $config['install_dir'] . "/includes/polling/status/" . $status_db['status_type'] . ".inc.php"; if (is_file($file)) { include $file; } else { // Take value from $oid_cache if we have it, else snmp_get it if (is_numeric($oid_cache[$status_db['status_oid']])) { print_debug("value taken from oid_cache"); $status_value = $oid_cache[$status_db['status_oid']]; } else { $status_value = snmp_get($device, $status_db['status_oid'], "-OUqnv", "SNMPv2-MIB"); } $status_value = snmp_fix_numeric($status_value); } } else { if ($status_db['poller_type'] == "agent") { if (isset($agent_sensors['state'])) { $status_value = $agent_sensors['state'][$status_db['status_type']][$status_db['status_index']]['current']; } else { print_warning("No agent status data available."); continue; } } else { if ($status_db['poller_type'] == "ipmi") { if (isset($ipmi_sensors['state'])) { $status_value = $ipmi_sensors['state'][$status_db['status_type']][$status_db['status_index']]['current']; } else { print_warning("No IPMI status data available."); continue; } } else { print_warning("Unknown status poller type."); continue; } } } $status_polled_time = time(); // Store polled time for current status // Write new value and humanize (for alert checks) $state_array = get_state_array($status_db['status_type'], $status_value, $status_db['poller_type']); $status_poll['status_value'] = $state_array['value']; $status_poll['status_name'] = $state_array['name']; if ($status_db['status_ignore'] || $status_db['status_disable']) { $status_poll['status_event'] = 'ignore'; } else { $status_poll['status_event'] = $state_array['event']; } // If last change never set, use current time if (empty($status_db['status_last_change'])) { $status_db['status_last_change'] = $status_polled_time; } if ($status_poll['status_event'] != $status_db['status_event']) { // Status event changed, log and set status_last_change $status_poll['status_last_change'] = $status_polled_time; if ($status_poll['status_event'] == 'ignore') { print_message("[%ystatus Ignored%n]", 'color'); } else { if ($status_db['status_event'] != '') { // If old state not empty and new state not equals to new state $msg = 'Status '; switch ($status_poll['status_event']) { case 'alert': // New state alerted $msg .= "Alert: " . $device['hostname'] . " " . $status_db['status_descr'] . " entered ALERT state: " . $status_poll['status_name'] . " (previous: " . $status_db['status_name'] . ")"; log_event($msg, $device, 'status', $status_db['status_id'], 'warning'); break; case 'warning': // New state warned $msg .= "Warning: " . $device['hostname'] . " " . $status_db['status_descr'] . " entered WARNING state: " . $status_poll['status_name'] . " (previous: " . $status_db['status_name'] . ")"; log_event($msg, $device, 'status', $status_db['status_id']); break; case 'ok': // New state ok $msg .= "Ok: " . $device['hostname'] . " " . $status_db['status_descr'] . " entered OK state: " . $status_poll['status_name'] . " (previous: " . $status_db['status_name'] . ")"; log_event($msg, $device, 'status', $status_db['status_id'], 'warning'); break; } } } } else { // If status not changed, leave old last_change $status_poll['status_last_change'] = $status_db['status_last_change']; } if (OBS_DEBUG > 1) { print_vars($status_poll); } // Send statistics array via AMQP/JSON if AMQP is enabled globally and for the ports module if ($config['amqp']['enable'] == TRUE && $config['amqp']['modules']['status']) { $json_data = array('value' => $status_value); messagebus_send(array('attribs' => array('t' => time(), 'device' => $device['hostname'], 'device_id' => $device['device_id'], 'e_type' => 'status', 'e_type' => $status_db['status_type'], 'e_index' => $status_db['status_index']), 'data' => $json_data)); } // Update StatsD/Carbon if ($config['statsd']['enable'] == TRUE) { StatsD::gauge(str_replace(".", "_", $device['hostname']) . '.' . 'status' . '.' . $status_db['status_class'] . '.' . $status_db['status_type'] . '.' . $status_db['status_index'], $status_value); } // Update RRD - FIXME - can't convert to NG because filename is dynamic! new function should return index instead of filename. $rrd_file = get_status_rrd($device, $status_db); rrdtool_create($device, $rrd_file, "DS:status:GAUGE:600:-20000:U"); rrdtool_update($device, $rrd_file, "N:{$status_value}"); // Enable graph $graphs[$sensor_db['status']] = TRUE; // Check alerts $metrics = array(); $metrics['status_value'] = $status_value; $metrics['status_name'] = $status_poll['status_name']; $metrics['status_name_uptime'] = $status_polled_time - $status_poll['status_last_change']; $metrics['status_event'] = $status_poll['status_event']; //print_cli_data("Event (State)", $status_poll['status_event'] ." (".$status_poll['status_name'].")", 3); $GLOBALS['table_rows'][] = array($status_db['status_descr'], $status_db['status_type'], $status_db['status_index'], $status_db['poller_type'], $status_poll['status_name'], $status_poll['status_event'], format_unixtime($status_poll['status_last_change'])); check_entity('status', $status_db, $metrics); // Update SQL State if (is_numeric($status_db['status_polled'])) { dbUpdate(array('status_value' => $status_value, 'status_name' => $status_poll['status_name'], 'status_event' => $status_poll['status_event'], 'status_last_change' => $status_poll['status_last_change'], 'status_polled' => $status_polled_time), 'status-state', '`status_id` = ?', array($status_db['status_id'])); } else { dbInsert(array('status_id' => $status_db['status_id'], 'status_value' => $status_value, 'status_name' => $status_poll['status_name'], 'status_event' => $status_poll['status_event'], 'status_last_change' => $status_poll['status_last_change'], 'status_polled' => $status_polled_time), 'status-state'); } } }
// Get processors count if exist for MIB $processor_count = snmp_get($device, $entry['oid_count'], '-OQUvs', $mib); if ($processor_count > 1) { $descr .= ' x' . $processor_count; } } // Idle $idle = isset($entry['idle']) && $entry['idle'] ? 1 : 0; // Precision (scale) $precision = 1; if (isset($entry['scale']) && is_numeric($entry['scale']) && $entry['scale'] != 1) { // FIXME, currently we support only int precision, need convert all to float scale! $precision = round(1 / $entry['scale'], 0); } $usage = snmp_get($device, $entry['oid'], '-OQUvs', $mib); $usage = snmp_fix_numeric($usage); if (is_numeric($usage)) { if (empty($entry['oid_num'])) { // Use snmptranslate if oid_num not set $entry['oid_num'] = snmp_translate($entry['oid'], $mib); } if (isset($entry['rename_rrd'])) { $old_rrd = 'processor-' . $entry['rename_rrd']; $new_rrd = 'processor-' . $entry_name . '-' . $index; rename_rrd($device, $old_rrd, $new_rrd); unset($old_rrd, $new_rrd); } discover_processor($valid['processor'], $device, $entry['oid_num'], $index, $entry_name, $descr, $precision, $usage, NULL, NULL, $idle); $entry['found'] = TRUE; } }
function poll_status($device) { global $config, $agent_status, $ipmi_status, $graphs, $oid_cache; $sql = "SELECT *, `status`.`status_id` AS `status_id`"; $sql .= " FROM `status`"; $sql .= " LEFT JOIN `status-state` ON `status`.status_id = `status-state`.status_id"; $sql .= " WHERE `device_id` = ?"; foreach (dbFetchRows($sql, array($device['device_id'])) as $status_db) { print_debug("Checking (" . $status_db['poller_type'] . ") " . $status_db['status_descr'] . " "); // $status_poll = $status_db; // Cache non-humanized status array for use as new status state if ($status_db['poller_type'] == "snmp") { // Check if a specific poller file exists for this status, else collect via SNMP. $file = $config['install_dir'] . "/includes/polling/status/" . $status_db['status_type'] . ".inc.php"; if (is_file($file)) { include $file; } else { // Take value from $oid_cache if we have it, else snmp_get it if (is_numeric($oid_cache[$status_db['status_oid']])) { print_debug("value taken from oid_cache"); $status_value = $oid_cache[$status_db['status_oid']]; } else { $status_value = snmp_fix_numeric(snmp_get($device, $status_db['status_oid'], "-OUqnv", "SNMPv2-MIB", mib_dirs())); } } } else { if ($status_db['poller_type'] == "agent") { if (isset($agent_status)) { $status_value = $agent_status[$class][$status_db['status_type']][$status_db['status_index']]['current']; // FIXME pass unit? } else { print_warning("No agent status data available."); continue; } } else { if ($status_db['poller_type'] == "ipmi") { if (isset($ipmi_status)) { $status_value = $ipmi_status[$class][$status_db['status_type']][$status_db['status_index']]['current']; $unit = $ipmi_status[$class][$status_db['status_type']][$status_db['status_index']]['unit']; } else { print_warning("No IPMI status data available."); continue; } } else { print_warning("Unknown status poller type."); continue; } } } $rrd_file = get_status_rrd($device, $status_db); rrdtool_create($device, $rrd_file, "DS:status:GAUGE:600:-20000:U"); echo "{$status_value} {$unit} "; // Write new value and humanize (for alert checks) $status_poll['status_value'] = $status_value; // Set status_event and status_name if they're not already set. if (isset($config['status_states'][$status_db['status_type']]) && !isset($status['status_event'])) { $status_poll['status_value'] = (int) $status_poll['status_value']; $status_poll['status_name'] = $config['status_states'][$status_db['status_type']][$status_poll['status_value']]['name']; if ($status_poll['status_ignore'] || $status['status_disable']) { $status_poll['status_event'] = 'ignore'; } else { $status_poll['status_event'] = $config['status_states'][$status_db['status_type']][$status_poll['status_value']]['event']; } } // FIXME I left the eventlog code for now, as soon as alerts send an entry to the eventlog this can go. if ($status_poll['status_event'] != 'ignore') { if ($status_db['status_event'] != '' && $status_poll['status_event'] != $status_db['status_event']) { // If old state not empty and new state not equals to new state switch ($status_poll['status_event']) { case 'alert': // New state alerted $msg = "Alarm: " . $device['hostname'] . " " . $status_db['status_descr'] . " entered ALERT state: " . $status_poll['status_name'] . " (previous: " . $status_db['status_name'] . ")"; log_event($msg, $device, 'status', $status_db['status_id'], 'warning'); break; case 'warning': // New state warned $msg = "Warning: " . $device['hostname'] . " " . $status_db['status_descr'] . " entered WARNING state: " . $status_poll['status_name'] . " (previous: " . $status_db['status_name'] . ")"; log_event($msg, $device, 'status', $status_db['status_id']); break; case 'up': // New state ok $msg = "Up: " . $device['hostname'] . " " . $status_db['status_descr'] . " entered NORMAL state: " . $status_poll['status_name'] . " (previous: " . $status_db['status_name'] . ")"; log_event('Status ' . $msg, $device, 'status', $status_db['status_id'], 'warning'); break; } } } else { print_message("[%ystatus Ignored%n]", 'color'); } print_r($status_poll); echo PHP_EOL; // Send statistics array via AMQP/JSON if AMQP is enabled globally and for the ports module if ($config['amqp']['enable'] == TRUE && $config['amqp']['modules']['status']) { $json_data = array('value' => $status_value); messagebus_send(array('attribs' => array('t' => time(), 'device' => $device['hostname'], 'device_id' => $device['device_id'], 'e_type' => 'status', 'e_type' => $status_db['status_type'], 'e_index' => $status_db['status_index']), 'data' => $json_data)); } // Update StatsD/Carbon if ($config['statsd']['enable'] == TRUE) { StatsD::gauge(str_replace(".", "_", $device['hostname']) . '.' . 'status' . '.' . $status_db['status_class'] . '.' . $status_db['status_type'] . '.' . $status_db['status_index'], $status_value); } // Update RRD rrdtool_update($device, $rrd_file, "N:{$status_value}"); // Enable graph $graphs[$status_db['status_class']] = TRUE; // Check alerts $metrics = array(); $metrics['status_value'] = $status_value; $metrics['status_name'] = $status_poll['status_name']; $metrics['status_event'] = $status_poll['status_event']; check_entity('status', $status_db, $metrics); // Update SQL State if (is_numeric($status_db['status_polled'])) { dbUpdate(array('status_value' => $status_value, 'status_name' => $status_poll['status_name'], 'status_event' => $status_poll['status_event'], 'status_polled' => time()), 'status-state', '`status_id` = ?', array($status_db['status_id'])); } else { dbInsert(array('status_id' => $status_db['status_id'], 'status_value' => $status_value, 'status_name' => $status_poll['status_name'], 'status_event' => $status_poll['status_event'], 'status_polled' => time()), 'status-state'); } } }
function discover_processor(&$valid, $device, $processor_oid, $processor_index, $processor_type, $processor_descr, $processor_precision = "1", $current = NULL, $entPhysicalIndex = NULL, $hrDeviceIndex = NULL) { global $config; print_debug($device['device_id'] . " -> {$processor_oid}, {$processor_index}, {$processor_type}, {$processor_descr}, {$processor_precision}, {$current}, {$entPhysicalIndex}, {$hrDeviceIndex}"); // Check processor description if (!$processor_descr) { print_debug("Skipped by empty description: {$processor_descr} "); return FALSE; } else { $processor_descr = substr($processor_descr, 0, 64); // Limit descr to 64 chars accordingly as in DB } // Skip discovery processor if value not numeric or null(default) if ($current !== NULL) { $current = snmp_fix_numeric($current); } // Remove unnecessary spaces if (!(is_numeric($current) || $current === NULL)) { print_debug("Skipped by not numeric value: {$current}, {$processor_descr} "); return FALSE; } // Check processor ignore filters foreach ($config['ignore_processor'] as $bi) { if (strcasecmp($bi, $processor_descr) == 0) { print_debug("Skipped by equals: {$bi}, {$processor_descr} "); return FALSE; } } foreach ($config['ignore_processor_string'] as $bi) { if (stripos($processor_descr, $bi) !== FALSE) { print_debug("Skipped by strpos: {$bi}, {$processor_descr} "); return FALSE; } } foreach ($config['ignore_processor_regexp'] as $bi) { if (preg_match($bi, $processor_descr) > 0) { print_debug("Skipped by regexp: {$bi}, {$processor_descr} "); return FALSE; } } $params = array('processor_index', 'entPhysicalIndex', 'hrDeviceIndex', 'processor_oid', 'processor_type', 'processor_descr', 'processor_precision'); //$params_state = array('processor_usage'); $processor_db = dbFetchRow("SELECT * FROM `processors` WHERE `device_id` = ? AND `processor_index` = ? AND `processor_type` = ?", array($device['device_id'], $processor_index, $processor_type)); if (!isset($processor_db['processor_id'])) { $update = array('device_id' => $device['device_id']); foreach ($params as $param) { $update[$param] = ${$param} === NULL ? array('NULL') : ${$param}; } $id = dbInsert($update, 'processors'); $update_state = array('processor_id' => $id, 'processor_usage' => $current); //foreach ($params_state as $param) { $update_state[$param] = $$param; } dbInsert($update_state, 'processors-state'); echo '+'; log_event("处理器已添加: index {$processor_index}, type {$processor_type}, descr {$processor_descr}", $device, 'processor', $id); } else { $update = array(); foreach ($params as $param) { if (${$param} != $processor_db[$param]) { $update[$param] = ${$param} === NULL ? array('NULL') : ${$param}; } } if (count($update)) { dbUpdate($update, 'processors', '`processor_id` = ?', array($processor_db['processor_id'])); echo 'U'; log_event("处理器已更新: index {$processor_index}, mib {$processor_type}, descr {$processor_descr}", $device, 'processor', $processor_db['processor_id']); } else { echo '.'; } } $valid[$processor_type][$processor_index] = 1; }
* */ $table_rows = array(); $sql = "SELECT `processors`.*, `processors-state`.`processor_usage`, `processors-state`.`processor_polled`"; $sql .= " FROM `processors`"; $sql .= " LEFT JOIN `processors-state` USING(`processor_id`)"; $sql .= " WHERE `device_id` = ?"; foreach (dbFetchRows($sql, array($device['device_id'])) as $processor) { // echo("Processor " . $processor['processor_descr'] . " "); $file = $config['install_dir'] . "/includes/polling/processors/" . $processor['processor_type'] . ".inc.php"; if (is_file($file)) { include $file; } else { $proc = snmp_get($device, $processor['processor_oid'], "-OUQnv"); } $proc = snmp_fix_numeric($proc); if (!$processor['processor_precision']) { $processor['processor_precision'] = 1; } $proc = round($proc / $processor['processor_precision'], 2); if ($processor['processor_returns_idle'] == 1) { $proc = 100 - $proc; } // The OID returns idle value, so we subtract it from 100. $graphs['processor'] = TRUE; // echo($proc . "%\n"); // Update StatsD/Carbon if ($config['statsd']['enable'] == TRUE) { StatsD::gauge(str_replace(".", "_", $device['hostname']) . '.' . 'processor' . '.' . $processor['processor_type'] . "-" . $processor['processor_index'], $proc); } // Update RRD
$descr = $sensor[$entry['oid_descr']]; } else { $descr = ''; } if (!$descr) { if (isset($entry['descr'])) { if (strpos($entry['descr'], '%i%') === FALSE) { $descr = $entry['descr'] . ' ' . $index; } else { $descr = str_replace('%i%', $i, $entry['descr']); } } else { $descr = 'Sensor ' . $index; } } $value = snmp_fix_numeric($sensor[$entry['oid']]); if (is_numeric($value)) { // Check for min/max values, when sensors report invalid data as sensor does not exist if (isset($entry['min']) && $value <= $entry['min'] || isset($entry['max']) && $value >= $entry['max']) { continue; } $options = array(); // Check limits oids if set foreach (array('limit_low', 'limit_low_warn', 'limit_high_warn', 'limit_high') as $limit) { if (isset($entry['oid_' . $limit])) { if (isset($sensor[$entry['oid_' . $limit]])) { $options[$limit] = $sensor[$entry['oid_' . $limit]]; } else { $options[$limit] = snmp_get($device, $entry['oid_' . $limit] . $dot_index, '-OQUvs'); } // Numeric oid
/** * @dataProvider providerSnmpFixNumeric */ public function testSnmpFixNumeric($value, $result) { $this->assertSame($result, snmp_fix_numeric($value)); }