kev*_*rpe 20 unix shell logging tee
我想捕获UNIX进程的输出,但限制最大文件大小和/或旋转到新文件.
我见过logrotate,但它不能实时工作.据我了解,这是一项并行运行的"清理"工作.
什么是正确的解决方案?我想我会编写一个小脚本来完成它,但我希望现有的文本工具有一个简单的方法.
想像:
my_program | tee --max-bytes 100000 log/my_program_log
会给...总是将最新的日志文件写为:log/my_program_log
然后,当它填充...重命名为log/my_program_log000001并启动一个新的log/my_program_log.
Foo*_*Bah 22
使用拆分:
my_program | tee >(split -d -b 100000 -)
Run Code Online (Sandbox Code Playgroud)
或者,如果您不想看到输出,可以直接管道拆分:
my_program | split -d -b 100000 -
Run Code Online (Sandbox Code Playgroud)
至于日志轮换,coreutils中没有自动执行此操作的工具.您可以创建符号链接并使用bash命令定期更新它:
while ((1)); do ln -fns target_log_name $(ls -t | head -1); sleep 1; done
Run Code Online (Sandbox Code Playgroud)
包apache2-utils中存在称为 的实用程序rotatelogs,它完全满足您的要求。
概要:
rotatelogs [ -l ] [ -L链接名] [ -p程序] [ -f ] [ -t ] [ -v ] [ -e ] [ -c ] [ -n文件数] 日志文件轮换时间| 文件大小(B|K|M|G) [偏移量]
例子:
your_program | rotatelogs -n 5 /var/log/logfile 1M
Run Code Online (Sandbox Code Playgroud)
您可以在此链接上阅读完整的手册。
或使用awk
program | awk 'BEGIN{max=100} {n+=length($0); print $0 > "log."int(n/max)}'
Run Code Online (Sandbox Code Playgroud)
它将线条保持在一起,因此最大值并不精确,但这对于记录目的来说可能很好.您可以使用awk的sprintf格式化文件名.
这是一个使用awk的pipable脚本
#!/bin/bash
maxb=$((1024*1024)) # default 1MiB
out="log" # output file name
width=3 # width: log.001, log.002
while getopts "b:o:w:" opt; do
case $opt in
b ) maxb=$OPTARG;;
o ) out="$OPTARG";;
w ) width=$OPTARG;;
* ) echo "Unimplented option."; exit 1
esac
done
shift $(($OPTIND-1))
IFS='\n' # keep leading whitespaces
if [ $# -ge 1 ]; then # read from file
cat $1
else # read from pipe
while read arg; do
echo $arg
done
fi | awk -v b=$maxb -v o="$out" -v w=$width '{
n+=length($0); print $0 > sprintf("%s.%0.*d",o,w,n/b)}'
Run Code Online (Sandbox Code Playgroud)
将其保存到名为'bee'的文件中,运行' chmod +x bee',您可以将其用作
program | bee
Run Code Online (Sandbox Code Playgroud)
或者将现有文件拆分为
bee -b1000 -o proglog -w8 file
Run Code Online (Sandbox Code Playgroud)
要将大小限制为 100 字节,您可以简单地使用 dd:
my_program | dd bs=1 count=100 > log
Run Code Online (Sandbox Code Playgroud)
当写入 100 个字节时,dd 将关闭管道,my_program 接收 EPIPE。