icingaweb2/modules/monitoring/application/controllers/TimelineController.php

307 lines
11 KiB
PHP
Raw Normal View History

2013-10-22 17:02:59 +02:00
<?php
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
use \DateTime;
use \DateInterval;
use \Zend_Config;
use Icinga\Web\Url;
use Icinga\Application\Config;
use Icinga\Util\DateTimeFactory;
use Icinga\Web\Controller\ActionController;
use Icinga\Module\Monitoring\Timeline\TimeLine;
use Icinga\Module\Monitoring\Timeline\TimeRange;
use Icinga\Module\Monitoring\Web\Widget\TimelineIntervalBox;
use Icinga\Module\Monitoring\DataView\EventHistory as EventHistoryView;
2013-10-22 17:02:59 +02:00
class Monitoring_TimelineController extends ActionController
{
public function indexAction()
2013-10-22 17:02:59 +02:00
{
// TODO: filter for hard_states (precedence adjustments necessary!)
$this->setupIntervalBox();
list($displayRange, $forecastRange) = $this->buildTimeRanges();
$detailUrl = Url::fromPath(
'/monitoring/list/eventhistory',
Url::fromRequest()->getParams()
)->setAliases(
array(
'name' => 'type',
'end' => 'raw_timestamp>',
'start' => 'raw_timestamp<'
)
)->remove(array('start', 'end', 'extend', 'interval'));
$timeline = new TimeLine(
EventHistoryView::fromRequest(
$this->getRequest(),
array(
'name' => 'type',
'time' => 'raw_timestamp'
)
),
array(
'notify' => array(
'detailUrl' => $detailUrl,
'label' => t('Notifications'),
'color' => '#3a71ea'
),
'hard_state' => array(
'detailUrl' => $detailUrl,
'label' => t('Hard state changes'),
'color' => '#ff7000'
),
'comment' => array(
'detailUrl' => $detailUrl,
'label' => t('Comments'),
'color' => '#79bdba'
),
'ack' => array(
'detailUrl' => $detailUrl,
'label' => t('Acknowledgements'),
'color' => '#a2721d'
),
'dt_start' => array(
'detailUrl' => $detailUrl,
'label' => t('Started downtimes'),
'color' => '#8e8e8e'
),
'dt_end' => array(
'detailUrl' => $detailUrl,
'label' => t('Ended downtimes'),
'color' => '#d5d6ad'
)
)
);
$timeline->setMaximumCircleWidth('6em');
2014-03-28 15:25:23 +01:00
$timeline->setMinimumCircleWidth('0.3em');
$timeline->setDisplayRange($displayRange);
$timeline->setForecastRange($forecastRange);
$beingExtended = $this->getRequest()->getParam('extend') == 1;
$timeline->setSession($this->getWindowSession('timeline', !$beingExtended));
2013-10-22 17:02:59 +02:00
$this->view->timeline = $timeline;
$this->view->nextRange = $forecastRange;
$this->view->beingExtended = $beingExtended;
$this->view->intervalFormat = $this->getIntervalFormat();
$oldBase = $timeline->getCalculationBase(false);
$this->view->switchedContext = $oldBase !== null && $oldBase !== $timeline->getCalculationBase(true);
2013-10-22 17:02:59 +02:00
}
/**
* Create a select box the user can choose the timeline interval from
*/
private function setupIntervalBox()
{
$box = new TimelineIntervalBox(
'intervalBox',
array(
'4h' => t('4 Hours'),
'1d' => t('One day'),
'1w' => t('One week'),
'1m' => t('One month'),
'1y' => t('One year')
)
);
$box->applyRequest($this->getRequest());
$this->view->intervalBox = $box;
}
/**
* Return the chosen interval
*
* @return DateInterval The chosen interval
*/
private function getTimelineInterval()
{
switch ($this->view->intervalBox->getInterval())
{
case '1d':
return new DateInterval('P1D');
case '1w':
return new DateInterval('P1W');
case '1m':
return new DateInterval('P1M');
case '1y':
return new DateInterval('P1Y');
default:
return new DateInterval('PT4H');
}
}
2013-10-22 17:02:59 +02:00
/**
* Get an appropriate datetime format string for the chosen interval
2013-10-22 17:02:59 +02:00
*
* @return string
2013-10-22 17:02:59 +02:00
*/
private function getIntervalFormat()
2013-10-22 17:02:59 +02:00
{
switch ($this->view->intervalBox->getInterval())
{
case '1d':
return $this->getDateFormat();
case '1w':
return '\W\e\ek #W\<b\r\>\of Y';
case '1m':
return 'F Y';
case '1y':
return 'Y';
default:
return $this->getDateFormat() . '\<b\r\>' . $this->getTimeFormat();
2013-10-22 17:02:59 +02:00
}
}
/**
* Return a preload interval based on the chosen timeline interval and the given date and time
2013-10-22 17:02:59 +02:00
*
* @param DateTime $dateTime The date and time to use
*
* @return DateInterval The interval to pre-load
2013-10-22 17:02:59 +02:00
*/
private function getPreloadInterval(DateTime $dateTime)
2013-10-22 17:02:59 +02:00
{
switch ($this->view->intervalBox->getInterval())
{
case '1d':
return DateInterval::createFromDateString('1 week -1 second');
case '1w':
return DateInterval::createFromDateString('8 weeks -1 second');
case '1m':
$dateCopy = clone $dateTime;
for ($i = 0; $i < 6; $i++) {
$dateCopy->sub(new DateInterval('PT' . DateTimeFactory::getSecondsByMonth($dateCopy) . 'S'));
}
return $dateCopy->add(new DateInterval('PT1S'))->diff($dateTime);
case '1y':
$dateCopy = clone $dateTime;
for ($i = 0; $i < 4; $i++) {
$dateCopy->sub(new DateInterval('PT' . DateTimeFactory::getSecondsByYear($dateCopy) . 'S'));
}
return $dateCopy->add(new DateInterval('PT1S'))->diff($dateTime);
default:
return DateInterval::createFromDateString('1 day -1 second');
2013-10-22 17:02:59 +02:00
}
}
/**
* Extrapolate the given datetime based on the chosen timeline interval
2013-10-22 17:02:59 +02:00
*
* @param DateTime $dateTime The datetime to extrapolate
2013-10-22 17:02:59 +02:00
*/
private function extrapolateDateTime(DateTime &$dateTime)
2013-10-22 17:02:59 +02:00
{
switch ($this->view->intervalBox->getInterval())
{
case '1d':
$dateTime->setTimestamp(strtotime('tomorrow', $dateTime->getTimestamp()) - 1);
break;
case '1w':
$dateTime->setTimestamp(strtotime('next monday', $dateTime->getTimestamp()) - 1);
break;
case '1m':
$dateTime->setTimestamp(
strtotime(
'last day of this month',
strtotime(
'tomorrow',
$dateTime->getTimestamp()
) - 1
)
);
break;
case '1y':
$dateTime->setTimestamp(strtotime('1 january next year', $dateTime->getTimestamp()) - 1);
break;
default:
$hour = $dateTime->format('G');
$end = $hour < 4 ? 4 : ($hour < 8 ? 8 : ($hour < 12 ? 12 : ($hour < 16 ? 16 : ($hour < 20 ? 20 : 24))));
$dateTime = DateTime::createFromFormat(
'd/m/y G:i:s',
$dateTime->format('d/m/y') . ($end - 1) . ':59:59'
2013-10-22 17:02:59 +02:00
);
}
}
/**
* Return a display- and forecast time range
2013-10-22 17:02:59 +02:00
*
* Assembles a time range each for display and forecast purposes based on the start- and
* end time if given in the current request otherwise based on the current time and a
* end time that is calculated based on the chosen timeline interval.
2013-10-22 17:02:59 +02:00
*
* @return array The resulting time ranges
2013-10-22 17:02:59 +02:00
*/
private function buildTimeRanges()
2013-10-22 17:02:59 +02:00
{
$startTime = DateTimeFactory::create();
$startParam = $this->_request->getParam('start');
$startTimestamp = is_numeric($startParam) ? intval($startParam) : strtotime($startParam);
if ($startTimestamp !== false) {
$startTime->setTimestamp($startTimestamp);
} else {
$this->extrapolateDateTime($startTime);
}
2013-10-22 17:02:59 +02:00
$endTime = clone $startTime;
$endParam = $this->_request->getParam('end');
$endTimestamp = is_numeric($endParam) ? intval($endParam) : strtotime($endParam);
if ($endTimestamp !== false) {
$endTime->setTimestamp($endTimestamp);
} else {
$endTime->sub($this->getPreloadInterval($startTime));
}
2013-10-22 17:02:59 +02:00
$forecastStart = clone $endTime;
$forecastStart->sub(new DateInterval('PT1S'));
$forecastEnd = clone $forecastStart;
$forecastEnd->sub($this->getPreloadInterval($forecastStart));
2013-10-22 17:02:59 +02:00
$timelineInterval = $this->getTimelineInterval();
return array(
new TimeRange($startTime, $endTime, $timelineInterval),
new TimeRange($forecastStart, $forecastEnd, $timelineInterval)
);
2013-10-22 17:02:59 +02:00
}
/**
* Get the application's global configuration or an empty one
2013-10-22 17:02:59 +02:00
*
* @return Zend_Config
2013-10-22 17:02:59 +02:00
*/
private function getGlobalConfiguration()
2013-10-22 17:02:59 +02:00
{
$globalConfig = Config::app()->global;
2013-10-22 17:02:59 +02:00
if ($globalConfig === null) {
$globalConfig = new Zend_Config(array());
}
2013-10-22 17:02:59 +02:00
return $globalConfig;
2013-10-22 17:02:59 +02:00
}
/**
* Get the user's preferred time format or the application's default
2013-10-22 17:02:59 +02:00
*
* @return string
2013-10-22 17:02:59 +02:00
*/
private function getTimeFormat()
2013-10-22 17:02:59 +02:00
{
$globalConfig = $this->getGlobalConfiguration();
$preferences = $this->getRequest()->getUser()->getPreferences();
return $preferences->get('app.timeFormat', $globalConfig->get('timeFormat', 'g:i A'));
2013-10-22 17:02:59 +02:00
}
/**
* Get the user's preferred date format or the application's default
2013-10-22 17:02:59 +02:00
*
* @return string
2013-10-22 17:02:59 +02:00
*/
private function getDateFormat()
2013-10-22 17:02:59 +02:00
{
$globalConfig = $this->getGlobalConfiguration();
$preferences = $this->getRequest()->getUser()->getPreferences();
return $preferences->get('app.dateFormat', $globalConfig->get('dateFormat', 'd/m/Y'));
2013-10-22 17:02:59 +02:00
}
}