function generate_device_popup_header($device, $vars = array()) { global $config; humanize_device($device); if ($device['os'] == "ios") { formatCiscoHardware($device, TRUE); } // FIXME or generic function for more than just IOS? [and/or do this at poll time] $contents = ' <table class="table table-striped table-bordered table-rounded table-condensed"> <tr class="' . $device['html_row_class'] . '" style="font-size: 10pt;"> <td class="state-marker"></td> <td width="40" style="padding: 10px; text-align: center; vertical-align: middle;">' . get_device_icon($device) . '</td> <td width="200"><a href="#" class="' . $class . '" style="font-size: 15px; font-weight: bold;">' . escape_html($device['hostname']) . '</a><br />' . escape_html(truncate($device['location'], 64, '')) . '</td> <td>' . escape_html($device['hardware']) . ' <br /> ' . $device['os_text'] . ' ' . escape_html($device['version']) . '</td> <td>' . deviceUptime($device, 'short') . '<br />' . escape_html($device['sysName']) . ' </tr> </table> '; return $contents; }
function get_status_array($status) { // Mike: I know that there are duplicated variables, but later will remove global global $config, $cache; $max_interval = filter_var($status['max']['interval'], FILTER_VALIDATE_INT, array('options' => array('default' => 24, 'min_range' => 1))); $max_count = filter_var($status['max']['count'], FILTER_VALIDATE_INT, array('options' => array('default' => 200, 'min_range' => 1))); $query_device_permitted = generate_query_permitted(array('device'), array('device_table' => 'D')); $query_port_permitted = generate_query_permitted(array('port'), array('port_table' => 'I')); // Show Device Status if ($status['devices']) { $query = 'SELECT * FROM `devices` AS D '; $query .= 'WHERE D.`status` = 0' . $query_device_permitted; $query .= 'ORDER BY D.`hostname` ASC'; $entries = dbFetchRows($query); foreach ($entries as $device) { $boxes[] = array('sev' => 100, 'class' => 'Device', 'event' => 'Down', 'device_link' => generate_device_link($device, short_hostname($device['hostname'])), 'time' => deviceUptime($device, 'short-3')); } } // Uptime if ($status['uptime']) { if (filter_var($config['uptime_warning'], FILTER_VALIDATE_FLOAT) !== FALSE && $config['uptime_warning'] > 0) { $query = 'SELECT * FROM `devices` AS D '; $query .= 'WHERE D.`status` = 1 AND D.`uptime` > 0 AND D.`uptime` < ' . $config['uptime_warning']; $query .= $query_device_permitted; $query .= 'ORDER BY D.`hostname` ASC'; $entries = dbFetchRows($query); foreach ($entries as $device) { $boxes[] = array('sev' => 10, 'class' => 'Device', 'event' => 'Rebooted', 'device_link' => generate_device_link($device, short_hostname($device['hostname'])), 'time' => deviceUptime($device, 'short-3'), 'location' => $device['location']); } } } // Ports Down if ($status['ports'] || $status['links']) { // warning about deprecated option: $config['warn']['ifdown'] if (isset($config['warn']['ifdown']) && !$config['warn']['ifdown']) { print_warning("<strong>Config option obsolete</strong>\n Please note that config option <strong>\$config['warn']['ifdown']</strong> is now obsolete.\n Use options: <strong>\$config['frontpage']['device_status']['ports']</strong> and <strong>\$config['frontpage']['device_status']['errors']</strong>\n To remove this message, delete <strong>\$config['warn']['ifdown']</strong> from configuration file."); } $query = 'SELECT * FROM `ports` AS I '; if ($status['links'] && !$status['ports']) { $query .= 'INNER JOIN `links` as L ON I.`port_id` = L.`local_port_id` '; } $query .= 'LEFT JOIN `devices` AS D ON I.`device_id` = D.`device_id` '; $query .= "WHERE I.`ifOperStatus` = 'down' AND I.`ifAdminStatus` = 'up' "; if ($status['links'] && !$status['ports']) { $query .= ' AND L.`active` = 1 '; } $query .= $query_port_permitted; $query .= ' AND I.`ifLastChange` >= DATE_SUB(NOW(), INTERVAL ' . $max_interval . ' HOUR) '; $query .= 'ORDER BY I.`ifLastChange` DESC, D.`hostname` ASC, I.`ifDescr` * 1 ASC '; $entries = dbFetchRows($query); $i = 1; foreach ($entries as $port) { if ($i > $max_count) { // Limit to 200 ports on overview page break; } humanize_port($port); $boxes[] = array('sev' => 50, 'class' => 'Port', 'event' => 'Down', 'device_link' => generate_device_link($port, short_hostname($port['hostname'])), 'entity_link' => generate_port_link($port, short_ifname($port['label'], 13)), 'time' => formatUptime($config['time']['now'] - strtotime($port['ifLastChange'])), 'location' => $device['location']); } } // Ports Errors (only deltas) if ($status['errors']) { foreach ($cache['ports']['errored'] as $port_id) { $port = get_port_by_id($port_id); $device = device_by_id_cache($port['device_id']); humanize_port($port); if ($port['ifInErrors_delta']) { $port['string'] .= 'Rx: ' . format_number($port['ifInErrors_delta']); } if ($port['ifInErrors_delta'] && $port['ifOutErrors_delta']) { $port['string'] .= ', '; } if ($port['ifOutErrors_delta']) { $port['string'] .= 'Tx: ' . format_number($port['ifOutErrors_delta']); } $boxes[] = array('sev' => 75, 'class' => 'Port', 'event' => 'Errors', 'device_link' => generate_device_link($device, short_hostname($device['hostname'])), 'entity_link' => generate_port_link($port, short_ifname($port['label'], 13)), 'time' => $port['string'], 'location' => $device['location']); } } // Services if ($status['services']) { $query = 'SELECT * FROM `services` AS S '; $query .= 'LEFT JOIN `devices` AS D ON S.device_id = D.device_id '; $query .= "WHERE S.`service_status` = 'down' AND S.`service_ignore` = 0"; $query .= $query_device_permitted; $query .= 'ORDER BY D.`hostname` ASC'; $entries = dbFetchRows($query); foreach ($entries as $service) { $boxes[] = array('sev' => 50, 'class' => 'Service', 'event' => 'Down', 'device_link' => generate_device_link($service, short_hostname($service['hostname'])), 'entity_link' => $service['service_type'], 'time' => formatUptime($config['time']['now'] - strtotime($service['service_changed']), 'short'), 'location' => $device['location']); } } // BGP if ($status['bgp']) { if (isset($config['enable_bgp']) && $config['enable_bgp']) { $query = 'SELECT * FROM `devices` AS D '; $query .= 'LEFT JOIN `bgpPeers` AS B ON B.`device_id` = D.`device_id` '; $query .= 'LEFT JOIN `bgpPeers-state` AS BS ON B.`bgpPeer_id` = BS.`bgpPeer_id` '; $query .= "WHERE (`bgpPeerAdminStatus` = 'start' OR `bgpPeerAdminStatus` = 'running') AND `bgpPeerState` != 'established' "; $query .= $query_device_permitted; $query .= 'ORDER BY D.`hostname` ASC'; $entries = dbFetchRows($query); foreach ($entries as $peer) { $peer_ip = strstr($peer['bgpPeerRemoteAddr'], ':') ? Net_IPv6::compress($peer['bgpPeerRemoteAddr']) : $peer['bgpPeerRemoteAddr']; $peer['wide'] = strstr($peer['bgpPeerRemoteAddr'], ':') ? TRUE : FALSE; $boxes[] = array('sev' => 75, 'class' => 'BGP Peer', 'event' => 'Down', 'device_link' => generate_device_link($peer, short_hostname($peer['hostname'])), 'entity_link' => $peer_ip, 'wide' => $peer['wide'], 'time' => formatUptime($peer['bgpPeerFsmEstablishedTime'], 'short-3'), 'location' => $device['location']); } } } // Return boxes array return $boxes; }
echo ' <td>' . htmlspecialchars(get_dev_attrib($device, 'override_sysContact_string')) . '</td> </tr> <tr> <td class="entity">SNMP Contact</td>'; } echo ' <td>' . htmlspecialchars($device['sysContact']) . '</td> </tr>'; } if ($device['location']) { echo '<tr> <td class="entity">Location</td> <td>' . htmlspecialchars($device['location']) . '</td> </tr>'; if (get_dev_attrib($device, 'override_sysLocation_bool') && !empty($device['real_location'])) { echo '<tr> <td class="entity">SNMP Location</td> <td>' . htmlspecialchars($device['real_location']) . '</td> </tr>'; } } if ($device['uptime']) { echo '<tr> <td class="entity">Uptime</td> <td>' . deviceUptime($device) . '</td> </tr>'; } echo "</table>"; echo "</div></div>"; // EOF
/** * @dataProvider providerDeviceUptime */ public function testDeviceUptime($value, $result) { $this->assertSame($result, deviceUptime($value)); }
/** * Check all alerts for a device to see if they should be notified or not * * @param array device * @return NULL */ function process_alerts($device) { global $config, $alert_rules, $alert_assoc; echo "Processing alerts for " . $device['hostname'] . PHP_EOL; $alert_table = cache_device_alert_table($device['device_id']); $sql = "SELECT * FROM `alert_table`"; $sql .= " LEFT JOIN `alert_table-state` ON `alert_table`.`alert_table_id` = `alert_table-state`.`alert_table_id`"; $sql .= " WHERE `device_id` = ?"; foreach (dbFetchRows($sql, array($device['device_id'])) as $entry) { echo 'Alert: ' . $entry['alert_table_id'] . ' Status: ' . $entry['alert_status'] . ' '; // If the alerter is now OK and has previously alerted, send an recovery notice. if ($entry['alert_status'] == '1' && $entry['has_alerted'] == '1') { $alert = $alert_rules[$entry['alert_test_id']]; $state = json_decode($entry['state'], TRUE); $conditions = json_decode($alert['conditions'], TRUE); $entity = get_entity_by_id_cache($entry['entity_type'], $entry['entity_id']); $graphs = ""; $metric_text = ""; foreach ($state['metrics'] as $metric => $value) { $metric_text .= $metric . " = " . $value . PHP_EOL . "<br />"; } // FIXME De-dup this shit soon. // - adama $message = ' <head> <title>Observium Alert</title> <style> .observium{ width:100%; max-width: 500px; -webkit-border-radius: 5px; -moz-border-radius: 5px; border-radius: 5px; border:1px solid #DDDDDD; background-color:#FAFAFA; font-size: 13px; color: #777777; } .header{ font-weight: bold; font-size: 16px; padding: 5px; color: #555555; } .red { color: #cc0000; } #deviceinfo tr:nth-child(odd) { background: #ffffff; } </style> <style type="text/css"></style></head> <body> <table class="observium"> <tbody> <tr> <td> <table class="observium" id="deviceinfo"> <tbody> <tr><td class="header">RECOVERY</td><td><a style="float: right;" href="' . generate_url(array('page' => 'device', 'device' => $device['device_id'], 'tab' => 'alert', 'alert_entry' => $entry['alert_table_id'])) . '">Modify</a></td></tr> <tr><td><b>Alert</b></font></td><td class="red">' . $alert['alert_message'] . '</font></td></tr> <tr><td><b>Entity</b></font></td><td>' . generate_entity_link($entry['entity_type'], $entry['entity_id'], $entity['entity_name']) . '</font></td></tr>'; if (strlen($entity['entity_descr']) > 0) { $message .= '<tr><td><b>Descr</b></font></td><td>' . $entity['entity_descr'] . '</font>'; } $message .= ' <tr><td><b>Metrics</b></font></td><td>' . $metric_text . '</font></td></tr> <tr><td><b>Duration</b></font></td><td>' . formatUptime(time() - $entry['last_failed']) . '</font></td></tr> <tr><td colspan="2" class="header">Device</td></tr> <tr><td><b>Device</b></font></td><td>' . generate_device_link($device) . '</font></td></tr> <tr><td><b>Hardware</b></font></td><td>' . $device['hardware'] . '</font></td></tr> <tr><td><b>Operating System</b></font></td><td>' . $device['os_text'] . ' ' . $device['version'] . ' ' . $device['features'] . '</font></td></tr> <tr><td><b>Location</b></font></td><td>' . htmlspecialchars($device['location']) . '</font></td></tr> <tr><td><b>Uptime</b></font></td><td>' . deviceUptime($device) . '</font></td></tr> </tbody></table> </td></tr> <tr><td> <center>' . $graphs . '</center></td></tr> </tbody></table> </body> </html>'; alert_notify($device, "RECOVER: [" . $device['hostname'] . "] [" . $alert['entity_type'] . "] [" . $entity['entity_name'] . "] " . $alert['alert_message'], $message); $update_array['last_recovered'] = time(); $update_array['has_alerted'] = 0; dbUpdate($update_array, 'alert_table-state', '`alert_table_id` = ?', array($entry['alert_table_id'])); } if ($entry['alert_status'] == '0') { echo 'Alert tripped. '; // Has this been alerted more frequently than the alert interval in the config? /// FIXME -- this should be configurable per-entity or per-checker if (time() - $entry['last_alerted'] < $config['alerts']['interval'] && !isset($GLOBALS['spam'])) { $entry['suppress_alert'] = TRUE; } // Check if alert has ignore_until set. if (is_numeric($entry['ignore_until']) && $entry['ignore_until'] > time()) { $entry['suppress_alert'] = TRUE; } if ($entry['suppress_alert'] != TRUE) { echo 'Requires notification. '; $alert = $alert_rules[$entry['alert_test_id']]; $state = json_decode($entry['state'], TRUE); $conditions = json_decode($alert['conditions'], TRUE); $entity = get_entity_by_id_cache($entry['entity_type'], $entry['entity_id']); $condition_text = ""; foreach ($state['failed'] as $failed) { $condition_text .= $failed['metric'] . " " . $failed['condition'] . " " . $failed['value'] . " (" . $state['metrics'][$failed['metric']] . ")<br />"; } $graphs = ""; $metric_text = ""; foreach ($state['metrics'] as $metric => $value) { $metric_text .= $metric . " = " . $value . PHP_EOL . "<br />"; } if (is_array($config['entities'][$entry['entity_type']]['graph'])) { // We can draw a graph for this type/metric pair! $graph_array = $config['entities'][$entry['entity_type']]['graph']; foreach ($graph_array as $key => $val) { // Check to see if we need to do any substitution if (substr($val, 0, 1) == "@") { $nval = substr($val, 1); echo " replaced " . $val . " with " . $entity[$nval] . " from entity. " . PHP_EOL . "<br />"; $graph_array[$key] = $entity[$nval]; } } print_r($graph_array); $image_data_uri = generate_alert_graph($graph_array); print_r(strlen($image_data_uri)); $graphs .= '<img src="' . $image_data_uri . '">' . "<br />"; unset($graph_array); } #$css = data_uri($config['html_dir'].'/css/bootstrap-mini.css' ,'text/css'); $message = ' <head> <title>Observium Alert</title> <style> .observium{ width:100%; max-width: 500px; -webkit-border-radius: 5px; -moz-border-radius: 5px; border-radius: 5px; border:1px solid #DDDDDD; background-color:#FAFAFA; font-size: 13px; color: #777777; } .header{ font-weight: bold; font-size: 16px; padding: 5px; color: #555555; } .red { color: #cc0000; } #deviceinfo tr:nth-child(odd) { background: #ffffff; } </style> <style type="text/css"></style></head> <body> <table class="observium"> <tbody> <tr> <td> <table class="observium" id="deviceinfo"> <tbody> <tr><td class="header">ALERT</td><td><a style="float: right;" href="' . generate_url(array('page' => 'device', 'device' => $device['device_id'], 'tab' => 'alert', 'alert_entry' => $entry['alert_table_id'])) . '">Modify</a></td></tr> <tr><td><b>Alert</b></font></td><td class="red">' . $alert['alert_message'] . '</font></td></tr> <tr><td><b>Entity</b></font></td><td>' . generate_entity_link($entry['entity_type'], $entry['entity_id'], $entity['entity_name']) . '</font></td></tr>'; if (strlen($entity['entity_descr']) > 0) { $message .= '<tr><td><b>Descr</b></font></td><td>' . $entity['entity_descr'] . '</font>'; } $message .= ' <tr><td><b>Conditions</b></font></td><td>' . $condition_text . '</font></td></tr> <tr><td><b>Metrics</b></font></td><td>' . $metric_text . '</font></td></tr> <tr><td><b>Duration</b></font></td><td>' . formatUptime(time() - $entry['last_failed']) . '</font></td></tr> <tr><td colspan="2" class="header">Device</td></tr> <tr><td><b>Device</b></font></td><td>' . generate_device_link($device) . '</font></td></tr> <tr><td><b>Hardware</b></font></td><td>' . $device['hardware'] . '</font></td></tr> <tr><td><b>Operating System</b></font></td><td>' . $device['os_text'] . ' ' . $device['version'] . ' ' . $device['features'] . '</font></td></tr> <tr><td><b>Location</b></font></td><td>' . htmlspecialchars($device['location']) . '</font></td></tr> <tr><td><b>Uptime</b></font></td><td>' . deviceUptime($device) . '</font></td></tr> </tbody></table> </td></tr> <tr><td> <center>' . $graphs . '</center></td></tr> </tbody></table> </body> </html>'; alert_notify($device, "ALERT: [" . $device['hostname'] . "] [" . $alert['entity_type'] . "] [" . $entity['entity_name'] . "] " . $alert['alert_message'], $message); $update_array['last_alerted'] = time(); $update_array['has_alerted'] = 1; dbUpdate($update_array, 'alert_table-state', '`alert_table_id` = ?', array($entry['alert_table_id'])); } else { echo "No notification required. " . (time() - $entry['last_alerted']); } } elseif ($entry['alert_status'] == '1') { echo "Status: OK. "; } else { echo "Unknown status."; } echo PHP_EOL; } }
function get_status_array($status) { // Mike: I know that there are duplicated variables, but later will remove global global $config, $cache; $max_interval = filter_var($status['max']['interval'], FILTER_VALIDATE_INT, array('options' => array('default' => 24, 'min_range' => 1))); $max_count = filter_var($status['max']['count'], FILTER_VALIDATE_INT, array('options' => array('default' => 200, 'min_range' => 1))); $query_device_permitted = generate_query_permitted(array('device'), array('device_table' => 'D', 'hide_ignored' => TRUE)); $query_port_permitted = generate_query_permitted(array('port'), array('port_table' => 'I', 'hide_ignored' => TRUE)); // Show Device Status if ($status['devices']) { $query = 'SELECT * FROM `devices` AS D '; $query .= 'WHERE D.`status` = 0' . $query_device_permitted; $query .= 'ORDER BY D.`hostname` ASC'; $entries = dbFetchRows($query); foreach ($entries as $device) { $boxes[] = array('sev' => 100, 'class' => 'Device', 'event' => 'Down', 'device_link' => generate_device_link($device, short_hostname($device['hostname'])), 'time' => deviceUptime($device, 'short-3')); } } // Uptime if ($status['uptime']) { if (filter_var($config['uptime_warning'], FILTER_VALIDATE_FLOAT) !== FALSE && $config['uptime_warning'] > 0) { $query = 'SELECT * FROM `devices` AS D '; // Since reboot event more complicated than just device uptime less than some time //$query .= ' WHERE D.`status` = 1 AND D.`uptime` > 0 AND D.`uptime` < ' . $config['uptime_warning']; $query .= ' WHERE D.`status` = 1 AND D.`uptime` > 0 AND D.`last_rebooted` > ?'; $query .= $query_device_permitted; $query .= 'ORDER BY D.`hostname` ASC'; $entries = dbFetchRows($query, array($config['time']['now'] - $config['uptime_warning'] - 10)); foreach ($entries as $device) { $boxes[] = array('sev' => 10, 'class' => 'Device', 'event' => 'Rebooted', 'device_link' => generate_device_link($device, short_hostname($device['hostname'])), 'time' => deviceUptime($device, 'short-3'), 'location' => $device['location']); } } } // Ports Down if ($status['ports'] || $status['neighbours']) { $status['neighbours'] = $status['neighbours'] && !$status['ports']; // Disable 'neighbours' if 'ports' already enabled $query = 'SELECT * FROM `ports` AS I '; if ($status['neighbours']) { $query .= 'INNER JOIN `neighbours` as L ON I.`port_id` = L.`port_id` '; } $query .= 'LEFT JOIN `devices` AS D ON I.`device_id` = D.`device_id` '; $query .= "WHERE D.`status` = 1 AND D.ignore = 0 AND I.ignore = 0 AND I.deleted = 0 AND I.`ifAdminStatus` = 'up' AND (I.`ifOperStatus` = 'lowerLayerDown' OR I.`ifOperStatus` = 'down') "; if ($status['neighbours']) { $query .= ' AND L.`active` = 1 '; } $query .= $query_port_permitted; $query .= ' AND I.`ifLastChange` >= DATE_SUB(NOW(), INTERVAL ' . $max_interval . ' HOUR) '; if ($status['neighbours']) { $query .= 'GROUP BY L.`port_id` '; } $query .= 'ORDER BY I.`ifLastChange` DESC, D.`hostname` ASC, I.`ifDescr` * 1 ASC '; $entries = dbFetchRows($query); $i = 1; foreach ($entries as $port) { if ($i > $max_count) { // Limit to 200 ports on overview page break; } humanize_port($port); $boxes[] = array('sev' => 50, 'class' => 'Port', 'event' => 'Down', 'device_link' => generate_device_link($port, short_hostname($port['hostname'])), 'entity_link' => generate_port_link($port, short_ifname($port['port_label'], 13)), 'time' => formatUptime($config['time']['now'] - strtotime($port['ifLastChange'])), 'location' => $device['location']); } } // Ports Errors (only deltas) if ($status['errors']) { foreach ($cache['ports']['errored'] as $port_id) { if (in_array($port_id, $cache['ports']['ignored'])) { continue; } // Skip ignored ports $port = get_port_by_id($port_id); $device = device_by_id_cache($port['device_id']); humanize_port($port); if ($port['ifInErrors_delta']) { $port['string'] .= 'Rx: ' . format_number($port['ifInErrors_delta']); } if ($port['ifInErrors_delta'] && $port['ifOutErrors_delta']) { $port['string'] .= ', '; } if ($port['ifOutErrors_delta']) { $port['string'] .= 'Tx: ' . format_number($port['ifOutErrors_delta']); } $boxes[] = array('sev' => 75, 'class' => 'Port', 'event' => 'Errors', 'device_link' => generate_device_link($device, short_hostname($device['hostname'])), 'entity_link' => generate_port_link($port, short_ifname($port['port_label'], 13)), 'time' => $port['string'], 'location' => $device['location']); } } // Services if ($status['services']) { $query = 'SELECT * FROM `services` AS S '; $query .= 'LEFT JOIN `devices` AS D ON S.`device_id` = D.`device_id` '; $query .= "WHERE S.`service_status` = 'down' AND S.`service_ignore` = 0"; $query .= $query_device_permitted; $query .= 'ORDER BY D.`hostname` ASC'; $entries = dbFetchRows($query); foreach ($entries as $service) { $boxes[] = array('sev' => 50, 'class' => 'Service', 'event' => 'Down', 'device_link' => generate_device_link($service, short_hostname($service['hostname'])), 'entity_link' => $service['service_type'], 'time' => formatUptime($config['time']['now'] - strtotime($service['service_changed']), 'short'), 'location' => $device['location']); } } // BGP if ($status['bgp']) { if (isset($config['enable_bgp']) && $config['enable_bgp']) { $query = 'SELECT * FROM `bgpPeers` AS B '; $query .= 'LEFT JOIN `devices` AS D ON B.`device_id` = D.`device_id` '; $query .= 'LEFT JOIN `bgpPeers-state` AS BS ON B.`bgpPeer_id` = BS.`bgpPeer_id` '; $query .= "WHERE D.`status` = 1 AND (`bgpPeerAdminStatus` = 'start' OR `bgpPeerAdminStatus` = 'running') AND `bgpPeerState` != 'established' "; $query .= $query_device_permitted; $query .= 'ORDER BY D.`hostname` ASC'; $entries = dbFetchRows($query); foreach ($entries as $peer) { humanize_bgp($peer); $peer_ip = generate_entity_link("bgp_peer", $peer, $peer['human_remoteip']); $peer['wide'] = strstr($peer['bgpPeerRemoteAddr'], ':') ? TRUE : FALSE; $boxes[] = array('sev' => 75, 'class' => 'BGP Peer', 'event' => 'Down', 'device_link' => generate_device_link($peer, short_hostname($peer['hostname'])), 'entity_link' => $peer_ip, 'wide' => $peer['wide'], 'time' => formatUptime($peer['bgpPeerFsmEstablishedTime'], 'short-3'), 'location' => $device['location']); } } } // Return boxes array return $boxes; }
<?php humanize_device($device); /// These should be summed at poller time $port_count = dbFetchCell("SELECT COUNT(*) FROM `ports` WHERE `device_id` = ?", array($device['device_id'])); $sensor_count = dbFetchCell("SELECT COUNT(*) FROM `sensors` WHERE `device_id` = ?", array($device['device_id'])); echo ' <tr class="' . $device['html_row_class'] . '" onclick="location.href=\'device/device=' . $device['device_id'] . '/\'" style="cursor: pointer;"> <td style="width: 1px; background-color: ' . $device['html_tab_colour'] . '; margin: 0px; padding: 0px"></td> <td style="width: 64px; text-align: center; vertical-align: middle;">' . getImage($device) . '</td> <td style="width: 300px;"><span class="entity-title">' . generate_device_link($device) . '</span> <br />' . htmlspecialchars(truncate($device['location'], 32, '')) . '</td>'; echo '<td style="width: 55px;">'; if ($port_count) { echo ' <i class="oicon-network-ethernet"></i> ' . $port_count; } echo '<br />'; if ($sensor_count) { echo ' <i class="oicon-dashboard"></i> ' . $sensor_count; } echo '</td>'; echo ' <td >' . $device['hardware'] . '<br />' . $device['features'] . '</td>'; echo ' <td >' . $device['os_text'] . '<br />' . $device['version'] . '</td>'; echo ' <td >' . deviceUptime($device, 'short') . ' <br />'; echo ' ' . htmlspecialchars($device['sysName']) . '</td>'; echo ' </tr>'; // EOF
function generate_device_link_header($device, $vars = array()) { global $config; if (isset($device['humanized_device']) == FALSE) { humanize_device($device); } if ($device['os'] == "ios") { formatCiscoHardware($device, true); } # print_r($device); $contents = ' <table class="table table-striped table-bordered table-rounded table-condensed"> <tr class="' . $device['html_row_class'] . '" style="font-size: 10pt;"> <td style="width: 10px; background-color: ' . $device['html_tab_colour'] . '; margin: 0px; padding: 0px"></td> <td width="40" style="padding: 10px; text-align: center; vertical-align: middle;">' . getImage($device) . '</td> <td width="200"><a href="#" class="' . $class . '" style="font-size: 15px; font-weight: bold;">' . $device['hostname'] . '</a><br />' . truncate($device['location'], 64, '') . '</td> <td>' . $device['hardware'] . ' <br /> ' . $device['os_text'] . ' ' . $device['version'] . '</td> <td>' . deviceUptime($device, 'short') . '<br />' . $device['sysName'] . ' </tr> </table> '; return $contents; }
function process_alerts($device) { global $config, $alert_rules, $alert_assoc; echo "处理警报 " . $device['hostname'] . PHP_EOL; $alert_table = cache_device_alert_table($device['device_id']); $sql = "SELECT * FROM `alert_table`"; $sql .= " LEFT JOIN `alert_table-state` ON `alert_table`.`alert_table_id` = `alert_table-state`.`alert_table_id`"; $sql .= " WHERE `device_id` = ? AND `alert_status` IS NOT NULL;"; foreach (dbFetchRows($sql, array($device['device_id'])) as $entry) { echo 'Alert: ' . $entry['alert_table_id'] . ' Status: ' . $entry['alert_status'] . ' '; // If the alerter is now OK and has previously alerted, send an recovery notice. if ($entry['alert_status'] == '1' && $entry['has_alerted'] == '1') { $alert = $alert_rules[$entry['alert_test_id']]; if (!$alert['suppress_recovery']) { $state = json_decode($entry['state'], TRUE); $conditions = json_decode($alert['conditions'], TRUE); $entity = get_entity_by_id_cache($entry['entity_type'], $entry['entity_id']); $metric_array = array(); foreach ($state['metrics'] as $metric => $value) { $metric_array[] = $metric . ' = ' . $value; } $message_tags = array('ALERT_STATE' => 'RECOVERY', 'ALERT_URL' => generate_url(array('page' => 'device', 'device' => $device['device_id'], 'tab' => 'alert', 'alert_entry' => $entry['alert_table_id'])), 'ALERT_MESSAGE' => $alert['alert_message'], 'METRICS' => implode(PHP_EOL . ' ', $metric_array), 'DURATION' => formatUptime(time() - $entry['last_failed']), 'ENTITY_LINK' => generate_entity_link($entry['entity_type'], $entry['entity_id'], $entity['entity_name']), 'ENTITY_NAME' => $entity['entity_name'], 'ENTITY_DESCRIPTION' => $entity['entity_descr'], 'DEVICE_HOSTNAME' => $device['hostname'], 'DEVICE_LINK' => generate_device_link($device), 'DEVICE_HARDWARE' => $device['hardware'], 'DEVICE_OS' => $device['os_text'] . ' ' . $device['version'] . ' ' . $device['features'], 'DEVICE_LOCATION' => $device['location'], 'DEVICE_UPTIME' => deviceUptime($device)); $message['text'] = simple_template('alert/email_text.tpl', $message_tags, array('is_file' => TRUE)); //$message_tags['CONDITIONS'] = nl2br($message_tags['CONDITIONS']); $message_tags['METRICS'] = nl2br($message_tags['METRICS']); $message['html'] = simple_template('alert/email_html.tpl', $message_tags, array('is_file' => TRUE)); //logfile('debug.log', var_export($message, TRUE)); alert_notify($device, alert_generate_subject('RECOVER', $device, $alert, $entity), $message, $entry['alert_test_id']); log_alert('恢复发送的通知', $device, $entry, 'RECOVER_NOTIFY'); } else { echo '已限制恢复.'; log_alert('限制恢复通知', $device, $entry, 'RECOVER_SUPPRESSED'); } $update_array['last_recovered'] = time(); $update_array['has_alerted'] = 0; dbUpdate($update_array, 'alert_table-state', '`alert_table_id` = ?', array($entry['alert_table_id'])); } if ($entry['alert_status'] == '0') { echo '警报已停止. '; // Has this been alerted more frequently than the alert interval in the config? /// FIXME -- this should be configurable per-entity or per-checker if (time() - $entry['last_alerted'] < $config['alerts']['interval'] && !isset($GLOBALS['spam'])) { $entry['suppress_alert'] = TRUE; } // Check if alert has ignore_until set. if (is_numeric($entry['ignore_until']) && $entry['ignore_until'] > time()) { $entry['suppress_alert'] = TRUE; } // Check if alert has ignore_until_ok set. if (is_numeric($entry['ignore_until_ok']) && $entry['ignore_until_ok'] == '1') { $entry['suppress_alert'] = TRUE; } if ($entry['suppress_alert'] != TRUE) { echo 'Requires notification. '; $alert = $alert_rules[$entry['alert_test_id']]; $state = json_decode($entry['state'], TRUE); $conditions = json_decode($alert['conditions'], TRUE); $entity = get_entity_by_id_cache($entry['entity_type'], $entry['entity_id']); $condition_array = array(); foreach ($state['failed'] as $failed) { $condition_array[] = $failed['metric'] . " " . $failed['condition'] . " " . $failed['value'] . " (" . $state['metrics'][$failed['metric']] . ")"; } $graphs = ""; $metric_array = array(); foreach ($state['metrics'] as $metric => $value) { $metric_array[] = $metric . ' = ' . $value; } if (is_array($config['entities'][$entry['entity_type']]['graph'])) { // We can draw a graph for this type/metric pair! $graph_array = $config['entities'][$entry['entity_type']]['graph']; foreach ($graph_array as $key => $val) { // Check to see if we need to do any substitution if (substr($val, 0, 1) == "@") { $nval = substr($val, 1); echo " replaced " . $val . " with " . $entity[$nval] . " from entity. " . PHP_EOL . "<br />"; $graph_array[$key] = $entity[$nval]; } } //print_r($graph_array); //logfile('debug.log', var_export($graph_array, TRUE)); $image_data_uri = generate_alert_graph($graph_array); //print_r($image_data_uri); //logfile('debug.log', var_export($image_data_uri, TRUE)); $graphs .= '<img src="' . $image_data_uri . '"><br />'; unset($graph_array); } $message_tags = array('ALERT_STATE' => 'ALERT', 'ALERT_URL' => generate_url(array('page' => 'device', 'device' => $device['device_id'], 'tab' => 'alert', 'alert_entry' => $entry['alert_table_id'])), 'ALERT_MESSAGE' => $alert['alert_message'], 'CONDITIONS' => implode(PHP_EOL . ' ', $condition_array), 'METRICS' => implode(PHP_EOL . ' ', $metric_array), 'DURATION' => formatUptime(time() - $entry['last_failed']), 'ENTITY_LINK' => generate_entity_link($entry['entity_type'], $entry['entity_id'], $entity['entity_name']), 'ENTITY_NAME' => $entity['entity_name'], 'ENTITY_DESCRIPTION' => $entity['entity_descr'], 'ENTITY_GRAPHS' => $graphs, 'DEVICE_HOSTNAME' => $device['hostname'], 'DEVICE_LINK' => generate_device_link($device), 'DEVICE_HARDWARE' => $device['hardware'], 'DEVICE_OS' => $device['os_text'] . ' ' . $device['version'] . ' ' . $device['features'], 'DEVICE_LOCATION' => $device['location'], 'DEVICE_UPTIME' => deviceUptime($device)); $message['text'] = simple_template('alert/email_text.tpl', $message_tags, array('is_file' => TRUE)); $message_tags['CONDITIONS'] = nl2br($message_tags['CONDITIONS']); $message_tags['METRICS'] = nl2br($message_tags['METRICS']); $message['html'] = simple_template('alert/email_html.tpl', $message_tags, array('is_file' => TRUE)); //logfile('debug.log', var_export($message, TRUE)); alert_notify($device, alert_generate_subject('ALERT', $device, $alert, $entity), $message, $entry['alert_test_id']); log_alert('Alert notification sent', $device, $entry, 'ALERT_NOTIFY'); $update_array['last_alerted'] = time(); $update_array['has_alerted'] = 1; dbUpdate($update_array, 'alert_table-state', '`alert_table_id` = ?', array($entry['alert_table_id'])); } else { echo "没有通知要求. " . (time() - $entry['last_alerted']); } } else { if ($entry['alert_status'] == '1') { echo "状态: OK. "; } else { if ($entry['alert_status'] == '2') { echo "Status: Notification Delayed. "; } else { if ($entry['alert_status'] == '3') { echo "Status: Notification Suppressed. "; } else { echo "未知的状态."; } } } } echo PHP_EOL; } }
function print_device_hostbox($device, $mode = 'basic') { global $config; if (!is_array($device)) { print_error("Invalid device passed to print_device_hostbox()!"); } if ($device['os'] == "ios") { formatCiscoHardware($device, TRUE); } humanize_device($device); $hostbox_tags = array('html_row_class' => $device['html_row_class'], 'device_id' => $device['device_id'], 'device_link' => generate_device_link($device), 'hardware' => escape_html($device['hardware']), 'features' => escape_html($device['features']), 'os_text' => $device['os_text'], 'version' => escape_html($device['version']), 'sysName' => escape_html($device['sysName']), 'device_uptime' => deviceUptime($device, 'short'), 'location' => escape_html(truncate($device['location'], 32, ''))); switch ($mode) { case 'detail': case 'details': $hostbox_tags['device_image'] = get_device_icon($device); $hostbox_tags['ports_count'] = dbFetchCell("SELECT COUNT(*) FROM `ports` WHERE `device_id` = ?;", array($device['device_id'])); $hostbox_tags['sensors_count'] = dbFetchCell("SELECT COUNT(*) FROM `sensors` WHERE `device_id` = ?;", array($device['device_id'])); $hostbox = ' <tr class="' . $hostbox_tags['html_row_class'] . '" onclick="location.href=\'device/device=' . $hostbox_tags['device_id'] . '/\'" style="cursor: pointer;"> <td class="state-marker"></td> <td style="width: 64px; text-align: center; vertical-align: middle;">' . $hostbox_tags['device_image'] . '</td> <td style="width: 300px;"><span class="entity-title">' . $hostbox_tags['device_link'] . '</span><br />' . $hostbox_tags['location'] . '</td> <td style="width: 55px;">'; if ($hostbox_tags['ports_count']) { $hostbox .= '<i class="oicon-network-ethernet"></i> ' . $hostbox_tags['ports_count']; } $hostbox .= '<br />'; if ($hostbox_tags['sensors_count']) { $hostbox .= '<i class="oicon-dashboard"></i> ' . $hostbox_tags['sensors_count']; } $hostbox .= '</td> <td>' . $hostbox_tags['hardware'] . '<br />' . $hostbox_tags['features'] . '</td> <td>' . $hostbox_tags['os_text'] . '<br />' . $hostbox_tags['version'] . '</td> <td>' . $hostbox_tags['device_uptime'] . '<br />' . $hostbox_tags['sysName'] . '</td> </tr>'; break; case 'status': $hostbox_tags['device_image'] = get_device_icon($device); // Graphs $graph_array = array(); $graph_array['height'] = "100"; $graph_array['width'] = "310"; $graph_array['to'] = $config['time']['now']; $graph_array['device'] = $device['device_id']; $graph_array['type'] = "device_bits"; $graph_array['from'] = $config['time']['day']; $graph_array['legend'] = "no"; $graph_array['height'] = "45"; $graph_array['width'] = "175"; $graph_array['bg'] = "FFFFFF00"; if (isset($config['os'][$device['os']]['over'])) { $graphs = $config['os'][$device['os']]['over']; } else { if (isset($device['os_group']) && isset($config['os'][$device['os_group']]['over'])) { $graphs = $config['os'][$device['os_group']]['over']; } else { $graphs = $config['os']['default']['over']; } } // Preprocess device graphs array foreach ($GLOBALS['device_graphs'][$device['device_id']] as $graph) { $graphs_enabled[] = $graph['graph']; } foreach ($graphs as $entry) { if ($entry['graph'] && in_array(str_replace('device_', '', $entry['graph']), $graphs_enabled)) { $graph_array['type'] = $entry['graph']; $graph_array['popup_title'] = $entry['text']; $hostbox_tags['graphs'][] = generate_graph_popup($graph_array); } } $hostbox = ' <tr class="' . $hostbox_tags['html_row_class'] . '" onclick="location.href=\'device/device=' . $hostbox_tags['device_id'] . '/\'" style="cursor: pointer;"> <td class="state-marker"></td> <td style="width: 64px; text-align: center; vertical-align: middle;">' . $hostbox_tags['device_image'] . '</td> <td style="width: 300px;"><span class="entity-title">' . $hostbox_tags['device_link'] . '</span><br />' . $hostbox_tags['location'] . '</td> <td>'; if ($hostbox_tags['graphs']) { $hostbox .= '<div class="pull-right" style="height: 50px; padding: 2px; margin: 0;">' . implode($hostbox_tags['graphs']) . '</div>'; } $hostbox .= '</td> </tr>'; break; default: // basic $hostbox = ' <tr class="' . $hostbox_tags['html_row_class'] . '" onclick="location.href=\'device/device=' . $hostbox_tags['device_id'] . '/\'" style="cursor: pointer;"> <td style="width: 300;"><span class="entity-title">' . $hostbox_tags['device_link'] . '</span><br />' . $hostbox_tags['location'] . '</td> <td>' . $hostbox_tags['hardware'] . ' ' . $hostbox_tags['features'] . '</td> <td>' . $hostbox_tags['os_text'] . ' ' . $hostbox_tags['version'] . '</td> <td>' . $hostbox_tags['device_uptime'] . '</td> </tr>'; } echo $hostbox; }
function process_syslog($entry, $update) { global $config; global $rules; global $device_rules; global $maint; foreach ($config['syslog']['filter'] as $bi) { if (strpos($entry['msg'], $bi) !== FALSE) { //echo('D-'.$bi); return FALSE; } } $entry['msg_orig'] = $entry['msg']; // Initial rewrites $entry['host'] = strtolower(trim($entry['host'])); // Rewrite priority and level from strings to numbers $entry['priority'] = priority_string_to_numeric($entry['priority']); $entry['level'] = priority_string_to_numeric($entry['level']); $entry['device_id'] = get_cache($entry['host'], 'device_id'); //print_vars($entry); //print_vars($GLOBALS['dev_cache']); if ($entry['device_id']) { $os = get_cache($entry['host'], 'os'); $os_group = get_cache($entry['host'], 'os_group'); if (in_array($os, array('ios', 'iosxe', 'catos', 'asa'))) { $matches = array(); # if (preg_match('#%(?P<program>.*):( ?)(?P<msg>.*)#', $entry['msg'], $matches)) { # $entry['msg'] = $matches['msg']; # $entry['program'] = $matches['program']; # } # unset($matches); //NOTE. Please include examples for syslog entries, to know why need some preg_replace() if (strstr($entry['msg'], '%')) { //10.0.0.210||23||4||4||26644:||2013-11-08 07:19:24|| 033884: Nov 8 07:19:23.993: %FW-4-TCP_OoO_SEG: Dropping TCP Segment: seq:-1169729434 1500 bytes is out-of-order; expected seq:3124765814. Reason: TCP reassembly queue overflow - session 10.10.32.37:56316 to 93.186.239.142:80 on zone-pair Local->Internet class All_Inspection||26644 //hostname||17||5||5||192462650:||2014-06-17 11:16:01|| %SSH-5-SSH2_SESSION: SSH2 Session request from 10.95.0.42 (tty = 0) using crypto cipher 'aes256-cbc', hmac 'hmac-sha1' Succeeded||192462650 if (strpos($entry['msg'], ': %')) { list(, $entry['msg']) = explode(': %', $entry['msg'], 2); $entry['msg'] = "%" . $entry['msg']; } $entry['msg'] = preg_replace("/^%(.+?):\\ /", "\\1||", $entry['msg']); } else { $entry['msg'] = preg_replace("/^.*[0-9]:/", "", $entry['msg']); $entry['msg'] = preg_replace("/^[0-9][0-9]\\ [A-Z]{3}:/", "", $entry['msg']); $entry['msg'] = preg_replace("/^(.+?):\\ /", "\\1||", $entry['msg']); } //$entry['msg'] = preg_replace("/^.+\.[0-9]{3}:/", "", $entry['msg']); /// FIXME. Show which entries this should replace. It's broke all entries with 'IP:PORT'. $entry['msg'] = preg_replace("/^.+-Traceback=/", "Traceback||", $entry['msg']); list($entry['program'], $entry['msg']) = explode("||", $entry['msg'], 2); $entry['msg'] = preg_replace("/^[0-9]+:/", "", $entry['msg']); if (!$entry['program']) { $entry['msg'] = preg_replace("/^([0-9A-Z\\-]+?):\\ /", "\\1||", $entry['msg']); list($entry['program'], $entry['msg']) = explode("||", $entry['msg'], 2); } if (!$entry['msg']) { $entry['msg'] = $entry['program']; unset($entry['program']); } } else { if ($os == 'iosxr') { //1.1.1.1||23||5||5||920:||2014-11-26 17:29:48||RP/0/RSP0/CPU0:Nov 26 16:29:48.161 : bgp[1046]: %ROUTING-BGP-5-ADJCHANGE : neighbor 1.1.1.2 Up (VRF: default) (AS: 11111) ||920 //1.1.1.2||23||6||6||253:||2014-11-26 17:30:21||RP/0/RSP0/CPU0:Nov 26 16:30:21.710 : SSHD_[65755]: %SECURITY-SSHD-6-INFO_GENERAL : Client closes socket connection ||253 //1.1.1.3||local0||err||err||83||2015-01-14 07:29:45||oly-er-01 LC/0/0/CPU0:Jan 14 07:29:45.556 CET: pfilter_ea[301]: %L2-PFILTER_EA-3-ERR_IM_CAPS : uidb set acl failed on interface Bundle-Ether1.1501.ip43696. (null) ||94795 list(, $entry['msg']) = explode(': %', $entry['msg'], 2); list($entry['program'], $entry['msg']) = explode(' : ', $entry['msg'], 2); } else { if ($os == 'linux' && get_cache($entry['host'], 'version') == 'Point') { // Cisco WAP200 and similar $matches = array(); if (preg_match('#Log: \\[(?P<program>.*)\\] - (?P<msg>.*)#', $entry['msg'], $matches)) { $entry['msg'] = $matches['msg']; $entry['program'] = $matches['program']; } unset($matches); } else { if ($os_group == 'unix') { $matches = array(); // User_CommonName/123.213.132.231:39872 VERIFY OK: depth=1, /C=PL/ST=Malopolska/O=VLO/CN=v-lo.krakow.pl/emailAddress=root@v-lo.krakow.pl if ($entry['facility'] == 'daemon' && preg_match('#/([0-9]{1,3}\\.) {3}[0-9]{1,3}:[0-9]{4,} ([A-Z]([A-Za-z])+( ?)) {2,}:#', $entry['msg'])) { $entry['program'] = 'OpenVPN'; } else { if ($entry['facility'] == 'mail' && preg_match('/^(((pop3|imap)\\-login)|((POP3|IMAP)\\(.*\\))):/', $entry['msg'])) { $entry['program'] = 'Dovecot'; } else { if (preg_match('/^(?P<program>(\\S((\\(|\\[).*(\\)|\\])))):(?P<msg>.*)$/', $entry['msg'], $matches)) { $entry['msg'] = $matches['msg']; $entry['program'] = $matches['program']; } else { if (preg_match('/^(?P<program>[^\\s\\(\\[]*):\\ (?P<msg>.*)$/', $entry['msg'], $matches)) { $entry['msg'] = $matches['msg']; $entry['program'] = $matches['program']; } else { if (!empty($entry['program']) && preg_match('/^.*:\\ ' . $entry['program'] . ':\\ (?P<msg>[^(]+\\((?P<program>[^:]+):.*)$/', $entry['msg'], $matches)) { $entry['msg'] = $matches['msg']; $entry['program'] = $matches['program']; } else { if (empty($entry['program']) && !empty($entry['facility'])) { $entry['program'] = $entry['facility']; } } } } } } unset($matches); } else { if ($os == 'ftos') { if (empty($entry['program'])) { //1.1.1.1||23||5||5||||2014-11-23 21:48:10|| Nov 23 21:48:10.745: hostname: %STKUNIT0-M:CP %SEC-5-LOGOUT: Exec session is terminated for user rancid on line vty0|| list(, , $entry['program'], $entry['msg']) = explode(': ', $entry['msg'], 4); list(, $entry['program']) = explode(' %', $entry['program'], 2); } //Jun 3 02:33:23.489: %STKUNIT0-M:CP %SNMP-3-SNMP_AUTH_FAIL: SNMP Authentication failure for SNMP request from host 176.10.35.241 //Jun 1 17:11:50.806: %STKUNIT0-M:CP %ARPMGR-2-MAC_CHANGE: IP-4-ADDRMOVE: IP address 11.222.30.53 is moved from MAC address 52:54:00:7b:37:ad to MAC address 52:54:00:e4:ec:06 . //if (strpos($entry['msg'], '%STKUNIT') === 0) //{ // list(, $entry['program'], $entry['msg']) = explode(': ', $entry['msg'], 3); // //$entry['timestamp'] = date("Y-m-d H:i:s", strtotime($entry['timestamp'])); // convert to timestamp // list(, $entry['program']) = explode(' %', $entry['program'], 2); //} } else { if ($os == 'netscaler') { //10/03/2013:16:49:07 GMT dk-lb001a PPE-4 : UI CMD_EXECUTED 10367926 : User so_readonly - Remote_ip 10.70.66.56 - Command "stat lb vserver" - Status "Success" list(, , , $entry['msg']) = explode(' ', $entry['msg'], 4); list($entry['program'], $entry['msg']) = explode(' : ', $entry['msg'], 3); } } } } } } if ($entry['program'] == '') { /** FIXME, WHAT? Pls examples. $entry['program'] = $entry['msg']; unset($entry['msg']); */ if ($entry['msg'] == '') { // Something wrong, both program and msg empty return $entry; } } else { if (strpos($entry['program'], '(BZ2') === 0) { // Wtf is BZ2LR and BZ@.. /** *Old: 10.10.34.10||3||6||6||hostapd:||2014-07-18 11:29:35|| ath2: STA c8:dd:c9:d1:d4:aa IEEE 802.11: associated||hostapd *New: 10.10.34.10||3||6||6||(BZ2LR,00272250c1cd,v3.2.5.2791)||2014-12-12 09:36:39|| hostapd: ath2: STA dc:a9:71:1b:d6:c7 IEEE 802.11: associated||(BZ2LR,00272250c1cd,v3.2.5.2791) */ list($entry['program'], $entry['msg']) = explode(': ', $entry['msg'], 2); } } $entry['program'] = strtoupper($entry['program']); array_walk($entry, 'trim'); if ($update) { $log_id = dbInsert(array('device_id' => $entry['device_id'], 'host' => $entry['host'], 'program' => $entry['program'], 'facility' => $entry['facility'], 'priority' => $entry['priority'], 'level' => $entry['level'], 'tag' => $entry['tag'], 'msg' => $entry['msg'], 'timestamp' => $entry['timestamp']), 'syslog'); } //$req_dump = print_r(array($entry, $rules, $device_rules), TRUE); //$fp = fopen('/tmp/syslog.log', 'a'); //fwrite($fp, $req_dump); //fclose($fp); $notification_type = 'syslog'; /// FIXME, I not know how 'syslog_rules_assoc' is filled, I pass rules to all devices /// FIXME, this is copy-pasted from above, while not have WUI for syslog_rules_assoc foreach ($rules as $la_id => $rule) { if ((empty($device_rules) || isset($device_rules[$entry['device_id']][$la_id])) && preg_match($rule['la_rule'], $entry['msg_orig'])) { // Mark no notification during maintenance if (isset($maint['device'][$entry['device_id']]) || isset($maint['global']) && $maint['global'] > 0) { $notified = '-1'; } else { $notified = '0'; } $log_id = dbInsert(array('device_id' => $entry['device_id'], 'la_id' => $la_id, 'syslog_id' => $log_id, 'timestamp' => $entry['timestamp'], 'program' => $entry['program'], 'message' => $entry['msg_orig'], 'notified' => $notified), 'syslog_alerts'); // Get contacts for $la_id $transports = get_alert_contacts($entry['device_id'], $la_id, $notification_type); // Add notification to queue if ($notified != '-1' && !empty($transports)) { $device = device_by_id_cache($entry['device_id']); $message_tags = array('ALERT_STATE' => "SYSLOG", 'ALERT_URL' => generate_url(array('page' => 'device', 'device' => $device['device_id'], 'tab' => 'alert', 'entity_type' => 'syslog')), 'ALERT_ID' => $la_id, 'ALERT_MESSAGE' => $rule['la_descr'], 'CONDITIONS' => $rule['la_rule'], 'METRICS' => $entry['msg'], 'SYSLOG_RULE' => $rule['la_rule'], 'SYSLOG_MESSAGE' => $entry['msg'], 'SYSLOG_PROGRAM' => $entry['program'], 'TIMESTAMP' => $entry['timestamp'], 'DEVICE_HOSTNAME' => $device['hostname'], 'DEVICE_LINK' => generate_device_link($device), 'DEVICE_HARDWARE' => $device['hardware'], 'DEVICE_OS' => $device['os_text'] . ' ' . $device['version'] . ' ' . $device['features'], 'DEVICE_LOCATION' => $device['location'], 'DEVICE_UPTIME' => deviceUptime($device)); $message_tags['TITLE'] = alert_generate_subject($device, 'SYSLOG', $message_tags); $notification = array('device_id' => $entry['device_id'], 'log_id' => $log_id, 'aca_type' => $notification_type, 'severity' => $entry['priority'], 'endpoints' => json_encode($transports), 'notification_added' => time(), 'notification_lifetime' => 300, 'notification_entry' => json_encode($entry)); //unset($message_tags['ENTITY_GRAPHS_ARRAY']); $notification['message_tags'] = json_encode($message_tags); $notification_id = dbInsert($notification, 'notifications_queue'); } } } unset($os); } else { if ($config['syslog']['unknown_hosts']) { if ($update) { array_walk($entry, 'trim'); // Store entries for unknown hosts with NULL device_id $log_id = dbInsert(array('host' => $entry['host'], 'program' => $entry['program'], 'facility' => $entry['facility'], 'priority' => $entry['priority'], 'level' => $entry['level'], 'tag' => $entry['tag'], 'msg' => $entry['msg'], 'timestamp' => $entry['timestamp']), 'syslog'); //var_dump($entry); } } } return $entry; }
function get_status_array($status) { // Mike: I know that there are duplicated variables, but later will remove global global $config; global $cache; $param = array(); if ($_SESSION['userlevel'] >= 5) { $query_perms = ''; $query_user = ''; } else { $query_perms = 'LEFT JOIN devices_perms AS P ON D.device_id = P.device_id '; $query_user = '******'; $param[] = $_SESSION['user_id']; } // Don't show ignored and disabled devices $query_device = ' AND D.ignore = 0 '; if (!$config['web_show_disabled']) { $query_device .= 'AND D.disabled = 0 '; } // Show Device Status if ($status['devices']) { $query = 'SELECT * FROM `devices` AS D '; $query .= $query_perms; $query .= 'WHERE D.status = 0' . $query_device . $query_user; $query .= 'ORDER BY D.hostname ASC'; $entries = dbFetchRows($query, $param); foreach ($entries as $device) { $boxes[] = array('sev' => 100, 'class' => 'Device', 'event' => 'Down', 'device_link' => generate_device_link($device, shorthost($device['hostname'])), 'time' => deviceUptime($device, 'short-3')); } } // Uptime if ($status['uptime']) { if (filter_var($config['uptime_warning'], FILTER_VALIDATE_FLOAT) !== FALSE && $config['uptime_warning'] > 0) { $query = 'SELECT * FROM `devices` AS D '; $query .= $query_perms; $query .= 'WHERE D.status = 1 AND D.uptime > 0 AND D.uptime < ' . $config['uptime_warning'] . $query_device . $query_user; $query .= 'ORDER BY D.hostname ASC'; $entries = dbFetchRows($query, $param); foreach ($entries as $device) { $boxes[] = array('sev' => 10, 'class' => 'Device', 'event' => 'Rebooted', 'device_link' => generate_device_link($device, shorthost($device['hostname'])), 'time' => deviceUptime($device, 'short-3'), 'location' => $device['location']); } } } // Ports Down if ($status['ports'] || $status['links']) { // warning about deprecated option: $config['warn']['ifdown'] if (isset($config['warn']['ifdown']) && !$config['warn']['ifdown']) { echo ' <div class="alert"> <button type="button" class="close" data-dismiss="alert">×</button> <p><i class="oicon-bell"></i> <strong>Config option obsolete</strong></p> <p>Please note that config option <strong>$config[\'warn\'][\'ifdown\']</strong> is now obsolete.<br />Use options: <strong>$config[\'frontpage\'][\'device_status\'][\'ports\']</strong> and <strong>$config[\'frontpage\'][\'device_status\'][\'errors\']</strong></p> <p>To remove this message, delete <strong>$config[\'warn\'][\'ifdown\']</strong> from configuration file.</p> </div>'; } $query = 'SELECT * FROM `ports` AS I '; if ($status['links'] && !$status['ports']) { $query .= 'INNER JOIN links as L ON I.port_id = L.local_port_id '; } $query .= 'LEFT JOIN `devices` AS D ON I.device_id = D.device_id '; $query .= $query_perms; $query .= "WHERE I.ifOperStatus = 'down' AND I.ifAdminStatus = 'up' AND I.ignore = 0 AND I.deleted = 0 "; if ($status['links'] && !$status['ports']) { $query .= ' AND L.active = 1 '; } $query .= $query_device . $query_user; $query .= ' AND I.ifLastChange >= DATE_SUB(NOW(), INTERVAL 24 HOUR) '; $query .= 'ORDER BY I.ifLastChange DESC, D.hostname ASC, I.ifDescr * 1 ASC '; $entries = dbFetchRows($query, $param); //$count = count($entries); $i = 1; foreach ($entries as $port) { if ($i > 200) { // Limit to 200 ports on overview page $string .= ' <tr><td></td><td><span class="badge badge-info">Port</span></td>'; $string .= '<td><span class="label label-important">Port Down</span></td>'; $string .= '<td colspan=3>Too many ports down. See <strong><a href="' . generate_url(array('page' => 'ports'), array('state' => 'down')) . '">All DOWN ports</a></strong>.</td></tr>' . PHP_EOL; break; } humanize_port($port); $boxes[] = array('sev' => 50, 'class' => 'Port', 'event' => 'Down', 'device_link' => generate_device_link($port, shorthost($port['hostname'])), 'entity_link' => generate_port_link($port, truncate(makeshortif($port['label']), 13, '')), 'time' => formatUptime($config['time']['now'] - strtotime($port['ifLastChange'])), 'location' => $device['location']); // We don't do anything with this here at the moment. There is no comment on it, what is it for? // if ($status['links'] && !$status['ports']) { $string .= ' ('.strtoupper($port['protocol']).': ' .$port['remote_hostname'].' / ' .$port['remote_port'] .')'; } } } // Ports Errors (only deltas) if ($status['errors']) { foreach ($cache['ports_errored'] as $port_id) { $port = get_port_by_id($port_id); if (port_permitted($port)) { $device = device_by_id_cache($port['device_id']); humanize_port($port); if ($port['ifInErrors_delta']) { $port['string'] .= 'Rx: ' . $port['ifInErrors_delta']; } if ($port['ifInErrors_delta'] && $port['ifOutErrors_delta']) { $port['string'] .= ', '; } if ($port['ifOutErrors_delta']) { $port['string'] .= 'Tx: ' . $port['ifOutErrors_delta']; } $boxes[] = array('sev' => 75, 'class' => 'Port', 'event' => 'Errors', 'device_link' => generate_device_link($device, shorthost($device['hostname'])), 'entity_link' => generate_port_link($port, truncate(makeshortif($port['label']), 13, '')), 'time' => $port['string'], 'location' => $device['location']); } } } // Services if ($status['services']) { $query = 'SELECT * FROM `services` AS S '; $query .= 'LEFT JOIN `devices` AS D ON S.device_id = D.device_id '; $query .= $query_perms; $query .= "WHERE S.service_status = 'down' AND S.service_ignore = 0" . $query_device . $query_user; $query .= 'ORDER BY D.hostname ASC'; $entries = dbFetchRows($query, $param); foreach ($entries as $service) { $boxes[] = array('sev' => 50, 'class' => 'Service', 'event' => 'Down', 'device_link' => generate_device_link($service, shorthost($service['hostname'])), 'entity_link' => $service['service_type'], 'time' => formatUptime($config['time']['now'] - strtotime($service['service_changed']), 'short'), 'location' => $device['location']); } } // BGP if ($status['bgp']) { if (isset($config['enable_bgp']) && $config['enable_bgp']) { // Description for BGP states $bgpstates = 'IDLE - Router is searching routing table to see whether a route exists to reach the neighbor. 
'; $bgpstates .= 'CONNECT - Router found a route to the neighbor and has completed the three-way TCP handshake. 
'; $bgpstates .= 'OPEN SENT - Open message sent, with parameters for the BGP session. 
'; $bgpstates .= 'OPEN CONFIRM - Router received agreement on the parameters for establishing session. 
'; $bgpstates .= 'ACTIVE - Router did not receive agreement on parameters of establishment. 
'; //$bgpstates .= 'ESTABLISHED - Peering is established; routing begins.'; $query = 'SELECT * FROM `devices` AS D '; $query .= 'LEFT JOIN bgpPeers AS B ON B.device_id = D.device_id '; $query .= $query_perms; $query .= "WHERE (bgpPeerAdminStatus = 'start' OR bgpPeerAdminStatus = 'running') AND bgpPeerState != 'established' " . $query_device . $query_user; $query .= 'ORDER BY D.hostname ASC'; $entries = dbFetchRows($query, $param); foreach ($entries as $peer) { $peer_ip = strstr($peer['bgpPeerRemoteAddr'], ':') ? Net_IPv6::compress($peer['bgpPeerRemoteAddr']) : $peer['bgpPeerRemoteAddr']; if (strstr($peer['bgpPeerRemoteAddr'], ':')) { $peer['wide'] = TRUE; } $boxes[] = array('sev' => 75, 'class' => 'BGP Peer', 'event' => 'Down', 'device_link' => generate_device_link($peer, shorthost($peer['hostname'])), 'entity_link' => $peer_ip, 'wide' => $peer['wide'], 'time' => formatUptime($peer['bgpPeerFsmEstablishedTime'], 'shorter'), 'location' => $device['location']); } } } $string .= ' </tbody>' . PHP_EOL; $string .= '</table>'; // Final print all statuses return $boxes; }
/** * Generate notifications for an alert entry * * @param array entry * @return NULL */ function alert_notifier($entry, $type = "alert") { global $config, $alert_rules; $device = device_by_id_cache($entry['device_id']); $alert = $alert_rules[$entry['alert_test_id']]; $state = json_decode($entry['state'], TRUE); $conditions = json_decode($alert['conditions'], TRUE); $entity = get_entity_by_id_cache($entry['entity_type'], $entry['entity_id']); $condition_array = array(); foreach ($state['failed'] as $failed) { $condition_array[] = $failed['metric'] . " " . $failed['condition'] . " " . $failed['value'] . " (" . $state['metrics'][$failed['metric']] . ")"; } $metric_array = array(); foreach ($state['metrics'] as $metric => $value) { $metric_array[] = $metric . ' = ' . $value; } $graphs = array(); $graph_done = array(); foreach ($state['metrics'] as $metric => $value) { if ($config['email']['graphs'] !== FALSE && is_array($config['entities'][$entry['entity_type']]['metric_graphs'][$metric]) && !in_array($config['entities'][$entry['entity_type']]['metric_graphs'][$metric]['type'], $graph_done)) { $graph_array = $config['entities'][$entry['entity_type']]['metric_graphs'][$metric]; foreach ($graph_array as $key => $val) { // Check to see if we need to do any substitution if (substr($val, 0, 1) == '@') { $nval = substr($val, 1); //echo(" replaced " . $val . " with " . $entity[$nval] . " from entity. " . PHP_EOL . "<br />"); $graph_array[$key] = $entity[$nval]; } } $image_data_uri = generate_alert_graph($graph_array); $image_url = generate_graph_url($graph_array); $graphs[] = array('label' => $graph_array['type'], 'type' => $graph_array['type'], 'url' => $image_url, 'data' => $image_data_uri); $graph_done[] = $graph_array['type']; } unset($graph_array); } if ($config['email']['graphs'] !== FALSE && count($graph_done) == 0 && is_array($config['entities'][$entry['entity_type']]['graph'])) { // We can draw a graph for this type/metric pair! $graph_array = $config['entities'][$entry['entity_type']]['graph']; foreach ($graph_array as $key => $val) { // Check to see if we need to do any substitution if (substr($val, 0, 1) == '@') { $nval = substr($val, 1); //echo(" replaced ".$val." with ". $entity[$nval] ." from entity. ".PHP_EOL."<br />"); $graph_array[$key] = $entity[$nval]; } } //print_vars($graph_array); $image_data_uri = generate_alert_graph($graph_array); $image_url = generate_graph_url($graph_array); $graphs[] = array('label' => $graph_array['type'], 'type' => $graph_array['type'], 'url' => $image_url, 'data' => $image_data_uri); unset($graph_array); } $graphs_html = ""; foreach ($graphs as $graph) { $graphs_html .= '<h4>' . $graph['type'] . '</h4>'; $graphs_html .= '<a href="' . $graph['url'] . '"><img src="' . $graph['data'] . '"></a><br />'; } //print_vars($graphs); //print_vars($graphs_html); //print_vars($entry); $message_tags = array('ALERT_STATE' => $entry['alert_status'] == '1' ? "RECOVER" : "ALERT", 'ALERT_URL' => generate_url(array('page' => 'device', 'device' => $device['device_id'], 'tab' => 'alert', 'alert_entry' => $entry['alert_table_id'])), 'ALERT_ID' => $entry['alert_table_id'], 'ALERT_MESSAGE' => $alert['alert_message'], 'CONDITIONS' => implode(PHP_EOL . ' ', $condition_array), 'METRICS' => implode(PHP_EOL . ' ', $metric_array), 'DURATION' => $entry['alert_status'] == '1' ? $entry['last_ok'] > 0 ? formatUptime(time() - $entry['last_ok']) . " (" . format_unixtime($entry['last_ok']) . ")" : "Unknown" : ($entry['last_ok'] > 0 ? formatUptime(time() - $entry['last_ok']) . " (" . format_unixtime($entry['last_ok']) . ")" : "Unknown"), 'ENTITY_LINK' => generate_entity_link($entry['entity_type'], $entry['entity_id'], $entity['entity_name']), 'ENTITY_NAME' => $entity['entity_name'], 'ENTITY_TYPE' => $alert['entity_type'], 'ENTITY_DESCRIPTION' => $entity['entity_descr'], 'ENTITY_GRAPHS_ARRAY' => json_encode($graphs), 'DEVICE_HOSTNAME' => $device['hostname'], 'DEVICE_LINK' => generate_device_link($device), 'DEVICE_HARDWARE' => $device['hardware'], 'DEVICE_OS' => $device['os_text'] . ' ' . $device['version'] . ' ' . $device['features'], 'DEVICE_LOCATION' => $device['location'], 'DEVICE_UPTIME' => deviceUptime($device)); //logfile('debug.log', var_export($message, TRUE)); $title = alert_generate_subject($device, $message_tags['ALERT_STATE'], $message_tags); $message_tags['TITLE'] = $title; $alert_id = $entry['alert_test_id']; $notify_status = FALSE; // Set alert notify status to FALSE by default $notification_type = 'alert'; $transports = get_alert_contacts($device, $alert_id, $notification_type); if (!empty($transports)) { // WARNING, alerts queue currently experimental if (isset($config['alerts']['queue']) && isset($config['alerts']['queue'])) { // Add notification to queue $notification = array('device_id' => $device['device_id'], 'log_id' => $log_id, 'aca_type' => $notification_type, 'endpoints' => json_encode($transports), 'message_graphs' => $message_tags['ENTITY_GRAPHS_ARRAY'], 'notification_added' => time(), 'notification_lifetime' => 300, 'notification_entry' => json_encode($entry)); $notification_message_tags = $message_tags; unset($notification_message_tags['ENTITY_GRAPHS_ARRAY']); $notification['message_tags'] = json_encode($notification_message_tags); $notification_id = dbInsert($notification, 'notifications_queue'); } else { // Use classic instant notifications send $notification_count = 0; foreach ($transports as $method => $endpoints) { if (isset($config['alerts']['disable'][$method]) && $config['alerts']['disable'][$method]) { continue; } // Skip if method disabled globally foreach ($endpoints as $endpoint) { $method_include = $config['install_dir'] . "/includes/alerting/" . $method . ".inc.php"; if (is_file($method_include)) { print_cli_data("Notifying", "[" . $method . "] " . $endpoint['contact_descr'] . ": " . $endpoint['contact_endpoint']); // Split out endpoint data as stored JSON in the database into array for use in transport // The original string also remains available as the contact_endpoint key foreach (json_decode($endpoint['contact_endpoint']) as $field => $value) { $endpoint[$field] = $value; } include $method_include; // FIXME check success // FIXME log notification + success/failure! if ($notify_status['success']) { $notification_count++; } } else { print_cli_data("Missing include", $method_include); } } } if ($notification_count) { dbUpdate(array('notified' => 1), 'alert_log', '`event_id` = ?', array($notification['log_id'])); } } } }