logrotate copytruncate와 create의 차이
로그를 돌렸는데 새 파일만 계속 비어 있고 프로세스는 옛 파일에 계속 쓰는 상황이 있습니다. 애플리케이션이 로그 파일 디스크립터를 열어둔 채 재개(reopen)하지 않을 때 생깁니다. 이때 logrotate의 create와 copytruncate 동작 차이를 알아두면 됩니다.
logrotate의 기본 회전 동작은 현재 로그의 이름을 바꿔 옮기는 것입니다(app.log -> app.log.1). create는 그와 별개로 회전 직후(postrotate 실행 전) 같은 이름의 새 파일을 생성할지 정하는 지시어이며, nocreate로 끌 수 있습니다. 문제는 프로세스가 이전 파일 디스크립터를 그대로 들고 있으면 새로 만든 빈 파일이 아니라 이름 바뀐 옛 파일에 계속 쓴다는 점입니다. 그래서 보통 postrotate에서 프로세스에 재개 신호(예: nginx는 USR1)를 보내야 합니다.
재개 신호를 못 보내는 프로그램이라면 copytruncate를 씁니다. 원본을 복사한 뒤 원본을 그 자리에서 0바이트로 truncate하므로 디스크립터가 유지돼도 됩니다. 이때 옛 로그 파일이 그 자리에 그대로 남기 때문에 create는 효과가 없다고 문서는 설명합니다("the create option will have no effect, as the old log file stays in place"). 또 "복사와 truncate 사이의 아주 짧은 시간"에 기록되는 로그 일부가 유실될 수 있다는 경고도 함께 붙어 있습니다.
/var/log/myapp/*.log {
daily
rotate 14
compress
missingok
notifempty
copytruncate
}정리하면 재개 신호를 보낼 수 있으면 create + postrotate가 안전하고, 그럴 수 없는 앱에만 유실 위험을 감수하고 copytruncate를 쓰는 편이 낫습니다.
로그인 후 답글을 남길 수 있습니다.