Instalar Monit: monitoreo de servicios para servidores Unix

MonitHoy voy a explicar cómo instalar Monit, un software muy completo para monitoreo de servicios (locales y remotos) de cualquier sistema Unix. Con él podremos estar atentos ante posibles problemas en alguno de nuestros servidores y realizar algunas tareas automaticamente.

¿Qué es Monit?

De acuerdo con su propia definición, Monit es una utilidad gratuita y Open Source para administrar y monitorear procesos, archivos, directorios y filesystems en un sistema Unix. Realiza tareas automáticas de mantenimiento y reparación y puede ejecutar acciones significativas durante situaciones de error.

Está desarrollado en C (pueden ver el código fuente en Google Code) y su demonio corre de manera casi imperceptible para el sistema, en tanto consume muy pocos recursos.

Para más información, se puede consultar el sitio oficial de Monit y su manual online (ambos en inglés).

Instalación

La instalación de Monit es muy sencilla.

# cd /usr/src
# wget http://mmonit.com/monit/dist/monit-5.1.1.tar.gz
# tar zxvf monit-5.1.1.tar.gz
# cd monit-5.1.1
# ./configure --prefix=/usr
# make && make install

Luego, si estamos instalando en CentOS o algún Linux similar, vamos a querer copiar el archivo rc.

# cp contrib/rc.monit /etc/init.d/monit
# chown root:root /etc/init.d/monit
# chmod 755 /etc/init.d/monit
# chkconfig --add monit
# chkconfig monit on

Configuración

Una vez instalado podemos pasar a la configuración, que será lo más importante del proceso. Para ello yo suelo crear un archivo inicial /etc/monitrc que tiene la configuración general del Monit, y luego dentro de una carpeta /etc/monit creo un archivo por cada servicio que quiero monitorear.

Les dejo aquí mi configuración.

Archivo: /etc/monitrc

set daemon  120
set logfile syslog facility log_daemon
set mailserver localhost

set alert administrator@domain.com                      # receive all alert
set alert anotheradmin@domain2.com

set httpd port 2812 and
   use address localhost  # only accept connection from localhost
    allow localhost        # allow localhost to connect to the server and
#    allow admin:monit      # require user 'admin' with password 'monit'
#
#
###############################################################################
## Services
###############################################################################
##
## Check general system resources such as load average, cpu and memory
## usage. Each test specifies a resource, conditions and the action to be
## performed should a test fail.
#
  check system fqdn.domain.com
    if loadavg (1min) > 5 then alert
    if loadavg (5min) > 10 then alert
    if loadavg (1min) > 20 then exec "/bin/bash /root/handle_high_load.sh"
    if memory usage > 75% then alert
    if cpu usage (user) > 70% for 3 cycles then alert
    if cpu usage (system) > 30% for 3 cycles then alert
    if cpu usage (wait) > 20% for 3 cycles then alert

include /etc/monit/*.monitrc

Algunas cosas para anotar de esta primera parte. El daemon va a revisar cada 120 segundos los servicios, va a loguear en Syslog y va enviar mails usando el mailserver local. Cuando haya alguna alerta, la enviará a administrador@domain.com y anotheradmin@domain2.com. Luego habilito el servicio web que ofrece monit para que escuche en la IP local (esto es para poder utilizar todas las opciones del comando `monit`). Por último defino las reglas para el chequeo del sistema, cuyo FQDN es fqdn.domain.com (acá iría el hostname de su servidor). Las reglas son bastante sencillas. En algunos casos lo que hago es enviar una alerta y si el loadavg es más de 20 ejecuto un script para controlarlo.

La última línea incluye todos los archivos *.monit del directorio /etc/monit. Que es lo que vamos a ver ahora.

Archivo: /etc/monit/httpd.monitrc

#
# Monitor Apache (httpd)
#
check process httpd with pidfile /var/run/httpd.pid
    start program = "/sbin/service httpd start"
    stop program  = "/sbin/service httpd stop"
    if cpu > 80% for 3 cycles then alert
    if totalmem > 1500.0 MB for 5 cycles then alert
    if children > 250 then alert
    if children > 255 for 5 cycles then stop
    if cpu usage > 95% for 3 cycles then restart
    if failed port 80 protocol http then restart

check file httpd.conf with path /etc/httpd/conf/httpd.conf
    if changed checksum then alert

Aquí defino un proceso de nombre “httpd” con un pidfile en /var/run/httpd.pid. Luego defino los comandos para iniciar y detener el proceso. Y luego las acciones a realizar según el evento. En algunos casos será “alert” (enviar aviso por mail), en otros “restart” (reinicar el proceso). Hay otras opciones que podrán ver en la documentación. Por último agrego una verificación del archivo httpd.conf. Si se modifica me notificará por mail.

De la misma forma, en el directorio /etc/monit tengo archivos similares para MySQL, SMTP, POP3, IMAP, SSH, etc. Y además tengo archivos para controlar algunos servicios externos. Esto es por una cuestión básica: hasta ahora estamos haciendo todos chequeos locales, si el servidor se cae o por alguna razón no puede enviarme las alertas, podría nunca enterarme de qué pasa. Entonces voy a agregar este otro archivo para controlar un servidor externo que me diga si los servicios están accesibles.

Archivo: server1.monitrc

# server1.domain.com check
check host server1.domain.com with address 1.2.3.4
      if failed icmp type echo count 10 with timeout 15 seconds
         then alert
      if failed port 21 proto ftp then alert
      if failed port 25 proto smtp then alert
      if failed port 80 proto http then alert
      if failed port 110 proto pop then alert

Aquí estoy monitreando el servidor server1.domain.com con IP 1.2.3.4 (este archivo debería estar en otro servidor con Monit, por ejemplo, servidor2.domain.com). Lo primero que intento es hacer un Echo ICMP. Lamentablemente Monit no soporta hacer ping, pero un echo ICMP es lo más cercano que nos permite. Si falla 10 veces seguidas, le pido que me avise (la cantidad de veces tan alta es para asegurarme de no recibir una alerta por un paquete perdido y llenar mi mail de alertas inútiles que no me permitan ver las importantes). Luego agrego que testee los principales puertos a través de los protocolos correspondientes y que si falla me avise.

Iniciando Monit

Una vez que tenemos la configuración, ya podemos probarlo. Para ello iniciaremos el servicio, veremos si se inicia correctamente en el log y veremos el status.

Iniciamos:

# service monit start

Luego vemos en syslog:

Apr  4 11:35:23 fqdn monit[24820]: Starting monit daemon with http interface at [localhost:2812]
Apr  4 11:35:23 fqdn monit[24822]: Starting monit HTTP server at [localhost:2812]
Apr  4 11:35:23 fqdn monit[24822]: monit HTTP server started
Apr  4 11:35:23 fqdn monit[24822]: 'fqdn.domain.com' Monit started

Monit inició y tiene su servidor HTTP escuchando en localhost:2812. Ahora veamos el resumen del status de los servicios.

# monit status
The Monit daemon 5.0.3 uptime: 1m 

System 'fqdn.domain.com' running
Process 'sshd'                      running
File 'sshd_config'                  accessible
Process 'exim'                      running
File 'exim.conf'                    accessible
Process 'mysqld'                    running
File 'my.cnf'                       accessible
Process 'httpd'                     running
File 'httpd.conf'                   accessible
Remote Host 'fqdn.domain.com' online with all services

Para ver los comandos disponibles:

# monit -h

Al mismo tipo de información podremos acceder por vía web si accedemos a http://localhost:2812. También, si queremos acceder desde afuera, podemos configurar Monit para que escuche en otra IP (por ejemplo, 0.0.0.0) y definir un método de autenticación (para que no pueda acceder cualquiera).

Leave a comment ?

24 Comments.

  1. Muchas gracias por los tips, me han orientado considerablemente a instalar MONIT en varios servidores en producción.

  2. Me alegro que te haya servido! Saludos.

  3. Hola, tengo una pregunta, yo tengo que monitorizar un script de python que a veces se cae, la idea, sería reiniciarlo cuando esto pase, el tema, es que no tengo definido un PID, es necesario supongo?
    Como monitorizar un script python, alguna idea?

    Desde ya, me ha servido en el resto tus “tips”
    Gracias.

  4. Sí, si lo querés monitorear con Monit vas a necesitar generar un PID file. Sino lo otro que podés hacer es poner un cronjob con un script que chequee si el script de python está corriendo y sino lo relance.

    Hacerlo con Monit te da otras posibilidades adicionales como lanzar notificaciones, etc.

    Otra cosa que podés hacer es configurar tu script en el inittab y ponerle respawn. Eso te sirve si el script es un daemon, cuando se cae, el init lo relanza:
    http://www.netadmintools.com/html/5inittab.man.html

  5. Muchas gracias. Al final si, he generado con algo de ayuda desde el propio script py un pid file, ahora estoy viendo la mejor forma de quitarlo cuando el script se muera… pero por lo menos he avanzado mucho. Gracias!

  6. Sebastian Espinosa

    Muy bueno el tutorial. Yo lo instale en una servidor de prueba en mi empresa, pero al momento de acceder por el browser, no me muestra nada. sera que el Firewall me esta bloqueando el puerto que elegi ?

    agradeceria tu respuesta.

    Muchas gracias.

  7. Puede ser el firewall o puede ser la IP en la que esté escuchando el monit. Si está escuchando en localhost, solamente vas a poder acceder por localhost.

    Fijate con:

    netstat -natp |grep LISTEN |grep monit

  8. Estimado:
    Felicitaciones por el tutorial. yo estoy instalando monit en un servidor de prueba en mi empresa. el problema es que seguí tus pasos y no puedo lograr hacer funcionar el sistema.
    mira reinicie la maquina y me apareció esto

    Loading configuration files.
    Setting hostname: monit.empresa.
    Creating and/or trimming log files:.
    Starting syslogd.
    syslogd: child pid 95370 exited with return code 1
    ELF ldconfig path: /lib /usr/lib /usr/lib/compat /usr/local/lib /usr/local/lib/mysql
    a.out ldconfig path: /usr/lib/aout /usr/lib/compat/aout
    Starting monit.
    /etc/monit/httpd.monitrc:5: Warning: the executable does not exist ‘/sbin/service’
    /etc/monit/httpd.monitrc:6: Warning: the executable does not exist ‘/sbin/service’
    checksum: file /etc/httpd/conf/httpd.conf is not regular file
    Starting monit daemon with http interface at [10.50.1.93:9999]
    Clearing /tmp (X related).
    Starting local daemons:.
    Updating motd.
    Performing sanity check on apache22 configuration:
    Syntax OK
    Starting apache22.
    (48)Address already in use: make_sock: could not bind to address 0.0.0.0:80
    no listening sockets available, shutting down
    Unable to open logs
    Starting sshd.
    Starting cron.
    Local package initialization:.

    y ya no se me ocurre como solucionar esto, debido a que no encuentro mucho de monit en internet.
    puedes ayudarme?

    de ante mano
    muchas gracias.

  9. Me parece que tenés algunos problemas de configuración. Deberías editar la configuración que yo puse de ejemplo para que se ajuste a tu sistema. Por ejemplo, cuando dice:

    /etc/monit/httpd.monitrc:5: Warning: the executable does not exist ‘/sbin/service’

    Si no es un RedHat/CentOS probablemente no tengas el comando service. Por ahí deberías reemplazarlo por /etc/init.d/apache2 start y /etc/init.d/apache2 stop.

    Después hay otros mensajes en ese log que no son del monit, sino que son de tu sistema.

    Saludos

  10. ok gracias veré que pasa

  11. sabes?, mejor te digo que estoy trabajando con FreeBSD, haber si me puedes ayudar. porque el comando /etc/init.d/apache2 start y /etc/init.d/apache2 stop no los reconoce

  12. Debe ser algo tipo:
    /usr/local/etc/init.d/apache2 start
    /usr/local/etc/init.d/apache2 stop
    Los que uses para iniciar y detener apache…

  13. ya lo solucione, gracias, era /usr/local/etc/rc.d/apache22 start
    ahora bien, esta linea “checksum: file /etc/httpd/conf/httpd.conf is not regular file” aparece por …

    te agradecería ayudarme

  14. cabe destacar q ese archivo no existe en mi maquina

  15. Deberías reemplazarlo por la ubicación de tu httpd.conf, probablemente /usr/local/etc/apache22/httpd.conf

  16. gracias, se solucionó

  17. esto no me deja funcionar monit “(48)Address already in use: make_sock: could not bind to address 0.0.0.0:80
    no listening sockets available, shutting down”

    tienes alguna solución para eso?

    se agradecería

    saludos

  18. Si pusiste el monit a escuchar en el puerto 80 no te va a andar porque ya tenés el Apache corriendo ahí.

  19. Sebastian Espinosa

    Estimado, alfinal logre visualizar el Monit en el browser. No era problema del firewall ni de configuración, solo tube que matar el proceso “monit” y hacerlo correr denuevo.
    Ahora estoy intentando complementar con MMonit. existe un port en freebsd para mmonit ?. al no encontrarlo lo descargue, luego entre a bin y ejecuto “mmonit” pero me dice “Command not found” :???: . Que puede ser ?

    Gracias por la ayuda :lol:

  20. No sé, no he usado mmonit. Lo de command not found habría que ver cómo estás ejecutando el binario. Si “.” no está en tu path, tendrías que poner ./mmonit (estando dentro de la carpeta correspondiente).

  21. No me funciona el mandar alertas a traves de mail con el servidor smtp de google.alguna idea?

  22. Te estás autenticando en el smtp de Google para enviar? Cómo estás haciendo eso? Estás utilizando una conexión con TLS?

  23. Muy bueno el tutorial.
    Personalmente deje de usar Monit, ya que en sitios con una carga media~alta monit me estaba produciendo problemas de performance, mas alla de haber incrementado varios de los valores por defecto.
    Reiniciar cientos de conexiones/procesos para volverlos a crear a veces tiene un costo elevado.

  24. Es cierto. Una opción más completa en términos de notificaciones (más liviano y con un menor manejo de prioridades) es Nagios aunque, que yo sepa, no permite realizar operaciones como reiniciar servicios ante determinados fallos.

Leave a Comment


NOTE - You can use these HTML tags and attributes:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>