Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
yhabteab committed Feb 17, 2023
1 parent 6c00c92 commit e1a180b
Show file tree
Hide file tree
Showing 4 changed files with 108 additions and 85 deletions.
31 changes: 21 additions & 10 deletions library/Icingadb/Model/HostSlaHistory.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,12 @@

namespace Icinga\Module\Icingadb\Model;

use Icinga\Module\Icingadb\ProvidedHook\Reporting\Common\SlaTimeline;
use ipl\Orm\Relations;
use ipl\Orm\UnionModel;
use ipl\Sql\Connection;
use ipl\Sql\Expression;
use ipl\Stdlib\Filter;

class HostSlaHistory extends UnionModel
{
Expand All @@ -27,12 +30,24 @@ public function getColumns()
'display_name',
'event_time',
'event_type',
'event_priority',
'hard_state',
'previous_hard_state'
];
}

public static function on(Connection $db)
{
$query = parent::on($db);
$unions = $query->getUnions();

$downtimeFilter = Filter::unlike('sla_history_downtime.service_id', '*');
$unions[0]->filter($downtimeFilter);
$unions[1]->filter($downtimeFilter);
$unions[2]->filter(Filter::unlike('sla_history_state.service_id', '*'));

return $query;
}

public function getUnions()
{
return [
Expand All @@ -43,9 +58,8 @@ public function getUnions()
],
[
'display_name' => 'host.display_name',
'event_priority' => new Expression('1'),
'event_time' => 'sla_history_downtime.downtime_start',
'event_type' => new Expression('\'downtime_start\''),
'event_type' => new Expression(SlaTimeline::DOWNTIME_START),
'hard_state' => new Expression('NULL'),
'host_id' => 'id',
'previous_hard_state' => new Expression('NULL'),
Expand All @@ -58,9 +72,8 @@ public function getUnions()
],
[
'display_name' => 'host.display_name',
'event_priority' => new Expression('2'),
'event_time' => 'sla_history_downtime.downtime_end',
'event_type' => new Expression('\'downtime_end\''),
'event_type' => new Expression(SlaTimeline::DOWNTIME_END),
'hard_state' => new Expression('NULL'),
'host_id' => 'id',
'previous_hard_state' => new Expression('NULL'),
Expand All @@ -73,9 +86,8 @@ public function getUnions()
],
[
'display_name' => 'display_name',
'event_priority' => new Expression('0'),
'event_time' => 'sla_history_state.event_time',
'event_type' => new Expression('\'state_change\''),
'event_type' => new Expression(SlaTimeline::STATE_CHANGE),
'hard_state' => 'sla_history_state.hard_state',
'host_id' => 'id',
'previous_hard_state' => 'sla_history_state.previous_hard_state',
Expand All @@ -87,9 +99,8 @@ public function getUnions()
[],
[
'display_name' => 'host.display_name',
'event_priority' => new Expression('3'),
'event_time' => new Expression('NULL'),
'event_type' => new Expression('\'end\''),
'event_type' => new Expression(SlaTimeline::END_RESULT),
'hard_state' => new Expression('NULL'),
'host_id' => 'id',
'previous_hard_state' => new Expression('NULL'),
Expand All @@ -100,7 +111,7 @@ public function getUnions()

public function getDefaultSort()
{
return ['display_name', 'event_time', 'event_priority'];
return ['display_name', 'event_time', 'event_type'];
}

public function createRelations(Relations $relations)
Expand Down
16 changes: 6 additions & 10 deletions library/Icingadb/Model/ServiceSlaHistory.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

namespace Icinga\Module\Icingadb\Model;

use Icinga\Module\Icingadb\ProvidedHook\Reporting\Common\SlaTimeline;
use ipl\Orm\Relations;
use ipl\Orm\UnionModel;
use ipl\Sql\Expression;
Expand All @@ -29,7 +30,6 @@ public function getColumns()
'host_display_name',
'event_time',
'event_type',
'event_priority',
'hard_state',
'previous_hard_state'
];
Expand All @@ -47,9 +47,8 @@ public function getUnions()
[
'display_name' => 'display_name',
'host_display_name' => 'host.display_name',
'event_priority' => new Expression('1'),
'event_time' => 'sla_history_downtime.downtime_start',
'event_type' => new Expression('\'downtime_start\''),
'event_type' => new Expression(SlaTimeline::DOWNTIME_START),
'hard_state' => new Expression('NULL'),
'host_id' => 'host.id',
'service_id' => 'id',
Expand All @@ -65,9 +64,8 @@ public function getUnions()
[
'display_name' => 'display_name',
'host_display_name' => 'host.display_name',
'event_priority' => new Expression('2'),
'event_time' => 'sla_history_downtime.downtime_end',
'event_type' => new Expression('\'downtime_end\''),
'event_type' => new Expression(SlaTimeline::DOWNTIME_END),
'hard_state' => new Expression('NULL'),
'host_id' => 'host.id',
'service_id' => 'id',
Expand All @@ -83,9 +81,8 @@ public function getUnions()
[
'display_name' => 'display_name',
'host_display_name' => 'host.display_name',
'event_priority' => new Expression('0'),
'event_time' => 'sla_history_state.event_time',
'event_type' => new Expression('\'state_change\''),
'event_type' => new Expression(SlaTimeline::STATE_CHANGE),
'hard_state' => 'sla_history_state.hard_state',
'host_id' => 'host.id',
'service_id' => 'id',
Expand All @@ -101,9 +98,8 @@ public function getUnions()
[
'display_name' => 'display_name',
'host_display_name' => 'host.display_name',
'event_priority' => new Expression('3'),
'event_time' => new Expression('NULL'),
'event_type' => new Expression('\'end\''),
'event_type' => new Expression(SlaTimeline::END_RESULT),
'hard_state' => new Expression('NULL'),
'host_id' => 'host.id',
'service_id' => 'id',
Expand All @@ -115,7 +111,7 @@ public function getUnions()

public function getDefaultSort()
{
return ['host_display_name', 'display_name', 'event_time', 'event_priority'];
return ['host_display_name', 'display_name', 'event_time', 'event_type'];
}

public function createRelations(Relations $relations)
Expand Down
102 changes: 45 additions & 57 deletions library/Icingadb/ProvidedHook/Reporting/Common/SlaReportUtils.php
Original file line number Diff line number Diff line change
Expand Up @@ -48,61 +48,49 @@ protected function fetchSla(DateTime $start, DateTime $end, Rule $filter = null)
$query = ServiceSlaHistory::on($this->getDb());
}

$index = 0;
foreach ($query->getUnions() as $union) {
$filterAll = Filter::all();
if ($index >= 2) {
if ($index < 3) {
if ($this->getReportType() === 'host') {
$filterAll->add(Filter::unlike('sla_history_state.service_id', '*'));
}

$filterAll
->add(Filter::greaterThan('sla_history_state.event_time', $start))
->add(Filter::lessThan('sla_history_state.event_time', $end));
} else {
$union->columns(
array_merge($union->getColumns(), [
'event_time' => new Expression($end->format('Uv'))
])
);
}
} else {
if ($this->getReportType() === 'host') {
$filterAll->add(Filter::unlike('sla_history_downtime.service_id', '*'));
}

$filterAll
->add(Filter::lessThan('sla_history_downtime.downtime_start', $end))
->add(Filter::greaterThanOrEqual('sla_history_downtime.downtime_end', $start));

if ($index === 1) {
$filterAll->add(Filter::lessThan('sla_history_downtime.downtime_end', $end));
} else {
$union->columns(
array_merge(
$union->getColumns(),
[
'event_time' => new Expression(
sprintf(
'GREATEST(%s_sla_history_downtime.downtime_start, %s)',
$this->getReportType(),
$start->format('Uv')
)
)
]
$unions = $query->getUnions();
$slaDowntimeFilter = Filter::all(
Filter::lessThan('sla_history_downtime.downtime_start', $end),
Filter::greaterThanOrEqual('sla_history_downtime.downtime_end', $start)
);

$unions[0]
->filter($slaDowntimeFilter)
->columns(
array_merge(
$unions[0]->getColumns(),
[
'event_time' => new Expression(
sprintf(
'GREATEST(%s_sla_history_downtime.downtime_start, %s)',
$this->getReportType(),
$start->format('Uv')
)
)
);
}
}

++$index;

$union->filter($filterAll);

if ($filter !== null) {
$union->filter($filter);
}
]
)
);

$unions[1]
->filter($slaDowntimeFilter)
->filter(Filter::lessThan('sla_history_downtime.downtime_end', $end));

$unions[2]->filter(Filter::all(
Filter::greaterThan('sla_history_state.event_time', $start),
Filter::lessThan('sla_history_state.event_time', $end)
));

$unions[3]->columns(
array_merge($unions[3]->getColumns(), [
'event_time' => new Expression($end->format('Uv'))
])
);

if ($filter !== null) {
$unions[0]->filter($filter);
$unions[1]->filter($filter);
$unions[2]->filter($filter);
$unions[3]->filter($filter);
}

if (method_exists($this, 'applyRestrictions')) {
Expand Down Expand Up @@ -158,7 +146,7 @@ protected function fetchReportData(DateTime $reportStart, DateTime $reportEnd, a
if (isset($reports[$key])) {
$timeline = $reports[$key];
} else {
$timeline = new SlaTimeline($start, $end);
$timeline = new SlaTimeline($start, $end, $this->getReportType());
$serviceId = null;
if (! $this instanceof HostSlaReport) {
$serviceId = $row->service_id;
Expand Down Expand Up @@ -212,7 +200,7 @@ protected function fetchReportData(DateTime $reportStart, DateTime $reportEnd, a
if ($rd->hasTimelines($key)) {
$timeline = current($rd->getTimelines($key));
} else {
$timeline = new SlaTimeline($reportStart, $reportEnd);
$timeline = new SlaTimeline($reportStart, $reportEnd, $this->getReportType());
$serviceId = null;
if (! $isHostQuery) {
$serviceId = $row->service_id;
Expand All @@ -231,7 +219,7 @@ protected function fetchReportData(DateTime $reportStart, DateTime $reportEnd, a

$rd->setTimeline($key, $timeline);

if ($row->event_type === 'end') {
if ($row->event_type === SlaTimeline::END_RESULT) {
$row->sla = $timeline->getResult();
$rows[] = $this->createReportRow($row);
}
Expand Down
44 changes: 36 additions & 8 deletions library/Icingadb/ProvidedHook/Reporting/Common/SlaTimeline.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,18 @@
*/
class SlaTimeline implements Countable
{
/** @var int Sla history event type state change */
public const STATE_CHANGE = 0;

/** @var int Sla history event type downtime start */
public const DOWNTIME_START = 1;

/** @var int Sla history event type downtime end */
public const DOWNTIME_END = 2;

/** @var int End of this timeline events */
public const END_RESULT = 3;

/** @var DateTimeInterface Start time of the generated report timeframe */
protected $start;

Expand Down Expand Up @@ -39,10 +51,13 @@ class SlaTimeline implements Countable
/** @var int The initial hard state of this timeline */
protected $initialHardState = 0;

public function __construct(DateTimeInterface $start, DateTimeInterface $end)
protected $objectType;

public function __construct(DateTimeInterface $start, DateTimeInterface $end, string $objectType)
{
$this->start = clone $start;
$this->end = clone $end;
$this->objectType = $objectType;
}

/**
Expand Down Expand Up @@ -78,18 +93,31 @@ public function getResult(): ?float
$time = $this->time[$i];
$state = $this->state[$i];

if ($this->previousState[$i] === 99 || ($lastHardState === 99 && $event !== 'state_change')) {
if ($this->previousState[$i] === 99 || ($lastHardState === 99 && $event !== static::STATE_CHANGE)) {
$totalTime -= $time - $lastEventTime;
} elseif ($lastHardState > 0 && $lastHardState !== 99 && $activeDowntimes === 0) {
} elseif (
(
(
$this->objectType === 'host'
&& $lastHardState > 0
)
|| (
$this->objectType === 'service'
&& $lastHardState > 1
)
)
&& $lastHardState !== 99
&& $activeDowntimes === 0
) {
$problemTime += $time - $lastEventTime;
}

$lastEventTime = $time;
if ($event === 'state_change') {
if ($event === static::STATE_CHANGE) {
$lastHardState = $state;
} elseif ($event === 'downtime_start') {
} elseif ($event === static::DOWNTIME_START) {
++$activeDowntimes;
} elseif ($event === 'downtime_end') {
} elseif ($event === static::DOWNTIME_END) {
--$activeDowntimes;
}
}
Expand Down Expand Up @@ -121,11 +149,11 @@ public function addTime(int $time): self
/**
* Add event type to this timeline
*
* @param string $event
* @param int $event
*
* @return $this
*/
public function addEvent(string $event): self
public function addEvent(int $event): self
{
$this->event[] = $event;

Expand Down

0 comments on commit e1a180b

Please sign in to comment.