diff --git a/modules/monitoring/application/controllers/AlertsummaryController.php b/modules/monitoring/application/controllers/AlertsummaryController.php new file mode 100644 index 0000000000..bc4f41115f --- /dev/null +++ b/modules/monitoring/application/controllers/AlertsummaryController.php @@ -0,0 +1,219 @@ +view->intervalBox = $this->createIntervalBox(); + $this->view->recentAlerts = $this->createRecentAlerts(); + $this->view->interval = $this->getInterval(); + } + + public function defectimageAction() + { + $gridChart = new GridChart(); + $interval = $this->getInterval(); + + $gridChart->alignTopLeft(); + $gridChart->setAxisLabel('', t('Services')) + ->setXAxis(new StaticAxis()) + ->setAxisMin(null, 0) + ->setYAxis(new \Icinga\Chart\Unit\LinearUnit(10)); + + $query = $this->backend->select()->from('notification', array( + 'host', + 'service', + 'notification_output', + 'notification_contact', + 'notification_start_time', + 'notification_state' + )); + + $query->setFilter( + new Icinga\Data\Filter\FilterExpression( + 'n.start_time', + '>=', + $this->getBeginDate($interval)->format('Y-m-d H:i:s') + ) + ); + + $query->order('notification_start_time', 'asc'); + + + $records = $query->paginate(10000); + $data = array(); + $defects = array(); + $period = $this->createPeriod($interval); + + foreach ($period as $entry) { + $id = $this->getPeriodFormat($interval, $entry->getTimestamp()); + $data[$id] = array($id, 0); + $defects[$id] = array($id, 0); + } + + foreach ($records as $item) { + $id = $this->getPeriodFormat($interval, $item->notification_start_time); + if (empty($data[$id])) { + $data[$id] = array($id, 0); + } + + $data[$id][1]++; + } + + $gridChart->drawBars( + array( + 'label' => $this->translate('Notifications'), + 'color' => 'green', + 'data' => $data, + 'showPoints' => true + ) + ); + + $query = null; + $records = null; + $item = null; + + $query = $this->backend->select()->from('eventhistory', array( + 'host_name', + 'service_description', + 'object_type', + 'timestamp', + 'state', + 'attempt', + 'max_attempts', + 'output', + 'type', + 'host', + 'service', + 'service_host_name' + )); + + $query->addFilter( + new Icinga\Data\Filter\FilterExpression( + 'timestamp', + '>=', + $this->getBeginDate($interval)->getTimestamp() + ) + ); + + $query->addFilter( + new Icinga\Data\Filter\FilterExpression( + 'state', + '>', + 0 + ) + ); + + $records = $query->paginate(10000); + + foreach ($records as $item) { + $id = $this->getPeriodFormat($interval, $item->timestamp); + if (empty($data[$id])) { + $defects[$id] = array($id, 0); + } + + $defects[$id][1]++; + } + + $gridChart->drawLines( + array( + 'label' => $this->translate('Defects'), + 'color' => 'red', + 'data' => $defects, + 'showPoints' => true + ) + ); + + $this->view->chart = $gridChart; + } + + private function createRecentAlerts() + { + $query = $this->backend->select()->from('notification', array( + 'host', + 'service', + 'notification_output', + 'notification_contact', + 'notification_start_time', + 'notification_state' + )); + + $query->order('notification_start_time', 'desc'); + + return $query->paginate(5); + } + + private function createIntervalBox() + { + $box = new SelectBox( + 'intervalBox', + array( + '1d' => t('One day'), + '1w' => t('One week'), + '1m' => t('One month'), + '1y' => t('One year') + ), + t('Report interval'), + 'interval' + ); + $box->applyRequest($this->getRequest()); + return $box; + } + + private function getPeriodFormat($interval, $timestamp) + { + $format = ''; + if ($interval === '1d') { + $format = '%H:00:00'; + } elseif ($interval === '1w') { + $format = '%Y-%m-%d'; + } elseif ($interval === '1m') { + $format = '%Y-%m-%d'; + } elseif ($interval === '1y') { + $format = '%Y-%m'; + } + + return strftime($format, $timestamp); + } + + private function createPeriod($interval) + { + if ($interval === '1d') { + return new DatePeriod($this->getBeginDate($interval), new DateInterval('PT1H'), 24); + } elseif ($interval === '1w') { + return new DatePeriod($this->getBeginDate($interval), new DateInterval('P1D'), 7); + } elseif ($interval === '1m') { + return new DatePeriod($this->getBeginDate($interval), new DateInterval('P1D'), 30); + } elseif ($interval === '1y') { + return new DatePeriod($this->getBeginDate($interval), new DateInterval('P1M'), 12); + } + } + + private function getBeginDate($interval) + { + $new = new DateTime(); + if ($interval === '1d') { + return $new->sub(new DateInterval('P1D')); + } elseif ($interval === '1w') { + return $new->sub(new DateInterval('P1W')); + } elseif ($interval === '1m') { + return $new->sub(new DateInterval('P1M')); + } elseif ($interval === '1y') { + return $new->sub(new DateInterval('P1Y')); + } + + return null; + } + + private function getInterval() + { + return $this->getParam('interval', '1d'); + } +} \ No newline at end of file diff --git a/modules/monitoring/application/views/helpers/MonitoringState.php b/modules/monitoring/application/views/helpers/MonitoringState.php index c20c08c96c..871e8ad08f 100644 --- a/modules/monitoring/application/views/helpers/MonitoringState.php +++ b/modules/monitoring/application/views/helpers/MonitoringState.php @@ -22,6 +22,15 @@ public function monitoringState($object, $type = 'service') } } + public function monitoringStateById($id, $type = 'service') + { + if ($type === 'service') { + return $this->servicestates[$id]; + } elseif ($type === 'host') { + return $this->hoststates[$id]; + } + } + /** * @deprecated Monitoring colors are clustered. */ diff --git a/modules/monitoring/application/views/scripts/alertsummary/defectimage.phtml b/modules/monitoring/application/views/scripts/alertsummary/defectimage.phtml new file mode 100644 index 0000000000..91f20a8375 --- /dev/null +++ b/modules/monitoring/application/views/scripts/alertsummary/defectimage.phtml @@ -0,0 +1,7 @@ +compact) { ?> +
+ render(); ?> +
+ + render(); ?> + diff --git a/modules/monitoring/application/views/scripts/alertsummary/index.phtml b/modules/monitoring/application/views/scripts/alertsummary/index.phtml new file mode 100644 index 0000000000..9fd3350c35 --- /dev/null +++ b/modules/monitoring/application/views/scripts/alertsummary/index.phtml @@ -0,0 +1,37 @@ +getHelper('MonitoringState'); +?> +
+
+ +
+
+ +
+

Alert summary

+ +

Notifications

+
+ action('defectimage', 'alertsummary', 'monitoring', array('interval' => $this->interval)); ?> +
+ + recentAlerts): ?> +

translate('Top 5 recent alerts'); ?>

+ + + + + + + + recentAlerts as $alert): ?> + + + + + + + +
translate('Host'); ?>translate('Service'); ?>translate('State'); ?>translate('Timestamp'); ?>
host; ?>service; ?>monitoringStateById($alert->notification_state, $alert->service ? 'service' : 'host')) ?>prefixedTimeSince($alert->notification_start_time, true) ?>
+ +
\ No newline at end of file diff --git a/modules/monitoring/configuration.php b/modules/monitoring/configuration.php index b40a8c282f..edcd37a245 100644 --- a/modules/monitoring/configuration.php +++ b/modules/monitoring/configuration.php @@ -122,6 +122,18 @@ )); $section->add($this->translate('Timeline'))->setUrl('monitoring/timeline'); +/* + * Reporting Section + */ +$section = $this->menuSection($this->translate('Reporting'), array( + 'icon' => 'img/icons/hostgroup.png', + 'priority' => 100 +)); + +$section->add($this->translate('Alert Summary'), array( + 'url' => 'monitoring/alertsummary/index' +)); + /* * System Section */