Existe uma maneira de remover as primeiras N
linhas de um log que está sendo anexado ativamente por um aplicativo?
Existe uma maneira de remover as primeiras N
linhas de um log que está sendo anexado ativamente por um aplicativo?
Respostas:
Não, sistemas operacionais como o Linux e seus sistemas de arquivos não prevêem a remoção de dados desde o início de um arquivo. Em outras palavras, o ponto inicial de armazenamento de um arquivo é fixo.
A remoção de linhas do início de um arquivo geralmente é realizada gravando os dados restantes em um novo arquivo e excluindo o antigo. Se um programa tiver o arquivo antigo aberto para gravação, a exclusão desse arquivo será adiada até que o aplicativo feche o arquivo.
Como comentaram os comentadores, pelas razões indicadas na minha frase anterior, você geralmente precisa coordenar a remoção do arquivo de log com os programas que estão escrevendo os logs. Exatamente como você faz isso depende dos programas. Alguns programas fecham e reabrem seus arquivos de log quando você envia um sinal (por exemplo, HUP) e isso pode ser usado para impedir que os registros sejam gravados em um arquivo de log 'excluído', sem interromper o serviço.
Existem muitos utilitários disponíveis para gerenciar o tamanho dos arquivos de log, por exemplo, logrotate
Alguns programas têm seus próprios utilitários. Por exemplo, o servidor da web Apache inclui um utilitário rotatelogs .
Eu acho que essa tarefa pode ser realizada com sed
sed -i '1,10d' myfile
iria remover as linhas de 1 r a o 10 th forma de linha do ficheiro.
Eu acho que todo mundo deveria, pelo menos, dar uma olhada neste sed 1 liners .
Observe que isso não funciona para arquivos de log que estão sendo anexados ativamente por um aplicativo (conforme indicado na pergunta).
sed -i
irá criar um novo arquivo e 'excluir' o arquivo que está sendo gravado. A maioria dos aplicativos continuará gravando registros de log no arquivo de log excluído e continuará preenchendo espaço em disco. O novo arquivo de log truncado não será anexado. Isso só cessará quando o aplicativo for reiniciado ou for sinalizado para fechar e reabrir seus arquivos de log. Nesse ponto, haverá uma lacuna (faltando registros de log) no novo arquivo de log se houver alguma atividade registrável entre o uso do sed e a reinicialização do aplicativo.
Uma maneira segura de fazer isso seria interromper o aplicativo, usar sed para truncar o log e reiniciar o aplicativo. Essa abordagem pode ser inaceitável para alguns serviços (por exemplo, um servidor Web com alto rendimento e altos requisitos de continuidade de serviço)
sed -i
cria um novo arquivo com o conteúdo editado e o antigo é removido para que você não esteja editando o arquivo ativo: $ ls -i --- 6823554 testfile --- $ sed -i 's/test/final/' testfile --- $ ls -i --- 6823560 testfile
------ Verifique como sed -i
funciona. Por que essa resposta errada tem tantos votos positivos?
Não. Uma solução para esse problema genérico de crescimento do arquivo de log é a rotação do log. Isso envolve a movimentação regular (noturna ou semanal, normalmente) de um arquivo de log existente para outro nome de arquivo e começar de novo com um arquivo de log vazio. Após um período, os arquivos de log antigos são descartados.
Consulte: http://www-uxsup.csx.cam.ac.uk/~jw35/courses/apache/html/x1670.htm
Esta é uma resposta , não uma solução. Não há solução para a questão. O solicitante declara claramente: "a partir de um log que está sendo anexado ativamente por um aplicativo". Você pode ler para entender mais e pular para o final para obter uma sugestão que faço com base na minha presunção de que esse código não está seguindo as práticas recomendadas de log.
Para ser claro: outras "respostas" aqui oferecem a promessa falsa . Nenhuma renomeação levará o aplicativo a usar o novo arquivo. As informações mais úteis estão ocultas nos comentários feitos para essas respostas incorretas.
Arquivos ATIVOS não são algum tipo de contêiner no qual você simplesmente coloca os dados. Um nome de arquivo aponta para UM inode (início do arquivo) e todo inode possui um ponteiro para outro inode (se houver mais dados). Isso significa que um arquivo gravado continuamente tem um fluxo constante de inodes sendo adicionado a ele, e o que você pensa de um "arquivo" é na verdade uma sequência de log de inodes.
Imagine que você estava rastreando alguém no Google Maps, e essa pessoa poderia se teletransportar para qualquer lugar do mundo, a qualquer momento, e você estava tentando conectar esses pontos.
A ferramenta Linux "truncar" pode descartar dados no final do arquivo, simplesmente andando na árvore de inodes e (no local / tamanho que você designar) descartará todos os ponteiros subseqüentes na pilha. Fazer o inverso - descartar dados no início do arquivo - seria um processo tão complexo e arriscado de reescrever a árvore de inodes em tempo real que ninguém escreverá essas ferramentas para o público, porque elas geralmente falham e levam a perda de dados. O wiki do Inodes é curto, mas explica alguns desses conceitos.
** Meu conselho: inverter esse problema - POR QUE esse aplicativo está se comportando dessa maneira? Existem muitas práticas recomendadas para registro em log, mas geralmente elas estão vinculadas ao que realmente é o seu sistema de registro (syslog, etc.). No núcleo, espera-se que um aplicativo "libere" seu identificador para o arquivo, para que o logrotate (etc) possa manipular o processamento adicional dos dados antigos.
Sempre que ouço "em um arquivo de log ATIVO", solicito imediatamente que essa pessoa me conte a "história especial" por trás deste aplicativo. Geralmente é "o desenvolvedor parou de trabalhar e não podemos alterar o código. Na verdade, é o inverso da segurança, tem seu próprio conjunto de riscos. Mas quero que você queira uma solução que evite tocar no código-fonte. Se esse for o Nesse caso, é necessária uma pergunta mais específica.
Abrindo em texto sublime A exclusão das linhas e o salvamento do arquivo funcionam de alguma forma, mesmo que o arquivo esteja sendo anexado, mas eu vim aqui para procurar a solução em busca de uma solução de linha de comando, para que eu deixasse essa solução útil, mas inútil aqui !!
Talvez copie, trunque, coloque a cópia de volta no tamanho = 0 e exclua a cópia?
Melhor ainda, copiar a cauda, truncar original, concat-copiar no original.
Você obtém linhas no log no comprimento da cauda, melhor do que um limite de comprimento de bytes.
Alterando detalhes do comentário:
Primeiro, temos um script de logger em Python3, o que você quiser
from time import sleep
idx = 0
while 1 == 1:
idx = (idx + 1)
lf = open('tailTrunc.log', 'a')
lf.write("line to file " + str(idx) + '\n')
lf.close()
sleep(0.01)
Então nós temos nosso truncador
#!/usr/bin/env bash
trap "kill 0" EXIT
rm tailTrunc.log
touch tailTrunc.log
python3 logLoop.py &
loggerPID=$!
sleep 1
kill -STOP $loggerPID
tail -10 tailTrunc.log > trimEnd.log
truncate -s 0 tailTrunc.log
kill -CONT $loggerPID
sleep 1
trimEnd.log mostra 80 a 89
log mostra 90 até o fim
De qualquer forma, onde há vontade, há um caminho.
Muitos exemplos mais complicados de consolidadores e como o fluxo de gravação é aberto ou fechado podem precisar de ajustes por núcleo da CPU, etc. basta pausar a gravação e a fila, se você puder no logger o processo de registro etc.