. * * @package LibreNMS * @link http://librenms.org * @copyright 2017 Tony Murray * @author Tony Murray */ namespace LibreNMS\RRD; use LibreNMS\Config; use LibreNMS\Exceptions\InvalidRrdTypeException; class RrdDefinition { private static $types = ['GAUGE', 'DERIVE', 'COUNTER', 'ABSOLUTE', 'DCOUNTER', 'DDERIVE']; private $dataSets = []; private $skipNameCheck = false; /** * Make a new empty RrdDefinition */ public static function make() { return new self(); } /** * Add a dataset to this definition. * See https://oss.oetiker.ch/rrdtool/doc/rrdcreate.en.html for more information. * * @param string $name Textual name for this dataset. Must be [a-zA-Z0-9_], max length 19. * @param string $type GAUGE | COUNTER | DERIVE | DCOUNTER | DDERIVE | ABSOLUTE. * @param int $min Minimum allowed value. null means undefined. * @param int $max Maximum allowed value. null means undefined. * @param int $heartbeat Heartbeat for this dataset. Uses the global setting if null. * @return RrdDefinition */ public function addDataset($name, $type, $min = null, $max = null, $heartbeat = null) { if (empty($name)) { d_echo("DS must be set to a non-empty string."); } $name = $this->escapeName($name); $this->dataSets[$name] = [ $name, $this->checkType($type), is_null($heartbeat) ? Config::get('rrd.heartbeat') : $heartbeat, is_null($min) ? 'U' : $min, is_null($max) ? 'U' : $max, ]; return $this; } /** * Get the RRD Definition as it would be passed to rrdtool * * @return string */ public function __toString() { return array_reduce($this->dataSets, function ($carry, $ds) { return $carry . 'DS:' . implode(':', $ds) . ' '; }, ''); } /** * Check if the give dataset name is valid for this definition * * @param $name * @return bool */ public function isValidDataset($name) { return $this->skipNameCheck || isset($this->dataSets[$this->escapeName($name)]); } public function disableNameChecking() { $this->skipNameCheck = true; } /** * Check that the data set type is valid. * * @param string $type * @return mixed * @throws InvalidRrdTypeException */ private function checkType($type) { if (!in_array($type, self::$types)) { $msg = "$type is not valid, must be: " . implode(' | ', self::$types); throw new InvalidRrdTypeException($msg); } return $type; } /** * Remove all invalid characters from the name and truncate to 19 characters. * * @param string $name * @return string */ private function escapeName($name) { $name = preg_replace('/[^a-zA-Z0-9_\-]/', '', $name); return substr($name, 0, 19); } }