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:

  1. Rename the log to the archived name
  2. Signal the application to reopen its logs
  3. 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
}