Logrotate O arquivo original bem-sucedido volta ao tamanho original

11

Alguém já teve problemas com o logrotate antes que faz com que um arquivo de log seja rotacionado e depois volte ao mesmo tamanho que era originalmente? Aqui estão minhas descobertas:

Script de logrotação:

/var/log/mylogfile.log {
    rodar 7
    diariamente
    comprimir
    olddir / log_archives
    missingok
    notifempty
    copytruncate
}

Saída detalhada do logrotate:

copiando /var/log/mylogfile.log para /log_archives/mylogfile.log.1
truncando /var/log/mylogfile.log
compactando log com: / bin / gzip
removendo o log antigo /log_archives/mylogfile.log.8.gz

Arquivo de log após a truncagem

[root @ server ~] # ls -lh /var/log/mylogfile.log
-rw-rw-r-- 1 parte1 parte1 0 11 de janeiro 17:32 /var/log/mylogfile.log

Literalmente segundos depois:

[root @ server ~] # ls -lh /var/log/mylogfile.log
-rw-rw-r-- 1 parte1 parte1 3.5G 11 de janeiro 17:32 /var/log/mylogfile.log

Versão RHEL:

[root @ server ~] # cat / etc / redhat-release 
Red Hat Enterprise Linux ES versão 4 (Nahant Update 4)

Versão do logrotate:

[raiz @ DAA21529WWW370 ~] # rpm -qa | grep logrotate
logrotate-3.7.1-10.RHEL4

Algumas notas:

  • O serviço não pode ser reiniciado em tempo real; é por isso que estou usando copytruncate
  • Os logs estão girando todas as noites, de acordo com o olddirdiretório que contém arquivos de log a cada noite.
drewrockshard
fonte

Respostas:

18

Provavelmente, porque, mesmo que você trunque o arquivo, o processo de gravação no arquivo continuará sendo gravado, independentemente do deslocamento anterior. Então, o que está acontecendo é que o logrotate trunca o arquivo, o tamanho é zero, o processo grava no arquivo novamente, continuando com o deslocamento que foi deixado e agora você tem um arquivo com NULL-bytes até o ponto em que você o truncou, mais o novo entradas gravadas no log.

od -c após crescimento truncado + repentino, gerou saída ao longo das linhas de:

0000000  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0
*
33255657600  \0   C   K   B   -   s   e   r   v   e   r       [   h   t   t
33255657620 <more log output>

O que isso diz é do deslocamento de 0 a 33255657600, seu arquivo consiste em bytes nulos e alguns dados legíveis. Chegar a esse estado não leva a mesma quantidade de tempo que levaria para gravar todos esses bytes nulos. Os sistemas de arquivos ext {2,3,4} suportam algo chamado arquivos esparsos; portanto, se você procurar uma região de um arquivo que não contenha nada, presume-se que essa região contenha bytes nulos e não ocupe espaço no disco. Na verdade, esses bytes nulos não serão gravados, apenas assumidos como estando lá; portanto, o tempo necessário para ir de 0 a 3,5 GB não leva muito tempo. (Você pode testar a quantidade de tempo que leva, fazendo algo como dd if=${HOME}/.bashrc of=largefile.bin seek=3432343264 bs=1: isso deve gerar um arquivo com mais de 3 GB em alguns milissegundos).

Se você executar ls -lsseus arquivos de log depois que eles foram truncados e tiveram um crescimento repentino novamente, agora deve informar um número no início da linha que representa o tamanho real (em blocos ocupados no disco), que provavelmente é de ordem de magnitude menor do que o tamanho relatado por apenas ls -l.

Kjetil Joergensen
fonte
Acho que não - em segundos, o arquivo de log passa de 0 bytes a 3,5 GB. O tempo total necessário para concluir a rotação do log é de aproximadamente 5 minutos. Os arquivos de log não são gravados com tanta rapidez E o tamanho sempre é o tamanho original, o que parece coincidência demais.
precisa saber é o seguinte
Deve haver uma maneira fácil de verificar isso, inspecionar o arquivo e verificar se há realmente algo nele. Comece executando od -c filename | head -n 100. Provavelmente, em poucas linhas, será informado que há um caminhão cheio de bytes nulos, além das últimas entradas de log.
Kjetil Joergensen
Se for esse o caso, podemos testar se cat / dev / null> /var/log/mylogfile.log trunca o arquivo de maneira a resolver esse problema, em vez de usar logrotate incorporado em copytruncate?
mtinberg
2
O problema não está no modo como o arquivo é truncado, mas no modo como o programa grava o arquivo de log. Para truncar o arquivo de log para ser uma abordagem viável, é necessário que o programa seja gravado no arquivo de log de alguma forma procurando a posição 0. É possível que um sistema de arquivos que não suporte arquivos esparsos não tenha esse problema, embora eu não Não há como testar isso agora.
Kjetil Joergensen
1
Essa resposta final realmente fez mais sentido e a correção provavelmente acabará sendo reiniciada.
precisa saber é o seguinte
2

Estou extremamente confiante de que a Kjetil conseguiu. Drew, você ainda não está convencido com a explicação dele, mas peço que leia com atenção o que ele disse.

Se você aceitar, a correção é parar e reiniciar o aplicativo quando os logs são girados ou usar uma ferramenta como os "rotatelogs" do apache, onde você alimenta a saída do log para a ferramenta por meio de um cano, e a ferramenta cuida de girando o arquivo de log de vez em quando. Por exemplo, uma das minhas instâncias do apache registra com

ErrorLog "|/usr/sbin/rotatelogs /www/logs/error_log 604800"

o que causa muitos arquivos de log com nomes como

-rw-r--r--    1 root     root         4078 Dec 21 01:04 error_log.1292457600
-rw-r--r--    1 root     root         4472 Dec 29 08:41 error_log.1293062400
-rw-r--r--    1 root     root        78630 Jan  4 12:57 error_log.1293667200
-rw-r--r--    1 root     root        15753 Jan 12 01:10 error_log.1294272000

aparecer sem reiniciar o apache; Eu posso então comprimi-los manualmente após o fato. Observe como a rotação é feita toda semana, ou seja, a cada 604800 segundos, sendo esse o argumento passado rotatelogs.

Se você não pode parar e reiniciar o aplicativo, e ele não pode logar através de um canal, acho que você tem um problema real. Talvez outros tenham sugestões.

Chapeleiro Louco
fonte
0

seria ótimo se você pudesse enviar o logrotate inteiro.

Por que tentar usar kill -HUP? (Recarregamento clássico não reiniciando ).

Além disso ... verifique com lsof quem está acessando o arquivo.

Nikolaidis Fotis
fonte
Não é possível usar, kill -HUPpois esse aplicativo não pode ser tocado de forma alguma - é um aplicativo confidencial que não possuo (nem o gerencio - apenas gerencio o lado do sistema operacional); portanto, preciso fazer as logotações dessa maneira caminho.
precisa saber é o seguinte
1
Desculpe, a mensagem original foi enviada com antecedência, eis o restante da minha mensagem original: Entrei no sistema hoje de manhã e o arquivo voltou ao normal após o início da rotação programada /etc/cron.daily. Pergunta para todos: Existe algo que o script logrotate faz de maneira diferente da execução manual do logrotate? Meu script logrotate parece literalmente /usr/sbin/logrotate /etc/logrotate.conf. Isso é bastante desconcertante.
precisa saber é o seguinte
-1

Basta usar ">>", que significa anexar em vez de ">", o que significa criar a partir de seus scripts que gravam neste arquivo. Eu tive exatamente o mesmo problema e o corrigi usando o acréscimo no meu script.

SomeScript.sh >> output.txt

Espero que seja mais claro.

user578558
fonte
Não há indicação de que a gravação no arquivo de log seja feita usando >um script. Além disso, essa resposta é confusa porque há uma grande diferença entre >e >( )nos scripts. Finalmente, se o código que estiver escrevendo for atualizado, seria muito melhor que ele simplesmente comece a gravar no novo arquivo de log depois de logrotatefazer o seu trabalho.
kasperd
Eu edito minha resposta para ficar mais clara.
user578558