Ubuntu 26.04 강좌 / 저널·파일 로그·로그 회전과 보존 설정하기

Ubuntu 로그 관리는 journald의 저장·보존과 일반 파일 로그의 회전을 구분해 설정합니다. 먼저 실제 수집기를 확인하고, 보존 기간을 줄이면 기존 기록이 삭제될 수 있으므로 보관할 로그를 확보한 뒤 정책을 바꿉니다.

실제 로그 수집 경로 확인하기

systemctl status systemd-journald rsyslog --no-pager
journalctl --disk-usage
journalctl --list-boots
ls /var/log

rsyslog가 설치되어 있지 않은 시스템에는 익숙한 /var/log/syslog가 없을 수 있습니다. journal의 이진 파일을 logrotate로 직접 회전하거나 파일을 강제로 지우지 않습니다. 앱이 자체 파일에 쓰는지 journal에 쓰는지도 해당 서비스 설정과 함께 확인합니다.

검색 조건과 실제 로그 생성 확인

logger -t ubuntu-course-log 'retention-lab-marker'
journalctl -t ubuntu-course-log --since '5 minutes ago' --no-pager
journalctl -b -p warning --no-pager

새 마커를 실제로 찾을 수 있는지 확인하고 부팅·시간 범위·unit·우선순위를 필요에 맞게 좁힙니다. 출력이 없다는 사실은 로그 생성 실패와 조회 조건 불일치 둘 다 가능하므로 따로 조사합니다. 일반 사용자에게 전체 시스템 로그 열람 권한을 불필요하게 넓히지 않습니다.

journal 보존 정책을 별도 파일로 관리

전용 VM에서 정책을 시험하려면 기존 설정을 백업하고 /etc/systemd/journald.conf.d/60-lab-retention.conf 같은 새 파일을 검토합니다. 다음 값은 작은 실습 환경의 예이며 법적·조직 보존 기준을 대신하지 않습니다. 원래 보관량보다 낮추면 오래된 기록이 없어질 수 있습니다.

[Journal]
Storage=persistent
SystemMaxUse=200M
RuntimeMaxUse=50M
MaxRetentionSec=7day

persistent 저장소 준비와 적용은 systemd 문서에 맞춰 확인하고, 계획한 시점에 journald를 restart한 뒤 journalctl --flush와 disk-usage·새 마커 검색을 확인합니다. 크기 제한은 활성 파일과 회전 시점 때문에 정확히 같은 바이트의 즉시 상한처럼 보이지 않을 수 있습니다.

journald.conf 문서는 영구 저장과 보존 용량·기간의 적용 조건을 설명합니다.

journal 설정 적용과 원래 상태 복원하기

보존할 기록을 독립 위치에 확보한 새 전용 VM에서만 시험합니다. 아래 코드는 기존 lab 파일이 있으면 멈추며 다른 관리자의 drop-in을 덮지 않습니다. 앞서 설명한 200M·50M·7day는 작은 실습 예이고 이미 삭제된 기록은 설정 복원으로 돌아오지 않습니다.

(
set -eu
lab_conf=/etc/systemd/journald.conf.d/60-lab-retention.conf
if sudo test -e "$lab_conf" || sudo test -L "$lab_conf"; then
    printf 'Existing lab file: inspect it instead of overwriting.\n' >&2
    exit 1
fi
backup_dir=$(sudo mktemp -d /root/journal-before-lab.XXXXXX)
sudo cp -a /etc/systemd/journald.conf "$backup_dir/"
if sudo test -d /etc/systemd/journald.conf.d; then
    sudo cp -a /etc/systemd/journald.conf.d "$backup_dir/"
fi
sudo install -d -m 0755 /etc/systemd/journald.conf.d
sudo sh -c 'set -C; cat > "$1"' sh "$lab_conf" <<'EOF'
[Journal]
Storage=persistent
SystemMaxUse=200M
RuntimeMaxUse=50M
MaxRetentionSec=7day
EOF
sudo systemd-analyze cat-config systemd/journald.conf
printf 'Review configuration and backup: %s\n' "$backup_dir"
)

cat-config에서 기대한 네 값과 뒤에서 덮는 다른 설정이 없는지 읽은 뒤에만 다음 적용을 진행합니다. 서비스 재시작은 로그 파일을 직접 지우는 작업과 다릅니다. Storage=persistent와 --flush의 결과, 마커 기록과 재부팅 이력 보존을 각각 확인합니다.

sudo systemctl restart systemd-journald.service && sudo journalctl --flush && sudo journalctl --disk-usage
logger -t ubuntu-course-log 'after-retention-change'
sudo journalctl -t ubuntu-course-log --since '5 minutes ago' --no-pager

복원은 이번에 새로 만든 60-lab-retention.conf 한 파일만 대상으로 합니다. 이후 다른 편집이 없고 해당 파일이 이번 내용인지 먼저 확인한 뒤 다음을 실행합니다. 기존 파일을 덮어쓰지 않았으므로 이를 제거하면 이전 설정 조합으로 돌아가며 과거 로그가 재생성되지는 않습니다.

sudo rm -- /etc/systemd/journald.conf.d/60-lab-retention.conf && sudo systemctl restart systemd-journald.service && sudo journalctl --flush
sudo systemd-analyze cat-config systemd/journald.conf

별도 연습 파일로 logrotate 실행하기

logrotate가 설치된 환경에서 아래 코드는 일반 사용자 홈의 새 임시 폴더와 별도 상태 파일만 사용합니다. 시스템의 logrotate 상태나 실제 앱 로그를 건드리지 않습니다. Bash에서 전체 블록을 실행하고 출력된 폴더 경로를 기록합니다.

work=$(mktemp -d "$HOME/logrotate-lab.XXXXXX")
for i in {1..200}; do printf 'lab line %04d\n' "$i"; done > "$work/app.log"
cat > "$work/logrotate.conf" <<EOF
"$work/app.log" {
    size 1k
    rotate 2
    compress
    missingok
    notifempty
    create 0600
}
EOF
logrotate -d -s "$work/state" "$work/logrotate.conf"
logrotate -s "$work/state" "$work/logrotate.conf"
ls -l "$work"
printf 'Lab folder: %s\n' "$work"

debug 실행은 계획을 보여 주며 실제 회전은 두 번째 명령에서 수행합니다. 새 app.log와 압축 보관 파일을 확인하고 gzip -cd "$work/app.log.1.gz"로 연습 내용이 남았는지 봅니다. 실제 앱은 파일 디스크립터를 유지할 수 있어 postrotate·reload 동작을 앱 문서에 맞게 별도로 설계해야 합니다.

복원과 보존 결과 확인

journal 정책 실습을 마치면 이번 drop-in만 원본 상태로 되돌리고 다시 적용합니다. 이미 삭제된 과거 로그는 설정을 복원해도 돌아오지 않으므로 별도 보관 자료가 필요합니다. 연습 폴더는 위치와 내용을 확인한 뒤 자신이 만든 파일만 정리합니다.

로그 정책에는 보존 용량·기간·열람 주체·개인정보 처리·실패 감지를 함께 기록합니다. 서비스 정상 응답과 로그 생성·검색·회전 후 읽기 가능 여부를 각각 검증해야 운영 기록을 잃지 않습니다.