. * * @package LibreNMS * @link https://www.librenms.org * @copyright 2020 Tony Murray * @author Tony Murray */ namespace LibreNMS\OS\Traits; use App\Models\Mempool; use Illuminate\Support\Collection; use LibreNMS\Device\YamlDiscovery; use LibreNMS\Util\Oid; trait YamlMempoolsDiscovery { private $mempoolsData = []; private $mempoolsOids = []; private $mempoolsFields = [ 'total', 'free', 'used', 'percent_used', ]; private $mempoolsPrefetch = []; public function discoverYamlMempools() { $mempools = new Collection(); $mempools_yaml = $this->getDiscovery('mempools'); foreach ($mempools_yaml['pre-cache']['oids'] ?? [] as $oid) { $options = $mempools_yaml['pre-cache']['snmp_flags'] ?? '-OQUb'; $this->mempoolsPrefetch = snmpwalk_cache_oid($this->getDeviceArray(), $oid, $this->mempoolsPrefetch, null, null, $options); } foreach ($mempools_yaml['data'] as $yaml) { $this->fetchData($yaml, $this->getDiscovery()['mib'] ?? 'ALL'); $snmp_data = array_replace_recursive($this->mempoolsPrefetch, $this->mempoolsData); $count = 1; foreach ($this->mempoolsData as $index => $data) { if (YamlDiscovery::canSkipItem(null, $index, $yaml, [], $data)) { echo 's'; continue; } $used = $this->getData('used', $index, $yaml); $total = $this->getData('total', $index, $yaml); $mempool = (new Mempool([ 'mempool_index' => isset($yaml['index']) ? YamlDiscovery::replaceValues('index', $index, $count, $yaml, $snmp_data) : $index, 'mempool_type' => $yaml['type'] ?? $this->getName(), 'mempool_class' => $yaml['class'] ?? 'system', 'mempool_precision' => $yaml['precision'] ?? 1, 'mempool_descr' => isset($yaml['descr']) ? ucwords(YamlDiscovery::replaceValues('descr', $index, $count, $yaml, $snmp_data)) : 'Memory', 'mempool_used_oid' => $this->getOid('used', $index, $yaml), 'mempool_free_oid' => ($used === null || $total === null) ? $this->getOid('free', $index, $yaml) : null, // only use "free" if we have both used and total 'mempool_perc_oid' => $this->getOid('percent_used', $index, $yaml), 'mempool_perc_warn' => isset($yaml['warn_percent']) ? YamlDiscovery::replaceValues('warn_percent', $index, $count, $yaml, $snmp_data) : 90, ]))->fillUsage( $used, $total, $this->getData('free', $index, $yaml), $this->getData('percent_used', $index, $yaml) ); if ($mempool->mempool_total) { $mempools->push($mempool); $count++; } } } return $mempools; } private function getData($field, $index, $yaml) { $data = $yaml[$field] ?? null; if (isset($this->mempoolsData[$index][$data])) { return $this->mempoolsData[$index][$data]; } if (isset($this->mempoolsPrefetch[$index][$data])) { return $this->mempoolsPrefetch[$index][$data]; } return is_numeric($data) ? $data : null; // hard coded number } private function getOid($field, $index, $yaml) { if (Oid::isNumeric($yaml[$field] ?? '')) { return $yaml[$field]; } if (isset($this->mempoolsOids[$field])) { return Oid::toNumeric("{$this->mempoolsOids[$field]}.$index"); } return null; } /** * @param array $yaml item yaml definition * @param string $mib * * @throws \LibreNMS\Exceptions\InvalidOidException */ private function fetchData($yaml, $mib) { $this->mempoolsOids = []; $this->mempoolsData = []; // clear data from previous mempools $options = $yaml['snmp_flags'] ?? '-OQUb'; if (isset($yaml['oid'])) { $this->mempoolsData = snmpwalk_cache_oid($this->getDeviceArray(), $yaml['oid'], $this->mempoolsData, null, null, $options); } foreach ($this->mempoolsFields as $field) { if (isset($yaml[$field]) && ! is_numeric($yaml[$field])) { // allow for hard-coded values $oid = $yaml[$field]; if (Oid::isNumeric($oid)) { // if numeric oid, it is not a table, just fetch it $this->mempoolsData[0][$oid] = snmp_get($this->getDeviceArray(), $oid, '-Oqv'); continue; } if (empty($yaml['oid'])) { // if table given, skip individual oids $this->mempoolsData = snmpwalk_cache_oid($this->getDeviceArray(), $oid, $this->mempoolsData, null, null, $options); } $this->mempoolsOids[$field] = Oid::toNumeric($oid, $mib); } } } }