Search code examples
bashredisoutputmonitoringredis-cli

Saving filtered redis-cli output to a file


I am trying to find when and how the cache is flushed, planned to use the command redis-cli monitor | grep -iE "del|flush" > redis_log.txt for that, but for some reason the file is empty. If i use the command without > redis_log.txt part - it shows a correct output in the terminal, if i use redis-cli monitor > redis_log.txt command - it also saves an actual output to the file, but together it fails, only an empty file is created. Has anybody met a similar issue before?


Solution

  • As mentioned in the comments, the issue you notice certainly comes from the I/O buffering applied to the grep command, especially when its standard output is not attached to a terminal, but redirected to a file or so.

    To be more precise, see e.g. this nice blog article which concludes with this wrap-up:

    Here’s how buffering is usually set up:

    • STDIN is always buffered.
    • STDERR is never buffered.
    • if STDOUT is a terminal, line buffering will be automatically selected. Otherwise, block buffering (probably 4096 bytes) will be used.

    […] these 3 points explain all “weird” behaviors.

    General solution

    To tweak the I/O streams buffering of a program, a very handy program provided by coreutils is stdbuf.

    So for your use case:

    • you may want to replace grep -iE "del|flush" with:
      stdbuf -o0 grep -iE "del|flush" to completely disable STDOUT buffering;
    • or if you'd like some trade-off and just have STDOUT line-buffering,
      you may want to replace grep -iE "del|flush" with:
      • either stdbuf -oL grep -iE "del|flush",
      • or grep --line-buffered -iE "del|flush".

    Wrap-up

    Finally as suggested by @jetchisel, you'll probably want to redirect STDERR as well to your log file in order not to miss some errors messages… Hence, for example:

    redis-cli monitor | stdbuf -o0 grep -iE "del|flush" > redis_log.txt 2>&1