Monitorización de Asterisk con Munin
Jueves, Diciembre 11th, 2008Todos los que nos dedicamos a esto de Asterisk hacemos nuestros pinitos con mon, nagios, snmp y similares para atender nuestras centralitas y saber cuándo algo va mal. Este tipo de monitorización, depende del soporte que se haya vendido, no le importa al cliente ya que a él sólo le importa que la centralita funcione. Pero hay algunas estadísticas que sí que le pueden interesar al cliente, como saber cuántas llamadas concurrentes suele tener, si las licencias de su ASR están en uso por picos o de forma constante, si el balanceo de sus primarios está correctamente hecho o si por el contrario estamos saturando alguno… etc. Me refiero a estadísticas de uso de los recursos de Asterisk.
Esto no es nada nuevo. Hay multitud de programas y desarrollos a medida que nos permiten monitorizar estos casos y que nos generan gráficos y estadísticas en flash, con animaciones y todo. En este post vamos a hablar de Munin como sistema de monitorización de la centralita.
Para los que no lo conozcan, Munin es un sistema que nos genera gráficos de cualquier cosa que podamos imaginar: Uso de la CPU, colas del MTA, queries de Mysql, uso de la swap, uso de la RAM… todo a base de unos sencillos plugins.
Para usar munin no tenemos más que instalar los paquetes correspondientes:
apt-get install munin munin-node apache2
Una vez hecho esto esperaramos hasta 5 minutos para que munin genere las primeras imágenes y al acceder a la URL http://localhost/munin ¡SORPRESA! Tenemos un fea y anticuada web maquetada con tablas en la que a medida que pase el tiempo veremos cómo van dibujándose gráficos referentes a los recursos y servicios que tengamos instalados.
Por defecto munin trae bastantes plugins de monitorización de servicios. Los plugins en el caso de Debian se guardan en /usr/share/munin/plugins y se activan mediante enlaces simbólicos en /etc/munin/plugins/ y configuran en /etc/munin/plugin-conf.d/munin-node. Claro que hasta ahora no ha hecho falta tocar nada de todo esto porque funciona de serie.
Ya tenemos un sistema que genera gráficas de los servicios típicos que tenemos en un servidor GNU/Linux. Ahora sólo falta la parte de monitorizar asterisk usando los plugins que no vienen de serie con el programa.

En la web de munin podemos encontrar plugins generados por los usuarios. A partir de un plugin genérico que se conecta al manager de asterisk, mete un comando y parsea la respuesta podemos sacar casi todas las estadísticas que nos interesen: Canales zap, misdn, sip, iax, llamadas simultáneas, licencias G729 en uso…
Veamos un ejemplo de un plugin de munin que vía Manager saca las llamadas concurrentes en el asterisk:
-
#!/usr/bin/perl -w
-
use strict;
-
{
-
$ret = "Net::Telnet not found";
-
}
-
if ($ARGV[0] and $ARGV[0] eq "config")
-
{
-
print "graph_title Asterisk active CALLS\n";
-
print "graph_args –base 1000 -l 0\n";
-
print "graph_vlabel calls\n";
-
print "graph_category asterisk\n";
-
print "channels.draw AREA\n";
-
print "channels.label channels\n";
-
exit 0;
-
}
-
-
-
my $username = "administrador";
-
my $secret = "secretillo";
-
-
my $pop = new Net::Telnet (Telnetmode => 0);
-
$pop->open(Host => $host,
-
Port => $port);
-
-
## Read connection message.
-
my $line = $pop->getline;
-
-
## Send user name.
-
$pop->print("Action: login");
-
$pop->print("Username: $username");
-
$pop->print("Secret: $secret");
-
$pop->print("Events: off");
-
$pop->print("");
-
-
## Request status of messages.
-
$pop->print("Action: command");
-
$pop->print("Command: core show channels");
-
$pop->print("");
-
my $result;
-
while (($line = $pop->getline) and ($line !~ /END COMMAND/o))
-
{
-
print $line;
-
$result = $line if $line =~ /active call/;
-
}
-
-
$pop->print("Action: logoff");
-
$pop->print("");
-
-
print "channels.value $nb\n";
Como puede verse leyendo un poco el código, la base del script es siempre el mismo, datos, establecimiento de la conexión… etc. Con sólo cambiar unas pocas líneas podemos ir sacando y monitorizando toda la información que deseemos. Las líneas clave serían:
$pop->print("Command: core show channels"); Donde metemos el comando que queremos.
$result = $line if $line =~ /active call/; Es la línea que tiene el resultado que queremos. Si ejecutamos a mano un asterisk -rx "core show channels" podemos ver que la respuesta es del estilo
root@pbx:/etc/asterisk/dialplan# asterisk -rx "core show channels" Está claro que en el caso de querer monitorizar las llamadas concurrentes a lo largo del tiempo lo que nos interesa es la línea última que es la que tiene el número de llamadas concurrentes en ese momento. Una vez tenemos la línea en la que está la información lo único que hace falta es sacar el dato de esa línea y sacar el resultado en el formato que a munin le interesa:
Channel Location State Application(Data)
SIP/sarenet-09130f90 946571015@default:1 Ringing AppDial((Outgoing Line))
SIP/2627-b32fade0 s-VOIP@macro-salient Ring Dial(SIP/sarenet/946571015|80|
SIP/2100-08f814c0 2100@desde-usuarios: Ringing AppDial((Outgoing Line))
SIP/2652-b2cdd190 s@macro-llamadainter Ring Dial(SIP/2100|45|Tt)
SIP/sarenet-08b4d478 (None) Up Bridged Call(SIP/2404-b2ff03f0
SIP/2404-b2ff03f0 s-VOIP@macro-salient Up Dial(SIP/sarenet/943446826|80|
mISDN/1-u981 s@ivr-operadorbuzon: Up BackGround(locuciones/EUS_IVR_
SIP/sarenet-082f7388 (None) Up Bridged Call(SIP/2612-089c0d50
SIP/2612-089c0d50 s-VOIP@macro-salient Up Dial(SIP/sarenet/944806571|80|
9 active channels
5 active calls
my $nb = (split ‘ ‘,$result)[0];
print "channels.value $nb\n";
De hecho, si ejecutamos el script a mano desde la consola lo que veremos será la salida que se le pasará a munin cuando éste ejecute dicho script de forma periódica:
root@pbx:~# /usr/share/munin/plugins/asteriskcalls
Response: Success
Message: Authentication accepted
Response: Follows
Privilege: Command
Channel Location State Application(Data)
mISDN/1-u994 s@macro-getcallerid: Ringing AGI(getcallerid.php|943085756)
SIP/sarenet-08e41cd0 (None) Up Bridged Call(SIP/2626-b318d338
SIP/2626-b318d338 s-VOIP@macro-salient Up Dial(SIP/sarenet/630642987|80|
SIP/sarenet-08b4d478 (None) Up Bridged Call(SIP/2404-b2ff03f0
SIP/2404-b2ff03f0 s-VOIP@macro-salient Up Dial(SIP/sarenet/943446826|80|
SIP/sarenet-082f7388 (None) Up Bridged Call(SIP/2612-089c0d50
SIP/2612-089c0d50 s-VOIP@macro-salient Up Dial(SIP/sarenet/944806571|80|
7 active channels
4 active calls
channels.value 4
Si nos fijamos en el principio del script podemos ver que “channels.value” es el valor que le interesa a munin para hacer la gráfica ya que hemos puesto “channels” en la vertical.
Este script hace las cosas bien, con manager y todo. Pero no tenemos por qué limitarnos a eso. Al final munin sólo quiere un valor para un campo vertical que irá pintando a lo largo del tiempo. Podemos hacer cosas menos bonitas y más imaginativas. Ejemplo de uso de un primario que pertenece a un grupo de varios:
-
#!/bin/sh
-
-
LISTAZAP=$(asterisk -rx ‘core show channels’ | cut -d ‘ ‘ -f 1 | grep -a ‘Zap/’ | cut -d ‘/’ -f 2 | cut -d ‘-’ -f 1)
-
-
ZAP1=0
-
ZAP2=0
-
ZAP3=0
-
if [ $# = 1 ]; then
-
if [ $1 == "config" ]; then
-
echo "graph_title Asterisk PRI 3";
-
echo "graph_args –base 1000 -l 0";
-
echo "graph_vlabel channels";
-
echo "graph_category asterisk";
-
echo "channels.draw AREA";
-
echo "channels.label channels";
-
exit 0
-
fi
-
fi
-
-
for actual in $LISTAZAP;do
-
if [ $actual -lt 32 ]; then
-
ZAP1=$(expr $ZAP1 + 1)
-
else if [ $actual -lt 63 ]; then
-
ZAP2=$(expr $ZAP2 + 1)
-
else if [ $actual -lt 94 ]; then
-
ZAP3=$(expr $ZAP3 + 1)
-
fi
-
fi
-
fi
-
done
-
-
echo "channels.value $ZAP3"
-
Muchas veces este sencillo programa, que hace gráficas feas, pero que es muy sencillo de instalar y de configurar puede salvarte la vida ya que puedes ver que los últimos días ha habido errores en eth0, que las querys de mysql han aumentado demasiado, que las interrupciones están por las nubes… y te permite diagnosticar momentos de congestión o fallos pasados que no son posibles reproducir en el presente.
