setName('cmts:cm:stats') ->setDescription('Obtener estadísticas de un CM') ->setHelp('Se requieren parámetros para poder realizar la correcta consulta. El comando requiere Redis.') ->setDefinition(array( new InputOption('cmts-device-id', null, InputOption::VALUE_OPTIONAL, "DeviceId del CMTS",1), new InputOption('cmts-server-id', null, InputOption::VALUE_OPTIONAL, "ServerDevice del CMTS",1), new InputOption('cm-ip', false, InputOption::VALUE_OPTIONAL, "IP del CM"), new InputOption('cm-mac', false, InputOption::VALUE_OPTIONAL, "MAC del CM"), new InputOption('cm', null, InputOption::VALUE_OPTIONAL|InputOption::VALUE_IS_ARRAY, "List of CM: --cm=ip1,mac1 --cm=ip2,mac2"), new InputOption('cm-community', false, InputOption::VALUE_OPTIONAL, "Community del CMTS",'public'), new InputOption('cm-snmp-library', false, InputOption::VALUE_OPTIONAL, "Versión de librería SNMP",'OIDSBase'), new InputOption('save-historic', null, InputOption::VALUE_OPTIONAL, "Send data to StatsD",1) )) ; } /** * @param InputInterface $input * @param OutputInterface $output */ protected function execute(InputInterface $input, OutputInterface $output) { parent::execute($input, $output); $statsdService = $this->getContainer()->get('statsd'); $key_cm_stats = "cm_stats_{$this->d_s}"; // group by cmts $saveHistoric = (int) $input->getOption('save-historic'); $inicio = microtime(true); $count = 0; if(is_null($this->cmIp)) { $cablemodems = $input->getOption('cm'); if(is_null($cablemodems) || empty($cablemodems)) { $this->removeLock($this->flag); exit(); } foreach($cablemodems as $dupla) { list($ip, $mac) = explode(",",$dupla); $metrics = $this->metrics($key_cm_stats, $ip, $mac); $count++; if($metrics && $saveHistoric) $this->sendData($metrics, $statsdService); } } else { $metrics = $this->metrics($key_cm_stats, $this->cmIp, $this->cmMac); $count++; if($metrics && $saveHistoric) $this->sendData($metrics, $statsdService); } /* End Of Blockout */ $this->removeLock($this->flag); $fin = microtime(true); $time = $fin - $inicio; $this->output->writeln("Cantidad CM: {$count} / Tiempo: {$time} segundos / Date: ".date("Y-m-d H:i:s")); exit(); } private function sendData($data, $service) { $t_start_script = microtime(true); $service->send($data); $t_end_script = microtime(true); $time = $t_end_script - $t_start_script; $this->output->writeln("Tiempo de envío al StatsD: {$time} ms / Cantidad: ".count($data)); } private function sla($ip) { $kernel = $this->getContainer()->get('kernel'); $application = new Application($kernel); $application->setAutoExit(false); $args = ['','ping',$ip]; $input = new ArgvInput($args); $output = new BufferedOutput(); $application->run($input, $output); return $output->fetch(); } private function metrics($key, $ip, $mac) { $inicio = microtime(true); $SNMP = new SNMP($ip, $this->cmCommunity); $SNMP->setTimeout(2500000); // 2.5 seconds of timeout $SNMP->setRetry(1); // 1 query per metric $library = "use".$this->cmSnmpLibrary; $this->apiSNMP = $SNMP->$library(); $uptime = $this->getSNMP("sysUpTimeInstance","cmUptime"); if(!$uptime) $SNMP->setTimeout(1000000); // 1 seconds of timeout $txPower = $this->getSNMP("docsIfCmStatusTxPower","cmTxPower"); if($txPower) $SNMP->setTimeout(2500000); $rxPower = $this->getSNMP("docsIfDownChannelPower","cmRxPower"); if(!$txPower && !$rxPower) { $this->removeLock($this->flag); $fin = microtime(true); $time = $fin - $inicio; $this->output->writeln("CM no responde uptime, tx y rx => cortamos! Tiempo: $time segundos"); return false; } $signal = $this->getSNMP("docsIfSigQSignalNoise","cmSignal"); $microreflection = $this->getSNMP("docsIfSigQMicroreflections","cmMicroreflection"); $unerroreds = $this->getSNMP("docsIfSigQUnerroreds","cmUnerroreds"); $correcteds = $this->getSNMP("docsIfSigQCorrecteds","cmCorrecteds"); $uncorrectables = $this->getSNMP("docsIfSigQUncorrectables","cmUncorrectables"); $slaJson = $this->sla($ip); try{ $sla = json_decode($slaJson,true); } catch(\Exception $e) { $sla = array(); } $metrics = array('txPower' => 'cm_tx_', 'rxPower' => 'cm_rx_', 'signal' => 'cm_signal_', 'microreflection' => 'cm_microreflection_', 'unerroreds' => 'cm_unerroreds_', 'correcteds' => 'cm_correcteds_', 'uncorrectables' => 'cm_uncorrectables_'); $sendData = $data = array(); foreach($metrics as $var => $m) { $data[$var] = array(); if(!is_array($$var)) continue; $multiplicator = 1; if(in_array($var, array('txPower','rxPower','signal'))) { $multiplicator = 0.1; } foreach($$var as $channel => $value) { $v = $value * $multiplicator; $_m = "{$m}{$mac}.{$channel}"; $data[$var][$channel] = $v; $sendData[$_m] = "{$v}|g"; } } if($uptime) { foreach($uptime as $oid => $value) { $data['uptime'] = $this->convertSysUpTimeInstance($value); } } if(isset($sla['latency'])) { $data['latency'] = $sla['latency']; $sendData["cm_latency_{$mac}"] = "{$sla['latency']}|g"; } if(isset($sla['jitter'])) { $data['jitter'] = $sla['jitter']; $sendData["cm_jitter_{$mac}"] = "{$sla['jitter']}|g"; } if(isset($sla['loss'])) { $data['loss'] = $sla['loss']; $sendData["cm_loss_{$mac}"] = "{$sla['loss']}|g"; } $this->hset($key, $mac, $data, true); return $sendData; } }