diff --git a/modules/monitoring/application/controllers/EventController.php b/modules/monitoring/application/controllers/EventController.php new file mode 100644 index 000000000..4663be0c5 --- /dev/null +++ b/modules/monitoring/application/controllers/EventController.php @@ -0,0 +1,542 @@ + 'notificationevent', + 'comment' => 'commentevent', + 'comment_deleted' => 'commentevent', + 'ack' => 'commentevent', + 'ack_deleted' => 'commentevent', + 'dt_comment' => 'commentevent', + 'dt_comment_deleted' => 'commentevent', + 'flapping' => 'flappingevent', + 'flapping_deleted' => 'flappingevent', + 'hard_state' => 'statechangeevent', + 'soft_state' => 'statechangeevent', + 'dt_start' => 'downtimeevent', + 'dt_end' => 'downtimeevent' + ); + + /** + * Cache for {@link time()} + * + * @var DateTimeZone + */ + protected $timeZone; + + public function showAction() + { + $type = $this->params->shiftRequired('type'); + $id = $this->params->shiftRequired('id'); + + if (! isset($this->dataViewsByType[$type]) + || $this->applyRestriction( + 'monitoring/filter/objects', + $this->backend->select()->from('eventhistory', array('id'))->where('id', $id) + )->fetchRow() === false + ) { + $this->httpNotFound($this->translate('Event not found')); + } + + $event = $this->query($type, $id)->fetchRow(); + + if ($event === false) { + $this->httpNotFound($this->translate('Event not found')); + } + + $this->view->object = $object = $event->service_description === null + ? new Host($this->backend, $event->host_name) + : new Service($this->backend, $event->host_name, $event->service_description); + $object->fetch(); + + list($icon, $label) = $this->getIconAndLabel($type); + + $this->view->details = array_merge( + array(array($this->view->escape($this->translate('Type')), $label)), + $this->getDetails($type, $event) + ); + + $this->getTabs() + ->add('event', array( + 'title' => $label, + 'label' => $label, + 'icon' => $icon, + 'url' => Url::fromRequest(), + 'active' => true + )) + ->extend(new OutputFormat()) + ->extend(new DashboardAction()) + ->extend(new MenuAction()); + } + + /** + * Return translated and escaped 'Yes' if the given condition is true, 'No' otherwise, 'N/A' if NULL + * + * @param bool|null $condition + * + * @return string + */ + protected function yesOrNo($condition) + { + if ($condition === null) { + return $this->view->escape($this->translate('N/A')); + } + + return $this->view->escape($condition ? $this->translate('Yes') : $this->translate('No')); + } + + /** + * Render the given timestamp as human readable HTML in the user agent's timezone or 'N/A' if NULL + * + * @param int|null $stamp + * + * @return string + */ + protected function time($stamp) + { + if ($stamp === null) { + return $this->view->escape($this->translate('N/A')); + } + + if ($this->timeZone === null) { + $timezoneDetect = new TimezoneDetect(); + $this->timeZone = new DateTimeZone( + $timezoneDetect->success() ? $timezoneDetect->getTimezoneName() : date_default_timezone_get() + ); + } + + return $this->view->escape( + DateTime::createFromFormat('U', $stamp)->setTimezone($this->timeZone)->format('Y-m-d H:i:s') + ); + } + + /** + * Render the given duration in seconds as human readable HTML or 'N/A' if NULL + * + * @param int|null $seconds + * + * @return string + */ + protected function duration($seconds) + { + return $this->view->escape( + $seconds === null ? $this->translate('N/A') : DateFormatter::formatDuration($seconds) + ); + } + + /** + * Render the given percent number as human readable HTML or 'N/A' if NULL + * + * @param float|null $percent + * + * @return string + */ + protected function percent($percent) + { + return $this->view->escape( + $percent === null ? $this->translate('N/A') : sprintf($this->translate('%.2f%%'), $percent) + ); + } + + /** + * Render the given comment message as HTML or 'N/A' if NULL + * + * @param string|null $message + * + * @return string + */ + protected function comment($message) + { + return $this->view->nl2br($this->view->createTicketLinks($this->view->escapeComment($message))); + } + + /** + * Render a link to the given contact or 'N/A' if NULL + * + * @param string|null $name + * + * @return string + */ + protected function contact($name) + { + return $name === null + ? $this->view->escape($this->translate('N/A')) + : $this->view->qlink($name, Url::fromPath('monitoring/show/contact', array('contact_name' => $name))); + } + + /** + * Render the given monitored object state as human readable HTML or 'N/A' if NULL + * + * @param bool $isService + * @param int|null $state + * + * @return string + */ + protected function state($isService, $state) + { + if ($state === null) { + return $this->view->escape($this->translate('N/A')); + } + + try { + $stateText = $isService + ? Service::getStateText($state, true) + : Host::getStateText($state, true); + } catch (InvalidArgumentException $e) { + return $this->view->escape($this->translate('N/A')); + } + + return ' ' . $this->view->escape($stateText) . ''; + } + + /** + * Render the given plugin output as human readable HTML + * + * @param string $output + * + * @return string + */ + protected function pluginOutput($output) + { + return $this->view->getHelper('PluginOutput')->pluginOutput($output); + } + + /** + * Return the icon and the label for the given event type + * + * @param string $eventType + * + * @return string[] + */ + protected function getIconAndLabel($eventType) + { + switch ($eventType) { + case 'notify': + return array('bell', $this->translate('Notification', 'tooltip')); + case 'comment': + return array('comment-empty', $this->translate('Comment', 'tooltip')); + case 'comment_deleted': + return array('cancel', $this->translate('Comment removed', 'tooltip')); + case 'ack': + return array('ok', $this->translate('Acknowledged', 'tooltip')); + case 'ack_deleted': + return array('ok', $this->translate('Acknowledgement removed', 'tooltip')); + case 'dt_comment': + return array('plug', $this->translate('Downtime scheduled', 'tooltip')); + case 'dt_comment_deleted': + return array('plug', $this->translate('Downtime removed', 'tooltip')); + case 'flapping': + return array('flapping', $this->translate('Flapping started', 'tooltip')); + case 'flapping_deleted': + return array('flapping', $this->translate('Flapping stopped', 'tooltip')); + case 'hard_state': + return array('warning-empty', $this->translate('Hard state change')); + case 'soft_state': + return array('spinner', $this->translate('Soft state change')); + case 'dt_start': + return array('plug', $this->translate('Downtime started', 'tooltip')); + case 'dt_end': + return array('plug', $this->translate('Downtime ended', 'tooltip')); + } + } + + /** + * Return a query for the given event ID of the given type + * + * @param string $type + * @param int $id + * + * @return Queryable + */ + protected function query($type, $id) + { + switch ($this->dataViewsByType[$type]) { + case 'downtimeevent': + return $this->backend->select() + ->from('downtimeevent', array( + 'entry_time' => 'downtimeevent_entry_time', + 'author_name' => 'downtimeevent_author_name', + 'comment_data' => 'downtimeevent_comment_data', + 'is_fixed' => 'downtimeevent_is_fixed', + 'scheduled_start_time' => 'downtimeevent_scheduled_start_time', + 'scheduled_end_time' => 'downtimeevent_scheduled_end_time', + 'was_started' => 'downtimeevent_was_started', + 'actual_start_time' => 'downtimeevent_actual_start_time', + 'actual_end_time' => 'downtimeevent_actual_end_time', + 'was_cancelled' => 'downtimeevent_was_cancelled', + 'is_in_effect' => 'downtimeevent_is_in_effect', + 'trigger_time' => 'downtimeevent_trigger_time', + 'host_name', + 'service_description' + )) + ->where('downtimeevent_id', $id); + case 'commentevent': + return $this->backend->select() + ->from('commentevent', array( + 'entry_type' => 'commentevent_entry_type', + 'comment_time' => 'commentevent_comment_time', + 'author_name' => 'commentevent_author_name', + 'comment_data' => 'commentevent_comment_data', + 'is_persistent' => 'commentevent_is_persistent', + 'comment_source' => 'commentevent_comment_source', + 'expires' => 'commentevent_expires', + 'expiration_time' => 'commentevent_expiration_time', + 'deletion_time' => 'commentevent_deletion_time', + 'host_name', + 'service_description' + )) + ->where('commentevent_id', $id); + case 'flappingevent': + return $this->backend->select() + ->from('flappingevent', array( + 'event_time' => 'flappingevent_event_time', + 'reason_type' => 'flappingevent_reason_type', + 'percent_state_change' => 'flappingevent_percent_state_change', + 'low_threshold' => 'flappingevent_low_threshold', + 'high_threshold' => 'flappingevent_high_threshold', + 'host_name', + 'service_description' + )) + ->where('flappingevent_id', $id) + ->where('flappingevent_event_type', $type); + case 'notificationevent': + return $this->backend->select() + ->from('notificationevent', array( + 'notification_reason' => 'notificationevent_reason', + 'start_time' => 'notificationevent_start_time', + 'end_time' => 'notificationevent_end_time', + 'state' => 'notificationevent_state', + 'output' => 'notificationevent_output', + 'long_output' => 'notificationevent_long_output', + 'escalated' => 'notificationevent_escalated', + 'contacts_notified' => 'notificationevent_contacts_notified', + 'host_name', + 'service_description' + )) + ->where('notificationevent_id', $id); + case 'statechangeevent': + return $this->backend->select() + ->from('statechangeevent', array( + 'state_time' => 'statechangeevent_state_time', + 'state' => 'statechangeevent_state', + 'current_check_attempt' => 'statechangeevent_current_check_attempt', + 'max_check_attempts' => 'statechangeevent_max_check_attempts', + 'last_state' => 'statechangeevent_last_state', + 'last_hard_state' => 'statechangeevent_last_hard_state', + 'output' => 'statechangeevent_output', + 'long_output' => 'statechangeevent_long_output', + 'host_name', + 'service_description' + )) + ->where('statechangeevent_id', $id) + ->where('statechangeevent_state_change', 1) + ->where('statechangeevent_state_type', $type); + } + } + + /** + * Return the given event's data prepared for a name-value table + * + * @param string $type + * @param \stdClass $event + * + * @return string[][] + */ + protected function getDetails($type, $event) + { + switch ($type) { + case 'dt_start': + case 'dt_end': + $details = array(array( + array($this->translate('Entry time'), $this->time($event->entry_time)), + array($this->translate('Is fixed'), $this->yesOrNo($event->is_fixed)), + array($this->translate('Is in effect'), $this->yesOrNo($event->is_in_effect)), + array($this->translate('Was started'), $this->yesOrNo($event->was_started)) + )); + + if ($type === 'dt_end') { + $details[] = array( + array($this->translate('Was cancelled'), $this->yesOrNo($event->was_cancelled)) + ); + } + + $details[] = array( + array($this->translate('Trigger time'), $this->time($event->trigger_time)), + array($this->translate('Scheduled start time'), $this->time($event->scheduled_start_time)), + array($this->translate('Actual start time'), $this->time($event->actual_start_time)), + array($this->translate('Scheduled end time'), $this->time($event->scheduled_end_time)) + ); + + if ($type === 'dt_end') { + $details[] = array( + array($this->translate('Actual end time'), $this->time($event->actual_end_time))) + ; + } + + $details[] = array( + array($this->translate('Author'), $this->contact($event->author_name)), + array($this->translate('Comment'), $this->comment($event->comment_data)) + ); + + return call_user_func_array('array_merge', $details); + case 'comment': + case 'comment_deleted': + case 'ack': + case 'ack_deleted': + case 'dt_comment': + case 'dt_comment_deleted': + switch ($event->entry_type) { + case 'comment': + $entryType = $this->translate('User comment'); + break; + case 'downtime': + $entryType = $this->translate('Scheduled downtime'); + break; + case 'flapping': + $entryType = $this->translate('Flapping'); + break; + case 'ack': + $entryType = $this->translate('Acknowledgement'); + break; + default: + $entryType = $this->translate('N/A'); + } + + switch ($event->comment_source) { + case 'icinga': + $commentSource = $this->translate('Icinga'); + break; + case 'user': + $commentSource = $this->translate('User'); + break; + default: + $commentSource = $this->translate('N/A'); + } + + return array( + array($this->translate('Time'), $this->time($event->comment_time)), + array($this->translate('Source'), $this->view->escape($commentSource)), + array($this->translate('Entry type'), $this->view->escape($entryType)), + array($this->translate('Author'), $this->contact($event->author_name)), + array($this->translate('Is persistent'), $this->yesOrNo($event->is_persistent)), + array($this->translate('Expires'), $this->yesOrNo($event->expires)), + array($this->translate('Expiration time'), $this->time($event->expiration_time)), + array($this->translate('Deletion time'), $this->time($event->deletion_time)), + array($this->translate('Message'), $this->comment($event->comment_data)) + ); + case 'flapping': + case 'flapping_deleted': + switch ($event->reason_type) { + case 'stopped': + $reasonType = $this->translate('Flapping stopped normally'); + break; + case 'disabled': + $reasonType = $this->translate('Flapping was disabled'); + break; + default: + $reasonType = $this->translate('N/A'); + } + + return array( + array($this->translate('Event time'), $this->time($event->event_time)), + array($this->translate('Reason'), $this->view->escape($reasonType)), + array($this->translate('State change'), $this->percent($event->percent_state_change)), + array($this->translate('Low threshold'), $this->percent($event->low_threshold)), + array($this->translate('High threshold'), $this->percent($event->high_threshold)) + ); + case 'notify': + switch ($event->notification_reason) { + case 'normal_notification': + $notificationReason = $this->translate('Normal notification'); + break; + case 'ack': + $notificationReason = $this->translate('Problem acknowledgement'); + break; + case 'flapping_started': + $notificationReason = $this->translate('Flapping started'); + break; + case 'flapping_stopped': + $notificationReason = $this->translate('Flapping stopped'); + break; + case 'flapping_disabled': + $notificationReason = $this->translate('Flapping was disabled'); + break; + case 'dt_start': + $notificationReason = $this->translate('Downtime started'); + break; + case 'dt_end': + $notificationReason = $this->translate('Downtime ended'); + break; + case 'dt_cancel': + $notificationReason = $this->translate('Downtime was cancelled'); + break; + case 'custom_notification': + $notificationReason = $this->translate('Custom notification'); + break; + default: + $notificationReason = $this->translate('N/A'); + } + + $details = array( + array($this->translate('Start time'), $this->time($event->start_time)), + array($this->translate('End time'), $this->time($event->end_time)), + array($this->translate('Reason'), $this->view->escape($notificationReason)), + array( + $this->translate('State'), + $this->state($event->service_description !== null, $event->state) + ), + array($this->translate('Escalated'), $this->yesOrNo($event->escalated)), + array($this->translate('Contacts notified'), (int) $event->contacts_notified), + array( + $this->translate('Output'), + $this->pluginOutput($event->output) . $this->pluginOutput($event->long_output) + ) + ); + + return $details; + case 'hard_state': + case 'soft_state': + $isService = $event->service_description !== null; + + $details = array( + array($this->translate('State time'), $this->time($event->state_time)), + array($this->translate('State'), $this->state($isService, $event->state)), + array($this->translate('Check attempt'), $this->view->escape(sprintf( + $this->translate('%d of %d'), + (int) $event->current_check_attempt, + (int) $event->max_check_attempts + ))), + array($this->translate('Last state'), $this->state($isService, $event->last_state)), + array($this->translate('Last hard state'), $this->state($isService, $event->last_hard_state)), + array( + $this->translate('Output'), + $this->pluginOutput($event->output) . $this->pluginOutput($event->long_output) + ) + ); + + return $details; + } + } +} diff --git a/modules/monitoring/application/controllers/ListController.php b/modules/monitoring/application/controllers/ListController.php index 9d64522e6..ef8c0afb4 100644 --- a/modules/monitoring/application/controllers/ListController.php +++ b/modules/monitoring/application/controllers/ListController.php @@ -547,6 +547,7 @@ class ListController extends Controller ); $query = $this->backend->select()->from('eventhistory', array( + 'id', 'host_name', 'host_display_name', 'service_description', diff --git a/modules/monitoring/application/views/scripts/event/show.phtml b/modules/monitoring/application/views/scripts/event/show.phtml new file mode 100644 index 000000000..63f1cb965 --- /dev/null +++ b/modules/monitoring/application/views/scripts/event/show.phtml @@ -0,0 +1,28 @@ + +
+compact) { + echo $this->tabs; +} + +echo $object instanceof Service + ? '

' . $this->translate('Current Service State') . '

' . $this->render('partials/object/service-header.phtml') + : '

' . $this->translate('Current Host State') . '

' . $this->render('partials/object/host-header.phtml'); +?> +
+
+

escape($this->translate('Event Details')) ?>

+ + '; + } + ?> +
' . $this->escape($detail[0]) . '' . $detail[1] . '
+
diff --git a/modules/monitoring/application/views/scripts/partials/event-history.phtml b/modules/monitoring/application/views/scripts/partials/event-history.phtml index dac5cd339..7e7e1a574 100644 --- a/modules/monitoring/application/views/scripts/partials/event-history.phtml +++ b/modules/monitoring/application/views/scripts/partials/event-history.phtml @@ -1,6 +1,8 @@ limit($limit * $page); $dateFormat = $this->translate('%A, %B %e, %Y', 'date.verbose'); $lastDate = null; $flappingMsg = $this->translate('Flapping with a %.2f%% state change rate'); +$rowAction = Url::fromPath('monitoring/event/show'); ?> - class=""> +
class=""> peekAhead() as $event): $icon = ''; @@ -44,6 +47,11 @@ $flappingMsg = $this->translate('Flapping with a %.2f%% state change rate'); $isService = isset($event->service_description); $msg = $event->output; $stateName = 'no-state'; + + $rowAction->setParams(new UrlParams())->addParams(array( + 'type' => $event->type, + 'id' => $event->id + )); switch ($event->type) { case 'notify': $icon = 'bell'; @@ -134,7 +142,7 @@ $flappingMsg = $this->translate('Flapping with a %.2f%% state change rate'); - +
getIteratorPosition() % $limit === 0): ?> @@ -163,7 +171,6 @@ $flappingMsg = $this->translate('Flapping with a %.2f%% state change rate'); 'service' => $event->service_description ), array( - 'class' => 'rowaction', 'title' => sprintf( $this->translate('Show detailed information for service %s on host %s'), $event->service_display_name, diff --git a/modules/monitoring/application/views/scripts/partials/object/host-header.phtml b/modules/monitoring/application/views/scripts/partials/object/host-header.phtml index 3bfb35030..d4dac5fff 100644 --- a/modules/monitoring/application/views/scripts/partials/object/host-header.phtml +++ b/modules/monitoring/application/views/scripts/partials/object/host-header.phtml @@ -1,6 +1,11 @@ getPath() === 'monitoring/host/show' && $url->getParam('host') === $object->host_name); ?> @@ -15,10 +20,20 @@ use Icinga\Module\Monitoring\Object\Host;
iconImage()->host($object) ?> + $object->host_name)) . '">'; + } + ?> escape($object->host_display_name) ?> host_display_name !== $object->host_name): ?> (escape($object->host_name) ?>) + '; + } + ?> host_alias !== $object->host_display_name && $object->host_alias !== $object->host_name): ?>
escape($this->translate('Alias', 'host') . ': ' . $object->host_alias) ?> diff --git a/modules/monitoring/application/views/scripts/partials/object/service-header.phtml b/modules/monitoring/application/views/scripts/partials/object/service-header.phtml index a293ff6da..a525ce4bd 100644 --- a/modules/monitoring/application/views/scripts/partials/object/service-header.phtml +++ b/modules/monitoring/application/views/scripts/partials/object/service-header.phtml @@ -1,7 +1,12 @@ getPath() === 'monitoring/service/show' && $url->getParam('service') === $object->service_description); ?> @@ -16,10 +21,12 @@ use Icinga\Module\Monitoring\Object\Service; diff --git a/modules/monitoring/library/Monitoring/Backend/Ido/Query/CommentdeletionhistoryQuery.php b/modules/monitoring/library/Monitoring/Backend/Ido/Query/CommentdeletionhistoryQuery.php index 9635629f1..64ecb865b 100644 --- a/modules/monitoring/library/Monitoring/Backend/Ido/Query/CommentdeletionhistoryQuery.php +++ b/modules/monitoring/library/Monitoring/Backend/Ido/Query/CommentdeletionhistoryQuery.php @@ -17,6 +17,7 @@ class CommentdeletionhistoryQuery extends IdoQuery */ protected $columnMap = array( 'commenthistory' => array( + 'id' => 'cdh.id', 'object_type' => 'cdh.object_type' ), 'history' => array( diff --git a/modules/monitoring/library/Monitoring/Backend/Ido/Query/CommenteventQuery.php b/modules/monitoring/library/Monitoring/Backend/Ido/Query/CommenteventQuery.php new file mode 100644 index 000000000..c85adffe9 --- /dev/null +++ b/modules/monitoring/library/Monitoring/Backend/Ido/Query/CommenteventQuery.php @@ -0,0 +1,39 @@ + array( + 'commentevent_id' => 'ch.commenthistory_id', + 'commentevent_entry_type' => "(CASE ch.entry_type WHEN 1 THEN 'comment' WHEN 2 THEN 'downtime' WHEN 3 THEN 'flapping' WHEN 4 THEN 'ack' ELSE NULL END)", + 'commentevent_comment_time' => 'UNIX_TIMESTAMP(ch.comment_time)', + 'commentevent_author_name' => 'ch.author_name', + 'commentevent_comment_data' => 'ch.comment_data', + 'commentevent_is_persistent' => 'ch.is_persistent', + 'commentevent_comment_source' => "(CASE ch.comment_source WHEN 0 THEN 'icinga' WHEN 1 THEN 'user' ELSE NULL END)", + 'commentevent_expires' => 'ch.expires', + 'commentevent_expiration_time' => 'UNIX_TIMESTAMP(ch.expiration_time)', + 'commentevent_deletion_time' => 'UNIX_TIMESTAMP(ch.deletion_time)' + ), + 'object' => array( + 'host_name' => 'o.name1', + 'service_description' => 'o.name2' + ) + ); + + protected function joinBaseTables() + { + $this->select() + ->from(array('ch' => $this->prefix . 'commenthistory'), array()) + ->join(array('o' => $this->prefix . 'objects'), 'ch.object_id = o.object_id', array()); + + $this->joinedVirtualTables['commentevent'] = true; + $this->joinedVirtualTables['object'] = true; + } +} diff --git a/modules/monitoring/library/Monitoring/Backend/Ido/Query/CommenthistoryQuery.php b/modules/monitoring/library/Monitoring/Backend/Ido/Query/CommenthistoryQuery.php index 9bcaa6a1a..d49d6ea07 100644 --- a/modules/monitoring/library/Monitoring/Backend/Ido/Query/CommenthistoryQuery.php +++ b/modules/monitoring/library/Monitoring/Backend/Ido/Query/CommenthistoryQuery.php @@ -17,6 +17,7 @@ class CommenthistoryQuery extends IdoQuery */ protected $columnMap = array( 'commenthistory' => array( + 'id' => 'ch.id', 'object_type' => 'ch.object_type' ), 'history' => array( diff --git a/modules/monitoring/library/Monitoring/Backend/Ido/Query/DowntimeendhistoryQuery.php b/modules/monitoring/library/Monitoring/Backend/Ido/Query/DowntimeendhistoryQuery.php index b929279a4..99c2ed243 100644 --- a/modules/monitoring/library/Monitoring/Backend/Ido/Query/DowntimeendhistoryQuery.php +++ b/modules/monitoring/library/Monitoring/Backend/Ido/Query/DowntimeendhistoryQuery.php @@ -17,6 +17,7 @@ class DowntimeendhistoryQuery extends IdoQuery */ protected $columnMap = array( 'downtimehistory' => array( + 'id' => 'deh.id', 'object_type' => 'deh.object_type' ), 'history' => array( diff --git a/modules/monitoring/library/Monitoring/Backend/Ido/Query/DowntimeeventQuery.php b/modules/monitoring/library/Monitoring/Backend/Ido/Query/DowntimeeventQuery.php new file mode 100644 index 000000000..04e6aa56c --- /dev/null +++ b/modules/monitoring/library/Monitoring/Backend/Ido/Query/DowntimeeventQuery.php @@ -0,0 +1,42 @@ + array( + 'downtimeevent_id' => 'dth.downtimehistory_id', + 'downtimeevent_entry_time' => 'UNIX_TIMESTAMP(dth.entry_time)', + 'downtimeevent_author_name' => 'dth.author_name', + 'downtimeevent_comment_data' => 'dth.comment_data', + 'downtimeevent_is_fixed' => 'dth.is_fixed', + 'downtimeevent_scheduled_start_time' => 'UNIX_TIMESTAMP(dth.scheduled_start_time)', + 'downtimeevent_scheduled_end_time' => 'UNIX_TIMESTAMP(dth.scheduled_end_time)', + 'downtimeevent_was_started' => 'dth.was_started', + 'downtimeevent_actual_start_time' => 'UNIX_TIMESTAMP(dth.actual_start_time)', + 'downtimeevent_actual_end_time' => 'UNIX_TIMESTAMP(dth.actual_end_time)', + 'downtimeevent_was_cancelled' => 'dth.was_cancelled', + 'downtimeevent_is_in_effect' => 'dth.is_in_effect', + 'downtimeevent_trigger_time' => 'UNIX_TIMESTAMP(dth.trigger_time)' + ), + 'object' => array( + 'host_name' => 'o.name1', + 'service_description' => 'o.name2' + ) + ); + + protected function joinBaseTables() + { + $this->select() + ->from(array('dth' => $this->prefix . 'downtimehistory'), array()) + ->join(array('o' => $this->prefix . 'objects'), 'dth.object_id = o.object_id', array()); + + $this->joinedVirtualTables['downtimeevent'] = true; + $this->joinedVirtualTables['object'] = true; + } +} diff --git a/modules/monitoring/library/Monitoring/Backend/Ido/Query/DowntimestarthistoryQuery.php b/modules/monitoring/library/Monitoring/Backend/Ido/Query/DowntimestarthistoryQuery.php index f7203bbc2..dd6c18b7b 100644 --- a/modules/monitoring/library/Monitoring/Backend/Ido/Query/DowntimestarthistoryQuery.php +++ b/modules/monitoring/library/Monitoring/Backend/Ido/Query/DowntimestarthistoryQuery.php @@ -17,6 +17,7 @@ class DowntimestarthistoryQuery extends IdoQuery */ protected $columnMap = array( 'downtimehistory' => array( + 'id' => 'dsh.id', 'object_type' => 'dsh.object_type' ), 'history' => array( diff --git a/modules/monitoring/library/Monitoring/Backend/Ido/Query/EventhistoryQuery.php b/modules/monitoring/library/Monitoring/Backend/Ido/Query/EventhistoryQuery.php index 956e87450..e9e8f7d96 100644 --- a/modules/monitoring/library/Monitoring/Backend/Ido/Query/EventhistoryQuery.php +++ b/modules/monitoring/library/Monitoring/Backend/Ido/Query/EventhistoryQuery.php @@ -28,6 +28,7 @@ class EventhistoryQuery extends IdoQuery */ protected $columnMap = array( 'eventhistory' => array( + 'id' => 'eh.id', 'cnt_notification' => "SUM(CASE eh.type WHEN 'notify' THEN 1 ELSE 0 END)", 'cnt_hard_state' => "SUM(CASE eh.type WHEN 'hard_state' THEN 1 ELSE 0 END)", 'cnt_soft_state' => "SUM(CASE eh.type WHEN 'hard_state' THEN 1 ELSE 0 END)", @@ -51,6 +52,7 @@ class EventhistoryQuery extends IdoQuery protected function joinBaseTables() { $columns = array( + 'id', 'timestamp', 'output', 'type', diff --git a/modules/monitoring/library/Monitoring/Backend/Ido/Query/FlappingeventQuery.php b/modules/monitoring/library/Monitoring/Backend/Ido/Query/FlappingeventQuery.php new file mode 100644 index 000000000..d993467c5 --- /dev/null +++ b/modules/monitoring/library/Monitoring/Backend/Ido/Query/FlappingeventQuery.php @@ -0,0 +1,36 @@ + array( + 'flappingevent_id' => 'fh.flappinghistory_id', + 'flappingevent_event_time' => 'UNIX_TIMESTAMP(fh.event_time)', + 'flappingevent_event_type' => "(CASE fh.event_type WHEN 1000 THEN 'flapping' WHEN 1001 THEN 'flapping_deleted' ELSE NULL END)", + 'flappingevent_reason_type' => "(CASE fh.reason_type WHEN 1 THEN 'stopped' WHEN 2 THEN 'disabled' ELSE NULL END)", + 'flappingevent_percent_state_change' => 'fh.percent_state_change', + 'flappingevent_low_threshold' => 'fh.low_threshold', + 'flappingevent_high_threshold' => 'fh.high_threshold' + ), + 'object' => array( + 'host_name' => 'o.name1', + 'service_description' => 'o.name2' + ) + ); + + protected function joinBaseTables() + { + $this->select() + ->from(array('fh' => $this->prefix . 'flappinghistory'), array()) + ->join(array('o' => $this->prefix . 'objects'), 'fh.object_id = o.object_id', array()); + + $this->joinedVirtualTables['flappingevent'] = true; + $this->joinedVirtualTables['object'] = true; + } +} diff --git a/modules/monitoring/library/Monitoring/Backend/Ido/Query/FlappingstarthistoryQuery.php b/modules/monitoring/library/Monitoring/Backend/Ido/Query/FlappingstarthistoryQuery.php index ec203d743..9c24c0a47 100644 --- a/modules/monitoring/library/Monitoring/Backend/Ido/Query/FlappingstarthistoryQuery.php +++ b/modules/monitoring/library/Monitoring/Backend/Ido/Query/FlappingstarthistoryQuery.php @@ -17,6 +17,7 @@ class FlappingstarthistoryQuery extends IdoQuery */ protected $columnMap = array( 'flappinghistory' => array( + 'id' => 'fsh.id', 'object_type' => 'fsh.object_type' ), 'history' => array( diff --git a/modules/monitoring/library/Monitoring/Backend/Ido/Query/HostcommenthistoryQuery.php b/modules/monitoring/library/Monitoring/Backend/Ido/Query/HostcommenthistoryQuery.php index 30948a5af..9a4c9b032 100644 --- a/modules/monitoring/library/Monitoring/Backend/Ido/Query/HostcommenthistoryQuery.php +++ b/modules/monitoring/library/Monitoring/Backend/Ido/Query/HostcommenthistoryQuery.php @@ -28,6 +28,7 @@ class HostcommenthistoryQuery extends IdoQuery */ protected $columnMap = array( 'commenthistory' => array( + 'id' => 'hch.commenthistory_id', 'host' => 'ho.name1 COLLATE latin1_general_ci', 'host_name' => 'ho.name1', 'object_id' => 'hch.object_id', diff --git a/modules/monitoring/library/Monitoring/Backend/Ido/Query/HostdowntimestarthistoryQuery.php b/modules/monitoring/library/Monitoring/Backend/Ido/Query/HostdowntimestarthistoryQuery.php index de5f20b28..f3c989bfc 100644 --- a/modules/monitoring/library/Monitoring/Backend/Ido/Query/HostdowntimestarthistoryQuery.php +++ b/modules/monitoring/library/Monitoring/Backend/Ido/Query/HostdowntimestarthistoryQuery.php @@ -28,6 +28,7 @@ class HostdowntimestarthistoryQuery extends IdoQuery */ protected $columnMap = array( 'downtimehistory' => array( + 'id' => 'hdh.downtimehistory_id', 'host' => 'ho.name1 COLLATE latin1_general_ci', 'host_name' => 'ho.name1', 'object_id' => 'hdh.object_id', diff --git a/modules/monitoring/library/Monitoring/Backend/Ido/Query/HostflappingstarthistoryQuery.php b/modules/monitoring/library/Monitoring/Backend/Ido/Query/HostflappingstarthistoryQuery.php index a8af45c55..98677888d 100644 --- a/modules/monitoring/library/Monitoring/Backend/Ido/Query/HostflappingstarthistoryQuery.php +++ b/modules/monitoring/library/Monitoring/Backend/Ido/Query/HostflappingstarthistoryQuery.php @@ -28,6 +28,7 @@ class HostflappingstarthistoryQuery extends IdoQuery */ protected $columnMap = array( 'flappinghistory' => array( + 'id' => 'hfh.flappinghistory_id', 'host_name' => 'ho.name1', 'object_id' => 'hfh.object_id', 'object_type' => '(\'host\')', diff --git a/modules/monitoring/library/Monitoring/Backend/Ido/Query/HostnotificationQuery.php b/modules/monitoring/library/Monitoring/Backend/Ido/Query/HostnotificationQuery.php index c7ffc3308..025094043 100644 --- a/modules/monitoring/library/Monitoring/Backend/Ido/Query/HostnotificationQuery.php +++ b/modules/monitoring/library/Monitoring/Backend/Ido/Query/HostnotificationQuery.php @@ -27,6 +27,7 @@ class HostnotificationQuery extends IdoQuery 'host_display_name' => 'h.display_name COLLATE latin1_general_ci' ), 'history' => array( + 'id' => 'hn.notification_id', 'output' => null, 'state' => 'hn.state', 'timestamp' => 'UNIX_TIMESTAMP(hn.start_time)', diff --git a/modules/monitoring/library/Monitoring/Backend/Ido/Query/HoststatehistoryQuery.php b/modules/monitoring/library/Monitoring/Backend/Ido/Query/HoststatehistoryQuery.php index 1fa2760d2..baad6e1ef 100644 --- a/modules/monitoring/library/Monitoring/Backend/Ido/Query/HoststatehistoryQuery.php +++ b/modules/monitoring/library/Monitoring/Backend/Ido/Query/HoststatehistoryQuery.php @@ -61,6 +61,7 @@ class HoststatehistoryQuery extends IdoQuery 'service_host_name' => 'so.name1' ), 'statehistory' => array( + 'id' => 'hh.statehistory_id', 'host' => 'ho.name1 COLLATE latin1_general_ci', 'host_name' => 'ho.name1', 'object_id' => 'hh.object_id', diff --git a/modules/monitoring/library/Monitoring/Backend/Ido/Query/NotificationeventQuery.php b/modules/monitoring/library/Monitoring/Backend/Ido/Query/NotificationeventQuery.php new file mode 100644 index 000000000..87a71f6d0 --- /dev/null +++ b/modules/monitoring/library/Monitoring/Backend/Ido/Query/NotificationeventQuery.php @@ -0,0 +1,52 @@ + array( + 'notificationevent_id' => 'n.notification_id', + 'notificationevent_reason' => << 'UNIX_TIMESTAMP(n.start_time)', + 'notificationevent_end_time' => 'UNIX_TIMESTAMP(n.end_time)', + 'notificationevent_state' => 'n.state', + 'notificationevent_output' => 'n.output', + 'notificationevent_long_output' => 'n.long_output', + 'notificationevent_escalated' => 'n.escalated', + 'notificationevent_contacts_notified' => 'n.contacts_notified' + ), + 'object' => array( + 'host_name' => 'o.name1', + 'service_description' => 'o.name2' + ) + ); + + protected function joinBaseTables() + { + $this->select() + ->from(array('n' => $this->prefix . 'notifications'), array()) + ->join(array('o' => $this->prefix . 'objects'), 'n.object_id = o.object_id', array()); + + $this->joinedVirtualTables['notificationevent'] = true; + $this->joinedVirtualTables['object'] = true; + } +} diff --git a/modules/monitoring/library/Monitoring/Backend/Ido/Query/NotificationhistoryQuery.php b/modules/monitoring/library/Monitoring/Backend/Ido/Query/NotificationhistoryQuery.php index fd83e571f..b159a7415 100644 --- a/modules/monitoring/library/Monitoring/Backend/Ido/Query/NotificationhistoryQuery.php +++ b/modules/monitoring/library/Monitoring/Backend/Ido/Query/NotificationhistoryQuery.php @@ -22,6 +22,7 @@ class NotificationhistoryQuery extends IdoQuery */ protected $columnMap = array( 'history' => array( + 'id' => 'n.id', 'object_type' => 'n.object_type', 'output' => 'n.output', 'state' => 'n.state', diff --git a/modules/monitoring/library/Monitoring/Backend/Ido/Query/ServicecommenthistoryQuery.php b/modules/monitoring/library/Monitoring/Backend/Ido/Query/ServicecommenthistoryQuery.php index ead486738..39ffbfc10 100644 --- a/modules/monitoring/library/Monitoring/Backend/Ido/Query/ServicecommenthistoryQuery.php +++ b/modules/monitoring/library/Monitoring/Backend/Ido/Query/ServicecommenthistoryQuery.php @@ -28,6 +28,7 @@ class ServicecommenthistoryQuery extends IdoQuery */ protected $columnMap = array( 'commenthistory' => array( + 'id' => 'sch.commenthistory_id', 'host' => 'so.name1 COLLATE latin1_general_ci', 'host_name' => 'so.name1', 'object_id' => 'sch.object_id', diff --git a/modules/monitoring/library/Monitoring/Backend/Ido/Query/ServicedowntimestarthistoryQuery.php b/modules/monitoring/library/Monitoring/Backend/Ido/Query/ServicedowntimestarthistoryQuery.php index c076b5a52..e73baa1b6 100644 --- a/modules/monitoring/library/Monitoring/Backend/Ido/Query/ServicedowntimestarthistoryQuery.php +++ b/modules/monitoring/library/Monitoring/Backend/Ido/Query/ServicedowntimestarthistoryQuery.php @@ -28,6 +28,7 @@ class ServicedowntimestarthistoryQuery extends IdoQuery */ protected $columnMap = array( 'downtimehistory' => array( + 'id' => 'sdh.downtimehistory_id', 'host' => 'so.name1 COLLATE latin1_general_ci', 'host_name' => 'so.name1', 'object_id' => 'sdh.object_id', diff --git a/modules/monitoring/library/Monitoring/Backend/Ido/Query/ServiceflappingstarthistoryQuery.php b/modules/monitoring/library/Monitoring/Backend/Ido/Query/ServiceflappingstarthistoryQuery.php index f5dcfbd12..477807326 100644 --- a/modules/monitoring/library/Monitoring/Backend/Ido/Query/ServiceflappingstarthistoryQuery.php +++ b/modules/monitoring/library/Monitoring/Backend/Ido/Query/ServiceflappingstarthistoryQuery.php @@ -28,6 +28,7 @@ class ServiceflappingstarthistoryQuery extends IdoQuery */ protected $columnMap = array( 'flappinghistory' => array( + 'id' => 'sfh.flappinghistory_id', 'host_name' => 'so.name1', 'object_id' => 'sfh.object_id', 'object_type' => '(\'service\')', diff --git a/modules/monitoring/library/Monitoring/Backend/Ido/Query/ServicenotificationQuery.php b/modules/monitoring/library/Monitoring/Backend/Ido/Query/ServicenotificationQuery.php index 4827632bb..49fbc74b2 100644 --- a/modules/monitoring/library/Monitoring/Backend/Ido/Query/ServicenotificationQuery.php +++ b/modules/monitoring/library/Monitoring/Backend/Ido/Query/ServicenotificationQuery.php @@ -21,6 +21,7 @@ class ServicenotificationQuery extends IdoQuery 'notification_contact_name' => 'co.name1' ), 'history' => array( + 'id' => 'sn.notification_id', 'output' => null, 'state' => 'sn.state', 'timestamp' => 'UNIX_TIMESTAMP(sn.start_time)', diff --git a/modules/monitoring/library/Monitoring/Backend/Ido/Query/ServicestatehistoryQuery.php b/modules/monitoring/library/Monitoring/Backend/Ido/Query/ServicestatehistoryQuery.php index e79db3e5e..b53da858e 100644 --- a/modules/monitoring/library/Monitoring/Backend/Ido/Query/ServicestatehistoryQuery.php +++ b/modules/monitoring/library/Monitoring/Backend/Ido/Query/ServicestatehistoryQuery.php @@ -58,6 +58,7 @@ class ServicestatehistoryQuery extends IdoQuery 'service_display_name' => 's.display_name COLLATE latin1_general_ci' ), 'statehistory' => array( + 'id' => 'sh.statehistory_id', 'host' => 'so.name1 COLLATE latin1_general_ci', 'host_name' => 'so.name1', 'object_id' => 'sh.object_id', diff --git a/modules/monitoring/library/Monitoring/Backend/Ido/Query/StatechangeeventQuery.php b/modules/monitoring/library/Monitoring/Backend/Ido/Query/StatechangeeventQuery.php new file mode 100644 index 000000000..eae41087d --- /dev/null +++ b/modules/monitoring/library/Monitoring/Backend/Ido/Query/StatechangeeventQuery.php @@ -0,0 +1,40 @@ + array( + 'statechangeevent_id' => 'sh.statehistory_id', + 'statechangeevent_state_time' => 'UNIX_TIMESTAMP(sh.state_time)', + 'statechangeevent_state_change' => 'sh.state_change', + 'statechangeevent_state' => 'sh.state', + 'statechangeevent_state_type' => "(CASE sh.state_type WHEN 0 THEN 'soft_state' WHEN 1 THEN 'hard_state' ELSE NULL END)", + 'statechangeevent_current_check_attempt' => 'sh.current_check_attempt', + 'statechangeevent_max_check_attempts' => 'sh.max_check_attempts', + 'statechangeevent_last_state' => 'sh.last_state', + 'statechangeevent_last_hard_state' => 'sh.last_hard_state', + 'statechangeevent_output' => 'sh.output', + 'statechangeevent_long_output' => 'sh.long_output' + ), + 'object' => array( + 'host_name' => 'o.name1', + 'service_description' => 'o.name2' + ) + ); + + protected function joinBaseTables() + { + $this->select() + ->from(array('sh' => $this->prefix . 'statehistory'), array()) + ->join(array('o' => $this->prefix . 'objects'), 'sh.object_id = o.object_id', array()); + + $this->joinedVirtualTables['statechangeevent'] = true; + $this->joinedVirtualTables['object'] = true; + } +} diff --git a/modules/monitoring/library/Monitoring/Backend/Ido/Query/StatehistoryQuery.php b/modules/monitoring/library/Monitoring/Backend/Ido/Query/StatehistoryQuery.php index cd29b80d7..90befc60a 100644 --- a/modules/monitoring/library/Monitoring/Backend/Ido/Query/StatehistoryQuery.php +++ b/modules/monitoring/library/Monitoring/Backend/Ido/Query/StatehistoryQuery.php @@ -17,6 +17,7 @@ class StatehistoryQuery extends IdoQuery */ protected $columnMap = array( 'statehistory' => array( + 'id' => 'sth.id', 'object_type' => 'sth.object_type' ), 'history' => array( diff --git a/modules/monitoring/library/Monitoring/DataView/Commentevent.php b/modules/monitoring/library/Monitoring/DataView/Commentevent.php new file mode 100644 index 000000000..316700a37 --- /dev/null +++ b/modules/monitoring/library/Monitoring/DataView/Commentevent.php @@ -0,0 +1,30 @@ +from( 'eventhistory', array( + 'id', 'object_type', 'host_name', 'host_display_name', diff --git a/modules/monitoring/public/css/module.less b/modules/monitoring/public/css/module.less index 52294a60c..008d9a7ab 100644 --- a/modules/monitoring/public/css/module.less +++ b/modules/monitoring/public/css/module.less @@ -561,14 +561,14 @@ form.instance-features span.description, form.object-features span.description { background-color: @color-warning; color: @body-bg-color; padding: 0.2em; - } - + } + .state-down { background-color: @color-down; color: @body-bg-color; padding: 0.2em; } - + .state-up { background-color: @color-up; color: @body-bg-color; @@ -585,6 +585,17 @@ form.instance-features span.description, form.object-features span.description { } } +.event-details { + .badge { + font-size: 0.6em; + margin-right: 0.5em; + } + + .state-label { + vertical-align: middle; + } +} + //p.pluginoutput { // width: 100%; // white-space: pre-wrap;
iconImage()->host($object) ?> - escape($object->host_display_name) ?> - host_display_name !== $object->host_name): ?> - (escape($object->host_name) ?>) - + + escape($object->host_display_name) ?> + host_display_name !== $object->host_name): ?> + (escape($object->host_name) ?>) + + hostFlags($object) ?> host_address6 && $object->host_address6 !== $object->host_name): ?>
@@ -45,10 +52,24 @@ use Icinga\Module\Monitoring\Object\Service;
iconImage()->service($object) ?> - translate('Service') ?>: escape($object->service_display_name) ?> - service_display_name !== $object->service_description): ?> - (escape($object->service_description) ?>) - + translate('Service') ?>: + $object->host_name, + 'service' => $object->service_description + )) . '">'; + } + ?> + escape($object->service_display_name) ?> + service_display_name !== $object->service_description): ?> + (escape($object->service_description) ?>) + + '; + } + ?> serviceFlags($object) ?>