有人能帮我如何在 while 循环中压缩这些单独的日志文件吗

有人能帮我如何在 while 循环中压缩这些单独的日志文件吗

我能够使用 while 循环将大型日志文件 (filename.log) 的 o/p 拆分为每个 1 分钟的单个日志文件 (filename.log.140108),但由于 VM 的容量问题,我希望将这些文件保存为 zip 文件。有人可以帮忙吗?

#!/bin/bash
log_file=/home/tmp/filename.log
tmp_log_file=/home/tmp/filename.log.$$
while true;
do
    sleep 60
    cp $log_file $tmp_log_file
    >$log_file
    mv $tmp_log_file $log_file.$(date +%M%D%Y%H%M) // CODE

----------- 电流输出 ---------------

-rw-r--r-- 1 root     root    16789643 Nov  6 14:05 filename.log // Master log file
-rw-r--r-- 1 root     root     2277376 Nov  6 14:01 filename.log.140108 // 1 min log made from master log
-rw-r--r-- 1 root     root     3862528 Nov  6 14:02 filename.log.140208
-rw-r--r-- 1 root     root     5558272 Nov  6 14:03 filename.log.140308
-rw-r--r-- 1 root     root     7147520 Nov  6 14:04 filename.log.140408

------------ 预期输出 -----------------

rw-r--r-- 1 root     root     2277376 Nov  6 14:01 filename.log.140108.gz
-rw-r--r-- 1 root     root     3862528 Nov  6 14:02 filename.log.140208.gz
-rw-r--r-- 1 root     root     5558272 Nov  6 14:03 filename.log.140308.gz
-rw-r--r-- 1 root     root     7147520 Nov  6 14:04 filename.log.140408.gz  

答案1

对于压缩,您可以使用任意压缩工具,例如pigz(多线程gzip)、pbzip2(多线程bzip2) 或xz -T0。 旧的和众所周知的.gz格式由pigz或生成gzip

更多工具和算法(一些是多线程的,一些是单线程的):zstd -T0,,,,,lrziplzoplz4lzip

但是,您的代码片段存在明显的数据丢失问题:

    ...
    cp $log_file $tmp_log_file
    # Here. This is a race window.
    # Whatever gets logged here will be lost!
    >$log_file
    ...

附件是一个大纲,展示了如何解决原子性(数据丢失)问题,同时添加标准.gz压缩。

如果记录器进程长时间运行且不重新打开日志文件(在信号以外的场合HUP),那么您将不需要硬链接技巧(ln -f ...),并且mv后面跟一个kill -HUP就足够了。此方法将包括一个"$log_file"不存在的时间窗口。

如果记录器进程可以独立于脚本操作重新启动,并且/或者日志可以来自多个短暂的进程,则下面显示的原子日志文件交换过程将是必要的,以防止数据丢失。这种方法保证 (1)"$log_file"始终存在,并且 (2) 所有日志都将存储在每分钟日志文件中的一个中。

#!/bin/bash

log_file='/home/tmp/filename.log'
old_log_file="/home/tmp/filename.log.$$.old"
new_log_file="/home/tmp/filename.log.$$.new"

for ((;;)); do
    sleep 60
    logger_PID="$(... find the PID of the logging process ...)"
    # Alternative to the following 3 lines: man renameat2
    ln -f "$log_file" "$old_log_file"  # keep writing the log
    touch "$new_log_file"              # prepare a new, empty log
    mv "$new_log_file" "$log_file"     # break the link atomically
    kill -HUP "$logger_PID"            # switch to the new log
    # At this point:
    # * $log_file is written.
    # * $old_log_file is stable.
    pigz < "$old_log_file" > "$log_file.$(date +%M%D%Y%H%M).gz"
    # This^^^ can be pbzip2 or any other compression tool.
done

相关内容