Logrotate não truncar o arquivo aberto

3

Eu tenho um sistema que está atuando simultaneamente como uma plataforma de teste e demonstração. Estou gravando uma enorme quantidade de dados gerados pelos meus sistemas que eu não estaria gravando quando isso estiver em implantação e, por causa disso, meus arquivos de log estão sendo preenchidos muito rapidamente e acabo ficando sem espaço de partição no meu disco rígido. / p>

Eu tentei logrotate , mas parece funcionar apenas se meu programa não estiver em execução. Quando os programas estão desativados, trunca corretamente o arquivo, registra uma versão compactada e descarta o restante. No entanto, quando meus programas que preenchem o arquivo de log estiverem em execução, ele criará adequadamente o arquivo compactado, mas não truncará o arquivo ativo. Estou tentando descobrir como torná-lo truncado.

Estou escrevendo nos arquivos de log com um redirecionamento simples. ProgramA>logA , programB>logB etc. Meu progam é gerado toda vez que recebo um vetor de entrada, então ele sai rapidamente. Minha suposição é que o logrotate está falhando ao truncar por causa das gravações constantes no campo, mas pode alguém confirmar um pouco que é a razão?

Onde o logrotate mantém seu arquivo de erro?

Além disso: quero modificar o comportamento do logrotate. Se ele ativar e vir um arquivo de log grande, digamos 100 MB, eu gostaria que ele criasse uma cópia de somente os últimos 1 MB do arquivo (descartando os 99 MB mais antigos do conteúdo do arquivo) antes de truncar o arquivo de log original. Eu preciso manter os dados recentes, mas não me importo muito com qualquer coisa que seja muito antiga. Alguém pode me dizer como fazer isso?

    
por dsollen 28.08.2012 / 22:09

3 respostas

0

Como prometido, um "próximo o suficiente" para o programa de buffer de anel, em algumas linhas de Perl.

Para usá-lo, passe o tamanho dos arquivos de log desejados, em bytes (mais ou menos uma linha) e dois ou mais arquivos de log. Vai alternar entre os arquivos de log a cada X bytes. Tenho certeza de que já existe um programa para fazer isso, mas não consegui encontrá-lo com uma pesquisa rápida. Por exemplo,

$ your-app | log-splitter 1048576 /var/log/your-app/log1 /var/log/your-app/log2

assumindo, é claro, que o arquivo log-splitter é executável, em $ PATH, e contém:

#!/usr/bin/perl
use warnings qw(all);
use strict;
use autodie;
use Carp;
use Fcntl qw(SEEK_SET);
use IO::Handle;

# yes, we truncate all logs at start. Sorry.
@ARGV >= 2 or croak "Usage: $0 log-size log-file...";
my ($max_size, @lognames) = @ARGV;
my @logs = map {
    open my $fh, '+>', $_;
    $fh->autoflush(1);
    $fh;
} @lognames;

my $current_size = $max_size;
my $current_log  = $#logs;
while (defined(my $line = <STDIN>)) {
    if ($current_size >= $max_size) {
        $current_log  = ($current_log + 1) % @logs;
        $current_size = 0;
        seek($logs[$current_log], 0, SEEK_SET);
        truncate($logs[$current_log], 0);
    }

    $current_size += length($line);
    print {$logs[$current_log]} $line;
}

close($_) foreach @logs;

Para esclarecer dúvidas sobre o código:

CC0
To the extent possible under law, Anthony DeRobertis has waived all copyright and related or neighboring rights to the above program (log-splitter). This work is published from: United States.

    
por 29.08.2012 / 03:40
4

Eu sei que isso é um pouco antigo, mas eu tive o mesmo problema, e a solução foi usar o redirecionamento de acréscimo ao arquivo de saída em vez de obtê-lo. Desta forma, seu aplicativo / script não bloqueará o arquivo exclusivamente.

Em vez de:

ProgramA > logA

Uso:

ProgramA >> logA 

Atenciosamente.

    
por 06.09.2013 / 13:23
2

De man logrotate :

   copytruncate
          Truncate the original log file to zero size in place after creat‐
          ing a copy, instead of moving the old  log  file  and  optionally
          creating  a  new one.  It can be used when some program cannot be
          told to  close  its  logfile  and  thus  might  continue  writing
          (appending) to the previous log file forever.  Note that there is
          a very small time slice between copying the file  and  truncating
          it,  so  some  logging  data  might be lost.  When this option is
          used, the create option will have no effect, as the old log  file
          stays in place.

Essa é provavelmente a opção que você precisa colocar no seu arquivo de configuração.

Sobre sua outra pergunta: use a diretiva postrotate para executar um comando para truncar o arquivo depois de ter sido rotacionado. Nesse caso, você deve compactá-lo manualmente nesse estágio, após o truncamento. (não realmente, esta última parte, porque logrotate não compacta o primeiro arquivo.)

EDIT: Um pouco mais sobre como manter os últimos 1 MB. Você pode configurá-lo para girar quando o arquivo de log tiver mais de, digamos, 200 K, e para manter apenas 5 backups. Dessa forma, você sempre manterá aproximadamente o último 1 MB. Se o primeiro backup for muito grande, você pode esperar até que ele "caia" depois que 5 backups forem feitos.

    
por 28.08.2012 / 22:32