Mongodb - 适当的日志轮转方式

Mongo docs 说我可以:
  1. 使用 -SIGUSR1 信号来重新命名旧日志并切换当前日志
  2. 使用操作系统的 logrotate

我希望能够利用操作系统的 logrotate 功能来压缩旧文件并删除最旧的文件,但是似乎没有方法告诉 mongod 进程切换当前日志,除非发送 SIGUSR1 信号。

所以我写了

/var/log/mongodb/*.log {
    daily
    rotate 5
    compress
    dateext
    missingok
    notifempty
    sharedscripts
    postrotate
        /usr/bin/killall -SIGUSR1 mongod
        /usr/bin/killall -SIGUSR1 mongos
    endscript
}

转至 /etc/logrotate.d/mongo。

现在从 logrotate 中获取具有良好命名的日志文件和空日志文件,如 mongodb.log.2013-09-18T23-49-44,它们是 SIGUSR1 切换的迹象。如何摆脱后者?

6个回答

自从mongodb 3.0版本起,您可以通过logRotate参数更改mongodb的行为,在/etc/mongod.conf文件中进行更改。

systemLog:
  logAppend: true
  logRotate: reopen
另请参阅Mongo手册。 然后您可以使用以下logrotate配置:
/var/log/mongodb/*.log {
    daily
    rotate 30
    size 50M
    compress
    dateext
    missingok
    notifempty
    sharedscripts
    postrotate
        /bin/kill -SIGUSR1 `cat /var/lib/mongodb/mongod.lock 2> /dev/null` 2> /dev/null || true
    endscript
}

1从配置文件创建的PID文件应该被使用... 在配置中查看processManagement.pidFilePath或者SystemD单元文件的PIDFile设置(对我来说是/var/run/mongodb/mongod.pid)。 - Gert van den Berg
但要记住,现在/run是tmpfs,因此在重新启动时会被清除,只有在通过tmpfs conf创建后,mongo db文件夹才存在! - JeffRSon

如果你在使用logrotate把日志文件移出路径后,发送SIGUSR1给mongod服务器,那么服务器就会崩溃。 下面的配置是我测试过的版本安全的- 在ubuntu 12.04上的2.6.6版本 - 前面的例子会导致服务器崩溃。将以下内容放入/etc/logrotate.d/mongod文件中即可:
/var/log/mongodb/mongodb.log {
    weekly
    missingok
    rotate 4
    compress
    notifempty
    create
    postrotate
        /usr/bin/pkill -USR1 mongod
        rm /var/log/mongodb/mongodb.log.????-??-??T??-??-??
    endscript
}
请参考:https://jira.mongodb.org/browse/SERVER-11087 了解更多细节和Akshay Kumar的建议,我在上面使用了这个建议(使用create而不是nocreate,并将cp /dev/null写入日志文件)。 在以后的版本中,应该有一个logRotate选项可以用来重新打开文件 - 而不是重命名它 - 这将解决重命名问题 - 但在我的版本中没有起作用(不支持)。 请参考:https://github.com/mongodb/mongo/commit/616461d294bd9f5054ca38b302b6fc5d70fde20c。 我已经进行了测试。
logrotate -v -f /etc/logrotate.d/mongod

在CentOS 7上,Mongo 2.6.11对我来说运行得非常好。 - Tim
我不得不将mongodb.log替换为mongod.log,然后它就正常工作了。 - cwhisperer
可以确认,如果在mongod.conf中设置了systemLog.logRotate: reopen,那么pkill将按预期工作,并且不需要删除重命名的日志文件,因为不会创建任何文件。 - Julian H. Lam

copytruncate在日志轮转中工作得非常好。 类似于这样的配置应该能够完成你的工作:
/var/log/mongodb/*.log {
  daily
  missingok
  rotate 5
  compress
  dateext
  delaycompress
  copytruncate
  notifempty
}

1这在RedHat 6.5上对我没起作用。日志已经被轮转,但原始的.log文件仍然无限增长。 - Thomas Bratt
@ThomasBratt 这是正确的,因为如果不重新启动Mongo进程,文件处理程序将保持打开状态。fwics这种方法可能效果不太好。 - Mxx
@ThomasBratt 你看一下这个答案 http://stackoverflow.com/a/8396266/949859 - Mxx
1@Mxx 不错的发现 - 看起来copytruncate将与postrotate步骤一起使用,以向Mongo发送信号来截断日志文件。 - Thomas Bratt

我的MongoDB v4.4和Ubuntu 18.04的解决方案

创建logrotate配置文件/etc/logrotate.d/mongodb

/var/log/mongodb/mongod.log {
    rotate 7
    daily
    size 100M
    missingok
    create 0600 mongodb mongodb
    delaycompress
    compress
    sharedscripts
    postrotate
            /bin/kill -SIGUSR1 $(cat /var/run/mongodb/mongod.pid)
    endscript
}
修改/etc/mongod.conf文件以在kill命令信号时重新打开日志文件,并选择pid文件。
systemLog:
  destination: file
  logAppend: true
  path: /var/log/mongodb/mongod.log
  logRotate: reopen
processManagement:
  pidFilePath: /var/run/mongodb/mongod.pid
修改 `/lib/systemd/system/mongod.service` 文件。它将在服务启动时创建目录 `/var/run/mongodb`。
[Service]
RuntimeDirectory=mongodb
申请并检查更改
sudo systemctl daemon-reload
sudo systemctl restart mongod
sudo systemctl status mongod

ls -lah /var/log/mongodb/
logrotate -f /etc/logrotate.d/mongodb
ls -lah /var/log/mongodb/
警告! 在使用 `apt upgrade` 更新 Mongo 后,`/lib/systemd/system/mongod.service` 可能会被覆盖。

这很好。我使用了 systemctl show --property MainPID --value <service> 命令来获取进程ID。这样你就不用修改systemd并避免升级问题。所以在logrotate.d文件中,你需要加入以下内容:/bin/kill -SIGUSR1 $(systemctl show --property MainPID --value mongod) - AlexPi

以下的方法对我起了作用:
/var/log/mongo/mongod.log {
    missingok
    rotate 3
    size 100M
    nodateext
    postrotate
            /usr/bin/kill -USR1 $(cat /var/run/mongod.pid)
            rm -f /var/log/mongo/mongod.log.[0-9][0-9][0-9][0-9]-*
    endscript
}

注意:

  • 在RedHat 6.5上进行了测试
  • 我能找到的唯一有效的解决方案是删除Mongo生成的空日志文件
  • 锁文件的位置取决于MongoDB的安装方式
  • kill是Bash内置命令,但logrotate在/bin/sh下运行 - 在RedHat 6.5上无法识别SIGUSR1
  • 我没有测试过compress,但应该可以轻松添加


2看起来安德烈已经阅读了那份文件;你并没有真正回答他的问题。 - Law29