Append to compressed log

1

1

There is a couple of z-utilities (zless, zcat), which are able to read contents of zipped file in transparent manner.

Is it possible to append to compressed log file (in either format, not necessarily gzip)?

I want something like the following (ztee is imaginary utility with functionality of interest):

echo "[ $( date ) ] message" | ztee -a file.log.gz

Tomilov Anatoliy

Posted 2018-01-15T10:25:51.327

Reputation: 251

Did you try it? What was the result? – Seth – 2018-01-15T11:01:51.863

@Seth tried what? – Tomilov Anatoliy – 2018-01-15T11:40:42.017

Well you actually do have a command right there. Did you try to run it, assuming ztee exists? Also have a look at the man page for zless as it might give you some more leads.

– Seth – 2018-01-15T12:55:02.133

@Seth Where have I command? ztee not exists. I know about zless existance - how can it help me to solve the problem? If I run imaginary pseudocode in the shell, then I definitely get an error. For sure. Surely I didn't try to run it. Actually assumption of ztee existence gives nothing to me in real life. – Tomilov Anatoliy – 2018-01-15T13:15:49.207

You didn't make it clear. The man page kind of shows you what zless is actually doing (more or less an alias for gzip). Grawity already took his time to explain what you can do and you accepted it as an answer. The gzip man page has examples that pretty much do the same. – Seth – 2018-01-16T07:24:43.120

@Seth and.... what? You just listed the trivia. What do you want? – Tomilov Anatoliy – 2018-01-16T07:51:47.160

I'm providing feedback in order for you to ask better questions going forward and the reason I mentioned the man page. – Seth – 2018-01-16T08:01:03.973

@Seth Thank you. Maybe the problem (of mine) in the language barrier. – Tomilov Anatoliy – 2018-01-16T08:27:51.283

Answers

3

Yes, but it's useless.


Some compressed file formats – including the ones used by gzip, bzip2, and xzdo support concatenation natively. (It may require explicit opt-in when using low-level APIs, but command-line decompressors accept it by default.)

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

(Note that e.g. zcat is literally just a shellscript wrapper for gunzip...)

However, this means that each log message is compressed individually, without taking into account all the previous contents. As a result, if you try to chain many short log messages, your compression ratios will be very, very poor. (In my tests compressing a random log file this way, the resulting file actually grew to 120% its original size, because of all the repeated "header" overhead.)

$ 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

To my knowledge, there is no tool which would support loading the existing compressed file's headers and use it to compress new data. To achieve this, you would need to run a persistent gzip process and periodically feed it logs via stdin. For example:

#!/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]}>&-

In "standard" shell, you could achieve the same using named pipes, or even more simply redirecting the whole script through gzip. (Just print the same message once to stdout and once to stderr, and you have your tee.)


Further information on compressed stream concatenation:

user1686

Posted 2018-01-15T10:25:51.327

Reputation: 283 655

So with minimal usefulness it is required to reread whole the file. I don't want to loose intermediate progress in case of accidental system failure. – Tomilov Anatoliy – 2018-01-15T13:57:20.110

2Then just don't compress active logs in the first place. The more complexity the more likely it is to somehow fail. – user1686 – 2018-01-15T13:58:40.927

Eventually I came to the same conclusions. Thank you. – Tomilov Anatoliy – 2018-01-16T07:53:48.657