function generate_sensor_row($sensor, $vars) { global $config; humanize_sensor($sensor); $table_cols = 4; $graph_array = array(); $graph_array['to'] = $config['time']['now']; $graph_array['id'] = $sensor['sensor_id']; $graph_array['type'] = "sensor_graph"; $graph_array['width'] = 80; $graph_array['height'] = 20; $graph_array['bg'] = 'ffffff00'; $graph_array['from'] = $config['time']['day']; if ($sensor['sensor_event'] && is_numeric($sensor['sensor_value'])) { $mini_graph = generate_graph_tag($graph_array); } else { // Do not show "Draw Error" minigraph $mini_graph = ''; } $row = ' <tr class="' . $sensor['row_class'] . '"> <td class="state-marker"></td>'; if ($vars['page'] != "device" && $vars['popup'] != TRUE) { $row .= ' <td class="entity">' . generate_device_link($sensor) . '</td>' . PHP_EOL; $table_cols++; } if ($vars['entity_icon'] == TRUE) { $row .= ' <td width="20px"><i class="' . $config['sensor_types'][$sensor['sensor_class']]['icon'] . '"></i></td>'; } $row .= ' <td class="entity">' . generate_entity_link("sensor", $sensor) . '</td>'; if ($vars['show_class']) { $row .= ' <td>' . nicecase($sensor['sensor_class']) . '</td>' . PHP_EOL; $table_cols++; } if ($vars['tab'] != 'overview') { $row .= ' <td><span class="label ' . ($sensor['sensor_custom_limit'] ? 'label-warning' : '') . '">' . $sensor['sensor_thresholds'] . '</span></td>' . PHP_EOL; $table_cols++; } $row .= ' <td style="width: 90px; text-align: right;">' . generate_entity_link('sensor', $sensor, $mini_graph, NULL, FALSE) . '</td>'; if ($vars['tab'] != 'overview') { $row .= ' <td style="white-space: nowrap">' . generate_tooltip_link(NULL, formatUptime($config['time']['now'] - $sensor['sensor_last_change'], 'short-2') . ' ago', format_unixtime($sensor['sensor_last_change'])) . '</td>'; $table_cols++; $row .= ' <td style="text-align: right;"><strong><span class="' . $sensor['state_class'] . '">' . $sensor['sensor_event'] . '</span></strong></td>'; $table_cols++; } $row .= ' <td style="width: 80px; text-align: right;"><strong><span class="' . $sensor['state_class'] . '">' . $sensor['human_value'] . $sensor['sensor_symbol'] . '</span></strong> </tr>' . PHP_EOL; if ($vars['view'] == "graphs" || $vars['id'] == $sensor['sensor_id']) { $vars['graph'] = "graph"; } if ($vars['graph']) { $row .= ' <tr class="' . $sensor['row_class'] . '"> <td class="state-marker"></td> <td colspan="' . $table_cols . '">'; $graph_array = array(); $graph_array['to'] = $config['time']['now']; $graph_array['id'] = $sensor['sensor_id']; $graph_array['type'] = 'sensor_' . $vars['graph']; $row .= generate_graph_row($graph_array, TRUE); $row .= '</td></tr>'; } # endif graphs return $row; }
echo generate_url(array('page' => 'device', 'device' => $device['device_id'], 'tab' => 'health', 'metric' => $sensor_type)); ?> "> <i class="<?php echo $config['sensor_types'][$sensor_type]['icon']; ?> "></i> <?php echo nicecase($sensor_type); ?> </a></div> <div class="content"> <?php echo '<table class="table table-condensed-more table-striped table-bordered">'; foreach ($sensors as $sensor) { humanize_sensor($sensor); // FIXME - make this "four graphs in popup" a function/include and "small graph" a function. // FIXME - So now we need to clean this up and move it into a function. Isn't it just "print-graphrow"? // FIXME - DUPLICATED IN health/sensors $graph_colour = str_replace("#", "", $row_colour); $graph_array = array(); $graph_array['to'] = $config['time']['now']; $graph_array['id'] = $sensor['sensor_id']; $graph_array['type'] = "sensor_" . $sensor_type; $graph_array['from'] = $config['time']['day']; $graph_array['legend'] = "no"; $link_array = $graph_array; $link_array['page'] = "graphs"; unset($link_array['height'], $link_array['width'], $link_array['legend']); $link = generate_url($link_array); $overlib_content = generate_overlib_content($graph_array);
function poll_sensor($device, $class, $unit, &$oid_cache) { global $config, $agent_sensors, $ipmi_sensors; $sql = "SELECT *, `sensors`.`sensor_id` AS `sensor_id`"; $sql .= " FROM `sensors`"; $sql .= " LEFT JOIN `sensors-state` ON `sensors`.sensor_id = `sensors-state`.sensor_id"; $sql .= " WHERE `sensor_class` = ? AND `device_id` = ?"; foreach (dbFetchRows($sql, array($class, $device['device_id'])) as $sensor) { echo "Checking (" . $sensor['poller_type'] . ") {$class} " . $sensor['sensor_descr'] . " "; $sensor_new = $sensor; // Cache non-humanized sensor array humanize_sensor($sensor); if ($sensor['poller_type'] == "snmp") { # if ($class == "temperature" && $device['os'] == "papouch") // Why all temperature? if ($class == "temperature" && !$sensor['sensor_state']) { for ($i = 0; $i < 5; $i++) { // Take value from $oid_cache if we have it, else snmp_get it if (is_numeric($oid_cache[$sensor['sensor_oid']])) { print_debug("value taken from oid_cache"); $sensor_value = $oid_cache[$sensor['sensor_oid']]; } else { $sensor_value = preg_replace("/[^0-9\\-\\.]/", "", snmp_get($device, $sensor['sensor_oid'], "-OUqnv", "SNMPv2-MIB", mib_dirs())); } if (is_numeric($sensor_value) && $sensor_value != 9999) { break; } // TME sometimes sends 999.9 when it is right in the middle of an update; sleep(1); # Give the TME some time to reset } // Also reduce value by 32 if sensor in Fahrenheit unit if ($sensor['sensor_divisor'] == 9 && $sensor['sensor_multiplier'] == 5) { $sensor_value -= 32; } } else { if ($class == "runtime" && !$sensor['sensor_state']) { if (isset($oid_cache[$sensor['sensor_oid']])) { print_debug("value taken from oid_cache"); $sensor_value = timeticks_to_sec($oid_cache[$sensor['sensor_oid']]); } else { $sensor_value = trim(str_replace("\"", "", snmp_get($device, $sensor['sensor_oid'], "-OUqnv", "SNMPv2-MIB", mib_dirs()))); $sensor_value = timeticks_to_sec($sensor_value); } } else { // Take value from $oid_cache if we have it, else snmp_get it if (is_numeric($oid_cache[$sensor['sensor_oid']])) { print_debug("value taken from oid_cache"); $sensor_value = $oid_cache[$sensor['sensor_oid']]; } else { $sensor_value = trim(str_replace("\"", "", snmp_get($device, $sensor['sensor_oid'], "-OUqnv", "SNMPv2-MIB", mib_dirs()))); } } } } else { if ($sensor['poller_type'] == "agent") { if (isset($agent_sensors)) { $sensor_value = $agent_sensors[$class][$sensor['sensor_type']][$sensor['sensor_index']]['current']; # FIXME pass unit? } else { print_warning("No agent sensor data."); continue; } } else { if ($sensor['poller_type'] == "ipmi") { if (isset($ipmi_sensors)) { $sensor_value = $ipmi_sensors[$class][$sensor['sensor_type']][$sensor['sensor_index']]['current']; $unit = $ipmi_sensors[$class][$sensor['sensor_type']][$sensor['sensor_index']]['unit']; } else { print_warning("No IPMI sensor data."); continue; } } else { print_warning("Unknown sensor poller type."); continue; } } } if (!$sensor['sensor_state']) { if ($sensor_value == -32768) { echo "Invalid (-32768) "; $sensor_value = 0; } if ($sensor['sensor_divisor']) { $sensor_value = $sensor_value / $sensor['sensor_divisor']; } if ($sensor['sensor_multiplier']) { $sensor_value = $sensor_value * $sensor['sensor_multiplier']; } } $rrd_file = get_sensor_rrd($device, $sensor); if (!is_file($rrd_file)) { rrdtool_create($rrd_file, "DS:sensor:GAUGE:600:-20000:U"); //DS:sensor:GAUGE:600:-20000:20000 "); } echo "{$sensor_value} {$unit} "; // Write new value and humanize (for alert checks) $sensor_new['sensor_value'] = $sensor_value; humanize_sensor($sensor_new); // FIXME also warn when crossing WARN level!! if ($sensor['state_event'] != 'ignore') { if (!$sensor['sensor_state']) { if ($sensor['sensor_limit_low'] != "" && $sensor['sensor_value'] >= $sensor['sensor_limit_low'] && $sensor_value < $sensor['sensor_limit_low']) { $msg = ucfirst($class) . " Alarm: " . $device['hostname'] . " " . $sensor['sensor_descr'] . " is under threshold: " . $sensor_value . "{$unit} (< " . $sensor['sensor_limit_low'] . "{$unit})"; notify($device, ucfirst($class) . " Alarm: " . $device['hostname'] . " " . $sensor['sensor_descr'], $msg); print_message("[%rAlerting for " . $device['hostname'] . " " . $sensor['sensor_descr'] . "%n\n", 'color'); log_event(ucfirst($class) . ' ' . $sensor['sensor_descr'] . " under threshold: " . $sensor_value . " {$unit} (< " . $sensor['sensor_limit_low'] . " {$unit})", $device, $class, $sensor['sensor_id']); } else { if ($sensor['sensor_limit'] != "" && $sensor['sensor_value'] <= $sensor['sensor_limit'] && $sensor_value > $sensor['sensor_limit']) { $msg = ucfirst($class) . " Alarm: " . $device['hostname'] . " " . $sensor['sensor_descr'] . " is over threshold: " . $sensor_value . "{$unit} (> " . $sensor['sensor_limit'] . "{$unit})"; notify($device, ucfirst($class) . " Alarm: " . $device['hostname'] . " " . $sensor['sensor_descr'], $msg); print_message("[%rAlerting for " . $device['hostname'] . " " . $sensor['sensor_descr'] . "%n\n", 'color'); log_event(ucfirst($class) . ' ' . $sensor['sensor_descr'] . " above threshold: " . $sensor_value . " {$unit} (> " . $sensor['sensor_limit'] . " {$unit})", $device, $class, $sensor['sensor_id']); } } } else { if ($sensor_value != $sensor['sensor_value'] && $sensor['state_value'] != '') { $sensor_state_name = $sensor_new['state_name']; $sensor_state_event = $sensor_new['state_event']; switch ($sensor_state_event) { case 'alert': $msg = ucfirst($class) . " Alarm: " . $device['hostname'] . " " . $sensor['sensor_descr'] . " is under ALERT state: " . $sensor_state_name . " (previous state: " . $sensor['state_name'] . ")"; print_message("[%rSensor ALARM for " . $device['hostname'] . " " . $sensor['sensor_descr'] . "%n\n", 'color'); notify($device, ucfirst($class) . " Alarm: " . $device['hostname'] . " " . $sensor['sensor_descr'], $msg); log_event($msg, $device, $class, $sensor['sensor_id']); break; case 'warning': $msg = ucfirst($class) . " Warning: " . $device['hostname'] . " " . $sensor['sensor_descr'] . " in WARNING state: " . $sensor_state_name . " (previous state: " . $sensor['state_name'] . ")"; print_message("[%rSensor WARNING for " . $device['hostname'] . " " . $sensor['sensor_descr'] . "%n\n", 'color'); log_event($msg, $device, $class, $sensor['sensor_id']); break; case 'up': $msg = ucfirst($class) . " Up: " . $device['hostname'] . " " . $sensor['sensor_descr'] . " in NORMAL state: " . $sensor_state_name . " (previous state: " . $sensor['state_name'] . ")"; print_message("[%rSensor UP for " . $device['hostname'] . " " . $sensor['sensor_descr'] . "%n\n", 'color'); if ($sensor['state_event'] != 'warning') { notify($device, ucfirst($class) . " Up: " . $device['hostname'] . " " . $sensor['sensor_descr'], $msg); } log_event($msg, $device, $class, $sensor['sensor_id']); break; } } } } else { print_message("[%ySensor Ignored%n]", 'color'); } echo "\n"; // Send statistics array via AMQP/JSON if AMQP is enabled globally and for the ports module if ($config['amqp']['enable'] == TRUE && $config['amqp']['modules']['sensors']) { $json_data = array('value' => $sensor_value); messagebus_send(array('attribs' => array('t' => time(), 'device' => $device['hostname'], 'device_id' => $device['device_id'], 'e_type' => 'sensor', 'e_class' => $sensor['sensor_class'], 'e_type' => $sensor['sensor_type'], 'e_index' => $sensor['sensor_index']), 'data' => $json_data)); } // Update StatsD/Carbon if ($config['statsd']['enable'] == TRUE) { StatsD::gauge(str_replace(".", "_", $device['hostname']) . '.' . 'sensor' . '.' . $sensor['sensor_class'] . '.' . $sensor['sensor_type'] . '.' . $sensor['sensor_index'], $sensor_value); } // Update RRD rrdtool_update($rrd_file, "N:{$sensor_value}"); // Check alerts if (!$sensor['sensor_state']) { check_entity('sensor', $sensor, array('sensor_value' => $sensor_new['sensor_value'])); } check_entity('sensor', $sensor, array('sensor_event' => $sensor_new['state_event'])); // Update SQL State if (is_numeric($sensor['sensor_polled'])) { dbUpdate(array('sensor_value' => $sensor_value, 'sensor_polled' => time()), 'sensors-state', '`sensor_id` = ?', array($sensor['sensor_id'])); } else { dbInsert(array('sensor_id' => $sensor['sensor_id'], 'sensor_value' => $sensor_value, 'sensor_polled' => time()), 'sensors-state'); } } }