A medida que pasa el tiempo, los archivos de log (registro de errores y eventos) aumentan su tamaño considerablemente, con lo cual es recomendable implementar su rotación. Esto es, cada cierto tiempo o tamaño de archivo, guardar una copia comprimida del log y comenzar con un archivo nuevo (vacío). Ya que los archivos de log utilizan el formato de texto plano (con excepciones ridículas como los logs de eventos de Windows y journald), éstos ocupan mucho espacio. Sin embargo el formato de texto plano se puede comprimir considerablemente (se logran grandes tasas de compresión). De esta forma se ahorra espacio en disco sin perder información. Y, como efecto secundario, se organizan mejor los datos presentes en los logs, pues quedan separados por rangos de fechas.
Esta tarea se denomina rotación porque en general se guarda un número máximo de copias (no una sola copia) del archivo de log original. Una vez que se alcanza el número máximo de copias a guardar, en cada rotación se crea un nuevo archivo comprimido y se elimina el más antiguo. Efectivamente se están eliminando los datos más antiguos, aunque es la única solución posible para mantener el uso de disco acotado. Sin embargo es altamente probable que los archivos de log se hayan enviado ya a un sistema de backup (los logs deben ser una de las principales cosas a resguardar en una copia de seguridad después de los datos propiamente dichos).
En los sistemas operativos GNU/Linux, el estándar para la rotación de logs es logrotate. Una herramienta diseñada para simplificar la administración de archivos de log en sistemas que generan muchos archivos de log de gran tamaño. En la mayoría de las distribuciones viene instalado y configurado por defecto. Más aún, la mayoría de los paquetes incluyen su propia configuración de rotación de logs. Sin embargo ciertas instalaciones mínimas carecen del mismo, con lo cual debemos instalarlo manualmente. Tema que nos trae a este artículo.
En este caso de estudio, un servidor Nginx ha acumulado más de 800 MB de logs en un período de 30 días:
root@debian:~# ls -lhd /usr/local/nginx/logs/* -rw-r--r-- 1 www-data staff 684M Aug 7 11:55 /usr/local/nginx/logs/access.log -rw-r--r-- 1 www-data staff 165M Aug 7 11:44 /usr/local/nginx/logs/error.log
Veamos cómo instalar logrotate
para rotar estos archivos de log de manera automática:
Cómo instalar logrotate en Debian y derivados
En los sistemas operativos basados en Debian/Devuan y derivados, es posible instalar logrotate
simplemente ejecutando:
# apt-get install logrotate
El paquete instala una tarea de cron
que se ejecuta diariamente:
root@debian:~# cat /etc/cron.daily/logrotate #!/bin/sh test -x /usr/sbin/logrotate || exit 0 /usr/sbin/logrotate /etc/logrotate.conf
A su vez, el archivo de configuración de logrotate
se encuentra en la ruta /etc/logrotate.conf
.
Configuración de rotación de logs de Nginx
logrotate
incluye el directorio /etc/logrotate.d/
donde configurar los diferentes logs (demonios y servicios sobre los cuales se desee rotar logs). Este directorio posee archivos de configuración de servicios preexistentes a la instalación de logrotate
(por esto que mencionaba anteriormente acerca de que los paquetes suelen incluir una configuración de rotación de logs, aunque logrotate
no esté instalado en el sistema). Sin embargo, si hemos compilado Nginx desde los fuentes, será necesario definir nuestra propia configuración de rotación de logs de manera manual.
Crear el archivo /etc/logrotate.d/nginx
con el siguiente contenido:
/usr/local/nginx/logs/*.log { rotate 10 daily missingok notifempty compress delaycompress postrotate [ ! -f /var/run/nginx.pid ] || kill -USR1 `cat /var/run/nginx.pid` endscript }
¿Qué significa cada línea?
rotate 10
: guardar 10 copias del archivo de log.daily
: rotar todos los días.missingok
: ignorar si no se encuentra el archivo de log.notifempty
: no rotar si el archivo de log está vacío.compress
: comprimir las copias con gzip.delaycompress
: no comprimir la última rotación.postrotate
: script para controlar el proceso que está escribiendo en el log (se delimita conendscript
).
De acuerdo a la documentación de Nginx, es posible indicarle al servidor que reabra sus archivos de log enviando la señal USR1
(man kill
). Si se quisiera rotar un log manualmente, sería tan simple como:
# mv access.log access.log.0 # kill -USR1 `cat /var/run/nginx.pid` # sleep 1 # gzip access.log.0
En este caso Nginx guarda sus logs dentro del directorio /usr/local/nginx/logs/
y el PID en el archivo /var/run/nginx.pid
. De esta forma, el script definido desde postrotate
a endscript
envía la señal USR1
al servidor Nginx (verificando previamente que el archivo que contiene el PID exista):
[ ! -f /var/run/nginx.pid ] || kill -USR1 `cat /var/run/nginx.pid`
Ajustar estas rutas según sea necesario.
Para rotar los logs por primera vez, ejecutar:
root@debian:~# logrotate -f /etc/logrotate.conf
Se observa que los logs han sido rotados con éxito:
root@debian:~# ls -lhd /usr/local/nginx/logs/* -rw-r--r-- 1 www-data staff 44K Aug 7 12:01 /usr/local/nginx/logs/access-ssl.log -rw-r--r-- 1 www-data staff 685M Aug 7 12:00 /usr/local/nginx/logs/access-ssl.log.1 -rw-r--r-- 1 www-data staff 1.7K Aug 7 12:01 /usr/local/nginx/logs/access.log -rw-r--r-- 1 www-data staff 165M Aug 7 12:00 /usr/local/nginx/logs/access.log.1
Tener en cuenta que, con esta configuración, la primera rotación no se comprime. Esto es para mantener accesible de forma relativamente sencilla la última rotación, en caso de que el programa que escribe en el log siga escribiendo en el mismo luego de un tiempo. A partir de la segunda rotación, la copia se comprime.
Referencias