Compartilharemos aqui um script que desenvolvemos para monitorar o Asterisk através do Zabbix.
Com este script você será capaz de monitorar:
- Status de um SIP em específico
- Tempo (qualify) de um SIP em específico
- Quantidade de chamadas ativas
- Status do processo do asterisk, para saber se está rodando ou não
- Duração da chamada mais longa em curso
- Quantidade de SIP online
O resultado final, no seu Zabbix, será semelhante a este abaixo:

Perceba que, na imagem acima, estou monitorando o SIP 8009001.
Abaixo, segue um exemplo do script em execução, sendo executado pelo terminal:

Os arquivos que serão alterados no seu asterisk server são:
- ast_zabbix.php (novo!)
- manager.conf
- zabbix_agentd.conf
Este script foi batizado de "ast_zabbix.php". O que ele faz é coletar informações no Asterisk através da AMI (Asterisk Manager Interface) e apresentar em um formato adequado para o Zabbix monitorar.
Abaixo segue um "how-to" bem direto para fazer funcionar este código em seu asterisk.
Passo 01 - manager.conf
Acesse /etc/asterisk/manager.conf e adicione as linhas abaixo:
[ast-zabbix] secret=lkdjaskdj131 deny=0.0.0.0/0.0.0.0 permit=127.0.0.1/255.255.255.255 read=all write=all displayconnects=no
Após, na console do asterisk, dê um reload no módulo com o comando "module reload".
Passo 02 - ast_zabbix.php:
Copie o código abaixo em /var/local/ast_zabbix.php, dando permissão de execução ao mesmo (chmod +x /var/local/ast_zabbix.php).
<?php /* Criado por: Ronaldo Sacco - ronaldo@saperx.com.br Script criado para facilitar a comunicacao entre ZABBIX e ASTERISK, utilizando AMI (Asterisk Manager Interface). Este script monitora: "peerstatus peer - Retorna o status de um determinado peer"; "peertime peer - Retorna o tempo (qualify) de um determinado peer"; "activecalls - Retorna quantas chamadas estao em curso"; "longestcall - Retorna o valor em minutos da chamada com mais tempo em duracao"; "onlinepeers - Retorna a quantidade de SIP online"; Modo de execucao: php ast_zabbix.php COMANDO SIP_PEER Exemplo: php ast_zabbix sipstatus 200 */ /* Credenciais do manager Deve ser configurado as variaveis $MANAGER_ que seguem abaixo. */ $MANAGER_user = 'spx-modules'; $MANAGER_pass = 'SPDJA213$kk1'; $MANAGER_host = '127.0.0.1'; $MANAGER_port = 5038; /* Inicio do codigo. Nao alterar nada daqui para baixo. */ function manager_connect() { global $MANAGER_host, $MANAGER_user, $MANAGER_port, $MANAGER_pass; $manager_connection_timeout = 3; //segundos //Conexao com manager $socket = fsockopen($MANAGER_host, $MANAGER_port, $errno, $errstr, $manager_connection_timeout); if (!$socket) { echo "ERRO na conexao com manager\n"; exit(1); } else { $login = "Action: login\r\n"; $login .= "Username: " . $MANAGER_user . "\r\n"; $login .= "Secret: " . $MANAGER_pass . "\r\n"; $login .= "Events: Off\r\n"; $login .= "\r\n"; fwrite($socket, $login); //Coletando primeiras linhas $manager_version = fgets($socket); $cmd_response = fgets($socket); $response = fgets($socket); $blank_line = fgets($socket); if (substr($response, 0, 9) == "Message: ") { /* We have got a response */ $loginresponse = trim(substr($response, 9)); if ($loginresponse != "Authentication Accepted" && $loginresponse != "Authentication accepted") { echo("-- Unable to log in: $loginresponse\n"); fclose($socket); exit(1); } else { return $socket; } }else{ echo "Unexpected response: $response\n"; fclose($socket); exit(0); } } } function peerstatus($peer,$search) { //Returns a number of qualify OR peer status $socket = manager_connect(); $checkpeer = "Action: SIPpeerstatus\r\n"; $checkpeer .= "Peer: $peer\r\n"; $checkpeer .= "\r\n"; fwrite($socket, $checkpeer); $count = 0; $line=NULL; while ($line != "Event: SIPpeerstatusComplete") { //echo $line . "\n"; if($line=="Response: Error"){ echo $line."\nPeer existe?\n"; fclose($socket); exit(0); } $value = explode(":",$line); if($value[0]==$search){ echo ltrim($value[1])."\n"; fclose($socket); exit; } if($count++==1000){ echo "Algum erro ocorreu. Loop. Finalizando\n"; exit(1); } $line = trim(fgets($socket)); } fclose($socket); } function onlinepeers() { //Returns a number of online peers $socket = manager_connect(); $checkpeer = "Action: SIPpeerstatus\r\n"; $checkpeer .= "\r\n"; fwrite($socket, $checkpeer); $count = 0; $line=NULL; $onlinepeer=0; while ($line != "Event: SIPpeerstatusComplete") { //echo $line . "\n"; if($line=="Response: Error"){ echo $line."\nPeer existe?\n"; fclose($socket); exit(0); } $value = explode(":",$line); if($line=="PeerStatus: Reachable"){ $onlinepeer++; } if($count++==1000){ echo "Algum erro ocorreu. Loop. Finalizando\n"; exit(1); } $line = trim(fgets($socket)); } echo $onlinepeer."\n"; fclose($socket); } function activecalls(){ //Returns a number of active calls //Returns a number of qualify OR peer status $socket = manager_connect(); $checkpeer = "Action: CoreStatus\r\n"; $checkpeer .= "\r\n"; fwrite($socket, $checkpeer); $count = 0; $line=NULL; $line = trim(fgets($socket)); do { $line = trim(fgets($socket)); //echo $line . "\n"; if($line=="Response: Error"){ echo $line."\n"; fclose($socket); exit(0); } $value = explode(":",$line); if($value[0]=="CoreCurrentCalls"){ echo ltrim($value[1])."\n"; fclose($socket); exit; } $value = explode(":",$line); if($count++==1000){ echo "Algum erro ocorreu. Loop. Finalizando\n"; exit(1); } } while(substr($line,0,16) != "CoreCurrentCalls"); fclose($socket); } function asteriskrunning(){ //Return 1 = Asterisk is running // 0 = Asterisk is not running $ret = exec("/bin/ps -A | grep asterisk | wc -l"); if($ret>0) echo "1\n"; else echo "0\n"; } function longestcall(){ //Return the longest call, in seconds, running on asterisk $socket = manager_connect(); $checkpeer = "Action: CoreShowChannels\r\n"; $checkpeer .= "\r\n"; fwrite($socket, $checkpeer); $count = 0; $line=NULL; $line = trim(fgets($socket)); $seconds = 0; do { $line = trim(fgets($socket)); //echo $line . "\n"; if($line=="Response: Error"){ echo $line."\n"; fclose($socket); exit(0); } $value = explode(":",$line); if($value[0]=="Duration"){ //HH:MM:SS em segundos $tempo = ltrim($value[1])*60*60 + $value[2]*60 + $value[3]; if($tempo > $seconds) $seconds=$tempo; } $value = explode(":",$line); if($count++==1000){ echo "Algum erro ocorreu. Loop. Finalizando\n"; exit(1); } } while($line != "EventList: Complete"); echo $seconds."\n"; fclose($socket); } if(!isset($argv[1])){ echo "Parametros necessarios. Digite help para saber mais.\n"; exit; } switch($argv[1]){ case 'peerstatus': peerstatus($argv[2],"PeerStatus"); break; case 'peertime': peerstatus($argv[2],"Time"); break; case 'activecalls': activecalls(); break; case 'asteriskrunning': asteriskrunning(); break; case 'longestcall': longestcall(); break; case 'onlinepeers': onlinepeers(); break; case '--help': case '?': echo "Help\n\n"; echo "peerstatus peer - Retorna o status de um determinado peer\n"; echo "peertime peer - Retorna o tempo (qualify) de um determinado peer\n"; echo "activecalls - Retorna quantas chamadas estao em curso\n"; echo "asteriskrunning - Retorna 1 se asterisk estiver rodando. Senao 0\n"; echo "longestcall - Retorna o valor em minutos da chamada com mais tempo em duracao\n"; echo "onlinepeers - Retorna a quantidade de SIP online\n"; echo "\n"; break; Default: echo "Comando ".$argv[1]." não encontrado. Digite --help ou ? para saber mais\n\n"; break; }
Passo 03 - zabbix_agentd.conf
Agora acesse o seu /etc/zabbix/zabbix_agentd.conf e adicione esta linha no final do arquivo
UserParameter=spx.asterisk[*],/usr/bin/php /var/local/ast_zabbix.php $1 $2
Após, restarte o seu zabbix e pronto!
Passo 04 - Configurando o Zabbix:
Se você chegou até aqui, falta apenas este último passo, onde configuraremos o seu host no zabbix.
Adicione um novo item no seu host, configurando conforme o exemplo abaixo:

Veja a "Chave", que está monitorando o ramal 8009001.
Você pode adicionar quantos ramais você desejar monitorar. Basta adicionar um monitoramento para cada ramal.
Para consultar todas as chaves possíveis de serem utilizadas, basta rodar o script: php /var/local/ast_zabbix.php --help

Abaixo, mais um exemplo para facilitar o seu entendimento:

Finalizando
Fácil não?
Agora que você entendeu, pode monitorar o que você quiser no Asterisk. Basta usar a sua criatividade.
Pode usar este código como quiser, seja para fins acadêmicos ou comerciais.
