로그 보존 자동화: logrotate + systemd-journald로 용량·보존·압축 완전 정복(Ubuntu 24.04)
서버가 오래 버티는 비결은 로그 관리입니다. 로그가 무한 증가하면 디스크가 가득 차 서비스가 중단되고,
반대로 너무 공격적으로 지우면 장애 원인을 찾을 수 없습니다. 이 글은 Ubuntu 24.04 기준으로
logrotate와 systemd-journald를 조합해 용량 제어·보존 정책·압축·서비스 연동까지
실전 운영 패턴을 정리합니다.
1) 큰 그림: 텍스트 로그 vs 저널 로그
- 텍스트 로그(예:
/var/log/nginx/access.log,app.log):logrotate가 주기적으로 파일을 순환(rotate)·압축·삭제. - 저널 로그(
journalctl):systemd-journald가 이진 포맷으로 저장, 보존/용량은journald.conf에서 제어. - 둘을 섞어 쓰는 환경이 많습니다. 프록시/DB는 텍스트 로그, 시스템/서비스 표준 출력은 저널로 수집하는 식입니다.
2) logrotate 기본기(동작 원리)
man logrotate
cat /etc/logrotate.conf
ls /etc/logrotate.d/
/etc/logrotate.conf: 전역 기본값(주기/압축/보관 개수 등)/etc/logrotate.d/*: 서비스별 규칙 파일(Nginx, rsyslog, 커스텀 등)- 크론/타이머로 하루 한 번 실행 → 조건에 맞으면 로테이션 수행
# 전역 기본(예시): /etc/logrotate.conf
weekly
rotate 12
create
compress
delaycompress
include /etc/logrotate.d
용어:
rotate N: 과거 파일 N개 보관(.1,.2.gz…)daily/weekly/monthly또는size 100M: 회전 조건(시간/크기)compress/delaycompress: gzip 압축(바로/다음 회전 시)copytruncatevspostrotate/sharedscripts: 파일 핸들 재오픈 전략(아래 5장)
3) Nginx 예시: 트래픽 많은 서비스의 정석
# /etc/logrotate.d/nginx (권장 템플릿)
/var/log/nginx/*.log {
daily # 매일
missingok
rotate 14 # 2주 보관
compress
delaycompress
notifempty
create 0640 www-data adm
sharedscripts
postrotate
test -f /var/run/nginx.pid && kill -USR1 $(cat /var/run/nginx.pid)
endscript
}
Nginx는 SIGUSR1을 보내면 파일 핸들을 새로 열어 이어서 씁니다.
copytruncate보다 안전/정합성이 좋아 postrotate + USR1 방식을 권장합니다.
4) 스프링부트 앱 로그(파일로 남기는 경우)
Logback 등으로 파일 출력(app.log)을 쓰는 경우:
# /etc/logrotate.d/myapp
/var/log/myapp/app.log {
daily
rotate 10
size 50M # 크기 조건도 병행
missingok
compress
delaycompress
notifempty
create 0640 app app
sharedscripts
postrotate
# systemd 서비스 재시작 아님! 로그 핸들만 reopen 하도록 신호를 주는 스크립트가 있으면 최상
# 없으면 copytruncate 대안(아래 5장) 고려
endscript
}
대안 A: 파일 대신 표준 출력에 로그를 쓰고 systemd가 저널로 수집하도록 하면 파일 핸들 문제에서 해방됩니다(아래 7장).
5) copytruncate가 필요한 경우(차선책)
애플리케이션이 로그 핸들 재오픈을 지원하지 않으면 회전 시 파일 이름만 바뀌고 새 로그가 구파일로 계속 쓰이는 문제가 생깁니다.
이때 copytruncate는 현재 파일을 복사해 백업을 만들고, 원본을 0바이트로 잘라 이어 쓰게 만듭니다.
/var/log/myapp/app.log {
daily
rotate 7
size 100M
compress
delaycompress
copytruncate # <-- 차선책
notifempty
missingok
}
주의: 회전 타이밍에 몇 줄 손실 위험이 있습니다. 가능하면 postrotate로 핸들 reopen을 지원하도록 애플리케이션을 조정하세요.
6) 사이즈 기반 회전 + 시간 혼합
버스트 트래픽 환경에서는 날짜만 믿지 말고 size 조건을 함께 쓰는 게 안전합니다.
/var/log/app/*.log {
daily
size 200M
rotate 14
compress
delaycompress
notifempty
missingok
}
7) 저널(journald) 보존/용량 정책
systemd 서비스(ExecStart 앱)가 표준 출력/에러로 쓰는 로그는 journald가 수집합니다.
디스크에 영구 저장하려면 아래처럼 설정하세요.
# 영구화: 재부팅 후에도 보존
sudo mkdir -p /var/log/journal
sudo systemctl restart systemd-journald
# /etc/systemd/journald.conf (핵심 발췌)
[Journal]
Storage=persistent
SystemMaxUse=2G # 총 사용 상한
SystemMaxFileSize=200M # 파일 단위 상한
MaxRetentionSec=30day # 보존 기간
Compress=yes
확인:
journalctl --disk-usage
journalctl -u myapp.service --since "1 hour ago"
팁: 텍스트 파일로 남기던 애플리케이션 로그를 표준 출력으로 전환해 journald로 일원화하면, logrotate 규칙을 크게 줄일 수 있습니다.
8) systemd 서비스와 로그 전략 일원화
# /etc/systemd/system/myapp.service
[Unit]
Description=My Spring Boot App
After=network.target
[Service]
User=app
Group=app
WorkingDirectory=/srv/myapp
ExecStart=/usr/bin/java -jar app.jar --spring.profiles.active=prod
Restart=on-failure
# 로그는 표준 출력으로 → journald가 수집
StandardOutput=journal
StandardError=journal
# 리소스 제한(옵션)
MemoryMax=1G
CPUQuota=150%
[Install]
WantedBy=multi-user.target
이렇게 하면 journalctl -u myapp로 통합 조회가 가능하며, 보존/압축/용량은 journald.conf에서 제어합니다.
9) 수집·보관·검색: 외부로 보내기
- 텍스트 로그:
logrotate로 용량 관리 +Promtail/Filebeat로 중앙 수집 - 저널 로그:
promtail가 systemd-journal 입력을 직접 읽어 Loki 등으로 전송
# Promtail 예시 스니펫
scrape_configs:
- job_name: systemd-journal
journal:
json: false
path: /var/log/journal
relabel_configs:
- source_labels: ['__journal__systemd_unit']
target_label: 'unit'
10) 운영 점검 루틴
# logrotate 강제 실행(테스트)
sudo logrotate -d /etc/logrotate.conf # dry-run
sudo logrotate -f /etc/logrotate.conf # 강제 회전
# 마지막 실행 로그(우분투 기본)
sudo cat /var/lib/logrotate/status | tail
# 저널 용량
journalctl --disk-usage
# 특정 서비스 최근 에러
journalctl -u nginx -p 3 -n 50 --no-pager
11) 흔한 함정과 해결
- 회전했는데 파일 크기가 계속 증가 → 앱이 여전히 구파일 핸들에 쓰는 중.
postrotate로 reopen 신호(예: Nginx USR1). 미지원 앱은copytruncate고려. - 압축이 안 된다 →
compress/delaycompress확인. 바로 압축하면 다음 회전까지 tail이 불편할 수 있어delaycompress권장. - 저널이 디스크를 가득 채움 →
SystemMaxUse,MaxRetentionSec설정 후systemctl restart systemd-journald. - 중앙 수집 중복 → 같은 로그를 파일/저널 둘 다 수집하지 않게 경로·입력을 정리.
12) 최종 체크리스트
- Nginx/DB/애플리케이션 로그에
logrotate규칙 존재(시간+사이즈 혼합, 압축, 보관 수) - 재오픈 지원 서비스는
postrotate신호, 미지원은copytruncate로 차선 - 저널은
/var/log/journal영구화 +SystemMaxUse/MaxRetentionSec설정 - 중앙 수집 경로 일원화(Promtail/Filebeat), 중복 수집 제거
- 정기 점검:
logrotate --debug,journalctl --disk-usage, 알람 임계치 설정
이 구성을 적용하면 “로그가 디스크를 먹어치우는 문제”와 “필요한 순간 로그가 없는 문제”를 동시에 피할 수 있습니다. 다음 글에서는 Nginx 리버스 프록시 + Spring Boot 조합에서 CORS, 타임아웃, 업로드 제한을 운영 친화적으로 맞추는 실전 설정을 다룹니다.
'서버 인프라 실무' 카테고리의 다른 글
| SSH 보안 단단하게: Fail2ban + UFW로 무차별 대입 차단(필터/액션/알림/점검 루틴) (0) | 2025.10.25 |
|---|---|
| Nginx 리버스 프록시 + Spring Boot 실전 운영: CORS, 타임아웃, 업로드 제한, 보안 헤더 한 번에 정리 (0) | 2025.10.24 |
| 백업은 존재할 때만 복구된다: rsync/cron으로 무중단 증분 백업(로컬·원격·보안·검증 루틴) (0) | 2025.10.23 |
| 시스템 모니터링 첫걸음: top/htop/journalctl/ss로 원인 추적(근거 있는 장애 대응 루틴) (0) | 2025.10.23 |
| 시계가 틀리면 장애난다: chrony로 시간 동기화 정확히 잡기(Ubuntu 24.04, NTP 실무) (0) | 2025.10.22 |