====== Graficar tráfico del enlace con RRDTool ======
Este tutorial puede tener muchos aspectos sin pulir, porque es la primera vez que utilizo esta herramienta. Mi acercamiento fue motivado por el deseo de tener una solución rápida y de bajo consumo de recursos que me permitiera muestrear y graficar la transferencia del enlace de mi trabajo en intervalos de tiempo inferiores a los 5 minutos que suele utilizar MRTG.
===== Introducción a RRDTool =====
[[http://oss.oetiker.ch/rrdtool|RRDTool]] es una aplicación desarrollada por Tobias Oetiker (creador del popular MRTG) específicamente para registrar y graficar series de datos basados en el tiempo.
Esta herramienta ofrece mayor flexibilidad para graficar que MRTG y también mejor rendimiento, pues los gráficos se generan solo bajo demanda, de modo que la única carga para el sistema es el registro de los datos, que tiene muy bajo consumo de recursos.
Los datos se almacenan en una base de datos RRD (//round robin database//), que mantiene un tamaño constante y permite registrar diferentes intervalos de tiempo.
Aunque RRDTool puede utilizarse para muchas cosas, en este tutorial explicaremos cómo utilizarlo para llevar un registro histórico de la transferencia de un enlace.
Algunas cosas que se asumen en este tutorial:
* Poseemos un nivel intermedio de familiaridad con Linux (con todo lo que ello implica).
* Tenemos un enrutador que ya está configurado para enviar información mediante el protocolo SNMP, que tiene la dirección IP 192.168.1.1 y cuya cadena de comunidad es //MiComunidad//.
* El enlace que deseamos monitorear permite una transferencia sostenida de 128 kbps con picos que en ningún caso excederán los 160 kpbs.
* El servidor que utilizaremos para almacenar los datos tiene la dirección 192.168.1.2 y utiliza Debian Squeeze como sistema operativo.
* Deseamos mantener un registro histórico por un periodo de un año, con tres resoluciones de tiempo diferentes.
===== Instalación y configuración =====
Además de necesitar instalar RRDTool, para comunicarnos con el enrutador mediante SNMP necesitaremos tener instalados varios paquetes, pero podemos instalarlos todos de una vez:
sudo aptitude install snmp smistrip snmp-mibs-downloader rrdtool
Una aclaración:
A partir de Debian Squeeze los archivos MIB ya no pertenecen al paquete ''libsnmp-base'', sino que por un cambio en su licencia se movieron a la sección de componentes ''non-free'', de modo que para evitar errores en algunos comandos, conviene instalar el paquete ''snmp-mibs-downloader'', al menos temporalmente. También debemos colocar una marca de comentario en el archivo ''/etc/snmp/snmp.conf'', de modo que quedaría así:
#mibs :
==== Creación de la base de datos ====
El primer paso para utilizar RRDTool es crear la base de datos. Pueden utilizarse diferentes parámetros, sobre los cuales podremos conocer más con el comando ''man rrdcreate''. No obstante, para abreviar, utilizaremos un simple //script// de ''bash'':
#! /bin/sh
# Script para crear base de datos RRD para monitoreo de enlace
# Directorio de la base de datos
RRDATADIR=/var/log/rrd
# Archivo de la base de datos
RRDATAFILE=enrutador.rrd
# Crear directorio si no existe
mkdir -p $RRDATADIR
# Crear base de datos, si no existe
if [ ! -f "$RRDATADIR/$RRDATAFILE" ]; then
sudo rrdtool create "$RRDATADIR/$RRDATAFILE" \
--step 10 \
DS:in:COUNTER:20:0:20000 \
DS:out:COUNTER:20:0:20000 \
RRA:AVERAGE:0.5:3:8640 \
RRA:AVERAGE:0.5:30:25920 \
RRA:AVERAGE:0.5:720:4380
fi
exit 0
El significado de este //script// básicamente es el siguiente:
* Las muestras se recibirán cada 10 segundos (la base de datos se encarga de promediarlas).
* Se crearán dos orígenes de datos (uno para la entrada y otro para la salida) en los cuales se registrarán valores entre 0 y 20000 bytes por segundo, es decir, 16000 bytes (128 kilobits) mas un margen de 4000 bytes (32 kilobits, el 25%) para posbibles picos.
* Se almacenarán por por 72 horas los valores promediados de 30 segundos (para poder conocer con mayor detalle el comportamiento reciente del enlace).
* Se almacenarán por 90 días los valores promediados de 5 minutos.
* Se almacenarán por un año los valores promediados de 2 horas.
==== Consultar el dispositivo ====
Para consultar el enrutador utilizaremos el protocolo SNMP. Hay muchas herramientas que lo soportan, pero en este tutorial haremos el proceso manualmente.
Primeramente, necesitamos saber cuál es la interfaz del enrutador que deseamos monitorear, y para esto podemos utilizar el siguiente comando:
snmpwalk -v1 -c MiComunidad 192.168.1.1 interfaces.ifTable.ifEntry.ifDescr
Este comando debería producir un listado de interfaces, parecido a este:
IF-MIB::ifDescr.10000 = STRING: eth-0
IF-MIB::ifDescr.40000 = STRING: dsl-0
IF-MIB::ifDescr.140000 = STRING: atm-0
IF-MIB::ifDescr.150000 = STRING: aal5-0
IF-MIB::ifDescr.150001 = STRING: aal5-1
IF-MIB::ifDescr.150002 = STRING: aal5-2
IF-MIB::ifDescr.150003 = STRING: aal5-3
IF-MIB::ifDescr.150004 = STRING: aal5-4
IF-MIB::ifDescr.150005 = STRING: aal5-5
IF-MIB::ifDescr.150006 = STRING: aal5-7
IF-MIB::ifDescr.150007 = STRING: aal5-6
En este caso, nos interesa la interfaz ''dsl-0'', de modo que apuntamos su número (4000). Una vez hecho esto, buscamos las entradas MIB ''ifInOctets'' y ''ifOutOctets'', que son las que devuelven los valores de los bytes recibidos y enviados. Hay varias formas de encontrarlas, pero la mejor manera (para el sistema) es por su valor numérico, de modo que utilizaremos los siguientes comandos:
snmptranslate -Tz | grep ifInOctets
snmptranslate -Tz | grep ifOutOctets
Deberíamos obtener valores como estos:
1.3.6.1.2.1.2.2.1.10
1.3.6.1.2.1.2.2.1.16
Si deseamos conocer el significado de esta secuencia de números, podemos utilizar el siguiente comando:
snmptranslate -Onf -IR ifInOctets
Obtendremos algo como esto:
.org.dod.internet.mgmt.mib-2.interfaces.ifTable.ifEntry.ifInOctets
De todas maneras, consultaremos ahora el enrutador con la secuencia de números que obtuvimos, y al final agregaremos el número de la interfaz que obtuvimos anteriormente (4000):
snmpget -v1 -c MiComunidad 192.168.1.1 .1.3.6.1.2.1.2.2.1.10.40000 .1.3.6.1.2.1.2.2.1.16.40000
Deberíamos obtener algo como esto:
IF-MIB::ifInOctets.40000 = Counter32: 78906432
IF-MIB::ifOutOctets.40000 = Counter32: 26193216
Esto significa que el enrutador está respondiendo con los valores que tienen los contadores, que son los que necesitaremos para poblar la base de datos.
==== Registrar los datos ====
Como mencionamos anteriormente, para poblar la base de datos, utilizaremos un //script// de ''bash'', que consulte al enrutador y envíe los valores obtenidos a la base de datos. Como la consulta debe hacerse cada diez segundos, a mi se me ocurrió algo simple como esto:((Es probable que puedan encontrarse soluciones más eficientes (como crear un //daemon//), pero esta al menos funciona y se prepara rápido.))
#! /bin/sh
REPEAT=1
RRDATAFILE=/var/log/rrd/enrutador.rrd
while [ "$REPEAT" -eq 1 ]; do
BYTESIN=$(snmpget -v1 -c MiComunidad 192.168.1.1 .1.3.6.1.2.1.2.2.1.10.40000 | awk '{print $4}')
BYTESOUT=$(snmpget -v1 -c MiComunidad 192.168.1.1 .1.3.6.1.2.1.2.2.1.16.40000 | awk '{print $4}')
rrdtool update $RRDATAFILE N:$BYTESIN:$BYTESOUT
sleep 10
done
Como vemos, en este caso, utilizamos el comando ''snmpget'' en un ciclo que se repite mientras se ejecute el //script//, extraemos solo las cifras de los contadores mediante el comando AWK, las asignamos a variables, y luego las pasamos a la base de datos mediante el comando ''rrdtool update'' (aquí N significa la hora actual). Al final se hace una pausa de 10 segundos.
Podría utilizarse otra variante sin ciclo y simplemente llamar el //script// desde una tarea programada, pero ''crontab'' tiene un límite inferior de un minuto.
De modo que como no utilizaremos ''crontab'', queda decidir desde dónde llamaremos al //script//. Tiene sentido que se consulte al enrutador en cuanto el servidor levante las interfaces de red, asi que por ejemplo, podríamos colocar el //script// (que por cierto, debe tener permisos de ejecución) en ''/etc/network/if-up.d/'' o también puede agregarse esta línea al archivo ''/etc/network/interfaces'':
up /etc/network/enrutador.sh &
Una vez terminado este paso, podemos reiniciar la red o la interfaz, o simplemente llamar el //script// manualmente para que comience a llenar la base de datos. En todo caso, debemos esperar algunos minutos antes de hacer nuestra primera graficación, porque de lo contrario solo veremos unas barras enormes.
===== Graficar =====
Evidentemente, la parte más interesante y creativa es la graficación. Con RRDTool pueden hacerse gráficos realmente complejos, pues las versiones recientes soportan incluso niveles de transparencia.
----
(Pretendo terminar esta sección pronto, pero para los impacientes, aqui va un //script// que ejemplifica como utilizar el comando de graficación.)
#! /bin/sh
RRDATAFILE=/var/log/rrd/enrutador.rrd
if [ $# -lt 2 ]; then
echo "Faltan los momentos de inicio y fin. Ej. (end-6h now)"
exit 0
else
sudo rrdtool graph /var/www/rrd/rrdtool_ejemplo.png --imgformat PNG \
--start $1 --end $2 \
--title "Comportamiento del enlace" \
--vertical-label "Tasa de transferencia (kbps)" \
--upper-limit 160 \
--lower-limit 0 \
--rigid \
--width 600 --height 240 \
DEF:dsin=$RRDATAFILE:in:AVERAGE \
DEF:dsout=$RRDATAFILE:out:AVERAGE \
CDEF:download=dsin,0.008,* \
CDEF:down96=download,96,GT,0,download,IF \
CDEF:down64=download,64,GT,0,download,IF \
CDEF:down32=download,32,GT,0,download,IF \
CDEF:down13=download,13,GT,0,download,IF \
CDEF:upload=dsout,0.008,* \
HRULE:128#0000FF:"Capacidad contratada (128 kbps)\n" \
AREA:download#35DF7F:"Recepción superior al 75%\n" \
AREA:down96#AFDF3F:"Recepción inferior al 75% (96 kbps)\n" \
AREA:down64#EFDF1F:"Recepción inferior al 50% (64 kbps)\n" \
AREA:down32#FF9F00:"Recepción inferior al 25% (32 kbps)\n" \
AREA:down13#FF0000:"Recepción inferior al 10% (13 kbps)\n" \
LINE1:download#006000 \
LINE1.5:upload#005FBF:"Envío"
fi
exit 0
El primer parámetro que espera recibir el //script// es el //timestamp// de inicio y el segundo es el //timestamp// final, donde cada //timestamp// es la cantidad de segundos transcurridos desde 1970-01-01 00:00:00 UTC.
Afortunadamente, Oetiker también implementó abreviaturas al estilo de horario del comando ''at'':
^ Abreviatura ^ Significado ^
| now | El momento actual |
| s | Segundos |
| h | Horas |
| d | Días |
| w | Semanas |
| m | Meses |
| y | Años |
| start | Referencia al momento inicial |
| end | Referencia al momento final |
| midnight | 00:00 |
| noon | 12:00 |
| teatime | 16:00 |
| yesterday | Referencia al día anterior |
| today | Referencia al día actual |
| tomorrow | Referencia al día próximo |
| epoch | 1970-01-01 00:00:00 UTC |
Además puede utilizarse la hora (en formato de 24 horas), el nombre de los días (en inglés) o la fecha en alguno de estos formatos:
* MM/DD/[YY]YY
* DD.MM.[YY]YY
* YYYYMMDD
Esto facilita la invocación de nuestro //script//, por ejemplo, para obtener la última hora:
./graficar.sh now-1h now
===== Resultados =====
Con RRDTool se pueden obtener resultados visualmente superiores a los que brinda MRTG, aqui tienen un ejemplo del gráfico generado con el script anterior:
{{:tutoriales:rrdtool_ejemplo.png|}}
===== Atribuciones =====
* **Autor:** Hugo Florentino