Monitorando o Asterisk no Zabbix

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.

Ronaldo Sacco
Sócio Co-Fundador da SaperX. Diretor Técnico. Especialista em SIP, Asterisk e programação de alto desempenho. O cara que faz a vaca voar.
Post criado 20

Deixe uma resposta

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

Posts Relacionados

Comece a digitar sua pesquisa acima e pressione Enter para pesquisar. Pressione ESC para cancelar.

De volta ao topo