View source
<?php
define('NAGIOS_STATUS_OK', variable_get('nagios_status_ok_value', 0));
define('NAGIOS_STATUS_WARNING', variable_get('nagios_status_warning_value', 1));
define('NAGIOS_STATUS_CRITICAL', variable_get('nagios_status_critical_value', 2));
define('NAGIOS_STATUS_UNKNOWN', variable_get('nagios_status_unknown_value', 3));
function nagios_status() {
return array(
NAGIOS_STATUS_OK => 'OK',
NAGIOS_STATUS_WARNING => 'WARNING',
NAGIOS_STATUS_CRITICAL => 'CRITICAL',
NAGIOS_STATUS_UNKNOWN => 'UNKNOWN',
);
}
function nagios_init() {
if (arg(0) == 'nagios' && !arg(1)) {
$GLOBALS['conf']['cache'] = FALSE;
}
}
function nagios_functions() {
return array(
'requirements' => t('Checking of hook_requirements. This includes the following: module updates, database schema, files directory writability, update.php protected, Lots of other good stuff ...'),
'watchdog' => t('Check recent watchdog entries'),
'cron' => t('Check whether cron has been running regularly'),
'session_anon' => t('Check the number of anonymous sessions for nagios performance data'),
'session_auth' => t('Check the number of authenticated sessions for nagios performance data'),
'nodes' => t('Check the number of nodes for nagios performance data'),
'users' => t('Check the number of users for nagios performance data'),
'modules' => t('Check the number of modules for nagios performance data'),
'themes' => t('Check the number of themes for nagios performance data'),
);
}
function nagios_menu() {
$items = array();
$items['admin/settings/nagios'] = array(
'type' => MENU_NORMAL_ITEM,
'title' => t('Nagios monitoring'),
'description' => t('Settings for Nagios monitoring'),
'page callback' => 'drupal_get_form',
'page arguments' => array(
'nagios_settings',
),
'access arguments' => array(
'administer site configuration',
),
);
$items['nagios'] = array(
'type' => MENU_SUGGESTED_ITEM,
'title' => t('Nagios status page'),
'page callback' => 'nagios_status_page',
'access callback' => 'variable_get',
'access arguments' => array(
'nagios_enable_status_page',
TRUE,
),
);
return $items;
}
function nagios_settings() {
$group = 'modules';
$form['nagios_ua'] = array(
'#type' => 'textfield',
'#title' => t('Unique ID'),
'#default_value' => variable_get('nagios_ua', ''),
'#description' => t('Restrict sending information to requests identified by this Unique ID. You should change this to some unique string for your organization, and configure Nagios accordingly. This makes Nagios data less accessible to curious users. See the README.txt for more details.'),
);
$form['nagios_show_outdated_names'] = array(
'#type' => 'checkbox',
'#title' => t('Show outdated module/theme name?'),
'#default_value' => variable_get('nagios_show_outdated_names', TRUE),
);
$form['nagios_enable_status_page'] = array(
'#type' => 'checkbox',
'#title' => t('Enable status page?'),
'#default_value' => variable_get('nagios_enable_status_page', TRUE),
);
$form['nagios_error_levels'] = array(
'#type' => 'fieldset',
'#collapsible' => TRUE,
'#collapsed' => FALSE,
'#title' => t('Error levels'),
'#description' => t('Set the values to be used for error levels when reporting to Nagios.'),
);
$form['nagios_error_levels']['nagios_status_ok_value'] = array(
'#type' => 'textfield',
'#title' => t('Status OK'),
'#description' => t('The value to send to Nagios for a Status OK message.'),
'#default_value' => variable_get('nagios_status_ok_value', 0),
);
$form['nagios_error_levels']['nagios_status_warning_value'] = array(
'#type' => 'textfield',
'#title' => t('Warning'),
'#description' => t('The value to send to Nagios for a Warning message.'),
'#default_value' => variable_get('nagios_status_warning_value', 1),
);
$form['nagios_error_levels']['nagios_status_critical_value'] = array(
'#type' => 'textfield',
'#title' => t('Critical'),
'#description' => t('The value to send to Nagios for a Critical message.'),
'#default_value' => variable_get('nagios_status_critical_value', 2),
);
$form['nagios_error_levels']['nagios_status_unknown_value'] = array(
'#type' => 'textfield',
'#title' => t('Unknown'),
'#description' => t('The value to send to Nagios for an Unknown message.'),
'#default_value' => variable_get('nagios_status_unknown_value', 3),
);
$form[$group] = array(
'#type' => 'fieldset',
'#collapsible' => TRUE,
'#collapsed' => FALSE,
'#title' => t('Modules'),
'#description' => t('Select the modules that should report their data into Nagios.'),
);
foreach (nagios_invoke_all('nagios_info') as $module => $data) {
$form[$group]['nagios_enable_' . $module] = array(
'#type' => 'checkbox',
'#title' => $data['name'] . ' (' . $module . ')',
'#default_value' => variable_get('nagios_enable_' . $module, TRUE),
);
}
foreach (nagios_invoke_all('nagios_settings') as $module => $module_settings) {
$form[$module] = array(
'#type' => 'fieldset',
'#collapsible' => TRUE,
'#collapsed' => TRUE,
'#title' => $module,
);
foreach ($module_settings as $element => $data) {
$form[$module][$element] = $data;
}
}
return system_settings_form($form);
}
function nagios_status_page() {
$args = func_get_args();
$module = array_shift($args);
$id = array_shift($args);
drupal_set_header('Cache-Control: no-cache');
drupal_set_header('Pragma: no-cache');
drupal_set_header('Expires: -1');
$codes = nagios_status();
$ua = variable_get('nagios_ua', '');
if (user_access('administer site configuration') || $_SERVER['HTTP_USER_AGENT'] == $ua) {
if ($module) {
$nagios_data = array();
$nagios_data[$module] = module_invoke($module, 'nagios', $id);
}
else {
$nagios_data = nagios_invoke_all('nagios');
}
}
else {
$nagios_data = array(
'nagios' => array(
'DRUPAL' => array(
'status' => NAGIOS_STATUS_UNKNOWN,
'type' => 'state',
'text' => t('Unauthorized'),
),
),
);
}
$severity = NAGIOS_STATUS_OK;
$min_severity = variable_get('nagios_min_report_severity', NAGIOS_STATUS_WARNING);
foreach ($nagios_data as $module_name => $module_data) {
foreach ($module_data as $key => $value) {
if ($value['status'] >= $min_severity) {
$severity = max($severity, $value['status']);
}
}
}
$output = "\n" . 'nagios=' . $codes[$severity] . ', ';
$output_state = array();
$output_perf = array();
foreach ($nagios_data as $module_name => $module_data) {
foreach ($module_data as $key => $value) {
switch ($value['type']) {
case 'state':
if ($value['status'] >= $min_severity) {
$tmp_state = $key . ':' . $codes[$value['status']];
}
else {
$tmp_state = $key . ':' . $codes[NAGIOS_STATUS_OK];
}
if (!empty($value['text'])) {
$tmp_state .= '=' . $value['text'];
}
if (variable_get('nagios_show_outdated_names', TRUE) && $key == 'ADMIN' && $value['text'] == 'Module and theme update status') {
module_load_include('inc', 'update', 'update.compare');
$tmp_projects = update_calculate_project_data(update_get_projects());
$nagios_ignored_modules = variable_get('nagios_ignored_modules', array());
$nagios_ignored_themes = variable_get('nagios_ignored_themes', array());
$nagios_ignored_projects = $nagios_ignored_modules + $nagios_ignored_themes;
$outdated_count = 0;
$tmp_modules = '';
foreach ($tmp_projects as $projkey => $projval) {
if (!isset($nagios_ignored_projects[$projkey])) {
if ($projval['status'] < UPDATE_CURRENT && $projval['status'] >= UPDATE_NOT_SECURE) {
switch ($projval['status']) {
case UPDATE_NOT_SECURE:
$tmp_projstatus = t('NOT SECURE');
break;
case UPDATE_REVOKED:
$tmp_projstatus = t('REVOKED');
break;
case UPDATE_NOT_SUPPORTED:
$tmp_projstatus = t('NOT SUPPORTED');
break;
case UPDATE_NOT_CURRENT:
$tmp_projstatus = t('NOT CURRENT');
break;
default:
$tmp_projstatus = $projval['status'];
}
$tmp_modules .= ' ' . $projkey . ':' . $tmp_projstatus;
$outdated_count++;
}
}
}
if ($outdated_count > 0) {
$tmp_modules = trim($tmp_modules);
$tmp_state .= " ({$tmp_modules})";
}
}
$output_state[] = $tmp_state;
break;
case 'perf':
$output_perf[] = $key . '=' . $value['text'];
break;
}
}
}
$output .= implode(', ', $output_state) . ' | ' . implode(';', $output_perf) . "\n";
echo $output;
exit;
}
function nagios_invoke_all($hook = 'nagios') {
$return = array();
$args = func_get_args();
foreach (module_implements($hook) as $module) {
$function = $module . '_' . $hook;
$result = call_user_func_array($function, $args);
$return[$module] = $result;
}
return $return;
}
function nagios_nagios_info() {
return array(
'name' => 'Nagios monitoring',
'id' => 'NAGIOS',
);
}
function nagios_nagios_settings() {
foreach (nagios_functions() as $function => $description) {
$var = 'nagios_func_' . $function;
$form[$var] = array(
'#type' => 'checkbox',
'#title' => $function,
'#default_value' => variable_get($var, TRUE),
'#description' => $description,
);
}
$group = 'thresholds';
$form[$group] = array(
'#type' => 'fieldset',
'#collapsible' => TRUE,
'#collapsed' => FALSE,
'#title' => t('Thresholds'),
'#description' => t('Thresholds for reporting critical alerts to Nagios.'),
);
$form[$group]['nagios_cron_duration'] = array(
'#type' => 'textfield',
'#title' => t('Cron duration'),
'#default_value' => variable_get('nagios_cron_duration', 60),
'#description' => t('Issue a critical alert when cron has not been running for this duration (in minutes). Default is 60 minutes.'),
);
$form[$group]['nagios_min_report_severity'] = array(
'#type' => 'select',
'#title' => t('Mininum report severity'),
'#default_value' => variable_get('nagios_min_report_severity', NAGIOS_STATUS_WARNING),
'#options' => nagios_status(),
'#description' => t('Issue an alert only for this minimum severity, not for lower severities.'),
);
return $form;
}
function nagios_nagios() {
$status = array();
foreach (nagios_functions() as $function => $description) {
if (variable_get('nagios_func_' . $function, TRUE)) {
$func = 'nagios_check_' . $function;
$result = $func();
$status[$result['key']] = $result['data'];
}
}
return $status;
}
function nagios_check_requirements() {
include_once './includes/install.inc';
module_load_include('inc', 'update', 'update.compare');
drupal_load_updates();
$project_data = update_get_projects();
$nagios_ignored_modules = variable_get('nagios_ignored_modules', array());
$nagios_ignored_themes = variable_get('nagios_ignored_themes', array());
$nagios_ignored_projects = $nagios_ignored_modules + $nagios_ignored_themes;
$enabled_modules = array();
foreach ($project_data as $project) {
foreach ($project['includes'] as $key => $val) {
if (!isset($nagios_ignored_projects[$key])) {
$enabled_modules[] = $key;
}
}
}
$data = array();
if ($available = update_get_available(TRUE)) {
module_load_include('inc', 'update', 'update.compare');
$data = update_calculate_project_data($available);
}
foreach ($nagios_ignored_projects as $key => $value) {
unset($data[$key]);
}
$reqs = array();
$core_modules = array_keys($project_data['drupal']['includes']);
foreach ($enabled_modules as $module_name) {
$requirements_data = module_invoke($module_name, 'requirements', 'runtime');
if (count($requirements_data)) {
if ($module_name == 'update' && !empty($data)) {
unset($requirements_data['update_contrib']);
foreach ($enabled_modules as $module_name) {
if (!in_array($module_name, array_keys($project_data['drupal']['includes']))) {
if (isset($data[$module_name]['status']) && is_numeric($data[$module_name]['status'])) {
$contrib_req = _update_requirement_check($data[$module_name], 'contrib');
$contrib_req['name'] = $module_name;
if (!isset($contrib_req['severity'])) {
$contrib_req['severity'] = -1;
}
if ($contrib_req) {
$module_data[] = $contrib_req;
}
}
}
}
usort($module_data, '_nagios_updates_sort_by_severity');
$requirements_data['update_contrib'] = array_pop($module_data);
}
$reqs += $requirements_data;
}
}
$descriptions = array();
$severity = REQUIREMENT_OK;
$min_severity = variable_get('nagios_min_report_severity', NAGIOS_STATUS_WARNING);
foreach ($reqs as $key => $requirement) {
if (isset($requirement['severity'])) {
if (($key == 'update_core' || $key == 'update_contrib') && $requirement['severity'] == REQUIREMENT_ERROR && $requirement['reason'] == UPDATE_FETCH_PENDING) {
continue;
}
if ($requirement['severity'] >= $min_severity) {
if ($requirement['severity'] > $severity) {
$severity = $requirement['severity'];
}
$descriptions[] = $requirement['title'];
}
}
}
if (empty($descriptions)) {
$desc = t('No information.');
}
else {
$desc = join(', ', $descriptions);
}
switch ($severity) {
case REQUIREMENT_OK:
case REQUIREMENT_INFO:
$data = array(
'status' => NAGIOS_STATUS_OK,
'type' => 'state',
'text' => t('No known issues at this time.'),
);
break;
case REQUIREMENT_WARNING:
$data = array(
'status' => NAGIOS_STATUS_WARNING,
'type' => 'state',
'text' => t('@desc', array(
'@desc' => $desc,
)),
);
break;
case REQUIREMENT_ERROR:
$data = array(
'status' => NAGIOS_STATUS_CRITICAL,
'type' => 'state',
'text' => t('@desc', array(
'@desc' => $desc,
)),
);
break;
default:
$data = array(
'status' => NAGIOS_STATUS_UNKNOWN,
'type' => 'state',
'text' => t('severity is @severity', array(
'@severity' => $severity,
)),
);
break;
}
return array(
'key' => 'ADMIN',
'data' => $data,
);
}
function nagios_check_watchdog() {
$limit = variable_get('limit_watchdog_results', 50);
$limit_watchdog_timestamp = 0;
$limit_watchdog = variable_get('limit_watchdog_display', FALSE);
if (!empty($limit_watchdog)) {
$limit_watchdog_timestamp = variable_get('limit_watchdog_timestamp', FALSE);
}
$result = db_query('SELECT * FROM {watchdog} WHERE timestamp > %d ORDER BY timestamp DESC LIMIT %d', $limit_watchdog_timestamp, $limit);
if (!$result) {
return array(
'status' => NAGIOS_STATUS_UNKNOWN,
'type' => 'state',
'text' => t('Unable to SELECT FROM {watchdog}'),
);
}
$severity_translation = array(
WATCHDOG_DEBUG => NAGIOS_STATUS_OK,
WATCHDOG_INFO => NAGIOS_STATUS_OK,
WATCHDOG_NOTICE => NAGIOS_STATUS_OK,
WATCHDOG_WARNING => NAGIOS_STATUS_WARNING,
WATCHDOG_ERROR => NAGIOS_STATUS_CRITICAL,
WATCHDOG_CRITICAL => NAGIOS_STATUS_CRITICAL,
WATCHDOG_ALERT => NAGIOS_STATUS_CRITICAL,
WATCHDOG_EMERG => NAGIOS_STATUS_CRITICAL,
);
$severity = NAGIOS_STATUS_OK;
$min_severity = variable_get('nagios_min_report_severity', NAGIOS_STATUS_WARNING);
$messages = array();
$descriptions = array();
$count = 0;
while ($row = db_fetch_array($result)) {
if ($count == 0) {
$limit_watchdog_timestamp = variable_set('limit_watchdog_timestamp', $row['timestamp']);
$count++;
}
$nagios_severity = $severity_translation[$row['severity']];
if ($nagios_severity < $min_severity) {
continue;
}
if ($nagios_severity > $severity) {
$severity = $nagios_severity;
}
$message = "{$row['type']} {$row['message']}";
$variables = unserialize($row['variables']);
if (is_array($variables)) {
foreach ($variables as $key => $value) {
$message = str_replace("{$key}", $value, $message);
}
}
if (!in_array($message, $messages)) {
$messages[] = $message;
}
else {
continue;
}
$message = date('Y-m-d H:i:s', $row['timestamp']) . " " . $message;
$descriptions[] = $message;
}
$desc = join(', ', $descriptions);
return array(
'key' => 'WATCHDOG',
'data' => array(
'status' => $severity,
'type' => 'state',
'text' => t('@desc', array(
'@desc' => $desc,
)),
),
);
}
function nagios_check_cron() {
$cron_last = variable_get('cron_last', 0);
$mins = variable_get('nagios_cron_duration', 60);
if (time() > $cron_last + $mins * 60) {
$data = array(
'status' => NAGIOS_STATUS_CRITICAL,
'type' => 'state',
'text' => t('cron not running @mins mins', array(
'@mins' => $mins,
)),
);
}
else {
$data = array(
'status' => NAGIOS_STATUS_OK,
'type' => 'state',
'text' => '',
);
}
return array(
'key' => 'CRON',
'data' => $data,
);
}
function nagios_check_session_anon() {
$interval = time() - 900;
$count = (int) sess_count($interval, TRUE);
$data = array(
'status' => NAGIOS_STATUS_OK,
'type' => 'perf',
'text' => $count,
);
return array(
'key' => 'SAN',
'data' => $data,
);
}
function nagios_check_session_auth() {
$interval = time() - 900;
$count = (int) sess_count($interval, FALSE);
$data = array(
'status' => NAGIOS_STATUS_OK,
'type' => 'perf',
'text' => $count,
);
return array(
'key' => 'SAU',
'data' => $data,
);
}
function nagios_check_nodes() {
$count = (int) db_result(db_query("SELECT COUNT(*) FROM {node} WHERE status = 1"));
$data = array(
'status' => NAGIOS_STATUS_OK,
'type' => 'perf',
'text' => $count,
);
return array(
'key' => 'NOD',
'data' => $data,
);
}
function nagios_check_users() {
$count = (int) db_result(db_query("SELECT COUNT(*) FROM {users} WHERE status = 1"));
$data = array(
'status' => NAGIOS_STATUS_OK,
'type' => 'perf',
'text' => $count,
);
return array(
'key' => 'USR',
'data' => $data,
);
}
function nagios_check_modules() {
$count = (int) db_result(db_query("SELECT COUNT(*) FROM {system} WHERE status = 1 AND type = 'module'"));
$data = array(
'status' => NAGIOS_STATUS_OK,
'type' => 'perf',
'text' => $count,
);
return array(
'key' => 'MOD',
'data' => $data,
);
}
function nagios_nagios_checks() {
return nagios_functions();
}
function nagios_nagios_check($function) {
$func = 'nagios_check_' . $function;
$result = $func();
$status[$result['key']] = $result['data'];
return $status;
}
function nagios_check_themes() {
$count = (int) db_result(db_query("SELECT COUNT(*) FROM {system} WHERE status = 1 AND type = 'theme'"));
$data = array(
'status' => NAGIOS_STATUS_OK,
'type' => 'perf',
'text' => $count,
);
return array(
'key' => 'THM',
'data' => $data,
);
}
function _nagios_updates_sort_by_severity($a, $b) {
if (isset($a['severity']) && isset($b['severity'])) {
if ($a['severity'] == $b['severity']) {
return 0;
}
return $a['severity'] < $b['severity'] ? -1 : 1;
}
return 0;
}