Substituir cronolog en nginx mandando los logs por syslog
Es común usar cronolog con Apache para realizar la rotación de logs, pero en nginx no podremos usarlo. Vamos a ver como usar un script para realizar la rotación.
Suponiendo una configuración similar a la siguiente de cronolog:
ErrorLog "| /usr/local/sbin/cronolog -S /var/www/systemadmin.es/logs/current.error.log /var/www/systemadmin.es/logs/%Y/%m/%d/error.log" CustomLog "| /usr/local/sbin/cronolog -S /var/www/systemadmin.es/logs/current.custom.log /var/www/systemadmin.es/logs/%Y/%m/%d/custom.log" combined
Mediante el siguiente script realizaremos la rotación de logs cada día a las 12 de la noche:
#!/bin/bash
PIDNGINX=/usr/local/logs/nginx.pid
for i in /usr/local/etc/nginx.conf /usr/local/etc/nginx/vhosts/*;
do
ACCESSLOG=$(cat $i | grep access | awk '{ print $NF }' | sed 's/;//g' | grep -v "^off$"; )
if [ -n "$ACCESSLOG" ];
then
APATHLOG=$(dirname ${ACCESSLOG})
AFILENAME=$(basename ${ACCESSLOG})
fi
ERRORLOG=$(cat $i | grep error_log | awk '{ print $NF }' | sed 's/;//g' | grep -v "^off$"; )
if [ -n "$ERRORLOG" ];
then
EPATHLOG=$(dirname ${ERRORLOG})
EFILENAME=$(basename ${ERRORLOG})
fi
if [ -n "$ACCESSLOG" ];
then
mkdir -p $APATHLOG/$(date +%Y/%m/%d --date='1 day ago')
mv $ACCESSLOG $APATHLOG/$(date +%Y/%m/%d --date='1 day ago')/$AFILENAME
fi
if [ -n "$ERRORLOG" ];
then
mkdir -p $EPATHLOG/$(date +%Y/%m/%d --date='1 day ago')
mv $ERRORLOG $EPATHLOG/$(date +%Y/%m/%d --date='1 day ago')/$EFILENAME
fi
done
kill -USR1 $(cat $PIDNGINX)
for retry in $(seq 1 100);
do
SUM=0
for i in /usr/local/etc/nginx.conf /usr/local/etc/nginx/vhosts/*;
do
ACCESSLOG=$(cat $i | grep access | awk '{ print $NF }' | sed 's/;//g' | grep -v "^off$"; )
ERRORLOG=$(cat $i | grep error_log | awk '{ print $NF }' | sed 's/;//g' | grep -v "^off$"; )
if [ -n "$ERRORLOG" ];
then
EPATHLOG=$(dirname ${ERRORLOG})
EFILENAME=$(basename ${ERRORLOG})
if [ $(/usr/sbin/lsof $EPATHLOG/$(date +%Y/%m/%d --date='1 day ago')/$EFILENAME | wc -l) -gt 0 ];
then
SUM=$(echo $SUM+1 | bc)
sleep 1;
fi
fi
if [ -n "$ACCESSLOG" ];
then
APATHLOG=$(dirname ${ACCESSLOG})
AFILENAME=$(basename ${ACCESSLOG})
if [ $(/usr/sbin/lsof $APATHLOG/$(date +%Y/%m/%d --date='1 day ago')/$AFILENAME | wc -l) -gt 0 ];
then
SUM=$(echo $SUM+1 | bc)
sleep 1;
fi
fi
done
if [ $SUM -eq 0 ];
then
for i in /usr/local/etc/nginx.conf /usr/local/etc/nginx/vhosts/*;
do
ACCESSLOG=$(cat $i | grep access | awk '{ print $NF }' | sed 's/;//g' | grep -v "^off$"; )
ERRORLOG=$(cat $i | grep error_log | awk '{ print $NF }' | sed 's/;//g' | grep -v "^off$"; )
for LOG in $ERRORLOG $ACCESSLOG;
do
if [ -n "$LOG" ];
then
LPATHLOG=$(dirname ${LOG})
LFILENAME=$(basename ${LOG})
LTAG=$(basename $LPATHLOG)
cat $LPATHLOG/$(date +%Y/%m/%d --date='1 day ago')/$LFILENAME | (
while read line;
do
echo $line | logger -p local6.notice -t $LTAG;
done
)
ionice -n3 gzip -f $LPATHLOG/$(date +%Y/%m/%d --date='1 day ago')/$LFILENAME
fi
done
done
exit 0;
fi
done
echo "ERROR LOG ROTATE NGINX: $SUM"
exit 1
El script espera los siguientes ficheros:
- El PID del nginx en el path:
PIDNGINX=/usr/local/logs/nginx.pid
- La configuración del nginx en:
/usr/local/etc/nginx.conf
Con los virtualhosts separados en ficheros dentro de:
/usr/local/etc/nginx/vhosts/
Con esto busca los access log y los error log para rotarlos según lo haríamos con el cronolog por años, meses y días.
Una vez rotados comprueba que el nginx ya ha dejado de escribir en ellos mediante lsof, sino se espera hasta que los libere. Una vez ya sabemos que no se va a escribir ninguna lineas más en ellos se mandan al syslog mediante logger para luego comprimirlos con el gzip a baja prioridad.
Relacionados
Imprimir
Deja un comentario: