有一个web应用程序(php / apache2),它在请求处理开始时在某个地方打开日志文件,并在处理完成时closures它(据我所知)。 在日志文件打开和closures之间,条目当然是写入的。
让我们假设在请求处理中间的某个地方(即一些日志条目已经被写入,还有一些还没有被写入),使用logrotate执行日志轮转,其configuration如下:
/var/log/some/path/*.log { weekly missingok rotate 30 compress delaycompress notifempty create <mode> <owner> <group> size 10M }
如果我理解了logrotate手册页, create指令将导致当前的日志文件(由请求处理打开的文件正在进行)被重命名/移动,并创build一个新的空白日志文件。 如果是这样,那么未处理的请求处理生成的日志条目还会发生什么? 他们会被附加到重命名/移动的文件,也许他们会丢失? 第二个问题是关于postrotate和prerotate指令。 我需要他们吗? 我可以考虑的唯一的东西是一个Apache的优雅重启命令,但我真的需要它吗?
答案是,apache在每次附加文件时都不打开和closures文件,因为这会占用大量的文件系统开销。 它会在启动时在日志文件上打开一个文件句柄,并使其无限期地打开。
请注意, create指令不是创build新文件的东西,只是定义了在发生旋转时给出新文件的所有者和模式。
当apache写入日志文件时,它会写入打开的文件句柄 。 即使该文件的名称可能同时发生了变化,该句柄仍应附加到现有文件。 这是原始的apache logrotateconfiguration包含这样一个块的原因:
postrotate if [ -f "`. /etc/apache2/envvars ; echo ${APACHE_PID_FILE:-/var/run/apache2.pid}`" ]; then /etc/init.d/apache2 reload > /dev/null fi endscript
那是Debian的。 其他人可能会这样做,但效果是导致Apache重新加载其configuration,从而使其重新打开文件句柄在指定的日志文件。 由于logrotate刚刚创build了一个新的名称为空的日志文件,Apache将开始写入。
所以,没有日志条目丢失,但这种forms的旋转确实需要通过postrotate指令定期重新加载。 具有高stream量服务器的人不倾向于喜欢这种限制,并可能偏爱其他日志logging方法,如mod_log_spread