Como limpar um conteúdo do arquivo de log de redirecionamento no shell?

1

Eu uso o redirecionamento para registrar a saída da operação println para um arquivo xxx.log . Mas eu quero mover as informações de log para um arquivo separado com o nome da data atual, como 2017-08-18.log por crontab.

Eu tentei usar o comando > xxx.log shell para limpar o arquivo xxx.log , mas toda a recuperação de conteúdo quando um novo log foi gerado.

Como limpar o arquivo de log de redirecionamento?

UPDATE

  1. Depois que eu executar > xxx.log , o tamanho do arquivo xxx.log será 0.Mas se meu aplicativo imprimir um novo log, o xxx.log não apenas conterá as novas informações de log, mas também conterá as informações de log antigas desmarcadas.
  2. Depois de usar mv xxx.log xxx2.log , novas informações de log gravarão em xxx2.log .Mas se eu usar rm xxx.log em vez de renomear, a ação de log será interrompida. Além disso, o processo chamado por nohup java -jar xxx.jar > xxx.log 2>&1 & se você estiver familiarizado com playframework , o arquivo de execução será criado por um comando dist para gerar o jar arquivo.
  3. ps wx|grep "xxx.*.log output:
    1) 3912 pts/10 S+ 0:00 grep --color=auto xxx.log
    2) 26234 pts/10 Sl 0:16 /usr/lib/jvm/jdk1.8.0_111/bin/java -Duser.dir=...something ignored... play.core.server.ProdServerStart (é o comando de execução do processo)

Espero que seja útil, obrigado novamente!

    
por LoranceChen 18.08.2017 / 07:48

2 respostas

1

O problema é que seu arquivo de log permanece aberto pelo aplicativo que está gravando nele. Se você truncar o arquivo ( > file.log ), seu aplicativo ainda escreverá a partir do ponto de sua última gravação (devido ao truncamento, suponho que seu arquivo será preenchido com 0 bytes até esse ponto). Se você mover o arquivo, seu aplicativo continuará a gravar, pois, uma vez aberto, o nome não importa. Se você remover o arquivo, os blocos não serão liberados do disco e o aplicativo ainda estará gravando nele, mesmo que o arquivo não esteja mais visível em seu diretório.

Este é um cenário clássico. Sua inscrição deve:

  • reabra o arquivo de log periodicamente
  • ou detectar que ele foi truncado e reabri-lo
  • ou aguarde um sinal especial que diz "feche o arquivo de log atual e reabra-o"

Senão, não há nada que você possa fazer externamente, exceto reiniciar seu aplicativo. Você faria então da mesma maneira que logrotate :

  • primeiro mova o arquivo de log com um novo nome
  • opcionalmente touch do arquivo de log com seu nome antigo para que o arquivo exista
  • reinicie o aplicativo para forçá-lo a parar de gravar no arquivo de log antigo e começar a gravar no novo.
por 18.08.2017 / 11:53
0

Se você está bem com o Perl você pode rodar este pequeno script:

use POSIX qw(strftime);

$fbase = "tmp-%Y-%m-%d-%H-%M.log";

while(<>)
{
  $fnamenew = strftime $fbase, localtime;

  if ($fnamenew ne $fname)
  {
    print "logging to: $fnamenew\n";
    $fname = $fnamenew;
    close OUT;
    open OUT, ">$fname";
  }
  print OUT $_;
}

Use como: $mycomputation | perl script.pl . Ele adicionará todas as entradas a um nome de arquivo criado a partir do padrão de tempo especificado, aqui tmp-YYYY-MM-DD-HH-MI.log . Em cada nova linha de entrada, o padrão é recriado e verificado em relação ao antigo. Caso seja diferente, a entrada será canalizada para o novo arquivo e o antigo será fechado.

    
por 18.08.2017 / 20:01