
들어가며
디톡스메이트 서비스는 서버 에러를 Grafana에서 확인하고, Grafana Alert를 통해 Discord로 알림을 받고 있습니다. 그런데 며칠 동안 에러 알림이 오지 않았습니다. 이상해서 Grafana를 확인해보니, prod 백엔드 로그가 더 이상 쌓이지 않고 있었습니다. 처음에는 "백엔드 로그가 안 찍히나?"라고 생각했지만, 실제 원인은 백엔드 코드가 아니라 로그 수집 파이프라인과 디스크 용량 문제였습니다.
이 글은 Grafana에 로그가 보이지 않는 상황에서 어디부터 확인했고, 어떤 단서로 원인을 좁혀갔는지 정리한 디버깅 기록입니다.
로그가 Discord까지 도달하는 흐름
먼저 현재 서비스에서 로그가 어떻게 생성되고, Grafana와 Discord까지 도달하는지 큰 그림을 봅니다.

Grafana는 Spring Boot 로그 파일을 직접 읽지 않습니다. Spring Boot가 Logback으로 파일 로그를 남기고, Promtail이 이 파일을 읽어 Loki로 보냅니다. Grafana는 Loki에 쌓인 로그를 조회하고, Alert 조건에 걸리면 Discord로 알림을 보냅니다.
따라서 Grafana에 로그가 보이지 않는다는 것은 단순히 "백엔드가 로그를 안 찍는다"는 뜻이 아닙니다. 로그가 생성되고, 수집되고, 저장되고, 조회되는 과정 중 어딘가가 끊겼다는 뜻입니다.
문제 디버깅 과정
1. 프로세스가 살아 있는지 확인
먼저 WAS, Promtail, Loki 컨테이너가 살아 있는지 확인했습니다.
docker ps -a | grep -E 'detoxmate-prod|promtail|loki'
결과는 모두 Up 상태였습니다.
| Container ID | Image | Command | Created | Status | Ports | Name |
| 78af5ba75eb8 | detoxmate:prod | java -jar app.jar | 11 days ago | Up 11 days | 0.0.0.0:8081->8081/tcp, :::8081->8081/tcp | detoxmate-prod |
| 4ee90453ec91 | grafana/loki:latest | /usr/bin/loki -conf... | 4 weeks ago | Up 4 weeks | 0.0.0.0:3100->3100/tcp, :::3100->3100/tcp | loki |
| 19eb656fe48b | grafana/promtail:latest | /usr/bin/promtail -... | 2 months ago | Up 3 weeks | 없음 | promtail |
그래서 다음으로 Promtail 자체 로그를 확인했습니다.
2. Promtail 로그 확인
Grafana에 로그가 안 보일 때 Promtail을 먼저 보는 이유는 Promtail이 로그 파이프라인의 입구이기 때문입니다.
docker logs promtail 2>&1 | tail -200
다음 에러가 확인되었습니다.
level=error ts=2026-05-05T11:34:57.032284734Z caller=positions.go:179 msg="error writing positions file" error="open /tmp/.positions.yaml9015774036798675289: no space left on device"
핵심은 no space left on device입니다.
Promtail은 로그 파일을 읽으면서 "어디까지 읽었는지"를 positions 파일에 저장합니다. 그런데 디스크 공간이 부족하면 이 상태 파일을 쓸 수 없습니다. 이 단서 때문에 문제를 Promtail 설정 문제가 아니라 서버 디스크 부족 문제로 다시 바라보게 되었습니다.
3. 디스크 용량 확인
디스크 상태를 확인했습니다.
df -h
결과는 다음과 같았습니다.
Filesystem Size Used Avail Use% Mounted on
/dev/nvme0n1p1 8.0G 7.8G 183M 98% /
서버의 루트 디스크가 98% 사용 중이었습니다. Promtail이 상태 파일을 쓰지 못한 이유가 디스크 부족일 가능성이 높아졌습니다.
루트 파일시스템에서 큰 용량을 차지하는 항목을 찾았습니다.
sudo du -h -x / | sort -h | tail -30
결과 중 눈에 띄는 항목은 다음이었습니다.
1.2G /var/lib/docker/containers/4ee90453ec91261079736b2a65be3e043fd4c554f7dc95d1836079165bd81730
/var/lib/docker/containers/... 경로이므로 Docker 컨테이너 관련 파일입니다. 어떤 컨테이너인지 확인했습니다.
docker inspect 4ee90453ec91261079736b2a65be3e043fd4c554f7dc95d1836079165bd81730 --format '{{.Name}} {{.Image}}'
결과는 다음과 같았습니다.
/loki sha256:d060bcc2feb7d60999bdf4032b56f5fd2d8bcdd013ce3134050a91c6cbe68d75
즉 Loki 컨테이너 디렉터리가 1.2GB를 차지하고 있었습니다.
4. Loki 컨테이너 로그 파일 확인
Loki 컨테이너가 무엇 때문에 커졌는지 확인했습니다.
docker inspect loki --format '{{.LogPath}}'
결과는 다음과 같았습니다.
/var/lib/docker/containers/4ee90453ec91261079736b2a65be3e043fd4c554f7dc95d1836079165bd81730/4ee90453ec91261079736b2a65be3e043fd4c554f7dc95d1836079165bd81730-json.log
이 파일은 Loki에 저장된 애플리케이션 로그 데이터가 아니라, docker logs loki로 볼 수 있는 Loki 컨테이너 자체의 로그입니다. 어떤 로그가 쌓이고 있는지 확인했습니다.
docker logs --tail 50 loki
출력은 다음과 같은 형태였습니다.
uploading table index_20613
finished uploading table index_20613
cleaning up unwanted indexes from table index_20613
...
starting recalculate owned streams job
completed recalculate owned streams job
Loki 프로세스 자체의 운영 로그입니다. Loki가 index table을 업로드하고 정리하는 작업을 info level로 stdout에 출력하고 있었고, Docker는 이 stdout을 기본 json-file 로그로 저장합니다.
이런 중요하지 않은 로그가 쌓이고 있었고, Docker 로그 로테이션이 설정되어 있지 않아 이 파일이 계속 커졌습니다. 그 결과 루트 디스크가 거의 가득 찼고, Promtail이 상태 파일을 쓰지 못하면서 Grafana에 새 로그가 보이지 않게 되었습니다.
해결책
1. 즉시 Loki의 Docker 로그 파일 비우기
먼저 Loki 컨테이너의 Docker 로그 파일을 비워 디스크 공간을 확보했습니다.
sudo truncate -s 0 "$(docker inspect loki --format '{{.LogPath}}')"
이 명령은 Loki 컨테이너 자체의 stdout 로그 파일만 비웁니다.
2. Docker 로그 로테이션 설정
즉시 복구만으로는 같은 문제가 다시 생길 수 있습니다. Docker가 컨테이너 stdout/stderr 로그를 무제한으로 저장하지 않도록 로그 로테이션을 설정했습니다.
sudo tee /etc/docker/daemon.json > /dev/null <<'EOF'
{
"log-driver": "json-file",
"log-opts": {
"max-size": "50m",
"max-file": "3"
}
}
EOF
로그 파일이 최대 50MB가 되도록 하고, 그 파일은 3개까지 유지합니다. 아예 제거할 수도 있겠지만, 이런 디버깅을 위해서 최근 로그는 남겨둡니다.
3. Loki 로그 레벨 낮추기
위 로그의 문제가 info 수준의 로그를 모두 찍고 있기 때문입니다. docker-compose.yml 파일에서 Loki 로그 레벨을 warn으로 낮췄습니다.
command:
- -config.file=/etc/loki/local-config.yaml
- -log.level=warn
수정 후 Loki만 다시 적용했습니다.
docker-compose up -d loki
결과
조치 후 Grafana에 prod 로그가 다시 정상적으로 쌓이기 시작했습니다.

마치며
WAS - Promtail - Loki - Grafana - Discord 로 이어지는 로그 시스템을 파악해보면서 단계별로 디버깅을 해보았습니다. 눈에 보이는 것은 Grafana 와 Discord 이지만, 내부에 많은 시스템이 숨어있습니다. 로그를 읽고 분류하는 것은 Promtail, 로그가 검색 가능하게 만드는 것은 Loki, GUI 담당은 Grafana, Alert System 은 Grafana Alert, Webhook 은 Discord 가 담당합니다. 장애는 외부에 드러나지만, 내부 어딘가에 문제가 생긴 것입니다. 내부 문제를 찾을 땐 암묵지가 필요합니다. 외부 현상을 보고, 어떤 시스템이 문제가 생겼겠거니 하는 추론이 가능해야 합니다. 학습을 통해 암묵지를 꾸준히 명시지화 해야, 빠른 장애 대응이 가능해집니다. 이번 학습을 통해 로그 시스템에 대한 이해도를 높일 수 있었습니다.
'서버' 카테고리의 다른 글
| DB 를 Grafana 와 연동해서 대시보드 만들기 (1) | 2026.07.25 |
|---|---|
| DB 테이블 스키마 변경 전략 (0) | 2026.02.22 |
| Node.js 에서 Date 객체 Time Zone 다루기 (0) | 2026.02.09 |
| Characterization Test 로 안전하게 리팩터링 하기 (0) | 2026.02.07 |
| NestJS 철학 이해하기 1 : Layered Architecture (0) | 2026.02.01 |