Skip to content

Commit

Permalink
Do not evaluate invalid performance data
Browse files Browse the repository at this point in the history
  • Loading branch information
raviks789 committed Aug 30, 2023
1 parent 423c9a8 commit d6e397d
Show file tree
Hide file tree
Showing 4 changed files with 108 additions and 4 deletions.
60 changes: 57 additions & 3 deletions library/Icingadb/Util/PerfData.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

namespace Icinga\Module\Icingadb\Util;

use Exception;
use Icinga\Module\Icingadb\Common\ServiceStates;
use Icinga\Web\Widget\Chart\InlinePie;
use InvalidArgumentException;
Expand Down Expand Up @@ -71,6 +72,13 @@ class PerfData
*/
protected $criticalThreshold;

/**
* Whether the performance data is invalid
*
* @var bool
*/
protected $isValid;

/**
* Create a new PerfData object based on the given performance data label and value
*
Expand Down Expand Up @@ -312,7 +320,7 @@ public function isCounter(): bool
*/
public function isVisualizable(): bool
{
return isset($this->minValue) && isset($this->maxValue) && isset($this->value);
return isset($this->minValue, $this->maxValue, $this->value) && $this->isValid();
}

/**
Expand Down Expand Up @@ -416,6 +424,25 @@ public function __toString()
return $this->formatLabel();
}

/**
* Checks if the performance data can be evaluated
*/
protected function validate()
{
if (! $this->warningThreshold->isValid() || ! $this->criticalThreshold->isValid()) {
$this->isValid = false;
} else {
switch (true) {
case $this->minValue !== null && ! is_numeric($this->minValue):
case $this->maxValue !== null && ! is_numeric($this->maxValue):
$this->isValid = false;
break;
default:
$this->isValid = true;
}
}
}

/**
* Parse the current performance data value
*
Expand Down Expand Up @@ -450,10 +477,19 @@ protected function parse()
}
/* @noinspection PhpMissingBreakStatementInspection */
case 3:
$this->criticalThreshold = ThresholdRange::fromString(trim($parts[2]));
try {
$this->criticalThreshold = ThresholdRange::fromString(trim($parts[2]));
} catch (Exception $e) {
$this->criticalThreshold = trim($parts[2]);
}

// Fallthrough
case 2:
$this->warningThreshold = ThresholdRange::fromString(trim($parts[1]));
try {
$this->warningThreshold = ThresholdRange::fromString(trim($parts[1]));
} catch (Exception $e) {
$this->warningThreshold = trim($parts[1]);
}
}

if ($this->warningThreshold === null) {
Expand Down Expand Up @@ -509,6 +545,10 @@ protected function format($value)
}

if ($value instanceof ThresholdRange) {
if (! $value->isValid()) {
return $value;
}

if ($value->getMin()) {
return (string) $value;
}
Expand Down Expand Up @@ -643,4 +683,18 @@ public function worseThan(PerfData $rhs): bool

return false;
}

/**
* Returns whether the performance data could be evaluated
*
* @return bool
*/
public function isValid(): bool
{
if ($this->isValid === null) {
$this->validate();
}

return $this->isValid;
}
}
27 changes: 27 additions & 0 deletions library/Icingadb/Util/ThresholdRange.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

namespace Icinga\Module\Icingadb\Util;

use Exception;

/**
* The warning/critical threshold of a measured value
*/
Expand Down Expand Up @@ -37,12 +39,21 @@ class ThresholdRange
*/
protected $raw;

/**
* Whether the threshold range is valid
*
* @var bool
*/
protected $isValid = true;

/**
* Create a new instance based on a threshold range conforming to <https://nagios-plugins.org/doc/guidelines.html>
*
* @param string $rawRange
*
* @return ThresholdRange
*
* @throws Exception
*/
public static function fromString(string $rawRange): self
{
Expand All @@ -61,6 +72,12 @@ public static function fromString(string $rawRange): self

if (strpos($rawRange, ':') === false) {
$min = 0.0;
$max = trim($rawRange);
if (! is_numeric($max)) {
$range->isValid = false;
return $range;
}

$max = floatval(trim($rawRange));
} else {
list($min, $max) = explode(':', $rawRange, 2);
Expand All @@ -75,6 +92,11 @@ public static function fromString(string $rawRange): self
$min = null;
break;
default:
if (! is_numeric($min)) {
$range->isValid = false;
return $range;
}

$min = floatval($min);
}

Expand Down Expand Up @@ -168,6 +190,11 @@ public function contains(float $value): bool
));
}

public function isValid()
{
return $this->isValid;
}

/**
* Return the textual representation of $this, suitable for fromString()
*
Expand Down
20 changes: 19 additions & 1 deletion library/Icingadb/Widget/Detail/PerfDataTable.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,18 @@
use Icinga\Module\Icingadb\Util\PerfDataSet;
use Icinga\Module\Icingadb\Widget\EmptyState;
use ipl\Html\Attributes;
use ipl\Html\HtmlDocument;
use ipl\Html\HtmlElement;
use ipl\Html\HtmlString;
use ipl\Html\Table;
use ipl\Html\Text;
use ipl\I18n\Translation;
use ipl\Web\Widget\Icon;

class PerfDataTable extends Table
{
use Translation;

/** @var bool Whether the table contains a sparkline column */
protected $containsSparkline = false;

Expand Down Expand Up @@ -64,7 +69,7 @@ public function assemble()
]
);
foreach ($pieChartData as $perfdata) {
if ($perfdata->isVisualizable()) {
if ($perfdata->isVisualizable() || ! $perfdata->isValid()) {
$columns[''] = '';
$this->containsSparkline = true;
}
Expand Down Expand Up @@ -108,6 +113,19 @@ public function assemble()
HtmlString::create($perfdata->asInlinePie($this->color)->render()),
[ 'class' => 'sparkline-col']
);
} elseif (! $perfdata->isValid()) {
$cols[] = Table::td(
new Icon(
'triangle-exclamation',
[
'title' => $this->translate(
'Evaluation failed. Performance data is invalid.'
),
'class' => ['invalid-perfdata']
]
),
[ 'class' => 'sparkline-col']
);
} else {
$cols[] = Table::td('');
}
Expand Down
5 changes: 5 additions & 0 deletions public/css/widget/performance-data-table.less
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,11 @@
min-width: 1.75em;
width: 1.75em;
padding: 2/12em 0;
.invalid-perfdata {
font-size: 1.25em;
vertical-align: text-bottom;
color: @color-warning;
}
}

.inline-pie > svg {
Expand Down

0 comments on commit d6e397d

Please sign in to comment.