Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support new event types #216

Merged
merged 2 commits into from
Jun 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 31 additions & 1 deletion library/Notifications/Common/Icons.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ private function __construct()
{
}

public const WARNING = 'exclamation-triangle';
public const WARNING = 'triangle-exclamation';

public const OK = 'circle-check';

Expand Down Expand Up @@ -41,4 +41,34 @@ private function __construct()
public const RULE_MATCHED = 'filter';

public const UNDEFINED = 'notdef';

public const ACKNOWLEDGED = 'check';

public const UNACKNOWLEDGED = 'xmark';

public const DOWNTIME = 'plug';

public const FLAPPING = 'bolt';

public const INCIDENT_AGE = 'hourglass-end';

public const CUSTOM = 'message';

public const SEVERITY_OK = 'heart';

public const SEVERITY_CRIT = 'circle-exclamation';

public const SEVERITY_WARN = 'triangle-exclamation';

public const SEVERITY_ERR = 'circle-xmark';

public const SEVERITY_DEBUG = 'bug-slash';

public const SEVERITY_INFO = 'circle-info';

public const SEVERITY_ALERT = 'bell';

public const SEVERITY_EMERG = 'bullhorn';

public const SEVERITY_NOTICE = 'envelope';
}
110 changes: 110 additions & 0 deletions library/Notifications/Model/Event.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

use DateTime;
use Icinga\Module\Notifications\Common\Database;
use Icinga\Module\Notifications\Common\Icons;
use ipl\Orm\Behavior\Binary;
use ipl\Orm\Behavior\MillisecondTimestamp;
use ipl\Orm\Behaviors;
Expand All @@ -14,6 +15,7 @@
use ipl\Orm\Relations;
use ipl\Sql\Connection;
use ipl\Sql\Select;
use ipl\Web\Widget\Icon;

/**
* Event model
Expand Down Expand Up @@ -153,4 +155,112 @@ public static function mapSeverity(?string $severity): ?string

return $label;
}

/**
* Get the type text
*
* @return string
*/
public function getTypeText(): string
{
if ($this->type === 'state') {
if ($this->severity === 'ok') {
return t('recovered', 'notifications.type');
}

return t('ran into a problem', 'notifications.type');
}

switch ($this->type) {
case 'acknowledgement-set':
return t('has been acknowledged', 'notifications.type');
case 'acknowledgement-cleared':
return t('was unacknowledged', 'notifications.type');
case 'downtime-start':
return t('entered a downtime period', 'notifications.type');
case 'downtime-end':
return t('left a downtime period', 'notifications.type');
case 'downtime-removed':
return t('prematurely left a downtime period', 'notifications.type');
case 'flapping-start':
return t('entered a flapping period', 'notifications.type');
case 'flapping-end':
return t('left a flapping period', 'notifications.type');
case 'incident-age':
return t('exceeded a time constraint', 'notifications.type');
default: // custom
return '';
}
}

/**
* Get the icon for the event
*
* @return ?Icon
*/
public function getIcon(): ?Icon
{
$icon = null;

if ($this->type === 'state') {
$severity = $this->severity;
$class = 'severity-' . $severity;
switch ($severity) {
case 'ok':
$icon = (new Icon(Icons::SEVERITY_OK, ['class' => $class]))->setStyle('fa-regular');
break;
case 'crit':
$icon = new Icon(Icons::SEVERITY_CRIT, ['class' => $class]);
break;
case 'warning':
$icon = new Icon(Icons::SEVERITY_WARN, ['class' => $class]);
break;
case 'err':
$icon = (new Icon(Icons::SEVERITY_ERR, ['class' => $class]))->setStyle('fa-regular');
break;
case 'debug':
$icon = new Icon(Icons::SEVERITY_DEBUG);
break;
case 'info':
$icon = new Icon(Icons::SEVERITY_INFO);
break;
case 'alert':
$icon = new Icon(Icons::SEVERITY_ALERT);
break;
case 'emerg':
$icon = new Icon(Icons::SEVERITY_EMERG);
break;
case 'notice':
$icon = new Icon(Icons::SEVERITY_NOTICE);
break;
}

return $icon;
}

switch ($this->type) {
case 'acknowledgement-set':
$icon = new Icon(Icons::ACKNOWLEDGED);
break;
case 'acknowledgement-cleared':
$icon = new Icon(Icons::UNACKNOWLEDGED);
break;
case 'downtime-start':
case 'downtime-end':
case 'downtime-removed':
$icon = new Icon(Icons::DOWNTIME);
break;
case 'flapping-start':
case 'flapping-end':
$icon = new Icon(Icons::FLAPPING);
break;
case 'incident-age':
$icon = new Icon(Icons::INCIDENT_AGE);
break;
case 'custom':
$icon = new Icon(Icons::CUSTOM);
}

return $icon;
}
}
4 changes: 2 additions & 2 deletions library/Notifications/Widget/Detail/EventDetail.php
Original file line number Diff line number Diff line change
Expand Up @@ -109,8 +109,8 @@ protected function createIncident(): ?array
protected function createSource(): array
{
$elements = [];
if ($this->event->type === 'internal') {
// return no source elements for internal events
if ($this->event->type !== 'state') {
// return no source elements for non state events
return $elements;
}

Expand Down
66 changes: 5 additions & 61 deletions library/Notifications/Widget/ItemList/EventListItem.php
Original file line number Diff line number Diff line change
Expand Up @@ -51,50 +51,9 @@ protected function init(): void

protected function assembleVisual(BaseHtmlElement $visual): void
{
$content = null;
$severity = $this->item->severity;
$class = 'severity-' . $severity;

if ($this->item->type === 'internal') {
/*
* TODO(nc): Add proper handling of internal events once
* https://github.com/Icinga/icinga-notifications/issues/162 gets sorted out
*/
$content = new IconBall('square-up-right', 'fa-solid');
} else {
switch ($severity) {
case 'ok':
$content = (new Icon('heart', ['class' => $class]))->setStyle('fa-regular');
break;
case 'crit':
$content = new Icon('circle-exclamation', ['class' => $class]);
break;
case 'warning':
$content = new Icon('exclamation-triangle', ['class' => $class]);
break;
case 'err':
$content = (new Icon('circle-xmark', ['class' => $class]))->setStyle('fa-regular');
break;
case 'debug':
$content = new Icon('bug-slash');
break;
case 'info':
$content = new Icon('info');
break;
case 'alert':
$content = new Icon('bell');
break;
case 'emerg':
$content = new Icon('tower-broadcast');
break;
case 'notice':
$content = new Icon('envelope');
break;
}
}

if ($content) {
$visual->addHtml($content);
$icon = $this->item->getIcon();
if ($icon) {
$visual->addHtml($icon);
}
}

Expand All @@ -117,23 +76,8 @@ protected function assembleTitle(BaseHtmlElement $title): void
$content->addAttributes($name->getAttributes());
$content->addFrom($name);

if ($this->item->severity === null) {
$description = strtolower(trim($this->item->message ?? ''));
if (Str::startsWith($description, 'incident reached age')) {
$msg = t('exceeded time constraint');
} elseif (Str::startsWith($description, 'incident reevaluation')) {
$msg = t('was reevaluated at daemon startup');
} else {
$msg = t('was acknowledged');
}
} elseif ($this->item->severity === 'ok') {
$msg = t('recovered');
} else {
$msg = t('ran into a problem');
}

$title->addHtml($content);
$title->addHtml(Html::tag('span', ['class' => 'state'], $msg));
$title->addHtml(HtmlElement::create('span', ['class' => 'state'], $this->item->getTypeText()));
}

protected function assembleCaption(BaseHtmlElement $caption): void
Expand All @@ -144,7 +88,7 @@ protected function assembleCaption(BaseHtmlElement $caption): void
protected function assembleHeader(BaseHtmlElement $header): void
{
$content = [];
if ($this->item->type !== 'internal') {
if ($this->item->type === 'state') {
/** @var Objects $object */
$object = $this->item->object;
/** @var Source $source */
Expand Down
Loading