How does logrotate handle concurrency?
During a rotation log messages can end up in either the old or the new file, but in a deterministic way. Logrotate does roughly the following for each logfile:
- Rename the log to the archived name
- Signal the application to reopen its logs
- Optionally compress the logfile
If messages get logged between 1 and 2, these will end up in the renamed log, because a rename does not affect open file descriptors (this is also why compression only happens after applications reopen their logs). Messages logged after 2 will end up in the new log.
Here's an excerpt from my logrotate config that does what I described for nginx' logs:
/var/log/nginx/*.log {
compress
delaycompress
postrotate
[ ! -f /run/nginx.pid ] || kill -USR1 `cat /run/nginx.pid`
endscript
}