서비스가 멈췄고 오류 메시지가 평소와 달랐다.
No space left on device
Table of contents
Open Table of contents
증상 — 한 파일이 컸다
df -h 로 보니 사용률이 100%였다. 큰 것부터 찾았다.
$ du -sh /* | sort -h
/var/log 가 대부분이었고 들어가 보니 error.log 한 파일이 수십 기가였다.
$ tail -100 error.log
같은 메시지가 반복되고 있었다. 시각을 보니 초당 여러 번 찍혔다. 외부 연결이 실패할 때마다 남기는 줄이었다.
상대가 응답하지 않는 상태가 이어지면서 그 줄이 계속 쌓였다. 연결이 안 되는 원인 자체는 금방 고쳤지만 그것으로 끝이 아니었다. 같은 일이 다른 곳에서 또 날 수 있었다.
회전과 압축을 넣었다
logrotate 로 일정 크기가 되면 새 파일로 넘어가게 했다.
매일 새 파일
n개까지 보관
넘으면 삭제
logrotate 설정에 daily 와 보관 개수를 주니 한 파일이 무한정 커지는 상태가 없어졌다. 지난 파일은 gzip 으로 압축해 두었는데 같은 문구가 반복돼 압축률이 높았다.
프로세스가 그 파일을 열고 있어서 copytruncate 를 줬다. 이걸 안 주면 이름만 바뀌고 프로세스는 옛 파일에 계속 쓴다.
급할 때 rm 으로 지워도 마찬가지다. lsof 로 보면 지워진 파일을 아직 열고 있는 것이 나오고 그 상태에서는 df 의 남은 공간이 안 늘어난다.
보관 개수도 정해야 했다. 적게 두면 공간은 아끼는데 옛것을 못 보고 많이 두면 다 남는 대신 공간을 쓴다. 조사할 때 며칠 치를 보는지 물어보니 대개 일주일 안이어서 그 기간이 담기는 만큼만 남기게 했다.
알림을 두 단계로 나눴다
차기 전에 알리게 하면서 임계를 어디에 둘지가 걸렸다. 90%는 대응할 시간이 짧고 70%는 자주 울려 아무도 안 본다. 80%로 두고 시작했다.
한 번 겪고 나서 두 단계로 바꿨다.
80% 알림
90% 긴급 알림
여유가 있을 때와 급할 때를 구분한 것이다. 앞 단계는 기록만 남기고 뒤 단계는 사람을 부른다.
알림만으로는 어디가 차는지 몰라서 큰 폴더를 같이 알려주게 했다.
사용량 92%
가장 큰 폴더: /var/log (수십 기가)
그 한 줄이 있어서 알림을 받자마자 어디를 볼지 바로 정해졌다.
지우면 안 되는 것
로그 설정도 봤다. 운영에서 모든 수준을 다 남기고 있었다.
디버그
정보
경고
오류
개발에서는 DEBUG 까지 조사에 필요하지만 운영에서는 WARNING 이상만 남기게 했다. 그것만으로 하루 생성량이 크게 줄었다. 다만 문제를 조사할 때는 설정 파일에서 수준을 올려 잠깐 켤 수 있게 뒀다. 항상 켜 두는 것과 필요할 때 켜는 것은 다르다.
syslog 로 가는 것 말고 앱이 직접 쓰는 로그도 있었다. 이건 회전 설정이 따로 필요해서 둘 다 챙겨야 했다.
한 가지 조심할 것이 있었다. 정산이나 감사에 쓰이는 기록은 로그가 아니라 데이터다. 로그는 지워도 되지만 그런 기록은 보관 기간이 정해져 있는데 같은 폴더에 있으면 같이 지워진다.
/logs 회전·삭제 대상
/records 보관 대상
위치를 나눠서 지우는 설정이 안 닿게 했다.
정리
- 디스크가 차면 서비스가 멈춘다
- 로그 한 파일이 무한정 커질 수 있다
- 원인을 고쳐도 다른 곳에서 또 난다. 회전을 넣는다
logrotate에copytruncate를 주지 않으면 프로세스가 옛 파일에 계속 쓴다- 프로세스가 열고 있으면
rm해도 공간이 안 난다.lsof로 확인한다 - 로그는
gzip압축률이 높다 - 보관 개수는 조사에 필요한 기간으로 정한다
- 알림은 여유 있을 때와 급할 때를 나누고 어디가 차는지를 같이 넣는다
- 운영에서는 로그 수준을 줄이고 필요할 때 켠다
- 지우면 안 되는 기록은 위치를 나눠 둔다