1. 서론: 새벽 3시의 재앙, No space left on device
리눅스 서버 인프라를 운영하면서 겪는 가장 당혹스럽고 허탈한 장애 원인 중 1위는 단연 **디스크 용량 100% 고갈(Disk Full)**입니다.
웹 서비스 트래픽이 평소보다 조금만 급증해도 Nginx의 access.log나 Tomcat의 catalina.out 파일은 하루에 수 GB에서 수십 GB씩 눈덩이처럼 불어납니다. 디스크가 100% 차는 순간:
- 데이터베이스(MySQL, PostgreSQL)는 쓰기 작업을 거부하며 즉각 비정상 종료(Crash)됩니다.
- WAS는 세션 및 임시 파일을 생성하지 못해 500 에러를 뿜어냅니다.
- 관리자 터미널(SSH) 접속조차 PTY 할당 실패로 막혀버려 긴급 조치조차 어려워집니다.
이러한 참사를 사전에 방지하기 위한 리눅스 표준 솔루션이 바로 **logrotate**입니다. 이번 포스팅에서는 logrotate의 내부 동작 원리(시그널 방식 vs copytruncate), 파일 핸들의 비밀, 서버 3대장(Nginx, Apache, Tomcat)의 프로덕션 설정 템플릿, 그리고 디버깅 검증 기법까지 완벽히 정리합니다.
2. logrotate 동작 메커니즘: 시그널 vs copytruncate
리눅스에서 실행 중인 프로세스는 파일 이름이 아니라 **파일 디스크립터(File Descriptor, Inode)**를 통해 디스크에 로그를 기록합니다. 단순히 mv access.log access.log.bak으로 이름을 바꾸더라도, 프로세스는 이름이 바뀐 백업 파일에 계속해서 로그를 쏟아붓습니다.
logrotate는 이 문제를 해결하기 위해 두 가지 상반된 메커니즘을 제공합니다.
subgraph MethodB ["방식 B: 내용 복사 + 비우기 (copytruncate - Tomcat catalina.out)"]
direction TB
B1["1. 현재 catalina.out 내용을 catalina.out.1로 통째 복사 (Copy)"]
B2["2. 원본 catalina.out 크기를 0바이트로 절삭 (Truncate)"]
B3["3. 프로세스는 동일한 Inode에 중단 없이 계속 기록 유지"]
B1 --> B2 --> B3
end
- 방식 A (시그널 재오픈): Nginx나 Apache처럼 로그 파일을 다시 열 수 있는 프로세스에 적합하며, 데이터 유실이 전혀 없는 가장 깔끔한 방식입니다.
- 방식 B (
copytruncate): Tomcat의catalina.out처럼 셸 리다이렉션(>>)으로 열려 있어 시그널을 받을 수 없는 프로세스에 필수적입니다. 단, 복사와 비우기 사이의 찰나의 순간에 쓰인 몇 줄의 로그가 유실될 수 있는 미세한 한계가 있습니다.
3. logrotate 핵심 지시어(Directives) 총정리
/etc/logrotate.d/ 디렉토리에 정의하는 핵심 옵션들의 기능입니다.
| 지시어 | 설명 및 동작 | 실무 팁 |
|---|---|---|
daily / weekly |
로그 회전 주기 (매일 또는 매주) | 트래픽이 많다면 daily 필수 |
rotate N |
회전된 로그 파일을 최대 N개까지 보관 | rotate 14 (2주치 보관 후 자동 삭제) |
size 100M |
주기와 무관하게 파일 크기가 100MB를 넘으면 즉시 순환 | 대용량 트래픽 서버의 안전장치 |
compress |
회전된 로그 파일을 gzip으로 압축 보관 |
디스크 사용량을 80~90% 절감 |
delaycompress |
다음 회전 주기까지 압축을 1회 미룸 | 프로세스가 아직 물고 있는 파일 압축 방지 |
missingok |
대상 로그 파일이 없어도 에러를 내지 않고 패스 | 불필요한 크론 데몬 에러 알림 방지 |
notifempty |
파일 크기가 0바이트(빈 파일)이면 회전 생략 | 무의미한 빈 압축 파일 생성 방지 |
dateext |
.1, .2 대신 -20260223 형태의 날짜 접미사 사용 |
날짜별 로그 탐색에 압도적으로 편리 |
sharedscripts |
매치된 로그 파일이 여러 개여도 스크립트를 1번만 실행 | postrotate 시그널 중복 전송 방지 |
4. 서버 3대장별 프로덕션 설정 템플릿
1) Nginx 설정 (/etc/logrotate.d/nginx)
Nginx는 마스터 프로세스에 USR1 시그널을 보내면 다운타임 없이 열려 있는 모든 로그 파일 핸들을 즉시 닫고 새로 생성된 파일로 재연결합니다.
/var/log/nginx/*.log {
daily
missingok
rotate 14
compress
delaycompress
notifempty
create 0640 www-data adm
sharedscripts
dateext
dateformat -%Y%m%d
postrotate
if [ -f /var/run/nginx.pid ]; then
kill -USR1 $(cat /var/run/nginx.pid)
fi
endscript
}
2) Apache HTTP Server 설정 (/etc/logrotate.d/apache2)
Apache는 apachectl graceful을 통해 현재 연결된 클라이언트 세션을 끊지 않고 안전하게 로그를 갱신합니다.
/var/log/apache2/*.log {
daily
missingok
rotate 30
compress
delaycompress
notifempty
create 0640 root adm
sharedscripts
dateext
dateformat -%Y%m%d
postrotate
if /usr/sbin/apachectl configtest > /dev/null 2>&1; then
/usr/sbin/apachectl graceful > /dev/null 2>&1
fi
endscript
}
3) Tomcat WAS 설정 (/etc/logrotate.d/tomcat)
Tomcat의 catalina.out은 JVM 프로세스가 시작될 때 셸 리다이렉션으로 표준 출력(stdout)을 바인딩하므로 프로세스를 재시작하지 않는 한 Inode를 갱신할 수 없습니다. 따라서 **copytruncate**가 절대적 필수입니다.
/opt/tomcat/logs/catalina.out {
copytruncate
daily
size 100M
rotate 7
compress
delaycompress
missingok
notifempty
dateext
dateformat -%Y%m%d
}
size 100M병행:daily주기라도 갑작스러운 에러 폭풍(스택 트레이스 무한 출력)으로 하루에 10GB씩 쌓이는 것을 막기 위해 100MB 도달 시 즉시 순환하도록 복합 제약 조건을 겁니다.
5. 설정 검증 및 디버깅 명령어
logrotate 설정을 추가하거나 수정한 뒤, 실제로 크론 데몬이 돌기 전에 문법 오류나 권한 문제가 없는지 반드시 테스트해야 합니다.
1) 드라이런(Dry-run) 디버그 모드 (-d)
실제 파일을 삭제하거나 압축하지 않고, 어떤 파일이 어떤 규칙에 의해 회전될지 시뮬레이션 결과만 화면에 출력합니다.
# 디버그 모드 실행 (안전함, 실제 변경 없음)
sudo logrotate -d /etc/logrotate.d/nginx
2) 강제 즉시 실행 테스트 (-vf)
크론 주기와 무관하게 모든 조건을 무시하고 즉시 로그 회전을 1회 강제 실행합니다.
# 상세 출력(-v)과 강제 회전(-f)
sudo logrotate -vf /etc/logrotate.d/tomcat
실행 후 ls -lh /opt/tomcat/logs/를 확인하여 catalina.out의 크기가 0바이트로 초기화되고, catalina.out-20260223 파일이 정상 생성되었는지 확인합니다.
6. 실무 주의사항: 디렉토리 권한 보안 정책
최신 리눅스(Ubuntu 20.04+, RHEL 8+)의 logrotate는 보안 강화를 위해 **로그 대상 디렉토리가 group이나 other에 쓰기 권한(w)이 열려 있으면 실행을 전면 거부(Error: insecure permissions)**합니다.
# 에러 예시:
# error: skipping "/var/log/myapp/app.log" because parent directory has insecure permissions
이 경우 해당 로그 디렉토리의 퍼미션을 소유자 전용 쓰기 권한(chmod 755 또는 chmod 750)으로 조정해야 정상적으로 logrotate가 동작합니다.
7. 결론
로그 파일 관리는 인프라 엔지니어링의 가장 기본적이면서도 가장 소홀해지기 쉬운 영역입니다.
각 웹 서버의 특성에 맞게 Nginx/Apache에는 create + USR1 시그널, Tomcat catalina.out에는 copytruncate + size 100M 규칙을 철저히 적용하여 예측 불가능한 디스크 풀 장애로부터 서비스를 안전하게 지켜내시기 바랍니다.