X da Questão - Blog da Saper

Monitorando o Asterisk no Zabbix

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.

 

Descubra como simplificar de vez sua operação de voz

Símbolo Whatsapp
Avatar WhatsApp
WhatsApp
Conta comercial
Ao utilizar o chat, você aceita a nossa Política de Privacidade.

Seja bem vindo ao nosso atendimento por WhatsApp. Como podemos lhe ajudar?

online
Ao utilizar o chat, você aceita a nossa Política de Privacidade.
Avatar