function nagios_check_watchdog in Nagios Monitoring 8
Same name and namespace in other branches
- 6 nagios.module \nagios_check_watchdog()
- 7 nagios.module \nagios_check_watchdog()
Check Drupal {watchdog} table recent entries.
Corrensponds to opening the admin/reports/dblog page in the browser.
Return value
array
File
- ./
nagios.module, line 431 - Main file for Nagios service monitoring.
Code
function nagios_check_watchdog() {
// @TODO Allow multi-value 'type' and/or 'severity' inputs for filtering
// @TODO Allow datetime ranges
// Constuct base select query.
$conn = Database::getConnection();
$query = $conn
->select('watchdog', 'w');
$query
->fields('w', [
'wid',
'uid',
'type',
'severity',
'message',
'variables',
'link',
'location',
'hostname',
'timestamp',
]);
$query
->orderBy('timestamp', 'DESC');
$query
->orderBy('severity');
$state = Drupal::state();
$config = Drupal::config('nagios.settings');
$query
->range(0, 10);
// Check if we are limiting to only new logs since last check.
$limit_watchdog = $config
->get('nagios.limit_watchdog.display');
if (!empty($limit_watchdog)) {
// Get timestamp of the last watchdog entry retrieved.
$limit_watchdog_timestamp = $state
->get('nagios.limit_watchdog_timestamp') ?: FALSE;
if ($limit_watchdog_timestamp !== FALSE) {
// Ensure we only get entries that are greater than the timestamp.
$query
->condition('timestamp', $limit_watchdog_timestamp, '>');
}
}
$min_severity = $config
->get('nagios.min_report_severity') ?: NAGIOS_STATUS_WARNING;
// RFC3164/Watchdog has 8 levels. Nagios module has 3 (plus UNKNOWN).
// This maps Watchdog => Nagios.
$severity_translation = [
RfcLogLevel::EMERGENCY => NAGIOS_STATUS_CRITICAL,
RfcLogLevel::ALERT => NAGIOS_STATUS_CRITICAL,
RfcLogLevel::CRITICAL => NAGIOS_STATUS_CRITICAL,
RfcLogLevel::ERROR => NAGIOS_STATUS_CRITICAL,
RfcLogLevel::WARNING => NAGIOS_STATUS_WARNING,
RfcLogLevel::NOTICE => NAGIOS_STATUS_OK,
RfcLogLevel::INFO => NAGIOS_STATUS_OK,
RfcLogLevel::DEBUG => NAGIOS_STATUS_OK,
];
$query
->condition('severity', array_flip($severity_translation)[$min_severity], '<=');
$channel_filter = $config
->get('nagios.limit_watchdog.channel_filter');
if ($channel_filter) {
$negate = $config
->get('nagios.limit_watchdog.negate');
$query
->condition('type', $channel_filter, $negate ? 'IN' : 'NOT IN');
}
// Execute query.
try {
$result = $query
->execute();
} catch (Exception $e) {
$result = FALSE;
}
if (!$result) {
return [
'key' => 'WATCHDOG',
'data' => [
'status' => NAGIOS_STATUS_UNKNOWN,
'type' => 'state',
'text' => t('Unable to SELECT FROM {watchdog}'),
],
];
}
// Maximize this across the result set:
$severity = NAGIOS_STATUS_OK;
$messages = [];
$descriptions = [];
$count = 0;
while ($row = $result
->fetchAssoc()) {
// Set timestamp of the first watchdog error for use when restricting logs to only new entries.
if ($count == 0) {
$state
->set('nagios.limit_watchdog_timestamp', $row['timestamp']);
$count++;
}
// Get severity of log entry.
$nagios_severity = $severity_translation[$row['severity']];
// If the severity is greater then our current severity level, set it it to new level.
if ($nagios_severity > $severity) {
$severity = $nagios_severity;
}
// Create error message.
$message = "{$row['type']} {$row['message']}";
// @TODO Untangle l(truncate_utf8(_dblog_format_message($dblog), 56, TRUE, TRUE), 'admin/reports/event/'. $dblog->wid, array('html' => TRUE)) and use it here
try {
/** @noinspection SuspiciousBinaryOperationInspection */
if (PHP_VERSION_ID >= 70000) {
/* graceful approach which supports older versions of PHP */
$variables = unserialize($row['variables'], [
'allowed_classes' => [
TranslatableMarkup::class,
],
]);
}
else {
/** @noinspection UnserializeExploitsInspection */
$variables = unserialize($row['variables']);
}
} catch (Throwable $exception) {
// ignore "Object of class __PHP_Incomplete_Class could not be converted to string"
$variables = FALSE;
}
if (is_array($variables)) {
foreach ($variables as $key => $value) {
if ($value instanceof __PHP_Incomplete_Class) {
continue;
}
$message = str_replace((string) $key, $value, $message);
}
}
// Add message to messages array only if there isn't already an identical entry.
if (!in_array($message, $messages, TRUE)) {
$messages[] = $message;
}
else {
// We only want to show each message once so continue.
continue;
}
// Prepend the timestamp onto the front of the message.
$message = date('Y-m-d H:i:s', $row['timestamp']) . " " . $message;
// Add message to descriptions array.
$descriptions[] = $message;
}
// Join all descriptions together into a string.
$desc = implode(', ', $descriptions);
return [
'key' => 'WATCHDOG',
'data' => [
'status' => $severity,
'type' => 'state',
'text' => t('@desc', [
'@desc' => $desc,
]),
],
];
}