Rework behavior of perfdata visualization

Determine perfdata pie color from host or service state, display zero percent piecharts, only render displayabl PieCharts with min and max values, move perfdata to piechart conversion functions into the Perfdata object.

fixes #6423
fixes #6200
fixes #7170
fixes #7304
This commit is contained in:
Matthias Jentsch 2014-12-23 15:45:45 +01:00
parent cda5a6a903
commit c93b13b138
3 changed files with 90 additions and 69 deletions

View File

@ -9,33 +9,36 @@ use Icinga\Module\Monitoring\Plugin\PerfdataSet;
class Zend_View_Helper_Perfdata extends Zend_View_Helper_Abstract
{
public function perfdata($perfdataStr, $compact = false)
/**
* Display the given perfdata string to the user
*
* @param $perfdataStr The perfdata string
* @param bool $compact Whether to display the perfdata in compact mode
* @param $color The color indicating the perfdata state
*
* @return string
*/
public function perfdata($perfdataStr, $compact = false, $color = Perfdata::PERFDATA_GREEN)
{
$pset = PerfdataSet::fromString($perfdataStr)->asArray();
$onlyPieChartData = array_filter($pset, function ($e) { return $e->getPercentage() > 0; });
if ($compact) {
$onlyPieChartData = array_slice($onlyPieChartData, 0, 5);
} else {
$nonPieChartData = array_filter($pset, function ($e) { return $e->getPercentage() == 0; });
}
$pieChartData = PerfdataSet::fromString($perfdataStr)->asArray();
$result = '';
$table = array();
foreach ($onlyPieChartData as $perfdata) {
$pieChart = $this->createInlinePie($perfdata);
if ($compact) {
$result .= $pieChart->render();
} else {
if (! $perfdata->isPercentage()) {
// TODO: Should we trust sprintf-style placeholders in perfdata titles?
$pieChart->setTooltipFormat('{{label}}: {{formatted}} ({{percent}}%)');
foreach ($pieChartData as $perfdata) {
if ($perfdata->isVisualizable()) {
$pieChart = $perfdata->asInlinePie($color);
if ($compact) {
$result .= $pieChart->render();
} else {
$table[] = '<tr><th>' . $pieChart->render()
. htmlspecialchars($perfdata->getLabel())
. '</th><td> '
. htmlspecialchars($this->formatPerfdataValue($perfdata)) .
' </td></tr>';
}
// $pieChart->setStyle('margin: 0.2em 0.5em 0.2em 0.5em;');
$table[] = '<tr><th>' . $pieChart->render()
. htmlspecialchars($perfdata->getLabel())
. '</th><td> '
. htmlspecialchars($this->formatPerfdataValue($perfdata)) .
' </td></tr>';
} else {
$table[] = (string)$perfdata;
}
}
@ -43,32 +46,10 @@ class Zend_View_Helper_Perfdata extends Zend_View_Helper_Abstract
return $result;
} else {
$pieCharts = empty($table) ? '' : '<table class="perfdata">' . implode("\n", $table) . '</table>';
return $pieCharts . "\n" . implode("<br>\n", $nonPieChartData);
return $pieCharts;
}
}
protected function calculatePieChartData(Perfdata $perfdata)
{
$rawValue = $perfdata->getValue();
$minValue = $perfdata->getMinimumValue() !== null ? $perfdata->getMinimumValue() : 0;
$maxValue = $perfdata->getMaximumValue();
$usedValue = ($rawValue - $minValue);
$unusedValue = ($maxValue - $minValue) - $usedValue;
$gray = $unusedValue;
$green = $orange = $red = 0;
// TODO(#6122): Add proper treshold parsing.
if ($perfdata->getCriticalThreshold() && $perfdata->getValue() > $perfdata->getCriticalThreshold()) {
$red = $usedValue;
} elseif ($perfdata->getWarningThreshold() && $perfdata->getValue() > $perfdata->getWarningThreshold()) {
$orange = $usedValue;
} else {
$green = $usedValue;
}
return array($green, $orange, $red, $gray);
}
protected function formatPerfdataValue(Perfdata $perfdata)
{
if ($perfdata->isBytes()) {
@ -82,22 +63,4 @@ class Zend_View_Helper_Perfdata extends Zend_View_Helper_Abstract
return $perfdata->getValue();
}
protected function createInlinePie(Perfdata $perfdata)
{
$pieChart = new InlinePie($this->calculatePieChartData($perfdata),
$perfdata->getLabel() . ' ' . (int)$perfdata->getPercentage() . '%');
$pieChart->setDisableTooltip();
if (Zend_Controller_Front::getInstance()->getRequest()->isXmlHttpRequest()) {
$pieChart->disableNoScript();
}
if ($perfdata->isBytes()) {
$pieChart->setNumberFormat(InlinePie::NUMBER_FORMAT_BYTES);
} else if ($perfdata->isSeconds()) {
$pieChart->setNumberFormat(InlinePie::NUMBER_FORMAT_TIME);
} else {
$pieChart->setNumberFormat(InlinePie::NUMBER_FORMAT_RATIO);
}
return $pieChart;
}
}

View File

@ -5,9 +5,16 @@
namespace Icinga\Module\Monitoring\Plugin;
use InvalidArgumentException;
use Icinga\Exception\ProgrammingError;
use Icinga\Web\Widget\Chart\InlinePie;
use Zend_Controller_Front;
class Perfdata
{
const PERFDATA_GREEN = 'green';
const PERFDATA_ORANGE = 'orange';
const PERFDATA_RED = 'red';
/**
* The performance data value being parsed
*
@ -159,6 +166,16 @@ class Perfdata
return $this->unit === 'c';
}
/**
* Returns whether it is possible to display a visual representation
*
* @return bool True when the perfdata is visualizable
*/
public function isVisualizable()
{
return isset($this->minValue) && isset($this->maxValue) && isset($this->value);
}
/**
* Return this perfomance data's label
*/
@ -316,4 +333,50 @@ class Perfdata
}
}
}
protected function calculatePieChartData( $color)
{
$rawValue = $this->getValue();
$minValue = $this->getMinimumValue() !== null ? $this->getMinimumValue() : 0;
$maxValue = $this->getMaximumValue();
$usedValue = ($rawValue - $minValue);
$unusedValue = ($maxValue - $minValue) - $usedValue;
$gray = $unusedValue;
$green = $orange = $red = 0;
switch ($color) {
case self::PERFDATA_GREEN:
$green = $usedValue;
break;
case self::PERFDATA_RED:
$red = $usedValue;
break;
case self::PERFDATA_ORANGE:
$orange = $usedValue;
break;
}
// TODO(#6122): Add proper treshold parsing.
return array($green, $orange, $red, $gray);
}
public function asInlinePie($color)
{
if (! $this->isVisualizable()) {
throw new ProgrammingError('Cannot calculate piechart data for unvisualizable perfdata entry.');
}
$data = $this->calculatePieChartData($color);
$pieChart = new InlinePie($data, $this->getLabel() . ' ' . number_format($this->getPercentage(), 2) . '%');
$pieChart->setSparklineClass('sparkline-perfdata');
if (Zend_Controller_Front::getInstance()->getRequest()->isXmlHttpRequest()) {
$pieChart->disableNoScript();
}
return $pieChart;
}
}

View File

@ -289,11 +289,6 @@ li li .badge {
.sparkline {
width: 12px;
height: 12px;
}
.inlinepie {
width: 12px;
height: 12px;
position: relative;
top: 10px;
top: 4px;
}