O redirecionamento de log acontece para o log rotacionado em vez de um novo log ser criado

0

Objetivo

Portanto, escrevi um script que registra e rotaciona logs se atingir determinado tamanho. Eu desejo capturar todos os erros e gerar outros comandos também, em vez daqueles que eu deliberadamente faço eco no log.

A maneira como consegui isso foi redirecionando STDIN e STDOUT para tee em uma substituição de processo e escrevi uma pequena função que faz uso de savelog para rotacionar logs.

#!/bin/bash

LOGFILE="/var/log/ps.log"
exec > >(tee "$LOGFILE") 2>&1

LOGPATH="/var/log"
MAX_LOGFILE_SIZE=5
rotateLog() {
        currentsize=$(du -k $LOGFILE | cut -f1)
        if [ $currentsize -ge $MAX_LOGFILE_SIZE ]; then
                savelog -dn $LOGFILE &>/dev/null
        fi
}

while :; do
    echo "A computer program can easily produce gibberish - especially if it has been provided with garbage beforehand. This program does something a little different. It takes a block of text as input and works out the proportion of characters within the text according to a chosen order. For example, an order of 2 means the program looks at pairs of letters, an order of 3 means triplets of letters and so on. The software can regurgitate random text that is controlled by the proportion of characters. The results can be quite surprising."

    rotateLog

    sleep 5
done

Problema

O problema é que mesmo após o log ps.log ser rotacionado para ps.log.20180829131658 , todos os logs ainda são gravados em ps.log.20180829131658 e o seguinte erro é lançado:

du: não pode acessar '/var/log/ps.log': Nenhum arquivo ou diretório ./ps.sh: linha 12: [: -ge: operador unário esperado

Levando a nenhuma rotação adicional de logs !!!

Suposição

Eu estava assumindo que, quando ps.log for rotacionado para ps.log.20180829131658 , um novo arquivo de log ps.log será criado. Mas definitivamente esse não é o caso, já que exec é executado apenas uma vez ( alguém pode, por favor, explicar o que exatamente acontece aqui? ), isto é, no início do script.

Observação

O que eu também observei que um novo descritor de arquivo é criado para >(tee "$LOGFILE") que aponta para /var/log/p.log que é reatribuído para p.log.20180829131658 ! Isso é o que claramente resulta em registros ainda sendo gravados em p.log.20180829131658 . Alguém pode, por favor, explicar este comportamento?

root@b537ccc2c1ab:/var/log# ls -lrt
-rw-r--r-- 1 root root   7248 Aug 29 13:16 ps.log

root@b537ccc2c1ab:/var/log# ls -lrt /proc/*/fd
/proc/8979/fd:
total 0
l-wx------ 1 root root 64 Aug 29 13:16 3 -> /var/log/ps.log
lrwx------ 1 root root 64 Aug 29 13:16 2 -> /dev/pts/17
lrwx------ 1 root root 64 Aug 29 13:16 1 -> /dev/pts/17
lr-x------ 1 root root 64 Aug 29 13:16 0 -> pipe:[3889791]


root@b537ccc2c1ab:/var/log# ls -lrt
-rw-r--r-- 1 root root  11098 Aug 29 13:17 ps.log.20180829131658

root@b537ccc2c1ab:/var/log# ls -lrt /proc/*/fd
/proc/8979/fd:
total 0
l-wx------ 1 root root 64 Aug 29 13:16 3 -> /var/log/ps.log.20180829131658
lrwx------ 1 root root 64 Aug 29 13:16 2 -> /dev/pts/17
lrwx------ 1 root root 64 Aug 29 13:16 1 -> /dev/pts/17
lr-x------ 1 root root 64 Aug 29 13:16 0 -> pipe:[3889791]

Como posso alcançar meu objetivo com esse esquema de registro e rotação de log? Em particular, como meu script pode gravar em arquivos de log mais recentes além da rotação de log durante a captura de erros e saídas de todos os outros comandos no meu script ao lado?

    
por codingkapoor 29.08.2018 / 17:53

2 respostas

1

Quando um processo abre um arquivo, você pode fazer todo tipo de coisa para esse arquivo, como renomeá-lo, truncá-lo, até excluí-lo, mas o processo ainda terá esse arquivo aberto. Um erro comum é quando um arquivo de log usou todo o espaço em disco, um exclui o arquivo em uma tentativa de liberar espaço. No entanto, o processo de gravação no arquivo de log ainda é aberto, portanto, o espaço não é liberado. Somente quando o processo fechar o arquivo, os blocos alocados para o arquivo serão liberados. (A solução aqui é truncar o arquivo, ou seja, > logfile .)

No seu caso, você renomeou o arquivo, mas o processo de escrever para ele não sabe ou se importa com isso.

O utilitário logcheck tem uma opção copytruncate para tais situações: copia o arquivo de log para o nome rotacionado e, em seguida, trunca o original. Você pode fazer o mesmo:

rotateLog() {
    currentsize=$(du -k $LOGFILE | cut -f1)
    if [ $currentsize -ge $MAX_LOGFILE_SIZE ]; then
            ROTATEDLOG=$LOGFILE.$(date +%Y%m%d%H%M%S)
            cp -p $LOGFILE $ROTATEDLOG && true > $LOGFILE
    fi
}

Uma alternativa melhor seria modificar o processo para compreender, e. o sinal SIGHUP para fechar e reabrir o arquivo de registro. Veja o comando shell trap para lidar com isso.

    
por 30.08.2018 / 11:31
0

Com base em uma solução alternativa sugerida por @wurtel, eu trabalhei assim,

#!/bin/bash

LOGFILE="/root/logr/simple.log"

function sighuphandler() {
    exec > >(tee "$LOGFILE") 2>&1
}

trap sighuphandler SIGHUP

LOGPATH="/root/logr"
MAX_LOGFILE_SIZE=5
rotateLog() {
    currentsize=$(du -k $LOGFILE | cut -f1)
    if [ $currentsize -ge $MAX_LOGFILE_SIZE ]; then
            savelog -dn $LOGFILE &>/dev/null
            kill -s SIGHUP $$
    fi
}

sighuphandler
while :; do
    echo "['date "+%Y-%m-%d %H:%M:%S"'] [INFO] - A computer program can easily produce gibberish - especially if it has been provided with garbage beforehand. This program does something a little different. It takes a block of text as input and works out the proportion of characters within the text according to a chosen order. For example, an order of 2 means the program looks at pairs of letters, an order of 3 means triplets of letters and so on. The software can regurgitate random text that is controlled by the proportion of characters. The results can be quite surprising."

    ls +

    rotateLog

    sleep 5
done
    
por 31.08.2018 / 12:09

Tags