Prometheus Grafana Query Exporter 구성 중 발생한 문제 해결 과정 - fitpassTeam/fitpass GitHub Wiki
문제 상황
Prometheus와 Grafana를 이용해 RDB의 데이터를 모니터링하기 위한 환경을 구성하던 중, 초기 연결과 설정 자체는 비교적 수월하게 진행되었으나, 실제로 SQL 쿼리를 실행하고 메트릭을 수집하는 단계에서 문제가 발생했습니다.
처음에는 Prometheus가 query-exporter로부터 user_total이라는 메트릭 정보를 받아오지 못하면서, 쿼리 자체가 작동하지 않는 문제를 겪었습니다. 이후 문제를 추적하면서 여러 설정상의 실수와 컨테이너 간 타이밍 이슈가 있다는 것을 확인하게 되었습니다.
문제 분석
- Query Exporter 설정 누락 및 경로 지정 오류 초기에 다음과 같은 구조로 config.yml을 작성했습니다:
databases:
my-db:
dsn:
metrics:
user_total:
type: gauge
description: Total number of users
queries:
user_count_query:
interval: 30
databases: [my-db]
metrics: [user_total]
sql: |
SELECT COUNT(*) as user_total FROM users
구성 자체는 올바르게 작성했지만, Prometheus에서 user_total이라는 메트릭이 보이지 않음을 확인하며 문제가 있음을 인지했습니다. 처음에는 쿼리나 config 파일 내용을 의심했지만, 실제 문제는 Docker의 volumes 경로가 잘못 연결되어 Query Exporter가 config.yml 파일을 제대로 읽지 못한 것이었습니다.
잘못된 경로 예시
volumes:
- ./query-exporter/config.yml:/etc/query-exporter/config.yml
이 경로는 현재 Docker Compose의 실행 위치와 실제 config.yml 파일이 있는 위치가 일치하지 않아서 파일을 매핑하지 못했습니다.
올바른 경로 수정
volumes:
- ./GRAFANA-PROMETHEUS-RDBMS/query-exporter/config.yml:/etc/query-exporter/config.yml
루트 디렉터리를 기준으로 정확한 상대 경로를 입력한 뒤, 메트릭이 정상적으로 Prometheus에 노출되는 것을 확인할 수 있었습니다.
- Query Exporter 컨테이너에서 DB 연결 실패 경로 문제를 해결한 뒤에는 다음과 같은 에러가 발생했습니다:
[error] database error database=my-db
AssertionError
이는 query-exporter가 MySQL DB와 연결을 시도하는 중, DB가 아직 완전히 초기화되지 않은 상태에서 연결을 시도한 경우 발생할 수 있는 문제입니다.
에러 로그 중 일부:
assert not self._worker
AssertionError
이는 내부 비동기 연결 로직에서 DB가 아직 연결 가능한 상태가 아님에도 작업을 수행하려고 해서 발생한 문제입니다.
해결 방안
Docker Healthcheck 설정 활용
mysql-dev 컨테이너에 다음과 같은 healthcheck 설정을 추가했습니다:
container_name: mysql-dev
healthcheck:
test: [ "CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "root", "-p${DB_PASSWORD}" ]
interval: 10s
timeout: 20s
retries: 10
start_period: 40s
해당 설정을 통해 MySQL 컨테이너가 정상적으로 쿼리 가능한 상태인지 주기적으로 확인하도록 설정했습니다.
Query Exporter 컨테이너에 의존성 설정
depends_on:
mysql-dev:
condition: service_healthy
하지만 depends_on은 컨테이너의 실행 순서만 보장할 뿐, 네트워크나 MySQL이 완전히 준비되었는지를 보장하진 않기 때문에, 실제로는 쿼리 가능한 상태인지 재확인하는 wait-for-it 스크립트 또는 retry 로직을 query-exporter 쪽에 별도로 구현하거나 적용하는 것이 가장 확실한 방법입니다.
회고 및 배운 점
Docker에서 컨테이너 간 연결은 단순한 depends_on만으로 충분하지 않으며, 특히 DB 같은 경우에는 정상적으로 쿼리 가능한 상태가 되었는지를 명확히 판단할 수 있어야 합니다.
volume 경로 설정은 작지만 가장 빈번하게 발생하는 실수 중 하나이며, 상대 경로 기준이 docker-compose.yml이 위치한 디렉토리임을 항상 인지하고 있어야 합니다.
Query Exporter를 사용할 때 config.yml은 올바르게 mount 되었는지, 내부에서 정상적으로 읽히는지 로그나 /metrics 엔드포인트를 통해 반드시 확인해야 합니다.
설정에 대한 작은 실수 하나가 전체 시스템의 동작을 방해할 수 있으므로, 구성 파일이나 디렉토리 구조를 명확히 정의하고 팀 내에서 표준화된 형태로 공유하는 것이 중요합니다.