🤔 계기
사내 프로젝트를 진행하면서 Spring Scheduler로 구현한 기능을 테스트 하기 위해
EC2 인스턴스에 컨테이너 형태로 배포를 진행하고 정상적으로 동작하는 지 확인했었다.
여러 번의 수정을 거치면서 기능적인 문제는 해결되었으나,
가끔 로그가 남지 않고, 동작이 전혀 되지 않는 듯한 현상이 있었다.
이유는 디스크 용량 초과로 인한 문제였다.
그런데 용량이 초과된 원인은 알지 못했었다.
하지만 최근에 문제의 근본적인 원인을 찾았다.
이 부분을 많은 사람들이 놓칠 수 있을 것 같아 기록한다.
📃 본론
문제의 원인은 Docker의 로그 설정이었다.
Docker의 기본 로그 설정은 json-file인데 이는 log-rotation을 지원하지 않는다.
즉, 컨테이너가 run한 시점부터 현재까지의 로그가 보존되는 것이다.
나는 스케줄링 관련한 로그가 많이 남도록 설정된 컨테이너를 운영하고 있었고,
이로 인해 로그가 엄청나게 쌓여서 디스크 용량 초과 문제가 발생한 것이다.
그렇다면 Docker의 로그 설정은 어떤 것이 있을까?
| Driver | Description |
| json-file | 로그가 JSON 형식으로 저장, 로그 파일 크기 제한 없음 기본 로그 설정 |
| local | 정해진 형식에 맞춰 저장 (파일 크기, Rolling 수 등) |
| none | 로그를 출력하지 않음 |
| syslog | syslog daemon에 로그를 작성 |
| journald | journald daemon에 로그를 작성 |
| gelf | Graylog Extened Log Format의 endpoint에 로그를 작성 (Graylog or Logstash) |
| fluentd | fluentd daemon에 로그를 작성 |
| awslogs | Amazon CloudWatch에 로그를 작성 |
| splunk | splunk에 로그를 작성 |
| etwlogs | Event Tracing for Windows에 작성 (Windows만 가능) |
| gcplogs | GCP에 로그를 작성 |
나의 상황에서는
Spring boot에서 로그 파일을 생성하는 로직이 있기 때문에
none 이나 local 로 설정하는 것이 맞다고 생각한다.
(이후 local로 로그 드라이버 설정을 변경했다)
드라이버 설정은
- docker run 명령어를 실행할 때 log-driver를 설정하거나
- docker의 daemon.json 설정에서 log-driver 설정을 추가하여 기본 값을 지정하는 방법이 있다.
✨결론
Docker의 기본 로그 드라이버는 rotation을 지원하지 않는다.
되도록이면 local 로 설정하고,
컨테이너에서 로그를 직접 파일로 생성한다면 none도 고려해볼만 하다.
그 외의 경우는 환경에 따라 다른 드라이버를 설정하면 된다.
💡 새롭게 알게된 점
stdout log가 protobuf다?
회사 동료분이 로그 드라이버 관련한 이야기를 듣고 질문하셨다.
"docker log 파일 cat으로 읽으면 왜 깨지나요?"
그래서 실제로 실행해보니 stdout과 글자깨짐 현상이 있었다.

그래서 Local 설정도 바꾸는 등 여러 시도를 해봤지만,
글자 깨짐은 계속 있었다.

그래서 파일 형식을 보니 application/octet-stream / charset=binary 로 되어있었다.
(json-file은 application/json, charset=us-ascii 라서 json 형식으로 열람이 가능하다)
바이너리 형식이었기에 깨지는 것으로 생각해서 더 찾아봤다.
그리고 공식 문서에서 답을 찾았다.

여기서 By default 부분 글을 보면 automatic compression(자동 압축) 으로 사이즈를 줄인다고 나왔다.
그 사이즈를 줄이는 압축이 아마 protobuf가 아닐까 생각해본다. (stackoverflow 답변 참조)
📚 레퍼런스
https://docs.docker.com/engine/logging/configure/
