How to setup log rotation for MongoDB properly
To simply rotate logs you can call logrotation from mongoclient directly:
use admin db.runCommand( { logRotate : 1 } )
This is not very convenient for automation, since there is no deletion mechanism for large and old files. However, such a mechanism is present in the utility logrotate, which is available in almost all popular Linux distributions like Debian, Ubuntu or Centos.
To correctly setup the regular log rotation with logrotate.d /etc/mongod.conf needs a little fix:
systemLog: destination: file path: "/var/log/mongodb/mongod.log" logAppend: true logRotate: reopen
logAppend: true, we need to always append data to the end of the file, and logRotate: reopen is required for the file to be rediscovered after the rotation, because we will rotate the file using the external logrotate utility.
Please, pay attention to a pid-file path for mongod (look at processManagement: pidFilePath), we will use it later.
After correcting the configuration file, do not forget to restart MongoDB. Change /etc/logrotate.d/mongodb to:/var/log/mongodb/mongod.log { rotate 7 daily size 1M missingok create 0600 mongodb mongodb delaycompress compress sharedscripts postrotate /bin/kill -SIGUSR1 $(cat /var/run/mongodb.pid) endscript }
Command kill sends SIGUSR1 to a process with id from /var/run/mongodb.pid (use path from pidFilePath).
To test rotation of the logs run logrotate like this:
logrotate --force /etc/logrotate.d/mongodb
Make sure it works all right and you are good to go!
If you don't know what we have in /etc/logrotate.d/mongodb read the explanation below:
Option | Description |
---|---|
rotate 7 | keep 7 log files |
daily | rotate files at least once a day |
size 1M | rotate file when its size reaches 1MB, this option is especially useful on arbiters, because those nodes normally don't have a lot of space |
missingok | don't complain, if there is no log file |
create 0600 mongodb mongodb | automatically create new log file with permissions 0600 (only owner can read and write) under mondodb user and group |
delaycompress | keep one log file uncompressed |
compress | use file compression for older log files |
sharedscripts | don't run this configuration for every defined log file (prevents from multiple rotations) |
postrotate | defines beginning of the script which will run after log has been rotated |
endscript | end of the script |
At the end you have a proper log rotation because the logs will never eat all your space, you still have the most recent logs for last week. Also this configuration is scalable because even if load on your DB will grow you will never run out of space. If you have insane load on your instance, it is better to reduce verbosity of logger by enabling systemLog.quiet parameter. Be aware, you will have much less output therefore issues investigation will be much harder. Be mindful while setting this parameter.
I had to resort to getting the ip using `pgrep`:
postrotate
/bin/kill -SIGUSR1 $(pgrep -f mongod)
endscript