서버에서 로그 파일을 관리하지 않으면 디스크가 꽉 차 서버가 다운될 수 있습니다. logrotate는 로그 파일을 자동으로 회전(rotate)시키고 오래된 것은 삭제해주는 필수 도구입니다.
logrotate 동작 원리
오늘: app.log (현재 로그)
↓ 자동 처리
app.log.1 (어제 로그)
app.log.2.gz (그제 로그, 압축)
app.log.3.gz
...
app.log.7.gz (7일 전 로그)
[삭제] (8일 이상 된 것)
설정 파일 위치
/etc/logrotate.conf # 전역 기본 설정
/etc/logrotate.d/ # 서비스별 설정 디렉터리
/etc/logrotate.d/nginx # Nginx 로그 설정 (패키지가 자동 생성)
/etc/logrotate.d/mysql # MySQL 로그 설정
기본 설정 파일 구조
/var/log/myapp/*.log {
daily # 회전 주기 (daily/weekly/monthly/yearly)
rotate 7 # 7개 파일 보존 (7일치)
compress # 회전된 파일 gzip 압축
delaycompress # 최신 회전 파일은 압축 보류 (다음 번에 압축)
missingok # 파일 없어도 오류 없이 넘어감
notifempty # 빈 파일은 회전하지 않음
create 644 www-data www-data # 새 로그 파일 생성 (권한 소유자 그룹)
sharedscripts # postrotate 스크립트를 한 번만 실행
postrotate
# 로그 회전 후 실행할 명령 (서비스에 새 파일 사용 신호)
[ -f /var/run/nginx.pid ] && kill -USR1 `cat /var/run/nginx.pid`
endscript
}
Nginx 로그 설정 (기본 제공)
# 기존 설정 확인
cat /etc/logrotate.d/nginx
/var/log/nginx/*.log {
daily
missingok
rotate 52 # 52일(약 7주)치 보존
compress
delaycompress
notifempty
create 640 nginx adm
sharedscripts
postrotate
if [ -f /var/run/nginx.pid ]; then
kill -USR1 `cat /var/run/nginx.pid`
fi
endscript
}
MySQL 로그 설정
# /etc/logrotate.d/mysql
/var/log/mysql/*.log {
daily
rotate 7
compress
delaycompress
missingok
notifempty
create 640 mysql adm
sharedscripts
postrotate
test -x /usr/bin/mysqladmin || exit 0
if [ -f /var/run/mysqld/mysqld.pid ]; then
mysqladmin --defaults-file=/etc/mysql/debian.cnf flush-logs
fi
endscript
}
사용자 정의 애플리케이션 로그
# /etc/logrotate.d/myapp
/var/log/myapp/app.log
/var/log/myapp/error.log {
daily
rotate 30 # 30일치 보존
size 100M # 100MB 초과 시 즉시 회전 (daily와 OR 조건)
compress
delaycompress
missingok
notifempty
copytruncate # 파일을 복사 후 원본을 비움 (재시작 없이 로테이션)
# 주의: 데이터 손실 가능성 있음, postrotate 선호
create 644 appuser appgroup
}
copytruncate vs postrotate
copytruncate:
- 파일을 복사하고 원본을 0바이트로 만듦
- 애플리케이션 재시작/신호 없이 작동
- 복사~트런케이트 사이 짧은 시간 동안 로그 손실 가능
postrotate + kill -USR1:
- 파일 이름을 변경하고 새 파일 생성
- 애플리케이션에 새 파일 열도록 신호 전송
- 더 안전하고 권장됨 (Nginx, Apache 등 지원)
수동 실행 및 디버깅
# 특정 설정 파일 테스트 (실제 실행 없이)
sudo logrotate -d /etc/logrotate.d/myapp
# 강제 실행 (이미 오늘 실행했더라도)
sudo logrotate -f /etc/logrotate.d/myapp
# 전체 logrotate 강제 실행
sudo logrotate -f /etc/logrotate.conf
# 상세 출력으로 실행
sudo logrotate -v /etc/logrotate.d/myapp
logrotate 실행 확인
# logrotate 상태 파일 (마지막 실행 날짜 기록)
cat /var/lib/logrotate/status | grep myapp
# 시스템 logrotate 타이머 확인
sudo systemctl status logrotate.timer
sudo systemctl list-timers | grep logrotate
# 실행 로그 확인
sudo grep logrotate /var/log/syslog | tail -10
로그 보존 용량 계산
# 예상 디스크 사용량 계산
# 일일 로그 크기 * 보존 일수
# 현재 로그 파일 크기
du -sh /var/log/nginx/
du -sh /var/log/mysql/
# 압축 효율 확인 (텍스트 로그는 보통 5~10배 압축)
ls -lh /var/log/nginx/*.gz
로그 없는 정적 파일 요청 제외
Nginx 설정에서 정적 파일 접근 로그를 꺼두면 로그 크기를 크게 줄일 수 있습니다:
location ~* \.(jpg|jpeg|png|gif|ico|css|js|woff2)$ {
expires 1y;
access_log off; # 정적 파일 접근 로그 비활성화
}
logrotate를 올바르게 설정하면 디스크 부족으로 인한 갑작스러운 서버 장애를 예방할 수 있습니다. 새 서비스를 설치할 때마다 해당 서비스의 로그 파일에 대한 logrotate 설정을 추가하는 습관을 들이세요.