Source of file api.switchsonic.php
Size: 15,447 Bytes - Last Modified: 2024-04-27T15:26:05+03:00
/tmp/current_snapshot/api/libs/api.switchsonic.php
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507 | <?php /** * Live switch/routers SNMP bandwidth monitoring implementation */ class SwitchSonic { /** * Contains remote device IP address * * @var string */ protected $ip = ''; /** * Contains remote device SNMP read community * * @var string */ protected $community = ''; /** * SNMP helper object placeholder * * @var object */ protected $snmp = ''; /** * Caching engine object placeholder * * @var object */ protected $cache = ''; /** * Default caching timeout to store switch/auth data in seconds * * @var int */ protected $cachingTimeout = 120; /** * Time window to display on charts in seconds * * @var int */ protected $timeWindow = 300; /** * Contains default kilo-multiplier to convert bits in Kilo * * @var int */ protected $offsetKilo = 1024; /** * Contains default kilo-multiplier to convert bits in Mega * * @var int */ protected $offsetMega = 1024000; /** * Contains default kilo-multiplier to convert bits in Giga * * @var int */ protected $offsetGiga = 1024000000; //some predefined stuff const CACHE_KEY = 'SWITCHSONICDATA'; const AUTH_KEY = 'SWITCHSONICAUTH'; const OID_CHECK = '.1.3.6.1.2.1.1.1.0'; const OID_IFINDEX = '.1.3.6.1.2.1.2.2.1.1'; const OID_IFDESCR = '.1.3.6.1.2.1.31.1.1.1.18'; const OID_OCTIN = '.1.3.6.1.2.1.31.1.1.1.6'; const OID_OCTOUT = '.1.3.6.1.2.1.31.1.1.1.10'; const OID_STATE = '.1.3.6.1.2.1.2.2.1.8'; /** * Cretes new Sonic instance * * @param string $ip * @param string $community */ public function __construct($ip, $community) { $this->setOptions($ip, $community); $this->initCache(); $this->initSnmp(); // ___------__ // |\__-- /\ _- // |/ __ - // //\ / \ /__ // | o| 0|__ --_ // \\____-- __ \ ___- // (@@ __/ / /_ // -_____--- --_ // // \ \\ ___- // //|\__/ \\ \ // \_-\_____/ \-\ // // \\--\| // ____// ||_ // /_____\ /___\ } /** * Sets IP/community to current instance * * @param string $ip * @param string $community * * @return void */ protected function setOptions($ip, $community) { if (!empty($ip)) { if (filter_var($ip, FILTER_VALIDATE_IP)) { if (!empty($community)) { $this->ip = $ip; $this->community = $community; } else { throw new Exception('EX_EMPTY_SNMPCOMMUNITY'); } } else { throw new Exception('EX_WRONG_IP'); } } else { throw new Exception('EX_EMPTY_IP'); } } /** * Inits system caching engine * * @return void */ protected function initCache() { $this->cache = new UbillingCache(); } /** * Inits SNMP helper instance for further usage * * @return void */ protected function initSnmp() { $this->snmp = new SNMPHelper(); $this->snmp->setMode('system'); } /** * Returns array of available interfaces on device as port=>iface * * @return array */ protected function getIfaces() { return($this->receiveOidData(self::OID_IFINDEX)); } /** * Returns available ports description as port=>desc * * @return array */ protected function getIfDescr() { return($this->receiveOidData(self::OID_IFDESCR)); } /** * Returns array of interfaces octets in as port=>octets * * @return array */ protected function getOctIn() { return($this->receiveOidData(self::OID_OCTIN)); } /** * Returns array of interfaces octets out as port=>octets * * @return array */ protected function getOctOut() { return($this->receiveOidData(self::OID_OCTOUT)); } /** * Returns array of interface activity states as port=>state up/down * * @return array */ protected function getLinks() { return($this->receiveOidData(self::OID_STATE)); } /** * Checks can we auth on device and receive some data or not? * * @return bool */ public function checkAuth() { $result = false; $rawCache = $this->cache->get(self::AUTH_KEY, $this->cachingTimeout); if (empty($rawCache)) { $rawCache = array(); } if (isset($rawCache[$this->ip])) { $result = true; } else { $checkResult = $this->snmp->walk($this->ip, $this->community, self::OID_CHECK, false); if (!empty($checkResult)) { $rawCache[$this->ip] = 1; $this->cache->set(self::AUTH_KEY, $rawCache, $this->cachingTimeout); $result = true; } } return($result); } /** * Returns port/interface ID extracted from left part of OID * * @param string $rawSnmpData * @param string $oid * * @return string */ protected function extractPortNum($rawSnmpData, $oid) { $result = ''; $removeMask = $oid . '.'; if (!empty($rawSnmpData)) { $result = explode('=', $rawSnmpData); $result = trim($result[0]); $result = str_replace($removeMask, '', $result); } return($result); } /** * Returns preprocessed data extracted from OID as port=>value * * @param string $oid * * @return array */ protected function receiveOidData($oid) { $result = array(); $raw = $this->snmp->walk($this->ip, $this->community, $oid, false); if (!empty($raw)) { $raw = explodeRows($raw); if (!empty($raw)) { foreach ($raw as $io => $each) { if (!empty($each)) { $portNum = $this->extractPortNum($each, $oid); if (!empty($portNum)) { $result[$portNum] = zb_SanitizeSNMPValue($each); } } } } } return($result); } /** * Rturns array of preprocessed device stats * * @return array */ public function getStats() { $devStats = array(); $cachedStats = $this->cache->get(self::CACHE_KEY, $this->cachingTimeout); if (empty($cachedStats)) { $cachedStats = array(); } //initial filling if (!isset($cachedStats[$this->ip])) { $devIfindex = $this->getIfaces(); //interfaces index received? if (!empty($devIfindex)) { $devPortDesc = $this->getIfDescr(); $devInOcts = $this->getOctIn(); $devOutOcts = $this->getOctOut(); $devLinks = $this->getLinks(); $pollTime = time(); $devStats['lasttime'] = $pollTime; $devStats['ifaces'] = $devIfindex; $devStats['portdescr'] = $devPortDesc; $devStats['previn'] = $devInOcts; $devStats['prevout'] = $devOutOcts; $devStats['links'] = $devLinks; foreach ($devOutOcts as $eachOutPort => $eachOutOct) { $devStats['speedin'][$eachOutPort] = 0; $devStats['speedout'][$eachOutPort] = 0; } $devStats['speedline'] = array(); } } else { $devTmp = $cachedStats[$this->ip]; $newOctIn = $this->getOctIn(); $newOctOut = $this->getOctOut(); $newLinks = $this->getLinks(); $pollTime = time(); $timePast = $pollTime - $devTmp['lasttime']; $timePast = ($timePast != 0) ? $timePast : 1; //prevent div by zero foreach ($newOctIn as $io => $eachIn) { $speedIn = ($eachIn - $devTmp['previn'][$io]) / $timePast; $rawSpeed = round($speedIn); $devTmp['speedin'][$io] = $rawSpeed; $devTmp['speedline'][$io]['in'][$pollTime] = $rawSpeed; } foreach ($newOctOut as $io => $eachOut) { $speedOut = ($eachOut - $devTmp['prevout'][$io]) / $timePast; $rawSpeed = round($speedOut); $devTmp['speedout'][$io] = $rawSpeed; $devTmp['speedline'][$io]['out'][$pollTime] = $rawSpeed; } $devStats['lasttime'] = $pollTime; $devStats['ifaces'] = $devTmp['ifaces']; $devStats['portdescr'] = $devTmp['portdescr']; $devStats['previn'] = $newOctIn; $devStats['prevout'] = $newOctOut; $devStats['speedin'] = $devTmp['speedin']; $devStats['speedout'] = $devTmp['speedout']; $devStats['links'] = $newLinks; $devStats['speedline'] = $devTmp['speedline']; } //cache update $cachedStats[$this->ip] = $devStats; $this->cache->set(self::CACHE_KEY, $cachedStats, $this->cachingTimeout); return($devStats); } /** * Converts actual octet counters into human-readable speed value * * @param int $octets * * @return string */ protected function convertSpeed($octets) { $result = ''; $bits = $octets * 8; $result = $bits; if ($bits > $this->offsetKilo) { $result = round($bits / $this->offsetKilo) . ' ' . __('Kbit/s'); } if ($bits > $this->offsetMega) { $result = round($bits / $this->offsetMega, 1) . ' ' . __('Mbit/s'); } if ($bits > $this->offsetGiga) { $result = round($bits / $this->offsetGiga, 1) . ' ' . __('Gbit/s'); } return($result); } /** * Converts octet speed values into Mbit/s * * @param int $octetSpeed * * @return float */ protected function speedForCharts($octetSpeed) { $result = 0; $bits = $octetSpeed * 8; $result = $bits / $this->offsetMega; $result = round($result, 1); return($result); } /** * Converts basic port infor into link state led * * @param string $linkState * @param int $speedIn * @param int $speedOut * * @return string */ protected function convertLinkState($linkState, $speedIn = 0, $speedOut = 0) { $result = ''; $result = (ispos($linkState, 'up')) ? web_green_led() : web_red_led(); if (ispos($linkState, 'up')) { //ok, interface is up if ($speedIn OR $speedOut) { $result = web_green_led('Active'); } else { $result = web_yellow_led('Link up'); } } else { //port is offline at all $result = web_red_led('Offline'); } return($result); } /** * Renders device stats * * @return string */ public function renderSpeeds() { $result = ''; $devStats = $this->getStats(); if (!empty($devStats)) { $ifaces = $devStats['ifaces']; $ifdescr = $devStats['portdescr']; $prevOut = $devStats['prevout']; $cells = wf_tableCell(__('Interface'), '5%'); $cells .= wf_tableCell(__('Status'), '5%'); $cells .= wf_tableCell(__('Description')); $cells .= wf_tableCell(__('Speed') . ' ' . __('TX')); $cells .= wf_tableCell(__('Speed') . ' ' . __('RX')); $cells .= wf_tableCell(__('Bytes TX')); $cells .= wf_tableCell(__('Bytes RX')); $rows = wf_tableRow($cells, 'row1'); foreach ($prevOut as $portNum => $eachPrevOut) { $speedIn = $devStats['speedin'][$portNum]; $speedOut = $devStats['speedout'][$portNum]; $cells = wf_tableCell($ifaces[$portNum]); $cells .= wf_tableCell($this->convertLinkState($devStats['links'][$portNum], $speedIn, $speedOut)); $descrLabel = (isset($ifdescr[$portNum])) ? $ifdescr[$portNum] : ''; $cells .= wf_tableCell($descrLabel); $cells .= wf_tableCell($this->convertSpeed($speedIn)); $cells .= wf_tableCell($this->convertSpeed($speedOut)); $cells .= wf_tableCell(stg_convert_size($devStats['previn'][$portNum])); $cells .= wf_tableCell(stg_convert_size($devStats['prevout'][$portNum])); $rows .= wf_tableRow($cells, 'row5'); } $result .= wf_tableBody($rows, '100%'); } else { $messages = new UbillingMessageHelper(); $result .= $messages->getStyledMessage(__('Nothing to show'), 'warning'); } return($result); } /** * Renders charts based on speedline of some ports * * @return string */ public function renderCharts() { $result = ''; $devStats = $this->getStats(); if (!empty($devStats)) { $ifaces = $devStats['ifaces']; $ifdescr = $devStats['portdescr']; $prevOut = $devStats['prevout']; $speedLine = $devStats['speedline']; $options = ''; if (!empty($speedLine)) { foreach ($speedLine as $portNum => $speedData) { $csvData = ''; $portLabel = __('Interface') . ' ' . $portNum; if (isset($ifdescr[$portNum])) { $portDescr = $ifdescr[$portNum]; if (!empty($portDescr)) { $portLabel .= ' - ' . $portDescr; } foreach ($speedData['in'] as $timeIn => $speedIn) { $timeLabel = date("Y-m-d H:i:s", $timeIn); $speedOut = $speedData['out'][$timeIn]; if ($speedIn OR $speedOut) { $curTime = time(); if (($timeIn) > ($curTime - $this->timeWindow)) { $inLabel = $this->speedForCharts($speedIn); $outLabel = $this->speedForCharts($speedOut); $csvData .= $timeLabel . ',' . $inLabel . ',' . $outLabel . PHP_EOL; } } } } if (!empty($csvData)) { $result .= wf_Graph($csvData, '100%', '200px;', false, $portLabel, __('Time'), __('Mbit/s'), false); } } } else { $messages = new UbillingMessageHelper(); $result .= $messages->getStyledMessage(__('Nothing to show') . '. ' . __('Collecting data') . '...', 'warning'); } } return($result); } } |