logrotate copytruncate loses lines and nobody says so

copytruncate copies the file and then truncates the original, and anything written between those two operations is gone.

# the lossy option, used because it needs no signal
/var/log/app/*.log {
    daily
    copytruncate
}

# the correct one, for a process that can reopen
/var/log/app/*.log {
    daily
    missingok
    postrotate
        systemctl reload app-worker > /dev/null 2>&1 || true
    endscript
}

The window is small and the loss is real, and on a busy log it happens every rotation. copytruncate exists for processes that cannot be told to reopen their log file, which is fewer than the number of configurations using it — most application servers reopen on SIGUSR1 or a reload. The other failure of copytruncate is with a process holding the file offset, which continues writing at its old position and produces a file full of null bytes at the start.