我们使用 upstart 来管理 Ubuntu 服务器上的服务。它们会生成日志,并记录到 /var/log/upstart/SERVICE_NAME.log
然后每天使用 12.04 LTS 附带的 logrotation 脚本轮换日志文件:
/var/log/upstart/*.log {
daily
missingok
rotate 7
compress
notifempty
nocreate
}
问题是,虽然 logrotate 移动了文件,但它似乎并没有向 upstart 发出信号来关闭并重新打开文件,而导致 upstart 进程写入删除 PID。
init 1 root 8w REG 202,1 64 2431 /var/log/upstart/dbus.log.1 (deleted)
init 1 root 13w REG 202,1 95 2507 /var/log/upstart/acpid.log.1 (deleted)
init 1 root 14w REG 202,1 127 17377 /var/log/upstart/whoopsie.log.1 (deleted)
init 1 root 36w REG 202,1 122 6747 /var/log/upstart/SERVICE_NAME.log.1 (deleted)
init 1 root 37w REG 202,1 30 6762
显然,我可以将我自己的服务的输出重定向到其他日志文件,但系统进程仍然存在问题。另外,我宁愿不必构建超出我所需的基础设施。
答案1
我相信您有 3 个选择。
您可以通过添加“copytruncate”来修改现有配置
/var/log/upstart/*.log { copytruncate daily missingok rotate 7 compress notifempty nocreate }
如果您不能或(不允许)更改现有的 logrotate 配置,因为其他日志文件不会受到影响并且现有配置对它们有效,那么请将您的“SERVICE_NAME.log”文件移动到 /var/log 下的新文件夹(如果您愿意),使用“copytruncate”创建一个新的配置并将其添加到 cron.daily。
a) 如果您无权更改主机操作系统 logrotate 配置或添加到主机操作系统的 cron.daily,那么您的第三个选择是更改脚本或程序,以在写入文件之前检查文件是否存在。b) 另一种方法是上面第 2 点的一部分,即将您的日志文件移动到其他位置,然后在您的脚本或程序中执行特定于该程序日志文件的 logrotate 命令。
上面的第 3b 点更加棘手但更加优雅,而且是我大多数时候使用的,因为这意味着该程序是自给自足和自我管理的,不需要操作系统的工作来照顾它。
要了解如何手动运行 logrotate 并将其添加到您的程序或脚本中,只需输入:
man logrotate
或者
logrotate --help
如果您在程序中使用 Python,您可以检查该程序如何使用它来自行管理其日志文件。 http://bazaar.launchpad.net/~ferncasado/keep.awake/trunk/files/head:/v4/
答案2
事实证明,这是一个已知问题,票当我输入此内容时仍处于打开状态。
正确的做法可能是将全部删除/etc/logrotate.d/upstart
,然后单独轮换各个服务的文件。因为目录 ( /var/log/upstart/
) 仅包含各种服务的 stdout/stderr —— 并且没有要作为守护进程应该完全输出到这两个通道。除了在启动时。
在我管理的系统上,upstart 运行了三个服务:php5.6-fpm
、php7.1-fpm
和acpid
。这三个日志都不是活动的,但有时 fpm 会由于其主日志文件 ( /var/log/php5.6-fpm.log
) 被轮换而重新启动 - 并且它会导致这种噪音,因为它在启动时输出一些无用的信息。
如果您坚持要轮换这些文件,那么您可以依靠它们的名称与服务名称相匹配的事实并使用以下postrotate
脚本:
postrotate
service=${1##*/}
service=${service%.log*}
service $service restart > /dev/null
endscript
为了使上述操作有效,请确保不是使用其中的动词——我的脚本依赖于事实,文件的实际路径将作为第一个参数传递给它(sharedscripts
$1
)。
(重定向到/dev/null
很有用,因为service
-command 很嘈杂 —— 并且您不希望 cron 通过电子邮件将此类噪音发送给您。请注意,我没有重定向到stderr
那里,只是stdout
—— 如果出现问题,您仍然会收到有关它的电子邮件。)