icingaweb2/modules/monitoring/library/Monitoring/Plugin/Perfdata.php

223 lines
5.6 KiB
PHP

<?php
namespace Icinga\Module\Monitoring\Plugin;
class Perfdata
{
const COUNTER = 0x01;
const PERCENT = 0x02;
const BYTES = 0x04;
const SECONDS = 0x08;
protected $byte_map;
protected $min;
protected $max;
protected $warn;
protected $crit;
protected $val;
protected $unit;
public function getFormattedValue()
{
switch ($this->unit) {
case self::BYTES:
return $this->formatBytes() . ' von ' . $this->formatBytes($this->max);
break;
case self::SECONDS:
return $this->formatSeconds();
break;
case self::PERCENT:
return number_format($this->val, 2, ',', '.') . '%';
break;
default:
return $this->val;
}
}
public function hasMax()
{
return $this->max !== null && $this->max > 0;
}
public function getPercentage()
{
if ($this->unit === self::PERCENT) {
return $this->val;
}
if ($this->hasMax()) {
return $this->val / $this->max * 100;
}
return false;
}
public function getValue()
{
return $this->val;
}
protected function formatBytes($val = null)
{
$steps = array(
1 => 'Byte',
1024 => 'KByte',
1024 * 1024 => 'MByte',
1024 * 1024 * 1024 => 'GByte',
1024 * 1024 * 1024 * 1024 => 'TByte'
);
return $this->formatSpecial($steps, 1, $val);
}
protected function formatSeconds()
{
$steps = array(
1 => 'us',
1000 => 'ms',
10000000 => 's',
);
return $this->formatSpecial($steps, 1000000, $this->val);
}
protected function formatSpecial($steps, $multi = 1, $val = null)
{
if ($val === null) {
$val = abs($this->val);
} else {
$val = abs($val);
}
// TODO: Check this, prefix fails if $val is given
if ($this->val < 0) {
$prefix = '-';
} else {
$prefix = '';
}
$val *= $multi;
$step = 1;
foreach (array_keys($steps) as $key) {
if ($key > $val * 1) {
break;
}
$step = $key;
}
return $prefix
. number_format($val / $step, 1, ',', '.')
. ' '
. $steps[$step];
}
protected function __construct(& $perfdata)
{
$this->byte_map = array(
'b' => 1,
'kb' => 1024,
'mb' => 1024 * 1024,
'gb' => 1024 * 1024 * 1024,
'tb' => 1024 * 1024 * 1024 * 1024
);
// UGLY, fixes floats using comma:
$perfdata = preg_replace('~\,~', '.', $perfdata);
$parts = preg_split('~;~', $perfdata, 5);
while (count($parts) < 5) {
$parts[] = null;
}
list(
$this->val,
$this->warn,
$this->crit,
$this->min,
$this->max
) = $parts;
// TODO: check numbers!
$unit = null;
if (! preg_match('~^(\-?[\d+\.]+(?:E\-?\d+)?)([^\d]+)?$~', $this->val, $m)) {
return $perfdata;
// Numbers with an exponential base will be rendered invalid using the regex above
// throw new \Exception('Got invalid perfdata: ' . $perfdata);
}
$this->val = $m[1];
if (isset($m[2])) {
$unit = strtolower($m[2]);
}
if ($unit === 'c') {
$this->unit = self::COUNTER;
}
if ($unit === '%') {
if (! is_numeric($this->min)) {
$this->min = 0;
}
if (! is_numeric($this->max)) {
$this->max = 100;
}
$this->unit = self::PERCENT;
} else {
if (! is_numeric($this->max) && $this->crit > 0) {
$this->max = $this->crit;
}
}
if (array_key_exists($unit, $this->byte_map)) {
$this->unit = self::BYTES;
$this->val = $this->val * $this->byte_map[$unit];
$this->min = $this->min * $this->byte_map[$unit];
$this->max = $this->max * $this->byte_map[$unit];
}
if ($unit === 's') {
$this->unit = self::SECONDS;
}
if ($unit === 'ms') {
$this->unit = self::SECONDS;
$this->val = $this->val / 1000;
}
if ($unit === '%') {
if (! is_numeric($this->min)) {
$this->min = 0;
}
if (! is_numeric($this->max)) {
$this->max = 100;
}
} else {
if (! is_numeric($this->max) && $this->crit > 0) {
$this->max = $this->crit;
}
}
}
public function isCounter()
{
return $this->unit === self::COUNTER;
}
public static function fromString(& $perfdata)
{
$pdat = new Perfdata($perfdata);
return $pdat;
}
protected function normalizeNumber($num)
{
return $num;
// Bullshit, still TODO
/*
$dot = strpos($num, '.');
$comma = strpos($num, ',');
if ($dot === false) {
// No dot...
if ($comma === false) {
// ...and no comma, it's an integer:
return (int) $num;
} else {
// just a comma
}
} else {
if ($comma === false) {
}
*/
}
}