/** * Get the abbreviation or name of state. * @param string $abbr_or_name - can be abbreviation or name of a state. * @param boolean $abbrev - return the abbreviation or name? * @return boolean|string */ function get_state($abbr_or_name, $abbrev = true) { $states = get_state_array(); // Need to pass something. if (empty($abbr_or_name)) { return false; } // The user passed an abbreviation. if (array_key_exists($abbr_or_name, $states)) { return $abbrev ? $abbr_or_name : $states[$abbr_or_name]; // The user passed the name. } else { foreach ($states as $key => $value) { if (strcasecmp($abbr_or_name, $value) == 0) { return $abbrev ? $key : $value; } } } return false; }
/** * Discover a new status sensor on a device - called from discover_sensor() * * This function adds a status sensor to a device, if it does not already exist. * Data on the sensor is updated if it has changed, and an event is logged with regards to the changes. * * @param array $device Device array status sensor is being discovered on * @param string $oid SNMP OID of status sensor * @param string $index SNMP index of status sensor * @param string $type Type of status sensor (used as key in $config['status_states']) * @param string $status_descr Description of status sensor * @param string $value Current value of status sensor * @param array $options Options * @param string $poller_type Type of poller being used (SNMP, Agent, etc) - Used to check valid sensors per poller type * @return bool */ function discover_status($device, $oid, $index, $type, $status_descr, $value = NULL, $options = array(), $poller_type = 'snmp') { global $config; // Init main $param_main = array('oid' => 'status_oid', 'status_descr' => 'status_descr'); // Check state value $status_state = array(); //if ($value !== NULL) //{ $state_array = get_state_array($type, $value, $poller_type); $state = $state_array['value']; if ($state === FALSE) { print_debug("Skipped by unknown state value: {$value}, {$status_descr} "); return FALSE; } else { if ($state_array['event'] == 'ignore') { print_debug("Skipped by ignored state value: " . $config['status_states'][$type][$state]['name'] . ", {$status_descr} "); return FALSE; } } $value = $state; $status_state['status_event'] = $state_array['event']; $status_state['status_name'] = $state_array['name']; //} // Init optional $param_opt = array('entPhysicalIndex', 'entPhysicalClass', 'entPhysicalIndex_measured', 'measured_class', 'measured_entity'); foreach ($param_opt as $key) { ${$key} = $options[$key] ? $options[$key] : NULL; } print_debug("Discover status: " . $device['hostname'] . ", {$oid}, {$index}, {$type}, {$status_descr}, {$value}, {$poller_type}, {$entPhysicalIndex}, {$entPhysicalClass}"); // Check sensor ignore filters foreach ($config['ignore_sensor'] as $bi) { if (strcasecmp($bi, $status_descr) == 0) { print_debug("Skipped by equals: {$bi}, {$status_descr} "); return FALSE; } } foreach ($config['ignore_sensor_string'] as $bi) { if (stripos($status_descr, $bi) !== FALSE) { print_debug("Skipped by strpos: {$bi}, {$status_descr} "); return FALSE; } } foreach ($config['ignore_sensor_regexp'] as $bi) { if (preg_match($bi, $status_descr) > 0) { print_debug("Skipped by regexp: {$bi}, {$status_descr} "); return FALSE; } } $where = ' WHERE `device_id` = ? AND `status_type` = ? AND `status_index` = ? AND `poller_type`= ?'; $params = array($device['device_id'], $type, $index, $poller_type); if (dbFetchCell('SELECT COUNT(*) FROM `status`' . $where, $params) == '0') { $status_insert = array('poller_type' => $poller_type, 'device_id' => $device['device_id'], 'status_index' => $index, 'status_type' => $type); foreach ($param_main as $key => $column) { $status_insert[$column] = ${$key}; } foreach ($param_opt as $key) { if (is_null(${$key})) { ${$key} = array('NULL'); } // If param null, convert to array(NULL) $status_insert[$key] = ${$key}; } $status_id = dbInsert($status_insert, 'status'); // Insert initial state for status sensor $status_state['status_id'] = $status_id; $status_state['status_value'] = $value; $status_state['status_polled'] = array('NOW()'); dbInsert($status_state, 'status-state'); print_debug("( {$status_id} inserted )"); echo '+'; log_event("Status added: {$class} {$type} {$index} {$status_descr}", $device, 'status', $status_id); } else { $status_entry = dbFetchRow('SELECT * FROM `status`' . $where, $params); $update = array(); foreach ($param_main as $key => $column) { if (${$key} != $status_entry[$column]) { $update[$column] = ${$key}; } } foreach ($param_opt as $key) { if (${$key} != $status_entry[$key]) { $update[$key] = ${$key}; } } if (count($update)) { $updated = dbUpdate($update, 'status', '`status_id` = ?', array($status_entry['status_id'])); echo 'U'; log_event("Status updated: {$type} {$index} {$status_descr}", $device, 'status', $status_entry['status_id']); } else { echo '.'; } } $GLOBALS['valid']['status'][$type][$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'); } } }