1<?php 2/** 3 * Observium 4 * 5 * This file is part of Observium. 6 * 7 * @package observium 8 * @subpackage entities 9 * @copyright (C) 2006-2013 Adam Armstrong, (C) 2013-2019 Observium Limited 10 * 11 * 12 */ 13 14/** 15 * Return normalized state array by type, mib and value (numeric or string) 16 * 17 * @param string $type State type, in MIBs definition array $config['mibs'][$mib]['states'][$type] 18 * @param string $value Polled value for status 19 * @param string $mib MIB name 20 * @param string $event_map Polled value for event (this used only for statuses with event condition values) 21 * @param string $poller_type Poller type (snmp, ipmi, agent) 22 * 23 * @return array State array 24 */ 25function get_state_array($type, $value, $mib = '', $event_map = NULL, $poller_type = 'snmp') 26{ 27 global $config; 28 29 $state_array = array('value' => FALSE); 30 31 switch ($poller_type) 32 { 33 case 'agent': 34 case 'ipmi': 35 $state = state_string_to_numeric($type, $value, $mib, $poller_type); 36 if ($state !== FALSE) 37 { 38 $state_array['value'] = $state; // Numeric value 39 $state_array['name'] = $config[$poller_type]['states'][$type][$state]['name']; // Named value 40 $state_array['event'] = $config[$poller_type]['states'][$type][$state]['event']; // Event type 41 $state_array['mib'] = $mib; 42 } 43 break; 44 45 default: // SNMP 46 $state = state_string_to_numeric($type, $value, $mib); 47 if ($state !== FALSE) 48 { 49 if (!strlen($mib)) 50 { 51 $mib = state_type_to_mib($type); 52 } 53 $state_array['value'] = $state; // Numeric value 54 $state_array['name'] = $config['mibs'][$mib]['states'][$type][$state]['name']; // Named value 55 56 if (isset($config['mibs'][$mib]['states'][$type][$state]['event_map'])) 57 { 58 // For events based on additional Oid value, see: 59 // PowerNet-MIB::emsInputContactStatusInputContactState.1 = INTEGER: contactOpenEMS(2) 60 // PowerNet-MIB::emsInputContactStatusInputContactNormalState.1 = INTEGER: normallyOpenEMS(2) 61 62 // Find event associated event with event_value 63 $state_array['event'] = $config['mibs'][$mib]['states'][$type][$state]['event_map'][$event_map]; 64 65 } else { 66 // Normal static events 67 $state_array['event'] = $config['mibs'][$mib]['states'][$type][$state]['event']; // Event type 68 } 69 $state_array['mib'] = $mib; // MIB name 70 } 71 } 72 73 return $state_array; 74} 75 76/** 77 * Converts named oid values to numerical interpretation based on oid descriptions and stored in definitions 78 * 79 * @param string $type Sensor type which has definitions in $config['mibs'][$mib]['states'][$type] 80 * @param mixed $value Value which must be converted 81 * @param string $mib MIB name 82 * @param string $poller_type Poller type 83 * 84 * @return integer Note, if definition not found or incorrect value, returns FALSE 85 */ 86function state_string_to_numeric($type, $value, $mib = '', $poller_type = 'snmp') 87{ 88 switch ($poller_type) 89 { 90 case 'agent': 91 case 'ipmi': 92 if (!isset($GLOBALS['config'][$poller_type]['states'][$type])) 93 { 94 return FALSE; 95 } 96 $state_def = $GLOBALS['config'][$poller_type]['states'][$type]; 97 break; 98 99 default: 100 if (!strlen($mib)) 101 { 102 $mib = state_type_to_mib($type); 103 } 104 $state_def = $GLOBALS['config']['mibs'][$mib]['states'][$type]; 105 } 106 107 if (is_numeric($value)) 108 { 109 // Return value if already numeric 110 if ($value == (int)$value && isset($state_def[(int)$value])) 111 { 112 return (int)$value; 113 } else { 114 return FALSE; 115 } 116 } 117 foreach ($state_def as $index => $content) 118 { 119 if (strcasecmp($content['name'], trim($value)) == 0) { return $index; } 120 } 121 122 return FALSE; 123} 124 125/** 126 * Helper function for get MIB name by status type. 127 * Currently we use unique status types over all MIBs 128 * 129 * @param string $state_type Unique status type 130 * 131 * @return string MIB name corresponding to this type 132 */ 133function state_type_to_mib($state_type) 134{ 135 // By first cache all type -> mib from definitions 136 if (!isset($GLOBALS['cache']['state_type_mib'])) 137 { 138 $GLOBALS['cache']['state_type_mib'] = array(); 139 // $config['mibs'][$mib]['states']['dskf-mib-hum-state'][0] = array('name' => 'error', 'event' => 'alert'); 140 foreach ($GLOBALS['config']['mibs'] as $mib => $entries) 141 { 142 if (!isset($entries['states'])) { continue; } 143 foreach ($entries['states'] as $type => $entry) 144 { 145 if (isset($GLOBALS['cache']['state_type_mib'][$type])) 146 { 147 // Disabling because it's annoying for now - pending some rewriting. 148 //print_warning('Warning, status type name "'.$type.'" for MIB "'.$mib.'" also exist in MIB "'.$GLOBALS['cache']['state_type_mib'][$type].'". Type name MUST be unique!'); 149 } 150 $GLOBALS['cache']['state_type_mib'][$type] = $mib; 151 } 152 } 153 } 154 155 //print_vars($GLOBALS['cache']['state_type_mib']); 156 return $GLOBALS['cache']['state_type_mib'][$state_type]; 157} 158 159function discover_status_definition($device, $mib, $entry) 160{ 161 162 echo($entry['oid']. ' ['); 163 164 // Check that types listed in skip_if_valid_exist have already been found 165 if (discovery_check_if_type_exist($GLOBALS['valid'], $entry, 'status')) { echo '!]'; return; } 166 167 // Check array requirements list 168 if (discovery_check_requires_pre($device, $entry, 'status')) { echo '!]'; return; } 169 170 // Fetch table or Oids 171 $table_oids = array('oid', 'oid_descr', 'oid_class', 'oid_map', 'oid_extra', 'oid_entPhysicalIndex'); 172 $status_array = discover_fetch_oids($device, $mib, $entry, $table_oids); 173 174 if (empty($entry['oid_num'])) 175 { 176 // Use snmptranslate if oid_num not set 177 $entry['oid_num'] = snmp_translate($entry['oid'], $mib); 178 } else { 179 $entry['oid_num'] = rtrim($entry['oid_num'], '.'); 180 } 181 182 $i = 0; // Used in descr as $i++ 183 $status_count = count($status_array); 184 foreach ($status_array as $index => $status) 185 { 186 $options = array(); 187 188 $dot_index = '.' . $index; 189 $oid_num = $entry['oid_num'] . $dot_index; 190 191 //echo PHP_EOL; print_vars($entry); echo PHP_EOL; print_vars($status); echo PHP_EOL; print_vars($descr); echo PHP_EOL; 192 193 // %i% can be used in description 194 $i++; 195 196 if (isset($entry['oid_class']) && strlen($status[$entry['oid_class']])) 197 { 198 if (isset($entry['map_class'][$status[$entry['oid_class']]])) 199 { 200 // Try override measured class by map 201 $class = $entry['map_class'][$status[$entry['oid_class']]]; 202 if ($class == 'exclude' || !$class) 203 { 204 print_debug("Excluded by empty class map value."); 205 continue; // trigger for exclude statuses 206 } 207 } else { 208 $class = $status[$entry['oid_class']]; 209 } 210 } else { 211 $class = $entry['measured']; 212 } 213 // Generate specific keys used during rewrites 214 215 $status['class'] = nicecase($class); // Class in descr 216 $status['index'] = $index; // Index in descr 217 $status['i'] = $i; // i++ counter in descr 218 219 // Check array requirements list 220 if (discovery_check_requires($device, $entry, $status, 'status')) { continue; } 221 222 $value = $status[$entry['oid']]; 223 if (!strlen($value)) 224 { 225 print_debug("Excluded by empty current value."); 226 continue; 227 } 228 229 $options = array('entPhysicalClass' => $class); 230 231 // Definition based events 232 if (isset($entry['oid_map']) && $status[$entry['oid_map']]) 233 { 234 $options['status_map'] = $status[$entry['oid_map']]; 235 } 236 237 // Rule-based entity linking. 238 if ($measured = entity_measured_match_definition($device, $entry, $status, 'status')) 239 { 240 $options = array_merge($options, $measured); 241 $status = array_merge($status, $measured); // append to $status for %descr% tags, ie %port_label% 242 if (empty($class)) 243 { 244 $options['entPhysicalClass'] = $measured['measured']; 245 } 246 } 247 // End rule-based entity linking 248 else if (isset($entry['entPhysicalIndex'])) 249 { 250 // Just set physical index 251 $options['entPhysicalIndex'] = array_tag_replace($status, $entry['entPhysicalIndex']); 252 } 253 254 // Generate Description 255 $descr = entity_descr_definition('status', $entry, $status, $status_count); 256 257 // Rename old (converted) RRDs to definition format 258 if (isset($entry['rename_rrd'])) 259 { 260 $options['rename_rrd'] = $entry['rename_rrd']; 261 } 262 else if (isset($entry['rename_rrd_full'])) 263 { 264 $options['rename_rrd_full'] = $entry['rename_rrd_full']; 265 } 266 267 discover_status_ng($device, $mib, $entry['oid'], $oid_num, $index, $entry['type'], $descr, $value, $options); 268 269 } 270 271 echo '] '; 272 273} 274 275// Compatibility wrapper! 276function discover_status($device, $numeric_oid, $index, $type, $status_descr, $value = NULL, $options = array(), $poller_type = NULL) 277{ 278 if (isset($poller_type)) { $options['poller_type'] = $poller_type; } 279 280 return discover_status_ng($device, '', '', $numeric_oid, $index, $type, $status_descr, $value, $options); 281} 282 283// TESTME needs unit testing 284/** 285 * Discover a new status sensor on a device - called from discover_sensor() 286 * 287 * This function adds a status sensor to a device, if it does not already exist. 288 * Data on the sensor is updated if it has changed, and an event is logged with regards to the changes. 289 * 290 * @param array $device Device array status sensor is being discovered on 291 * @param string $mib SNMP MIB name 292 * @param string $object SNMP Named Oid of sensor (without index) 293 * @param string $oid SNMP Numeric Oid of sensor (without index) 294 * @param string $index SNMP index of status sensor 295 * @param string $type Type of status sensor (used as key in $config['status_states']) 296 * @param string $status_descr Description of status sensor 297 * @param string $value Current value of status sensor 298 * @param array $options Options 299 * 300 * @return bool 301 */ 302function discover_status_ng($device, $mib, $object, $oid, $index, $type, $status_descr, $value = NULL, $options = array()) 303{ 304 global $config; 305 306 $poller_type = (isset($options['poller_type']) ? $options['poller_type'] : 'snmp'); 307 308 $status_deleted = 0; 309 310 // Init main 311 $param_main = array('oid' => 'status_oid', 'status_descr' => 'status_descr', 'status_deleted' => 'status_deleted', 312 'index' => 'status_index', 'mib' => 'status_mib', 'object' => 'status_object'); 313 314 // Init optional 315 $param_opt = array('entPhysicalIndex', 'entPhysicalClass', 'entPhysicalIndex_measured', 'measured_class', 'measured_entity', 'status_map'); 316 foreach ($param_opt as $key) 317 { 318 $$key = ($options[$key] ? $options[$key] : NULL); 319 } 320 321 $state_array = get_state_array($type, $value, $mib, $status_map, $poller_type); 322 $state = $state_array['value']; 323 if ($state === FALSE) 324 { 325 print_debug("Skipped by unknown state value: $value, $status_descr "); 326 return FALSE; 327 } 328 else if ($state_array['event'] == 'exclude') 329 { 330 print_debug("Skipped by 'exclude' event value: ".$config['status_states'][$type][$state]['name'].", $status_descr "); 331 return FALSE; 332 } 333 $value = $state; 334 $index = strval($index); // Convert to string, for correct compare 335 336 print_debug("Discover status: [device: ".$device['hostname'].", oid: $oid, index: $index, type: $type, descr: $status_descr, CURRENT: $value, $entPhysicalIndex, $entPhysicalClass]"); 337 338 // Check sensor ignore filters 339 foreach ($config['ignore_sensor'] as $bi) { if (strcasecmp($bi, $status_descr) == 0) { print_debug("Skipped by equals: $bi, $status_descr "); return FALSE; } } 340 foreach ($config['ignore_sensor_string'] as $bi) { if (stripos($status_descr, $bi) !== FALSE) { print_debug("Skipped by strpos: $bi, $status_descr "); return FALSE; } } 341 foreach ($config['ignore_sensor_regexp'] as $bi) { if (preg_match($bi, $status_descr) > 0) { print_debug("Skipped by regexp: $bi, $status_descr "); return FALSE; } } 342 343 $new_definition = $poller_type == 'snmp' && strlen($mib) && strlen($object); 344 if ($new_definition) 345 { 346 $where = ' WHERE `device_id` = ? AND `status_mib` = ? AND `status_object` = ? AND `status_type` = ? AND `status_index` = ? AND `poller_type`= ?'; 347 $params = array($device['device_id'], $mib, $object, $type, $index, $poller_type); 348 $status_exist = dbExist('status', $where, $params); 349 350 // Check if old format of status was exist, than rename rrd 351 if (!$status_exist) 352 { 353 $old_where = ' WHERE `device_id` = ? AND `status_type` = ? AND `status_index` = ? AND `poller_type`= ?'; 354 $old_index = $object . '.' . $index; 355 $old_params = array($device['device_id'], $type, $old_index, $poller_type); 356 357 if ($status_exist = dbExist('status', $old_where, $old_params)) 358 { 359 $where = $old_where; 360 $params = $old_params; 361 362 // Rename old rrds without mib & object to new rrd name style 363 if (!isset($options['rename_rrd'])) 364 { 365 $options['rename_rrd'] = $type . "-" . $old_index; 366 } 367 } 368 } 369 } else { 370 // Old format of definitions 371 $where = ' WHERE `device_id` = ? AND `status_type` = ? AND `status_index` = ? AND `poller_type`= ?'; 372 $params = array($device['device_id'], $type, $index, $poller_type); 373 $status_exist = dbExist('status', $where, $params); 374 } 375 //if (dbFetchCell('SELECT COUNT(*) FROM `status`' . $where, $params) == '0') 376 if (!$status_exist) 377 { 378 $status_insert = array('poller_type' => $poller_type, 379 'device_id' => $device['device_id'], 380 'status_index' => $index, 381 'status_type' => $type, 382 //'status_id' => $status_id, 383 'status_value' => $value, 384 'status_polled' => time(), //array('NOW()'), // this field is INT(11) 385 'status_event' => $state_array['event'], 386 'status_name' => $state_array['name'] 387 ); 388 389 foreach ($param_main as $key => $column) 390 { 391 $status_insert[$column] = $$key; 392 } 393 394 foreach ($param_opt as $key) 395 { 396 if (is_null($$key)) { $$key = array('NULL'); } // If param null, convert to array(NULL) 397 $status_insert[$key] = $$key; 398 } 399 400 $status_id = dbInsert($status_insert, 'status'); 401 402 print_debug("( $status_id inserted )"); 403 echo('+'); 404 log_event("Status added: $entPhysicalClass $type $index $status_descr", $device, 'status', $status_id); 405 } else { 406 $status_entry = dbFetchRow('SELECT * FROM `status`' . $where, $params); 407 $status_id = $status_entry['status_id']; 408 409 print_debug_vars($status_entry); 410 $update = array(); 411 foreach ($param_main as $key => $column) 412 { 413 if ($$key != $status_entry[$column]) 414 { 415 $update[$column] = $$key; 416 } 417 } 418 foreach ($param_opt as $key) 419 { 420 if ($$key != $status_entry[$key]) 421 { 422 $update[$key] = $$key; 423 } 424 } 425 print_debug_vars($update); 426 427 if (count($update)) 428 { 429 $updated = dbUpdate($update, 'status', '`status_id` = ?', array($status_entry['status_id'])); 430 echo('U'); 431 log_event("Status updated: $entPhysicalClass $type $index $status_descr", $device, 'status', $status_entry['status_id']); 432 } else { 433 echo('.'); 434 } 435 } 436 437 // Rename old (converted) RRDs to definition format 438 // Allow with changing class or without 439 if (isset($options['rename_rrd_full'])) 440 { 441 // Compatibility with sensor option 442 $options['rename_rrd'] = $options['rename_rrd_full']; 443 } 444 if (isset($options['rename_rrd'])) 445 { 446 $rrd_tags = array('index' => $index, 'type' => $type, 'mib' => $mib, 'object' => $object, 'oid' => $object); 447 $options['rename_rrd'] = array_tag_replace($rrd_tags, $options['rename_rrd']); 448 $old_rrd = 'status-' . $options['rename_rrd']; 449 450 //$new_rrd = 'status-'.$type.'-'.$index; 451 $new_entry = ['status_descr' => $status_descr, 'status_mib' => $mib, 'status_object' => $object, 452 'status_type' => $type, 'status_index' => $index, 'poller_type' => $poller_type]; 453 $new_rrd = get_status_rrd($device, $new_entry); 454 rename_rrd($device, $old_rrd, $new_rrd); 455 } 456 457 if (strlen($mib)) 458 { 459 $GLOBALS['valid']['status'][$mib][$type][$index] = 1; 460 } else { 461 $GLOBALS['valid']['status']['__'][$type][$index] = 1; 462 } 463 464 return $status_id; 465 //return TRUE; 466} 467 468// DOCME needs phpdoc block 469// TESTME needs unit testing 470function check_valid_status($device, $valid, $poller_type = 'snmp') 471{ 472 $entries = dbFetchRows("SELECT * FROM `status` WHERE `device_id` = ? AND `poller_type` = ? AND `status_deleted` = '0'", array($device['device_id'], $poller_type)); 473 474 if (is_array($entries) && count($entries)) 475 { 476 foreach ($entries as $entry) 477 { 478 $index = $entry['status_index']; 479 $type = $entry['status_type']; 480 $mib = strlen($entry['status_mib']) ? $entry['status_mib'] : '__'; 481 if (!$valid[$mib][$type][$index]) 482 { 483 echo("-"); 484 print_debug("Status deleted: $index -> $type"); 485 //dbDelete('status', "`status_id` = ?", array($entry['status_id'])); 486 //dbDelete('status-state', "`status_id` = ?", array($entry['status_id'])); 487 488 dbUpdate(array('status_deleted' => '1'), 'status', '`status_id` = ?', array($entry['status_id'])); 489 490 foreach (get_entity_attribs('status', $entry['status_id']) as $attrib_type => $value) 491 { 492 del_entity_attrib('status', $entry['status_id'], $attrib_type); 493 } 494 log_event("Status deleted: ".$entry['status_class']." ".$entry['status_type']." ". $entry['status_index']." ".$entry['status_descr'], $device, 'status', $entry['status_id']); 495 } 496 } 497 } 498} 499 500function poll_status($device, &$oid_cache) 501{ 502 global $config, $agent_sensors, $ipmi_sensors, $graphs, $table_rows; 503 504 $sql = "SELECT * FROM `status`"; 505 //$sql .= " LEFT JOIN `status-state` USING(`status_id`)"; 506 $sql .= " WHERE `device_id` = ? AND `status_deleted` = ?"; 507 $sql .= ' ORDER BY `status_oid`'; // This fix polling some OIDs (when not ordered) 508 509 foreach (dbFetchRows($sql, array($device['device_id'], '0')) as $status_db) 510 { 511 //print_cli_heading("Status: ".$status_db['status_descr']. "(".$status_db['poller_type'].")", 3); 512 513 print_debug("Checking (" . $status_db['poller_type'] . ") " . $status_db['status_descr'] . " "); 514 515 // $status_poll = $status_db; // Cache non-humanized status array for use as new status state 516 517 if ($status_db['poller_type'] == "snmp") 518 { 519 $status_db['status_oid'] = '.' . ltrim($status_db['status_oid'], '.'); // Fix first dot in oid for caching 520 521 // Check if a specific poller file exists for this status, else collect via SNMP. 522 $file = $config['install_dir']."/includes/polling/status/".$status_db['status_type'].".inc.php"; 523 524 if (is_file($file)) 525 { 526 include($file); 527 } else { 528 // Take value from $oid_cache if we have it, else snmp_get it 529 if (isset($oid_cache[$status_db['status_oid']])) 530 { 531 print_debug("value taken from oid_cache"); 532 $status_value = $oid_cache[$status_db['status_oid']]; 533 } else { 534 $status_value = snmp_get_oid($device, $status_db['status_oid'], 'SNMPv2-MIB'); 535 } 536 //$status_value = snmp_fix_numeric($status_value); // Do not use fix, this broke not-enum (string) statuses 537 } 538 } 539 else if ($status_db['poller_type'] == "agent") 540 { 541 if (isset($agent_sensors['state'])) 542 { 543 $status_value = $agent_sensors['state'][$status_db['status_type']][$status_db['status_index']]['current']; 544 } else { 545 print_warning("No agent status data available."); 546 continue; 547 } 548 } 549 else if ($status_db['poller_type'] == "ipmi") 550 { 551 if (isset($ipmi_sensors['state'])) 552 { 553 $status_value = $ipmi_sensors['state'][$status_db['status_type']][$status_db['status_index']]['current']; 554 } else { 555 print_warning("No IPMI status data available."); 556 continue; 557 } 558 } else { 559 print_warning("Unknown status poller type."); 560 continue; 561 } 562 563 $status_polled_time = time(); // Store polled time for current status 564 565 // Write new value and humanize (for alert checks) 566 $state_array = get_state_array($status_db['status_type'], $status_value, $status_db['status_mib'], $status_db['status_map'], $status_db['poller_type']); 567 $status_value = $state_array['value']; // Override status_value by numeric for "pseudo" (string) statuses 568 $status_poll['status_value'] = $state_array['value']; 569 $status_poll['status_name'] = $state_array['name']; 570 if ($status_db['status_ignore'] || $status_db['status_disable']) 571 { 572 $status_poll['status_event'] = 'ignore'; 573 } else { 574 $status_poll['status_event'] = $state_array['event']; 575 } 576 577 // If last change never set, use current time 578 if (empty($status_db['status_last_change'])) 579 { 580 $status_db['status_last_change'] = $status_polled_time; 581 } 582 583 if ($status_poll['status_event'] != $status_db['status_event']) 584 { 585 // Status event changed, log and set status_last_change 586 $status_poll['status_last_change'] = $status_polled_time; 587 588 if ($status_poll['status_event'] == 'ignore') 589 { 590 print_message("[%ystatus Ignored%n]", 'color'); 591 } 592 else if ($status_db['status_event'] != '') 593 { 594 // If old state not empty and new state not equals to new state 595 $msg = 'Status ' . ucfirst($status_poll['status_event']) . ': ' . $device['hostname'] . ' ' . $status_db['status_descr'] . 596 ' entered ' . strtoupper($status_poll['status_event']) . ' state: ' . $status_poll['status_name'] . 597 ' (previous: ' . $status_db['status_name'] . ')'; 598 599 if (isset($config['entity_events'][$status_poll['status_event']])) 600 { 601 $severity = $config['entity_events'][$status_poll['status_event']]['severity']; 602 } else { 603 $severity = 'informational'; 604 } 605 log_event($msg, $device, 'status', $status_db['status_id'], $severity); 606 607 } 608 } else { 609 // If status not changed, leave old last_change 610 $status_poll['status_last_change'] = $status_db['status_last_change']; 611 } 612 613 print_debug_vars($status_poll); 614 615 // Send statistics array via AMQP/JSON if AMQP is enabled globally and for the ports module 616 if ($config['amqp']['enable'] == TRUE && $config['amqp']['modules']['status']) 617 { 618 $json_data = array('value' => $status_value); 619 messagebus_send(array('attribs' => array('t' => time(), 'device' => $device['hostname'], 'device_id' => $device['device_id'], 620 'e_type' => 'status', 'e_type' => $status_db['status_type'], 'e_index' => $status_db['status_index']), 'data' => $json_data)); 621 } 622 623 // Update StatsD/Carbon 624 if ($config['statsd']['enable'] == TRUE) 625 { 626 StatsD::gauge(str_replace(".", "_", $device['hostname']).'.'.'status'.'.'.$status_db['status_class'].'.'.$status_db['status_type'].'.'.$status_db['status_index'], $status_value); 627 } 628 629 // Update RRD - FIXME - can't convert to NG because filename is dynamic! new function should return index instead of filename. 630 $rrd_file = get_status_rrd($device, $status_db); 631 rrdtool_create($device, $rrd_file, "DS:status:GAUGE:600:-20000:U"); 632 rrdtool_update($device, $rrd_file,"N:$status_value"); 633 634 // Enable graph 635 $graphs[$status_db['status']] = TRUE; 636 637 // Check alerts 638 $metrics = array(); 639 640 $metrics['status_value'] = $status_value; 641 $metrics['status_name'] = $status_poll['status_name']; 642 $metrics['status_name_uptime'] = $status_polled_time - $status_poll['status_last_change']; 643 $metrics['status_event'] = $status_poll['status_event']; 644 645 //print_cli_data("Event (State)", $status_poll['status_event'] ." (".$status_poll['status_name'].")", 3); 646 647 $table_rows[] = array($status_db['status_descr'], $status_db['status_type'], $status_db['status_index'] ,$status_db['poller_type'], 648 $status_poll['status_name'], $status_poll['status_event'], format_unixtime($status_poll['status_last_change'])); 649 650 check_entity('status', $status_db, $metrics); 651 652 // Add to MultiUpdate SQL State 653 654 $GLOBALS['multi_update_db'][] = array( 655 'status_id' => $status_db['status_id'], // UNIQUE index 656 'status_value' => $status_value, 657 'status_name' => $status_poll['status_name'], 658 'status_event' => $status_poll['status_event'], 659 'status_last_change' => $status_poll['status_last_change'], 660 'status_polled' => $status_polled_time); 661 //dbUpdate(array('status_value' => $status_value, 662 // 'status_name' => $status_poll['status_name'], 663 // 'status_event' => $status_poll['status_event'], 664 // 'status_last_change' => $status_poll['status_last_change'], 665 // 'status_polled' => $status_polled_time), 666 // 'status', '`status_id` = ?', array($status_db['status_id'])); 667 } 668} 669 670// DOCME needs phpdoc block 671// TESTME needs unit testing 672function get_status_rrd($device, $status) 673{ 674 global $config; 675 676 # For IPMI, sensors tend to change order, and there is no index, so we prefer to use the description as key here. 677 if ($config['os'][$device['os']]['status_descr'] || ($status['poller_type'] != "snmp" && $status['poller_type'] != '')) 678 { 679 $rrd_file = "status-" . $status['status_type'] . "-" . $status['status_descr'] . ".rrd"; 680 } 681 elseif (strlen($status['status_mib']) && strlen($status['status_object'])) 682 { 683 // for discover_status_ng(), note here is just status index 684 $rrd_file = "status-" . $status['status_mib'] . "-" . $status['status_object'] . "-" . $status['status_index'] . ".rrd"; 685 } else { 686 // for discover_status(), note index == "%object%.%index%" 687 $rrd_file = "status-".$status['status_type']."-".$status['status_index'] . ".rrd"; 688 } 689 690 return($rrd_file); 691} 692 693// EOF 694