logrotate 后日志开头的空值

Null value in the beginning of log after logrotate

我正在使用 logrotate 来管理我的日志。因为我必须管理一堆日志文件。我的 logrotate 配置看起来像

/log/typeA*.log
/log/typeB*.log
/log/typeC*.log{
        daily
        rotate 7
        copytruncate
        size 1M
        compress
        su root root
        create 0644 root root
        missingok
}

logrotation 完成后,我在文件开头看到一堆空字符。看起来像

^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@

看起来像无限长的字符串。文件大小看起来也相似。 有解决方案建议 https://serverfault.com/a/510470 使用 postrotate 脚本,如

postrotate
   sed -i -e 's/\o00//g' ""
endscript

但是使用这个脚本会修改文件和改变流。所以日志不会被重定向到一些不存在的文件流。
我正在使用 python 日志模块

生成日志

同样的事情发生在我身上并且能够修复它。

其背后的原因是旋转文件没有用标志O_APPEND打开。因此,旋转时它仍然保持相同的写入偏移量并从新文件的中间开始写入。该偏移量之前的所有内容都标记为 NULL,因为文件的开头是空的。

换句话说,你在文件中写完第n个字符,并在触发旋转时截断它。您不再从第 0 个字符开始,而是从第 n+1 个字符继续,前 n 个字符将被标记为 NULL。

为避免此问题,您必须打开带有标志 O_APPEND 的文件。

可以在以下线程中找到更多信息: https://groups.google.com/g/comp.unix.solaris/c/Zc7ysjMGprQ?pli=1