Dividir registros cada hora con logrotate y comprimir con zstd
servidor
Lastmod: 2023-11-30
Published: 2021-03-29

Quería dividir los registros de nginx cada hora mientras los comprimía con zstd, así que aquí dejo una nota.

Resumen

Si se configura directamente en /etc/logrotate.conf o en /etc/logrotate.d/, se ejecutará normalmente a través del CRON diario en /etc/cron.daily/logrotate.

Como queremos hacer la rotación de registros cada hora, prepararemos una configuración de logrotate diferente y la haremos ejecutar utilizando la función de temporizador de systemd.

Habilitar zstd

# apt install zstd

logrotate

Crearemos /etc/logrotate-nginx.conf.
Aunque en esta ocasión usaremos zstd, se puede cambiar a bzip2 y configurarlo de la misma manera.

# cat << _EOF_ > /etc/logrotate-nginx.conf
compresscmd /usr/bin/zstd # Especificar la ruta de zstd
compressoptions -12       # Opciones para zstd. Personalmente, -12 funcionó bien
compressext .zst          # Extensión a añadir

/var/log/nginx/*.log {
        missingok
        rotate 720 # 24 horas * 30 días 
        dateext
        dateformat -%Y%m%d%H
        compress
        notifempty
        create 0640 www-data adm
        sharedscripts
        prerotate
                if [ -d /etc/logrotate.d/httpd-prerotate ]; then \
                        run-parts /etc/logrotate.d/httpd-prerotate; \
                fi \
        endscript
        postrotate
                invoke-rc.d nginx rotate >/dev/null 2>&1
        endscript
}
_EOF_

systemd

  • Definir el servicio
# cat << _EOF_ > /etc/systemd/system/logrotate-nginx.service
[Unit]
Description=logrotate-nginx
After=network.target
[Service]
Type=simple
ExecStart=/usr/sbin/logrotate -f /etc/logrotate-nginx.conf
PrivateTmp=true
[Install]
WantedBy=multi-user.target
_EOF_
  • Definir el temporizador
# cat << _EOF_ > /etc/systemd/system/logrotate-nginx.timer
[Unit]
Description=logrotate-nginx
[Timer]
OnCalendar=*:00:00
[Install]
WantedBy=timers.target
_EOF_
  • Cargar la configuración de systemd
# systemctl daemon-reload
  • Habilitar el temporizador
# systemctl enable logrotate-nginx.timer
  • Iniciar el temporizador
# systemctl start logrotate-nginx.timer
  • Comprobar el estado del temporizador
# systemctl status logrotate-nginx.timer
● logrotate-nginx.timer - logrotate-nginx
     Loaded: loaded (/etc/systemd/system/logrotate-nginx.timer; enabled; vendor preset: enabled)
     Active: active (running) since Mon 2021-03-29 20:00:00 JST; 5h 58min ago
    Trigger: n/a
   Triggers: ● logrotate-nginx.service

Mar 29 19:00:00 log systemd[1]: Started logrotate-nginx.

Se puede conocer la hora de la próxima ejecución y la hora de las ejecuciones pasadas usando Activo🎉

Actualización de noviembre de 2023

Si bien no es tan problemático con la rotación cada hora, al dividir los registros en intervalos de un minuto, puede haber un desfase debido a la precisión del temporizador. Esto puede resultar en tiempos que no se esperaban.

Por lo tanto, si desea que se ejecute exactamente en el segundo cero, es mejor configurar de la siguiente manera.

[Unit]
Description=logrotate-nginx
[Timer]
OnCalendar=*:*:00
AccuracySec=1s
[Install]
WantedBy=timers.target

Especificando AccuracySec se puede programar la ejecución con una precisión de un segundo.