Linux logrotate 로그 순환 설정
애플리케이션 로그 파일을 자동으로 순환(rotate), 압축, 정리하기 위한 logrotate 설정 템플릿입니다. 크기/시간 기반 순환, 압축, 사후 처리 스크립트 등을 포함합니다.
# /etc/logrotate.d/my-app
# logrotate 설정 파일 — 애플리케이션 로그 순환 설정
#
# 수동 실행 (테스트): logrotate -d /etc/logrotate.d/my-app (dry-run)
# 수동 강제 실행: logrotate -f /etc/logrotate.d/my-app
# 전체 상태 확인: cat /var/lib/logrotate/status
#
# logrotate는 기본적으로 cron에 의해 하루 한 번 실행됨
# /etc/cron.daily/logrotate 또는 systemd timer(logrotate.timer)
# ──────────────────────────────────────────────────
# 애플리케이션 일반 로그 (access, error)
# 와일드카드로 여러 파일을 하나의 블록으로 처리
# ──────────────────────────────────────────────────
/var/log/my-app/access.log
/var/log/my-app/error.log
/var/log/my-app/app-*.log {
# 순환 주기: daily(매일), weekly(매주), monthly(매월), yearly(매년)
daily
# 보관할 이전 로그 파일 수 (rotate 5 = 5개 보관 후 가장 오래된 것 삭제)
rotate 30
# 순환된 파일을 gzip으로 압축 (디스크 절약)
compress
# 압축을 한 사이클 늦게 적용 (현재 순환된 파일은 다음 번에 압축)
# 이유: 일부 애플리케이션이 아직 이전 로그에 쓰고 있을 수 있음
delaycompress
# 로그 파일이 없어도 오류 발생시키지 않음
missingok
# 로그 파일이 비어있으면 순환 건너뜀
notifempty
# 날짜를 파일명에 포함 (my-app.log-20240101.gz 형식)
dateext
# dateformat -%Y%m%d # 날짜 형식 커스터마이즈 (기본: -%Y%m%d)
# 로그 파일을 복사 후 원본을 비움 (copytruncate)
# 주의: 애플리케이션이 파일 디스크립터를 재열기하지 않는 경우에만 사용
# copytruncate
# 권한 설정: 새 로그 파일 생성 시 적용할 권한, 소유자, 그룹
create 0640 nodeapp nodeapp
# 특정 크기 초과 시에도 순환 (시간 조건과 AND 조건)
# size 100M: 100MB 초과 시 즉시 순환 (주기와 관계없이)
# minsize 10M: 이 크기 이상일 때만 순환 (주기 + 크기 조건)
minsize 10M
# 순환 후 실행할 스크립트 (서비스에 새 로그 파일 열도록 신호 전송)
postrotate
# 방법 1: systemd 서비스에 SIGUSR1 신호 보내기 (새 로그 파일 열기)
systemctl kill -s SIGUSR1 my-app.service 2>/dev/null || true
# 방법 2: PID 파일로 직접 신호 전송
# if [ -f /run/my-app.pid ]; then
# kill -USR1 $(cat /run/my-app.pid) 2>/dev/null || true
# fi
# 방법 3: nginx 방식 (로그 재열기)
# nginx -s reopen 2>/dev/null || true
endscript
# 순환 전에 실행할 스크립트 (예: 마지막 로그 라인에 구분자 추가)
# prerotate
# echo "=== 로그 순환: $(date) ===" >> /var/log/my-app/access.log
# endscript
}
# ──────────────────────────────────────────────────
# 크기 기반 순환 (시간과 무관하게 크기 기준)
# 빠르게 쌓이는 디버그 로그에 적합
# ──────────────────────────────────────────────────
/var/log/my-app/debug.log {
# 크기 기준 순환: 지정 크기 초과 시 즉시 순환 (주기 무시)
size 50M
# 소규모 보관: 최근 5개만 유지
rotate 5
compress
delaycompress
missingok
notifempty
dateext
create 0640 nodeapp nodeapp
postrotate
systemctl kill -s SIGUSR1 my-app.service 2>/dev/null || true
endscript
}
# ──────────────────────────────────────────────────
# 감사 로그 (장기 보관, 압축 필수)
# 규정 준수(Compliance) 목적의 로그 — 삭제 없이 장기 보관
# ──────────────────────────────────────────────────
/var/log/my-app/audit.log {
weekly
# 1년치(52주) 보관
rotate 52
compress
# delaycompress 미적용 (감사 로그는 즉시 압축)
missingok
notifempty
dateext
# 압축 방식 변경 (기본 gzip 대신 bzip2, 더 높은 압축률)
compresscmd /usr/bin/bzip2
compressoptions -9
uncompresscmd /usr/bin/bunzip2
compressext .bz2
# 권한 강화: 감사 로그는 root만 읽기 가능
create 0600 root root
# 마지막 로그 파일 삭제 시 실행할 스크립트
# (예: 보관 완료 알림)
lastaction
echo "감사 로그 순환 완료: $(date)" | mail -s "감사 로그 순환 알림" security@example.com
endscript
}
# ──────────────────────────────────────────────────
# Nginx 액세스/에러 로그 (참고용)
# ──────────────────────────────────────────────────
/var/log/nginx/*.log {
daily
rotate 14
compress
delaycompress
missingok
notifempty
sharedscripts
# sharedscripts: 여러 파일이 매칭되어도 post/prerotate를 한 번만 실행
postrotate
# nginx에 USR1 신호로 로그 재열기
if [ -f /run/nginx.pid ]; then
kill -USR1 $(cat /run/nginx.pid)
fi
endscript
}