systemadmin.es > LAMP y web > Substituir cronolog en nginx mandando los logs por syslog

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

Deja un comentario:

XHTML - Tags permitidos:<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>