我能够使用 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
,,,,,lrzip
lzop
lz4
lzip
但是,您的代码片段存在明显的数据丢失问题:
...
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