DOCS/troubleshooting/250714_system_metrics_implementation.md
happybell80 d2120d93a9 docs: 시스템 메트릭 문서 미해결 섹션 제거 및 해결 완료 표시
- "미해결 문제" → "최종 해결 (2025-07-15)"
- Prometheus + Grafana 대체 사실 명시
- frontend-base/backend/metrics_database.py 참조 추가
- "후속 작업" 섹션 삭제 (완료됨)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-15 12:17:47 +09:00

8.5 KiB

시스템 메트릭 구현 트러블슈팅

개요

  • 날짜: 2025-07-14
  • 작업: 관리자 대시보드에 시스템 메트릭 그래프 추가
  • 목표: PostgreSQL + TimescaleDB 기반 시계열 데이터 수집 및 Chart.js 그래프 표시

주요 문제들과 해결 과정

1. Docker 네트워크 통신 문제

문제: 관리자 대시보드에서 모든 서비스가 timeout/unreachable 상태 원인: Docker 컨테이너간 네트워크 격리 (DOCKER-ISOLATION iptables 체인) 해결:

  • 서비스 URL을 IP 주소에서 컨테이너 이름으로 변경
  • http://172.17.0.2:5173http://frontend:5173
  • http://172.17.0.1:10508http://rb10508_test:10508

2. TimescaleDB 설치 및 설정

문제: PostgreSQL에 TimescaleDB 확장 설치 필요 해결:

# TimescaleDB 확장 설치
sudo apt-get update
sudo apt-get install timescaledb-2-postgresql-15

# 데이터베이스 생성 및 확장 활성화
sudo -u postgres createdb robeing_metrics
sudo -u postgres psql robeing_metrics -c "CREATE EXTENSION IF NOT EXISTS timescaledb;"

3. HDD 저장소 설정

문제: 메트릭 데이터를 HDD에 저장하기 위한 테이블스페이스 생성 해결:

-- HDD 테이블스페이스 생성
CREATE TABLESPACE hdd_tablespace LOCATION '/hdd/postgresql_data';

-- 테이블 생성시 HDD 테이블스페이스 사용
CREATE TABLE system_metrics (
    time TIMESTAMPTZ NOT NULL,
    metric_type VARCHAR(50) NOT NULL,
    value DOUBLE PRECISION NOT NULL,
    hostname VARCHAR(100) DEFAULT 'localhost'
) TABLESPACE hdd_tablespace;

4. PostgreSQL 연결 인증 문제

문제: Docker 컨테이너에서 PostgreSQL 접속 시 password authentication failed 원인: PostgreSQL 사용자 비밀번호 미설정 해결:

# PostgreSQL 비밀번호 설정
sudo -u postgres psql -c "ALTER USER postgres PASSWORD '19800508';"

# docker-compose.yml에 환경변수 추가
environment:
  - METRICS_DB_PASSWORD=19800508

5. 테이블 구조 불일치 문제

문제:

  • 로그: column "timestamp" of relation "system_metrics" does not exist
  • 실제 테이블: time 컬럼 존재, timestamp 컬럼 없음

원인: 코드와 데이터베이스 스키마 불일치 해결 과정:

  1. 기존 테이블 구조 확인:
    \d system_metrics
    -- time (timestamptz), metric_type (varchar), value (double precision)
    
  2. 코드 수정하여 기존 테이블 구조에 맞춤:
    # 정규화된 구조로 데이터 삽입
    INSERT INTO system_metrics (time, metric_type, value)
    VALUES ($1, $2, $3)
    

6. 잘못된 대시보드 구현

문제: 고객용 React 앱에 시스템 메트릭을 구현함 원인: 두 개의 프론트엔드 구조 혼동

  • 고객용: React SPA (/client/)
  • 관리자용: 정적 HTML (/backend/admin_static/)

해결: 관리자 대시보드(정적 HTML)에 Chart.js 기반 그래프 구현

최종 구현 결과

파일 구조

backend/
├── admin_routes.py          # 관리자 API 엔드포인트
├── admin_static/
│   └── index.html          # 관리자 대시보드 (Chart.js 그래프)
├── metrics_collector.py    # 시스템 메트릭 수집기
├── metrics_database.py     # PostgreSQL 데이터베이스 연결
└── main.py                 # 메트릭 시스템 초기화

주요 기능

  1. 메트릭 수집: 1분 간격으로 CPU, 메모리, 디스크, 업타임 수집
  2. 데이터 저장: PostgreSQL TimescaleDB 하이퍼테이블에 시계열 데이터 저장
  3. 그래프 표시: Chart.js로 1h/1d/7d/30d/90d/1y 기간별 그래프
  4. 실시간 표시: 현재 메트릭 값과 진행률 바 표시

API 엔드포인트

  • GET /admin/metrics/current - 현재 메트릭 조회
  • GET /admin/metrics/history/{period} - 기간별 메트릭 히스토리
  • POST /admin/metrics/collect - 수동 메트릭 수집

최종 해결 (2025-07-15)

상태: 메트릭 수집 비활성화 (Prometheus + Grafana로 대체) 관련 파일: frontend-base/backend/metrics_database.py:58-60, 78-80, 148-150 해결 방법: system_metrics 테이블 사용 중단, TODO 주석 처리 참고: 아래 Prometheus + Grafana 방식으로 완전 전환

학습 포인트

  1. Docker 네트워크: 컨테이너간 통신 시 서비스 이름 사용
  2. TimescaleDB: PostgreSQL 확장으로 시계열 데이터 최적화
  3. 두 프론트엔드 구조: 고객용 React vs 관리자용 정적 HTML 구분
  4. 데이터베이스 스키마: 코드와 실제 테이블 구조 일치 중요성
  5. PostgreSQL 인증: Docker 환경에서 비밀번호 설정 필요

node-exporter + Prometheus + Grafana 를 이용한 compute 자원 모니터링

해당 문서는 직접 개발하는 방식이 아닌 기존에 널리 쓰이는
node-exporter + Prometheus + Grafana를 이용하여
cpu, memory disk 등을 수집하는 방식이다.

먼저 docker 및 물리적 서버로 동작시에는 아래와 같은 구조로 이용된다.

                 ┌───────────────────────────────┐
                 │            PC #1              │
                 │  ┌────────────────────────┐  │
                 │  │ Container: node-exporter│  │
                 │  │ - CPU, MEM, Disk, Net  │  │
                 │  │ - Prometheus metrics   │  │
                 │  └───────────┬────────────┘  │
                 └──────────────┼───────────────┘
                                │ (HTTP /metrics)
                                │
                 ┌───────────────────────────────┐
                 │            PC #2              │
                 │  ┌────────────────────────┐  │
                 │  │ Container: node-exporter│  │
                 │  │ - CPU, MEM, Disk, Net  │  │
                 │  │ - Prometheus metrics   │  │
                 │  └───────────┬────────────┘  │
                 └──────────────┼───────────────┘
                                │
                                ▼
           ┌─────────────────────────────────────────┐
           │             중앙 서버 (또는 PC #1)       │
           │ ┌─────────────┐                         │
           │ │ Prometheus  │<── scrape ──────────────┘
           │ │ (metrics DB)│  /metrics from each node
           │ └───────┬─────┘
           │         │
           │   ┌─────▼─────┐
           │   │  Grafana  │ (Dashboards)
           │   │ - Prometheus 연결
           │   │ - CPU/MEM/DISK/NET 시각화
           │   └───────────┘
           └─────────────────────────────────────────┘

해당 구조는 PC가 2대일 때를 가정했으며 중앙서버를 별도의 PC로 정의할 경우에는 PC가 3대인 모습이다.
해당 PC 는 K8s의 구조로 변경될 시에는 별도의 worker node로 대체해서 생각하면 된다.

여기에서 각각의 역할은 아래와 같다.

  • node-exporter : 각 PC의 cpu, memory 등을 수집한다. docker인 경우 각각의 컨테이너의 로그도 수집한다.
  • Prometheus: 각 node-exporter 에서 수집된 로그를 저장하며 PQL이라는 쿼리를 통해 로그를 조건에 맞게 추출할 수 있다.
  • Grafana: Prometheus에서 저장된 로그를 단지 시각화 하는 방식이다.

설치방법은 아래의 ref에 남겨놓았다.

ref