En la administración de cualquier sistema, una parte muy importante es tener un sistema de monitoring y alertas de cualquier incidente relevante. Existen en la actualidad múltiples sistemas open source creados y pensados para ello, algunos sencillos y otros muy complejos con distintos enfoques y finalidades. No es lo mismo monitorizar servidores homogéneos que routers via snmp que mezcla de diferentes SO, clusters, clouds…
Uno de mis preferidos es monit para servidores Linux/*BSD. Es un «sencillo» programa escrito en C ligero por definición con una versatilidad difícilmente igualable por otros «agentes» con una concepción KISS que me enamoró desde el principio y que con imaginación te permite tener el perfecto vigilante de tu servidor de cualquier evento que te puedas imaginar.
El complemente ideal para monit es M/Monit. Un panel centralizado al que monit puede, si lo configuras, enviar todas sus métricas y alertas y de forma unificada tener una visión de todos tus sistemas. La única pega de M/Monit es que no es open source y necesita licencia, pero es de los pocos software no open source que puedo recomendar y que merece la pena adquirir su licencia, tanto por su relativamente bajo coste como por su gran valor añadido. Además son los mismos desarrolladores de monit, que si es open source, y por si solo ya es una herramienta imprescindible. Al adquirir la licencia de M/Monit ayudas a mejorar monit.
Pero centrémonos en «monit» ya que en muchos casos será suficiente para pequeñas infraestructuras. Su ventaja como he comentado es su ligereza como proceso en ejecución, al estar escrito en C es muy liviano en consumo, ideal incluso para sistemas embebidos. Es autónomo y opera ofreciendo además un pequeño panel web donde muestra el estado de los diferentes servicios/eventos monitorizados y te permite hacer ciertas acciones como parar o reiniciar servicios. Su configuración aunque pueda intimidar inicialmente está muy bien pensada y permite vigilar cualquier cosa que te puedas imaginar en tu sistema ya que aparte de los «checks» que tiene incluido te permite utilizar cualquier programa externo como fuente de eventos a monitorizar, esta posibilidad junto con scripts shell te da opciones donde el único límite es tu imaginación.
Veamos un caso práctico en un servidor FreeBSD.
Para realizar la instalación podemos utilizar el siguiente playbook sencillo en ansible:
- name: Install monit
pkgng: name=monit state=present
- name: create monit directories
file: path={{item}} mode=0700 state=directory
with_items:
- /usr/local/etc/monit
- /usr/local/etc/monit/scripts
- /usr/local/etc/monit/conf.d
- /var/lib/monit
- /var/lib/monit/events
- name: monit logrotation
copy:
src: newsyslog.conf
dest: /usr/local/etc/newsyslog.conf.d/monit.conf
mode: 0600
- name: copy monit conf
template: src=monitrc
dest=/usr/local/etc/monitrc
owner=0 group=0 mode=0600
- name: enable monit on boot
service: name=monit enabled=yes state=started
El contenido del template monitrc básico:
set daemon 10 with start delay 10
set logfile /var/log/monit.log
set pidfile /var/run/monit.pid
set idfile /var/lib/monit/id
set statefile /var/lib/monit/state
set mailserver 127.0.0.1
set alert [email protected] not on { instance, action }
set httpd unixsocket /var/run/monit.sock
uid root
gid wheel
permission 0600
allow root:CHANGEMEPASS
set eventqueue
basedir /var/lib/monit/events
slots 100
include /usr/local/etc/monit/conf.d/*
check system $HOST
if memory usage > 90% for 10 cycles then alert
if swap usage > 20% for 10 cycles then alert
if cpu usage (user) > 80% for 10 cycles then alert
if cpu usage (system) > 30% for 10 cycles then alert
if cpu usage (wait) > 10% for 10 cycles then alert
El fichero /usr/local/etc/newsyslog.conf.d/monit.conf:
/var/log/monit.log root:wheel 640 7 * $W1D01 JC /var/run/monit.pid
Como habrás observado es necesario que tengas un servidor smtp activo para enviar las alertas, esto normalmente está instalado de base en cualquier servidor unix aunque sea solo para el envío de logs. Además debes de indicar el email donde se enviarán las alertas y establecer un user/pass de acceso que utilizará el cliente monit en consola para realizar operaciones con el propio daemon monit (monit es a la vez el servidor y el cliente cli en local).
Con esta sencilla configuración básica ya tenemos monitorizado con alertas la memoria y cpu de nuestro servidor. La comprobación se realiza a intervalos de 10s (set daemon 10 with start delay 10
).
En esta configuración está deshabilitado el puerto http del servidor web incluido, suelo manejarme mucho mejor en consola que con un panel web y prefiero, si no es necesario, evitar tener cualquier puerto abierto tcp, mas si este se ejecuta con privilegios root aunque en principio sea una aplicación segura y bien programada (todo es susceptible a tener un exploit oculto).
A partir de aquí las opciones incluidas en el propio monit son múltiples y os recomiendo encarecidamente revisar su documentación (https://mmonit.com/monit/documentation/monit.html) y su wiki con ejemplos (https://mmonit.com/wiki/Monit/ConfigurationExamples)
Si queréis conectar monit con M/Monit solo hay que indicarle en su configuración una línea como la siguiente:
set mmonit https://USER:PASS@MONITSERVER:25083/collector
Con esto (y habiendo creado el usuario/password correspondiente en M/Monit), además de los avisos y alertas tendrás disponible un panel con gráficas e histórico muy versátil y útil, sobre todo si quieres ver la evolución de un sistema en el tiempo y compararlo con otros servidores. Si no quieres utilizar M/Monit y solo utilizar las alertas de monit siempre puedes recurrir a otra herramienta sencilla como Munin para gráficas instalada en el propio servidor local pero eso ya es otra historia.
Veamos ahora otro ejemplo de la versatilidad de monit, aunque por defecto no tiene un «check» para verificar la temperatura de la CPU podemos crear una alerta de forma muy sencilla con un script shell. En el caso de este servidor FreeBSD utilizaremos la aplicación hwstats y este sencillo script que crearemos en /usr/local/etc/monit/scripts/cpu1temp.sh:
#!/bin/sh
TEMP=`/usr/local/bin/hwstat |grep CPU10|awk '{print $2}'|cut -d '.' -f 1`
echo $TEMP
exit $TEMP
En monit añadiremos el siguiente check:
check program CPUTemp1 with path "/usr/local/etc/monit/scripts/cpu1temp.sh" timeout 2 seconds
if status > 80 for 3 cycles then alert
De esta forma, cada 10s, se verificará la temperatura de la CPU y si durante 30s (3 ciclos) la temperatura de la CPU es mayor de 80º se enviará una alerta.
¿ Fácil no ?