Anexar ao log compactado

1

Existem alguns utilitários z ( zless , zcat ), que podem ler o conteúdo do arquivo compactado de maneira transparente.

É possível anexar ao arquivo de log compactado (em qualquer formato, não necessariamente gzip)?

Eu quero algo como o seguinte ( ztee é um utilitário imaginário com funcionalidade de interesse):

echo "[ $( date ) ] message" | ztee -a file.log.gz
    
por Orient 15.01.2018 / 11:25

1 resposta

3

Sim, mas é inútil.

Alguns formatos de arquivo compactados, incluindo os usados por gzip , bzip2 e xz - do suportam a concatenação nativamente. (Ele pode requer uma opção explícita ao usar APIs de baixo nível, mas os descompactadores de linha de comando aceitam isso por padrão.)

echo "test 1" | gzip >> log.txt.gz
echo "test 2" | gzip >> log.txt.gz
echo "test 3" | tee >(gzip >> log.txt.gz)
echo "test 4" | (tee /dev/fd/3 | gzip >> log.txt.gz) 3>&1
zcat log.txt.gz

(Observe que, por exemplo, zcat é literalmente apenas um invólucro de shellscript para gunzip ...)

No entanto, isso significa que cada mensagem de log é compactada individualmente, sem levar em conta todo o conteúdo anterior. Como resultado, se você tentar encadear muitas mensagens de log curtas, suas taxas de compactação serão muito muito ruins. (Nos meus testes compactando um arquivo de log aleatório dessa forma, o arquivo resultante, na verdade, cresceu para 120% do tamanho original, devido a toda a sobrecarga repetida de "cabeçalho".)

$ dmesg > test.log
$ cat test.log | gzip > test-single.log.gz
$ cat test.log | while read -r line; do
                     echo "$line" | gzip
                 done > test-concat.log.gz
$ du -h test*
500K     test-concat.log.gz
416K     test.log
64K      test-single.log.gz

No meu conhecimento, não há nenhuma ferramenta que suporte o carregamento dos cabeçalhos do arquivo compactado existente e use-o para compactar novos dados. Para conseguir isso, você precisaria executar um processo gzip persistente e periodicamente alimentá-lo com logs via stdin. Por exemplo:

#!/bin/bash

# open a subprocess (the bash equivalent of 'popen')
coproc LOG { gzip >> log.txt.gz; }

echo "doing stuff" >&${LOG[1]}
echo "doing more stuff" >&${LOG[1]}
echo "still doing stuff" >&${LOG[1]}

# close its stdin to finish compression
exec {LOG[1]}>&-

No shell "padrão", você pode conseguir o mesmo usando pipes nomeados, ou simplesmente redirecionando todo o script até gzip . (Basta imprimir a mesma mensagem uma vez para stdout e uma vez para stderr, e você terá seu tee .)

Mais informações sobre concatenação de fluxo compactado:

  • link

  • link

    Multiple compressed files can be concatenated. In this case, gunzip will extract all members at once. If one member is damaged, other members might still be recovered after removal of the damaged member

  • link

    Concatenation: Just like with .gz and .bz2 files, it is possible to concatenate .xz files as is. The decompressor can decompress a concatenated file as if it was a regular single-stream .xz file.

por 15.01.2018 / 14:41