Skip to content

Commit

Permalink
feat(attribute.state): prevent missing state in sensor and metric
Browse files Browse the repository at this point in the history
Introduced `SensorStateInterface` and `MetricStateInterface` to
formalize state handling in sensors and metrics.
Adjusted exception handling to throw `LogicException`
instead of `RuntimeException` for unset states.
Enhanced `CheckCommand` and `AttributeNormalizer` to incorporate
the new interfaces and handle state retrieval more robustly.
  • Loading branch information
Robin Lehrmann committed Aug 29, 2024
1 parent 82d093b commit 5f44547
Show file tree
Hide file tree
Showing 7 changed files with 82 additions and 26 deletions.
35 changes: 22 additions & 13 deletions src/Command/CheckCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
use whatwedo\MonitorBundle\Manager\MonitoringManager;
use whatwedo\MonitorBundle\Monitoring\AttributeInterface;
use whatwedo\MonitorBundle\Monitoring\Metric\AbstractMetric;
use whatwedo\MonitorBundle\Monitoring\Sensor\AbstractSensor;
use whatwedo\MonitorBundle\Util\StatusCodeDecider;
Expand Down Expand Up @@ -43,20 +44,28 @@ private function printResult(SymfonyStyle $io, $result, $previousGroup = null, $
$rows = [];
$subs = [];
foreach ($items as $subGroup => $row) {
if ($row instanceof AbstractSensor) {
$rows[] = [
sprintf('<fg=%s;options=bold>%s</>', $row->getState()->getCliColor(), $row->getState()->getIcon()),
$row->getName(),
$row->getDetails() ? json_encode($row->getDetails(), JSON_THROW_ON_ERROR | JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES) : '',
];
} elseif ($row instanceof AbstractMetric) {
$rows[] = [
sprintf('<fg=%s;options=bold>%s</>', $row->getState()->getCliColor(), $row->getState()->getIcon()),
$row->getName(),
$row->getValue(),
];
} elseif (is_array($row)) {
if (is_array($row)) {
$subs[$subGroup] = $row;

continue;
}

try {
if ($row instanceof AbstractSensor) {
$rows[] = [
sprintf('<fg=%s;options=bold>%s</>', $row->getState()->getCliColor(), $row->getState()->getIcon()),
$row->getName(),
$row->getDetails() ? json_encode($row->getDetails(), JSON_THROW_ON_ERROR | JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES) : '',
];
} elseif ($row instanceof AbstractMetric) {
$rows[] = [
sprintf('<fg=%s;options=bold>%s</>', $row->getState()->getCliColor(), $row->getState()->getIcon()),
$row->getName(),
$row->getValue(),
];
}
} catch (\LogicException) {
continue;
}
}

Expand Down
28 changes: 21 additions & 7 deletions src/Manager/MonitoringManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@
use whatwedo\MonitorBundle\Enums\MetricStateEnum;
use whatwedo\MonitorBundle\Enums\SensorStateEnum;
use whatwedo\MonitorBundle\Monitoring\AttributeInterface;
use whatwedo\MonitorBundle\Monitoring\Metric\MetricStateInterface;
use whatwedo\MonitorBundle\Monitoring\Sensor\AbstractSensor;
use whatwedo\MonitorBundle\Monitoring\Sensor\SensorStateInterface;

class MonitoringManager
{
Expand Down Expand Up @@ -106,15 +108,27 @@ public function getAttribute(string $className): AttributeInterface

private function wasSuccessful(AttributeInterface $attribute): bool
{
return $attribute instanceof AbstractSensor
? $attribute->getState() === SensorStateEnum::SUCCESSFUL
: $attribute->getState() === MetricStateEnum::OK;
if ($attribute instanceof SensorStateInterface) {
return $attribute->getState() === SensorStateEnum::SUCCESSFUL;
}

if ($attribute instanceof MetricStateInterface) {
return $attribute->getState() === MetricStateEnum::OK;
}

return false;
}

private function wasWarning(AttributeInterface $abstract): bool
private function wasWarning(AttributeInterface $attribute): bool
{
return $abstract instanceof AbstractSensor
? $abstract->getState() === SensorStateEnum::WARNING
: $abstract->getState() === MetricStateEnum::WARNING;
if ($attribute instanceof SensorStateInterface) {
return $attribute->getState() === SensorStateEnum::WARNING;
}

if ($attribute instanceof MetricStateInterface) {
return $attribute->getState() === MetricStateEnum::WARNING;
}

return false;
}
}
4 changes: 2 additions & 2 deletions src/Monitoring/Metric/AbstractMetric.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
use whatwedo\MonitorBundle\Enums\MetricStateEnum;
use whatwedo\MonitorBundle\Monitoring\AttributeInterface;

abstract class AbstractMetric implements AttributeInterface
abstract class AbstractMetric implements AttributeInterface, MetricStateInterface
{
public null|int|float $value = null;

Expand All @@ -16,7 +16,7 @@ abstract class AbstractMetric implements AttributeInterface
public function getState(): MetricStateEnum
{
if ($this->state === null) {
throw new \RuntimeException(static::class.'::$state is not set.');
throw new \LogicException(static::class.'::$state is not set.');
}

return $this->state;
Expand Down
13 changes: 13 additions & 0 deletions src/Monitoring/Metric/MetricStateInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php

declare(strict_types=1);

namespace whatwedo\MonitorBundle\Monitoring\Metric;

use whatwedo\MonitorBundle\Enums\MetricStateEnum;

interface MetricStateInterface
{
/** @throws \LogicException */
public function getState(): MetricStateEnum;
}
4 changes: 2 additions & 2 deletions src/Monitoring/Sensor/AbstractSensor.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
use whatwedo\MonitorBundle\Enums\SensorStateEnum;
use whatwedo\MonitorBundle\Monitoring\AttributeInterface;

abstract class AbstractSensor implements AttributeInterface
abstract class AbstractSensor implements AttributeInterface, SensorStateInterface
{
public ?SensorStateEnum $state = null;

Expand All @@ -16,7 +16,7 @@ abstract class AbstractSensor implements AttributeInterface
public function getState(): SensorStateEnum
{
if ($this->state === null) {
throw new \RuntimeException(__CLASS__.'::$state is not set.');
throw new \LogicException(static::class.'::$state is not set.');
}

return $this->state;
Expand Down
13 changes: 13 additions & 0 deletions src/Monitoring/Sensor/SensorStateInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php

declare(strict_types=1);

namespace whatwedo\MonitorBundle\Monitoring\Sensor;

use whatwedo\MonitorBundle\Enums\SensorStateEnum;

interface SensorStateInterface
{
/** @throws \LogicException */
public function getState(): SensorStateEnum;
}
11 changes: 9 additions & 2 deletions src/Normalizer/AttributeNormalizer.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
use whatwedo\MonitorBundle\Monitoring\AttributeInterface;
use whatwedo\MonitorBundle\Monitoring\Metric\AbstractMetric;
use whatwedo\MonitorBundle\Monitoring\Metric\MetricStateInterface;
use whatwedo\MonitorBundle\Monitoring\Sensor\AbstractSensor;
use whatwedo\MonitorBundle\Monitoring\Sensor\SensorStateInterface;

class AttributeNormalizer implements NormalizerInterface
{
Expand All @@ -20,13 +22,18 @@ public function normalize($object, string $format = null, array $context = []):
'name' => $object->getName(),
];

try {
if ($object instanceof MetricStateInterface || $object instanceof SensorStateInterface) {
$data['state'] = $object->getState();
}
} catch (\LogicException) {
}

if ($object instanceof AbstractSensor) {
$data['state'] = $object->getState();
$data['details'] = $object->getDetails();
}

if ($object instanceof AbstractMetric) {
$data['state'] = $object->getState();
$data['value'] = $object->getValue();
}

Expand Down

0 comments on commit 5f44547

Please sign in to comment.