LabHub
배우기 러닝패스 코스

ログパイプラインの設計

ローテーションが何を失うのかを自分で見る

LabHub 에서 이어서 보기

한국어 원문으로 표시합니다.

목표

로그 로테이션의 두 방식이 각각 무엇을 잃는지 직접 만들어 봅니다. 설명을 읽는 것과 파일이 0바이트로 남아 있는 걸 보는 것은 다릅니다.

왜 중요한가

로테이션을 잘못 걸면 두 가지 중 하나가 일어납니다.

둘 다 장애 조사 중에 발견하면 이미 늦습니다.

단계

  1. 계속 쓰는 프로세스 → /root/log/01-pid.txt
  2. 지웠는데 공간이 안 돌아오는 것 → /root/log/02-deleted.txt
  3. 재시작으로 정리 → /root/log/03-restart.txt
  4. rename 방식 흉내 → /root/log/04-rename.txt
  5. copytruncate 방식 흉내 → /root/log/05-truncate.txt
  6. logrotate 설정 작성 → /root/log/06-app.conf
  7. 무엇을 잃는지 → /root/log/07-tradeoff.md
  8. 정리 → /root/log/08-clean.txt

참고

계속 쓰는 프로세스를 만든다

계속 쓰는 프로세스 → /root/log/01-pid.txt

로그를 계속 쓰는 프로세스를 백그라운드로 띄웁니다. 파일을 계속 열어 둔 채로 써야 합니다 — 이 실습이 보여 주려는 현상이 전부 '열려 있는 파일' 때문에 생기기 때문입니다.

mkdir -p /root/log
( i=0; while true; do i=$((i+1)); echo "line $i"; sleep 0.05; done ) >> /root/log/app.log &
echo $! > /root/log/01-pid.txt

리다이렉션을 루프 바깥에 둔 것이 핵심입니다. echo ... >> 파일 처럼 안쪽에 두면 매번 열고 닫아서, 파일을 지워도 핸들이 남지 않고 rename 해도 새 파일에 쓰게 됩니다. 실제 데몬은 파일을 한 번 열고 계속 씁니다.

지웠는데 공간이 안 돌아오는 것을 본다

지웠는데 공간이 안 돌아오는 것 → /root/log/02-deleted.txt

rm /root/log/app.log 를 하고 나서 ls -l /proc/<PID>/fd | grep deleted 를 보세요. 결과를 /root/log/02-deleted.txt 에 저장합니다. 파일은 사라졌는데 프로세스는 아직 쓰고 있고, 그 블록은 반환되지 않습니다.

다시 시작해서 정리한다

재시작으로 정리 → /root/log/03-restart.txt

그 프로세스를 죽이고(kill <PID>) 새로 시작하세요. /root/log/03-restart.txt 에 두 줄: 죽인 뒤 ls -l /proc/*/fd 2>/dev/null | grep -c deleted 결과와, 왜 재시작이 해결책이 되는지 한 줄.

rename 방식을 흉내 낸다

rename 방식 흉내 → /root/log/04-rename.txt

새 writer 를 띄운 뒤 mv /root/log/app.log /root/log/app.log.1 하고 5초 기다린 다음 wc -l 로 두 파일의 줄 수를 보세요. /root/log/04-rename.txt 에 두 파일의 줄 수를 적습니다. 새 app.log 는 만들어지지도 않았을 것입니다 — 그게 SIGHUP 이 필요한 이유입니다.

copytruncate 방식을 흉내 낸다

copytruncate 방식 흉내 → /root/log/05-truncate.txt

cp /root/log/app.log.1 /root/log/app.log.2 && : > /root/log/app.log.1 로 복사 후 자르기를 합니다. 그리고 5초 뒤 wc -l /root/log/app.log.1 을 보세요. /root/log/05-truncate.txt 에 자른 직후와 5초 뒤의 줄 수를 적습니다. 프로세스가 계속 쓰고 있음을 확인하는 것이 목적입니다.

logrotate 설정을 쓴다

logrotate 설정 작성 → /root/log/06-app.conf

/root/log/06-app.conf 에 logrotate 설정을 씁니다. 필요한 것: 경로 패턴, daily, rotate 14, compress, delaycompress, missingok, notifempty, 그리고 create 또는 copytruncate 중 하나. logrotate 명령이 없어도 됩니다 — 설정을 읽고 쓸 줄 아는 것이 목적입니다.

무엇을 잃는지 적는다

무엇을 잃는지 → /root/log/07-tradeoff.md

/root/log/07-tradeoff.md 에 네 줄. create 가 잃는 것 / copytruncate 가 잃는 것 / 여러분이 고른 방식 / 그 이유. 둘 다 공짜가 아니라는 것이 이 실습의 결론입니다.

정리한다

정리 → /root/log/08-clean.txt

기록해 둔 PID 로 종료합니다: kill $(cat /root/log/01-pid.txt). 그다음 rm -f /root/log/app.log* 로 파일을 지우고, 남은 게 없음을 pgrep -f sleep | wc -l 같은 것으로 확인해 /root/log/08-clean.txt 에 적으세요.

⚠️ pkill -f 'while true' 는 쓰지 마세요. pkill 의 -f 는 자기 명령줄까지 검사 대상에 넣기 때문에, 그 문자열이 들어간 셸 자신을 죽입니다. 실무에서도 pkill -f 로 자기 세션을 끊는 사고가 흔합니다 — PID 를 기록해 두고 그걸로 죽이는 편이 항상 안전합니다.