日志旋转脚本未运行



我有以下日志旋转脚本

/path/to/folder {
daily
rotate 30
notifempty
sharedscripts
copytruncate
compress
dateext

preremove
if file --mime-type "$1" | grep -q gzip$; then
mkdir -p /path/to/archive/folder && cp $1 $_
fi
endscript
}

  • 我正在努力实现的目标:-

    在保留 30 天后删除日志文件之前,请复制到另一个文件夹。

我在调试模式下运行此日志存储配置

logrotate -d $CONFIG_FILE

从日志的外观来看,轮换工作正常,但它甚至没有运行preremove脚本。 我还没有在实时上运行这个配置,因为我想在这样做之前对其进行测试。

日志旋转版本 3.8.6

我不确定您是在问为什么 preremove 没有运行,或者您的脚本看起来是否正常。

预移除以及如何测试

我不相信 logrotate 如果不删除文件(每-d),它会运行preremove脚本。我设置了一个测试用例并在strace下运行它。logrotate -d找到了需要删除的文件,并写道它会删除它们,但没有运行preremove代码。老实说,这对我来说是有道理的,也是我所期望的,因为preremove可能会像删除本身一样具有破坏性。

要执行测试,我认为您需要在另一个目录中重现您的实时环境并实际运行它。不要使用全尺寸文件,只需使用几行的虚拟文件。创建一个脚本来生成测试文件夹,以便可以轻松重现测试。使用touch设置时间戳。例如:

for n in $(seq 1 30); do
cp test.log test.log.$n
gzip test.log.$n
touch -d "now - $n day" test.log.$n.gz
done

脚本本身

  • grep -q gzip$错了。$将在外壳解析中消失。您需要将其括在单引号中。
  • 正如其他人所写,我不希望$_起作用。重复目录名称,或在脚本中使用变量。
  • 我认为您不需要像建议的那样在 EOL 进行逃逸。
  • 你可能想要cp -p,正如有人建议的那样。
  • 如果您的文件很大,则cp会很慢。如果您的归档位于同一文件系统上,请考虑改用ln(而不是ln -s!这将是即时的。
  • 使用file --mime-type可能工作正常,但坦率地说,在这种情况下,我只是基于文件名,因为 logrotate 会可靠地将.gz附加到file将返回gzip的任何文件上。expr "$1" : '.*gz$'将给出一个非零数作为以.gz结尾的任何$1的标准输出。它将为不以.gz结尾的文件名提供准确的数字 0 作为标准输出。

我认为您的条件本身并没有实现,您可以将 echo 放在预删除之前进行调试。尝试手动执行您的 if 条件并查看。

# file --mime-type * | grep -i *.1
audit.log.1: text/plain
# file --mime-type * | grep -i *.1$
# file --mime-type * | grep -q *.1$
# file --mime-type * | grep -q *.1

您可能缺少行继续转义,如某些示例中所示

preremove
# debug line
systemd-cat -t "rot-pre-rm" echo "preremove block, file: $1"
if file --mime-type "$1" | grep -q gzip$; then 
cp -p "$1" /path/to/archive/syslog/; 
fi; 
endscript

最新更新