Published on

journalctl 로그 폭주로 디스크 찰 때 10분 해결

Authors

서버가 갑자기 느려지고, 배포나 SSH가 버벅이며, 심지어 서비스가 죽기 시작했다면 가장 먼저 디스크를 의심해야 합니다. 특히 systemd-journald가 남기는 저널이 폭주하면 /var/log/journal 또는 /run/log/journal이 순식간에 커져서 루트 파티션을 꽉 채웁니다. 이 글은 “지금 당장 공간을 확보”하고, “원인을 특정”하고, “재발 방지 설정”까지 10분 안에 끝내는 루틴으로 구성했습니다.

관련해서 서비스가 계속 재시작되며 로그가 폭주하는 케이스가 많습니다. 서비스 재시작 루프를 먼저 끊어야 할 때는 이 글도 함께 보세요: systemd 서비스가 계속 재시작될 때 원인 추적

0) 증상 확인: 정말 저널 때문에 찼나

먼저 “어디가 찼는지”를 30초 안에 확인합니다.

# 전체 파일시스템 사용량
sudo df -h

# /var에서 무엇이 큰지
sudo du -xh /var | sort -h | tail -n 20

# 저널 디스크 사용량 (가장 빠른 확인)
sudo journalctl --disk-usage
  • journalctl --disk-usage가 수 GB 이상이면 거의 확정입니다.
  • /run/log/journal이 커졌다면 휘발성(메모리 기반 tmpfs)일 가능성이 높고, /var/log/journal이 커졌다면 영구 저장입니다.

1) 1분 응급처치: 공간 즉시 회수(안전한 순서)

1-1. 가장 안전: 시간 기준으로 삭제

# 2일 이전 로그 삭제
sudo journalctl --vacuum-time=2d

# 6시간 이전만 남기기(상황이 급하면 더 공격적으로)
sudo journalctl --vacuum-time=6h

운영에서 보통 “최근 몇 시간”만 남겨도 장애 대응에는 충분한 경우가 많습니다.

1-2. 용량 기준으로 삭제

# 저널 총합을 500MB로 줄이기
sudo journalctl --vacuum-size=500M

# 정말 급하면 100MB까지
sudo journalctl --vacuum-size=100M

1-3. 파일 개수 기준(보조 옵션)

# 저널 파일을 10개만 유지
sudo journalctl --vacuum-files=10

1-4. “지금 당장 부팅”이 목적이면 런타임 저널만 비우기

/run이 꽉 찬 상태라면 재부팅으로도 풀리지만, 재부팅이 어렵다면 런타임 저널을 정리합니다.

# 런타임 저널만 정리(휘발성)
sudo journalctl --vacuum-time=1h

주의: rm -rf /var/log/journal 같은 직접 삭제는 권장하지 않습니다. 저널 파일은 인덱스/락이 있어 journalctl --vacuum-*로 정리하는 편이 안전합니다.

2) 2분: 로그 폭주 주범 서비스 1개를 찾아낸다

공간을 확보했으면 “무엇이 로그를 찍는지”를 찾아야 재발을 막습니다.

2-1. 최근 10분 동안 가장 시끄러운 유닛 찾기

# 최근 10분 로그를 유닛별로 훑기
sudo journalctl --since "10 min ago" | sed -n 's/.*\(systemd\[[0-9]\+\]\|\)\?//p' | head

위처럼 원시 로그를 보는 것보다, 유닛 단위로 바로 좁히는 게 빠릅니다.

# 특정 유닛(예: myapp.service)만 최근 로그 보기
sudo journalctl -u myapp.service --since "30 min ago" -n 200

# 커널/시스템 레벨(드라이버, 파일시스템, OOM 등)
sudo journalctl -k --since "30 min ago" -n 200

2-2. “재시작 루프”인지 즉시 확인

로그 폭주의 흔한 패턴은 Restart=always 같은 설정으로 서비스가 죽고 다시 뜨는 루프입니다.

sudo systemctl status myapp.service
sudo systemctl show myapp.service -p Restart,RestartUSec,StartLimitIntervalUSec,StartLimitBurst

재시작 루프라면 원인 파악 전 임시로 멈춰 로그 폭주를 끊습니다.

sudo systemctl stop myapp.service
# 자동 재시작 방지
sudo systemctl disable myapp.service

재시작 루프 원인 추적은 아래 글을 참고하면 시간을 크게 줄일 수 있습니다.

2-3. OOM이 원인이라면 로그가 “증상”일 수 있다

메모리 부족으로 프로세스가 죽고, systemd가 재시작하고, 그 과정이 로그를 폭주시키는 케이스가 많습니다.

# OOM 흔적 찾기
sudo journalctl -k | grep -i -E "oom|out of memory|killed process" | tail -n 50

OOM 루트 원인 추적은 이 글이 실전적으로 도움이 됩니다.

3) 3분: 재발 방지 핵심 설정(저널 상한선 걸기)

응급처치만 하면 며칠 뒤 다시 찹니다. journald.conf에 상한선을 걸어 “최악의 경우에도 디스크를 다 먹지 않게” 만드는 게 핵심입니다.

설정 파일은 보통 /etc/systemd/journald.conf 입니다.

sudo sed -n '1,200p' /etc/systemd/journald.conf

3-1. 가장 효과적인 4가지 옵션

아래는 운영에서 자주 쓰는 안전한 예시입니다.

# /etc/systemd/journald.conf

[Journal]
# 영구 저장을 쓸지(기본 auto). 디스크가 작으면 volatile 고려
Storage=persistent

# 저널이 디스크에서 차지할 최대치
SystemMaxUse=1G

# 파일시스템에 최소로 남겨둘 여유(루트 파티션 보호)
SystemKeepFree=2G

# 개별 저널 파일 최대 크기(너무 큰 파일 방지)
SystemMaxFileSize=128M

# 런타임 저널(tmpfs)도 상한선
RuntimeMaxUse=200M

적용:

sudo systemctl restart systemd-journald
sudo journalctl --disk-usage

팁:

  • 루트 파티션이 20GB 수준이면 SystemKeepFree를 크게 잡는 편이 안전합니다.
  • SystemMaxUse만 걸어도 대부분의 “디스크 100%” 사고를 막습니다.

3-2. 영구 저널이 필요 없으면 volatile로 전환

보안/감사 요구가 없고, 로그는 외부(예: Loki, ELK, CloudWatch)로 보내는 구조라면 영구 저장 자체를 끄는 선택지도 있습니다.

[Journal]
Storage=volatile
RuntimeMaxUse=200M

이 경우 재부팅하면 저널이 사라집니다. 장애 분석 요구사항과 트레이드오프를 반드시 확인하세요.

4) 2분: 애플리케이션 로그 폭주 자체를 줄이는 방법

저널 제한은 “피해 상한”을 만드는 것이고, 근본적으로는 로그 폭주를 줄여야 합니다.

4-1. systemd 서비스에 로그 레이트 리밋 적용

유닛 파일에 레이트 리밋을 걸면 같은 메시지가 초당 수천 줄씩 찍힐 때 완화됩니다.

# /etc/systemd/system/myapp.service
[Service]
# 동일/유사 로그가 너무 많이 찍힐 때 드롭
LogRateLimitIntervalSec=10s
LogRateLimitBurst=2000

적용:

sudo systemctl daemon-reload
sudo systemctl restart myapp.service

주의: 드롭이 발생하면 중요한 단서가 일부 유실될 수 있습니다. “장애 시만 임시 적용”하고, 원인 해결 후 원복하는 운영도 흔합니다.

4-2. stdout/stderr 로그 레벨 낮추기

컨테이너/서비스가 stdout으로 과도한 debug 로그를 뿜으면 journald가 그대로 받아 먹습니다. 애플리케이션 설정에서 로그 레벨을 info 또는 warn으로 조정하고, 반복 에러는 샘플링(예: 1초에 1번만 출력)하도록 바꾸는 것이 장기적으로 가장 효과적입니다.

5) 1분 체크리스트: “10분 해결” 실행 순서 요약

  1. sudo journalctl --disk-usage 로 저널이 범인인지 확인
  2. sudo journalctl --vacuum-size=500M 또는 --vacuum-time=6h 로 즉시 공간 회수
  3. sudo journalctl -u ... --since "30 min ago" 로 주범 유닛 특정
  4. 재시작 루프면 systemctl stop으로 폭주 차단 후 원인 분석
  5. /etc/systemd/journald.confSystemMaxUseSystemKeepFree 설정
  6. 필요 시 유닛에 LogRateLimit* 추가

부록: 자주 하는 실수와 주의점

  • rm -rf /var/log/journal로 지우기: 급할 때 유혹적이지만 권장하지 않습니다. 가능하면 journalctl --vacuum-* 사용.
  • 디스크가 100%인 상태에서 설정만 바꾸기: 설정은 “다음부터” 적용됩니다. 먼저 vacuum으로 숨통을 틔워야 합니다.
  • 로그 폭주를 journald 탓으로만 보기: 대부분은 앱의 예외 루프, 재시작 루프, OOM 같은 상위 원인이 있습니다.

위 루틴대로 하면 “지금 당장 디스크를 살리는 것”과 “다음번에 디스크가 다 차지 않게 만드는 것”을 함께 달성할 수 있습니다. 운영 환경에서는 저널 상한(SystemMaxUse, SystemKeepFree)을 기본값처럼 템플릿화해 두는 것이 가장 큰 예방책입니다.