When implementing log rotation for MongoDB, we face an interesting technical dilemma. The database engine provides native log rotation through SIGUSR1 signals, while system administrators typically prefer using the standard logrotate
utility for its compression and retention features.
The existing configuration creates two types of log files:
$ ls -l /var/log/mongodb/
-rw-r--r-- 1 mongodb mongodb 0 Sep 18 23:49 mongodb.log
-rw-r--r-- 1 mongodb mongodb 14250 Sep 18 23:49 mongodb.log.2013-09-18T23-49-44
-rw-r--r-- 1 mongodb mongodb 75026 Sep 18 23:49 mongodb.log-20130918.gz
This happens because:
- logrotate renames the original file and creates a new empty one
- MongoDB's SIGUSR1 handler then creates another rotated file
We need to modify our approach to prevent double rotation. Here's the refined logrotate configuration:
/var/log/mongodb/mongodb.log {
daily
rotate 30
compress
delaycompress
dateext
missingok
notifempty
sharedscripts
create 0600 mongodb mongodb
postrotate
# Only signal if mongod is running
if [ -f /var/lib/mongodb/mongod.lock ]; then
/usr/bin/killall -SIGUSR1 mongod >/dev/null 2>&1 || true
/usr/bin/killall -SIGUSR1 mongos >/dev/null 2>&1 || true
fi
endscript
}
- delaycompress: Ensures the previous log stays uncompressed until next rotation
- create: Sets proper permissions on the new log file
- Conditional signaling: Only sends SIGUSR1 if MongoDB is actually running
For newer MongoDB versions, consider using the built-in log rotation:
use admin
db.adminCommand({ logRotate: 1 })
This can be integrated with logrotate through a simple curl command if you have HTTP interface enabled.
After implementation, verify the rotation works correctly:
$ sudo logrotate -vf /etc/logrotate.d/mongo
$ ls -lh /var/log/mongodb/
You should see properly compressed logs without the intermediate SIGUSR1-created files.
When implementing log rotation for MongoDB, we face an interesting technical dilemma. The database provides two native approaches:
- Using the SIGUSR1 signal to trigger rotation
- Directly using the operating system's logrotate utility
# Basic SIGUSR1 rotation command
kill -SIGUSR1 pidof mongod
The naive approach of just configuring logrotate leads to empty timestamped log files because:
- MongoDB needs explicit notification to switch log files
- The rotation and compression happen as separate operations
- File handles aren't properly released without process notification
Here's the proper way to configure logrotate for MongoDB that handles both rotation and compression:
/var/log/mongodb/*.log {
daily
rotate 30
compress
delaycompress
missingok
notifempty
sharedscripts
postrotate
# Signal both mongod and mongos if running
[ -f /var/run/mongodb/mongod.pid ] && kill -USR1 $(cat /var/run/mongodb/mongod.pid)
[ -f /var/run/mongodb/mongos.pid ] && kill -USR1 $(cat /var/run/mongodb/mongos.pid)
endscript
}
The enhanced configuration includes several critical improvements:
delaycompress # Wait to compress until next rotation
copytruncate # Alternative approach for problematic setups
create 640 mongodb adm # Maintain proper permissions
su mongodb adm # Run as correct user if needed
To test your configuration:
# Dry run to check for errors
logrotate -d /etc/logrotate.d/mongodb
# Force immediate rotation
logrotate -vf /etc/logrotate.d/mongodb
# Verify process received signal
ps -eo pid,cmd | grep [m]ongod
For systems with multiple MongoDB instances or containers:
# Containerized MongoDB solution
docker exec mongodb_container bash -c "kill -USR1 1"
# Multiple instance handling
for pid in $(pgrep mongod); do
kill -USR1 $pid
done
When dealing with high-throughput systems:
- Schedule rotation during low-traffic periods
- Consider larger rotation intervals for busy systems
- Monitor disk I/O during compression operations