μ„œλΉ„μŠ€ & 툴

[Metric] ν”„λ‘œλ©”ν…Œμš°μŠ€ + κ·ΈλΌνŒŒλ‚˜

μ„œμ•„λž‘πŸ˜ 2024. 12. 23. 19:32

 

λ“€μ–΄κ°€λ©°

μ»¨ν…Œμ΄λ„ˆλ₯Ό κ΄€λ¦¬ν•˜λŠ” μΏ λ²„λ„€ν‹°μŠ€μ—μ„œ 항상 λ“±μž₯ν•˜λŠ” 것이 ν”„λ‘œλ©”ν…Œμš°μŠ€(Prometheus)와 κ·ΈλΌνŒŒλ‚˜(Grafana)μž…λ‹ˆλ‹€.두 κΈ°μˆ μ€ 철처히 μ„œλ‘œ λ‹€λ₯Έ 역할을 ν•˜μ§€λ§Œ, λͺ¨λ‹ˆν„°λ§ 툴둜 μ‚¬μš©ν•˜κΈ°μ—λŠ” ꢁ합이 μ’‹μŠ΅λ‹ˆλ‹€. μ˜€λŠ˜μ€ 두 κ°€μ§€ κΈ°μˆ μ— λŒ€ν•΄ μ‚΄νŽ΄λ³΄κ³ , κ°„λ‹¨νžˆ κ΅¬μΆ•ν•˜λŠ” λ°©λ²•κΉŒμ§€ μ‚΄νŽ΄λ³΄κ² μŠ΅λ‹ˆλ‹€.

 

ν”„λ‘œλ©”ν…Œμš°μŠ€ 맀트릭(Prometheus Metrics)μ΄λž€?

ν”„λ‘œλ©”ν…Œμš°μŠ€(Prometheus)λŠ” λͺ¨λ‹ˆν„°λ§ 및 μ•Œλ¦Όμ„ μœ„ν•œ μ˜€ν”ˆμ†ŒμŠ€ μ‹œμŠ€ν…œμœΌλ‘œ, μ‹œκ³„μ—΄ 데이터(time-series data)λ₯Ό μˆ˜μ§‘ν•˜κ³  μ €μž₯ν•©λ‹ˆλ‹€. μ—¬κΈ°μ„œ "맀트릭(metric)"은 ν”„λ‘œλ©”ν…Œμš°μŠ€κ°€ λͺ¨λ‹ˆν„°λ§ν•˜λŠ” 데이터 포인트λ₯Ό μ˜λ―Έν•˜λ©°, μ΄λŠ” μ‹œκ°„μ— 따라 λ³€κ²½λ˜λŠ” νŠΉμ • 츑정값을 λ‚˜νƒ€λƒ…λ‹ˆλ‹€.

ν”„λ‘œλ©”ν…Œμš°μŠ€ 맀트릭의 μ£Όμš” νŠΉμ§•

  1. μ‹œκ³„μ—΄ 데이터: λ§€νŠΈλ¦­μ€ νŠΉμ • μ‹œκ°„(timestamp)에 λŒ€ν•œ κ°’(value)κ³Ό ν•΄λ‹Ή 값이 λ°œμƒν•œ λ ˆμ΄λΈ”(label)의 μ§‘ν•©μœΌλ‘œ μ •μ˜λ©λ‹ˆλ‹€.
    • 예: cpu_usage{host="server1", core="0"} 0.85 @ 1672601983
  2. λ ˆμ΄λΈ”(Label): λ§€νŠΈλ¦­μ— μΆ”κ°€ 정보λ₯Ό μ œκ³΅ν•˜λŠ” key-value μŒμž…λ‹ˆλ‹€. λ ˆμ΄λΈ”μ„ 톡해 λ™μΌν•œ 맀트릭 이름을 κ°€μ§„ 데이터라도 ꡬ체적인 ꡬ뢄이 κ°€λŠ₯ν•©λ‹ˆλ‹€.
    • 예: http_requests_total{method="POST", status="500"} 10
  3. λ‹€μ–‘ν•œ μœ ν˜•: ν”„λ‘œλ©”ν…Œμš°μŠ€ λ§€νŠΈλ¦­μ€ λ„€ κ°€μ§€ κΈ°λ³Έ μœ ν˜•μœΌλ‘œ λΆ„λ₯˜λ©λ‹ˆλ‹€.

 

ν”„λ‘œλ©”ν…Œμš°μŠ€ 맀트릭의 μž₯점

  • κ³ λ„λ‘œ μ»€μŠ€ν„°λ§ˆμ΄μ§• κ°€λŠ₯ν•œ λ ˆμ΄λΈ”: λ³΅μž‘ν•œ 데이터 쿼리와 뢄석 κ°€λŠ₯.
  • 효율적인 μŠ€ν† λ¦¬μ§€: μ‹œκ³„μ—΄ 데이터λ₯Ό 효율적으둜 μ €μž₯ν•˜κ³  처리.
  • μ•Œλ¦Ό μ‹œμŠ€ν…œ 톡합: AlertManager와 ν•¨κ»˜ μ‚¬μš©ν•΄ 문제 λ°œμƒ μ‹œ μ•Œλ¦Όμ„ 보낼 수 있음.

 

즉, ν”„λ‘œλ©”ν…Œμš°μŠ€λŠ” 데이터 μˆ˜μ§‘λ§Œμ„ λ‹΄λ‹Ήν•˜λŠ” μ„œλΉ„μŠ€μž…λ‹ˆλ‹€.

 

 

 

κ·ΈλΌνŒŒλ‚˜(Grafana)λž€?

κ·ΈλΌνŒŒλ‚˜(Grafana)λŠ” 데이터 μ‹œκ°ν™”μ™€ λͺ¨λ‹ˆν„°λ§μ„ μœ„ν•œ μ˜€ν”ˆμ†ŒμŠ€ ν”Œλž«νΌμž…λ‹ˆλ‹€. λ‹€μ–‘ν•œ 데이터 μ†ŒμŠ€μ—μ„œ 데이터λ₯Ό 가져와 λŒ€μ‹œλ³΄λ“œλ₯Ό μƒμ„±ν•˜κ³ , μ‹œκ³„μ—΄ 데이터λ₯Ό μ‹œκ°ν™”ν•˜μ—¬ μ‹€μ‹œκ°„μœΌλ‘œ 뢄석할 수 μžˆλ„λ‘ λ„μ™€μ€λ‹ˆλ‹€. 주둜 ν”„λ‘œλ©”ν…Œμš°μŠ€(Prometheus)와 ν•¨κ»˜ μ‚¬μš©λ˜μ§€λ§Œ, λ‹€λ₯Έ 데이터 μ†ŒμŠ€μ™€λ„ 잘 ν†΅ν•©λ©λ‹ˆλ‹€.


κ·ΈλΌνŒŒλ‚˜μ˜ μ£Όμš” κΈ°λŠ₯

  1. 데이터 μ‹œκ°ν™”
    • μ‹œκ³„μ—΄ 데이터λ₯Ό 차트, κ·Έλž˜ν”„, ν…Œμ΄λΈ” ν˜•νƒœλ‘œ μ‹œκ°ν™”.
    • 데이터λ₯Ό μ΄ν•΄ν•˜κΈ° 쉽고 μ§κ΄€μ μœΌλ‘œ νŒŒμ•… κ°€λŠ₯.
  2. λ‹€μ–‘ν•œ 데이터 μ†ŒμŠ€ 지원
    • Prometheus, InfluxDB, Elasticsearch, OpenSearch, MySQL, PostgreSQL λ“±κ³Ό 연동 κ°€λŠ₯.
    • μ—¬λŸ¬ 데이터 μ†ŒμŠ€λ₯Ό ν•œ λŒ€μ‹œλ³΄λ“œμ— ν†΅ν•©ν•˜μ—¬ 뢄석 κ°€λŠ₯.
  3. λŒ€μ‹œλ³΄λ“œ 생성 및 μ»€μŠ€ν„°λ§ˆμ΄μ§•
    • λ“œλž˜κ·Έ μ•€ λ“œλ‘­ λ°©μ‹μœΌλ‘œ λŒ€μ‹œλ³΄λ“œ 생성.
    • λ‹€μ–‘ν•œ μœ„μ ―(κ·Έλž˜ν”„, κ²Œμ΄μ§€, 히트맡 λ“±) 제곡.
  4. μ•Œλ¦Ό(Alerting)
    • νŠΉμ • 쑰건을 μ„€μ •ν•΄ μ•Œλ¦Όμ„ μƒμ„±ν•˜κ³  이메일, Slack, PagerDuty λ“±μœΌλ‘œ μ•Œλ¦Ό 전솑.
    • 예: μ„œλ²„μ˜ CPU μ‚¬μš©λ₯ μ΄ 90%λ₯Ό μ΄ˆκ³Όν•  경우 μ•Œλ¦Ό λ°œμ†‘.
  5. μ‚¬μš©μž 관리 및 곡유
    • λŒ€μ‹œλ³΄λ“œλ₯Ό νŒ€κ³Ό κ³΅μœ ν•˜κ±°λ‚˜ μ‚¬μš©μžλ³„ μ ‘κ·Ό κΆŒν•œ μ„€μ •.
    • νŠΉμ • μ‚¬μš©μžλ‚˜ νŒ€μ— 맞좘 λŒ€μ‹œλ³΄λ“œ 제곡.
  6. ν”ŒλŸ¬κ·ΈμΈ ν™•μž₯μ„±
    • 수백 개의 ν”ŒλŸ¬κ·ΈμΈμ„ μ„€μΉ˜ν•˜μ—¬ μƒˆλ‘œμš΄ 데이터 μ†ŒμŠ€, 차트 μœ ν˜•, νŒ¨λ„ κΈ°λŠ₯ μΆ”κ°€ κ°€λŠ₯.

 

κ·ΈλΌνŒŒλ‚˜μ˜ μ£Όμš” ν™œμš© 사둀

  1. μ„œλ²„ 및 μ‹œμŠ€ν…œ λͺ¨λ‹ˆν„°λ§
    • CPU, λ©”λͺ¨λ¦¬, λ„€νŠΈμ›Œν¬ μ‚¬μš©λŸ‰ 좔적.
    • ν”„λ‘œλ©”ν…Œμš°μŠ€μ™€ μ—°λ™ν•˜μ—¬ μ„œλ²„ μƒνƒœλ₯Ό μ‹€μ‹œκ°„μœΌλ‘œ λͺ¨λ‹ˆν„°λ§.
  2. μ• ν”Œλ¦¬μΌ€μ΄μ…˜ μ„±λŠ₯ 관리(APM)
    • μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ˜ 응닡 μ‹œκ°„, μ—λŸ¬μœ¨, νŠΈλž˜ν”½ 뢄석.
    • 데이터 μ†ŒμŠ€λ‘œ New Relic, Jaeger λ“± μ‚¬μš©.
  3. λΉ„μ¦ˆλ‹ˆμŠ€ 데이터 μ‹œκ°ν™”
    • 맀좜, μ‚¬μš©μž 행동, νŠΈλžœμž­μ…˜ 데이터 뢄석.
    • MySQL, PostgreSQL λ“±μ—μ„œ 데이터 가져와 λŒ€μ‹œλ³΄λ“œ 생성.
  4. ν΄λΌμš°λ“œ 인프라 λͺ¨λ‹ˆν„°λ§
    • AWS, Google Cloud, Azure의 μ„œλΉ„μŠ€ μƒνƒœ 및 λΉ„μš© 뢄석.
    • CloudWatch, BigQuery와 같은 ν΄λΌμš°λ“œ 데이터 μ†ŒμŠ€μ™€ 톡합.

 

 

 

ν”„λ‘œλ©”ν…Œμš°μŠ€+κ·ΈλΌνŒŒλ‚˜ κ΅¬μΆ•ν•˜κΈ°

Python FastAPIλ₯Ό μ‚¬μš©ν•΄μ„œ μ‹¬ν”Œν•œ 데이터λ₯Ό μˆ˜μ§‘ν•˜κ³  κ·ΈλΌνŒŒλ‚˜μ—μ„œ λ³Ό 수 μžˆλ„λ‘ ν•˜κ² μŠ΅λ‹ˆλ‹€. λ¨Όμ € 둜그 카운트λ₯Ό μ„ΈλŠ” FastAPI μ½”λ“œλ₯Ό μž‘μ„±ν•©λ‹ˆλ‹€.

from fastapi import FastAPI
from prometheus_client import Counter, generate_latest

app = FastAPI()

# Prometheus Metrics
LOG_COUNTER = Counter("log_count", "Count of specific logs")

@app.get("/")
def read_root():
    return {"message": "Hello World"}

@app.get("/metrics")
def metrics():
    # Prometheus metrics endpoint
    return generate_latest(), {"Content-Type": "text/plain; version=0.0.4"}

@app.get("/log")
def log_event():
    LOG_COUNTER.inc()  # Increment the counter
    return {"message": "Log incremented"}

ν”„λ‘œλ©”ν…Œμš°μŠ€ ν΄λΌμ΄μ–ΈνŠΈμ™€ FastAPIλ₯Ό ꡬ동할 수 μžˆλŠ” νŒ¨ν‚€μ§€λ₯Ό μ„€μΉ˜ν•΄μ€λ‹ˆλ‹€.

pip install prometheus-client fastapi uvicorn

 

FastAPI μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ„ μ‹€ν–‰ν•΄μ€λ‹ˆλ‹€.

uvicorn app:app --host 0.0.0.0 --port 8000

http://localhost:8000/metricsμ—μ„œ ν”„λ‘œλ©”ν…Œμš°μŠ€κ°€ μˆ˜μ§‘ν•˜λŠ” λ©”νŠΈλ¦­μ„ ν™•μΈν•΄λ΄…λ‹ˆλ‹€. 제 개인적인 ν…ŒμŠ€νŠΈ ν™˜κ²½μ—μ„œλŠ” μ£Όμš” κ°€μƒμžμ‚°μ— λŒ€ν•œ μ˜€λ”λΆ 개수λ₯Ό μˆ˜μ§‘ν–ˆμŠ΅λ‹ˆλ‹€. μ•„λž˜μ™€ λΉ„μŠ·ν•˜κ²Œ κ²°κ³Όκ°€ λ‚˜μ™€μ•Ό ν•©λ‹ˆλ‹€.

process_cpu_seconds_total 4.460000000000001
# HELP process_open_fds Number of open file descriptors.
# TYPE process_open_fds gauge
process_open_fds 16.0
# HELP process_max_fds Maximum number of open file descriptors.
# TYPE process_max_fds gauge
process_max_fds 65535.0
# HELP btc_open_order BTC open order count
# TYPE btc_open_order gauge
btc_open_order 328.0
# HELP eth_open_order ETH open order count
# TYPE eth_open_order gauge
eth_open_order 220.0
# HELP xrp_open_order XRP open order count
# TYPE xrp_open_order gauge
xrp_open_order 227.0
# HELP doge_open_order DOGE open order count
# TYPE doge_open_order gauge
doge_open_order 231.0
# HELP sol_open_order SOL open order count
# TYPE sol_open_order gauge
sol_open_order 234.0

metrics의 λ°μ΄ν„°λŠ” jsonν˜•νƒœκ°€ μ•„λ‹Œ plain textμž…λ‹ˆλ‹€. λ§Œμ•½ metrics의 데이터가 λŒ€κ΄„ν˜Έλ‘œ μ‹œμž‘ν–ˆμ„ λ•ŒλŠ” json으둜 μ½μœΌλ €λ‹€κ°€ μ—λŸ¬κ°€ λ‚  수 μžˆμœΌλ‹ˆ FastAPI의 metric λΌμš°ν„°μ˜ λ°˜ν™˜κ°’μ„ μ•„λž˜μ™€ 같이 Response둜 λ³€κ²½ν•©λ‹ˆλ‹€.

from fastapi import FastAPI
from prometheus_client import generate_latest, CONTENT_TYPE_LATEST
from starlette.responses import Response

app = FastAPI()

@app.get("/metrics")
def metrics():
    # Return Prometheus metrics with explicit Content-Type
    return Response(content=generate_latest(), media_type=CONTENT_TYPE_LATEST)

 

λ‹€μŒμœΌλ‘œ ν”„λ‘œλ©”ν…Œμš°μŠ€μ™€ κ·ΈλΌνŒŒλ‚˜λ₯Ό 도컀 μ»¨ν…Œμ΄λ„ˆ μœ„μ— μ‹€ν–‰ν•  μ€€λΉ„λ₯Ό ν•©λ‹ˆλ‹€. docker-compose.yml을 μž‘μ„±ν•©λ‹ˆλ‹€.

services:
  prometheus:
    image: prom/prometheus
    container_name: prometheus
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml
    ports:
      - "9090:9090"
    networks:
      - monitoring

  grafana:
    image: grafana/grafana
    container_name: grafana
    ports:
      - "3000:3000"
    networks:
      - monitoring

networks:
  monitoring:
    driver: bridge

 

λ‹€μŒμœΌλ‘œ prometheus.yml을 μž‘μ„±ν•©λ‹ˆλ‹€.

global:
  scrape_interval: 15s

scrape_configs:
  - job_name: 'fastapi'
    metrics_path: /metrics
    static_configs:
      - targets: ['host.docker.internal:8000']

 

λ§ˆμ§€λ§‰μœΌλ‘œ Docker composeλ₯Ό μ‹€ν–‰ν•©λ‹ˆλ‹€.

docker-compose up -d

docker-compose psλ₯Ό 톡해 μ»¨ν…Œμ΄λ„ˆκ°€ μ œλŒ€λ‘œ μž‘λ™ν•˜λŠ” μ§€ 체크 ν•©λ‹ˆλ‹€. 

λ§Œμ•½ μ»¨ν…Œμ΄λ„ˆμ— λ¬Έμ œκ°€ μžˆλ‹€λ©΄ docker-compose logs ν˜Ήμ€ docker logs prometheus λͺ…λ Ήμ–΄μ—μ„œ ERRORλ₯Ό μ°Ύμ•„μ•Ό ν•©λ‹ˆλ‹€.

ν”„λ‘œλ©”ν…Œμš°μŠ€κ°€ μˆ˜μ§‘ν•˜λŠ” μ»¨ν…Œμ΄λ„ˆ μƒμ˜ ν¬νŠΈλŠ” 9090이며(http://localhost:9090), κ·ΈλΌνŒŒλ‚˜λ₯Ό λ³Ό 수 μžˆλŠ” ν¬νŠΈλŠ” 3000μž…λ‹ˆλ‹€( http://localhost:3000). http://localhost:9090/api/v1/targetsλ₯Ό μ‘°νšŒν•΄μ„œ health값이 "up" μƒνƒœμ΄μ–΄μ•Ό ν”„λ‘œλ©”ν…Œμš°μŠ€κ°€ μ œλŒ€λ‘œ 데이터λ₯Ό μˆ˜μ§‘ν•˜κ³  μžˆλŠ” κ²ƒμž…λ‹ˆλ‹€. λ§Œμ•½ "down"μƒνƒœμ΄λ©΄ lastErrorλ₯Ό μ°Έκ³ ν•΄μ„œ μˆ˜μ •ν•΄μ•Ό ν•©λ‹ˆλ‹€.

permission denied κΆŒν•œ λ¬Έμ œκ°€ λ‚˜μ™”λ‹€λ©΄,

sudo chown -R 472:472 ./grafana-data λͺ…λ Ήμ–΄λ₯Ό 톡해 Grafana Docker μ»¨ν…Œμ΄λ„ˆκ°€ μ‚¬μš©ν•˜λŠ” κΈ°λ³Έ μ‚¬μš©μž 그룹으둜 λ³€κ²½ν•΄μ€λ‹ˆλ‹€.

yml νŒŒμΌλ“€μ„ λ³€κ²½ν•˜κ³  λ‚˜λ©΄ docker-compose μž¬μ‹œμž‘ν•΄μ•Ό μ μš©λ©λ‹ˆλ‹€.

docker-compose down
docker-compose up -d

 

http://localhost:3000에 μ ‘μ†ν•˜μ—¬ κ·ΈλΌνŒŒλ‚˜κ°€ μ •μƒμ μœΌλ‘œ μ‹€ν–‰λ˜λŠ”μ§€ ν™•μΈν•©λ‹ˆλ‹€. 초기 둜그인 μ •λ³΄λŠ” admin/adminμž…λ‹ˆλ‹€. 첫 λ‘œκ·ΈμΈμ‹œ 변경이 ν•„μš”ν•©λ‹ˆλ‹€. 이 과정이 μ‹«μœΌμ‹œλ©΄ docker-compose.yml을 λ‹€μŒκ³Ό 같이 μˆ˜μ •ν•©λ‹ˆλ‹€.

grafana:
    image: grafana/grafana
    container_name: grafana
    ports:
      - "3000:3000"
    environment:
      - GF_SECURITY_ADMIN_USER=admin
      - GF_SECURITY_ADMIN_PASSWORD=my_grafana
    volumes:
      - ./grafana-data:/var/lib/grafana
    networks:
      - monitoring

 

κ·ΈλΌνŒŒλ‚˜ 섀정은 두 κ°€μ§€μž…λ‹ˆλ‹€. 첫 λ²ˆμ§ΈλŠ” data-source이고 두 λ²ˆμ§ΈλŠ” dashboard settingμž…λ‹ˆλ‹€. Connections의 Data sources둜 λ“€μ–΄κ°€μ…”μ„œ 기본으둜 μž‘ν˜€μžˆλŠ” connection을 ν”„λ‘œλ©”ν…Œμš°μŠ€λ‘œ μ„€μ •ν•΄μ€λ‹ˆλ‹€. μƒˆλ‘œμš΄ connection을 νƒλ°©ν•˜λ‹€λ³΄λ©΄ ν”„λ‘œλ©”ν…Œμš°μŠ€ 말고도 μˆ˜λ§Žμ€ 데이터 μ†ŒμŠ€κ°€ μžˆλŠ” 것을 보싀 수 μžˆμŠ΅λ‹ˆλ‹€.

 

λ‹€μŒμ€ Dashboard둜 λ“€μ–΄κ°€μ„œ μƒˆλ‘œμš΄ Dashboardλ₯Ό λ§Œλ“œμ‹œκ³  new panel μ„€μ •μ—μ„œ Metric Browserμ—μ„œ log_countλ₯Ό μ„ νƒν•˜λ©΄ μ‹œκ°ν™” κ·Έλž˜ν”„κ°€ λ‚˜μ˜€κ²Œ λ©λ‹ˆλ‹€.

제 μ˜ˆμ œμ—μ„œλŠ” μ•žμ„œ λ§μ”€λ“œλ¦° 것과 같이 κ°€μƒμžμ‚°μ— λŒ€ν•œ countλ₯Ό 좜λ ₯ν•©λ‹ˆλ‹€.

λ§Œμ•½ metric browserμ—μ„œ "log_count"λΌλŠ” νƒœκ·Έκ°€ μž‘νžˆμ§€ μ•ŠλŠ”λ‹€λ©΄, ν”„λ‘œλ©”ν…Œμš°μŠ€μ—μ„œ 데이터 μˆ˜μ§‘μ΄ μ›ν™œν•˜κ²Œ μ•ˆλ˜κ³  μžˆλŠ” κ²ƒμ΄λ‹ˆ ν”„λ‘œλ©”ν…Œμš°μŠ€μ—μ„œ 데이터 μˆ˜μ§‘μ΄ 잘 되고 μžˆλŠ”μ§€ logs와 http://localhost:9090/api/v1/targetsλ₯Ό λ‹€μ‹œ ν™•μΈν•΄μ£Όμ‹œλ©΄ λ©λ‹ˆλ‹€. data-source도 ν™•μΈν•΄λ³΄μ„Έμš”.

그리고 query optionμ—μ„œ interval을 μ‘°μ •ν•  수 있고, panel optionμ—μ„œ Legend, tooltip, Axis, Styleλ“± λ‹€μ–‘ν•œ μ‹œκ°ν™” 도ꡬλ₯Ό μ œκ³΅ν•©λ‹ˆλ‹€. μ•„μ˜ˆ 차트 μ’…λ₯˜λ₯Ό λ³€κ²½ν•  수 있죠. Time seriesλ₯Ό Bar chart둜 λ³€κ²½ν•œ λͺ¨μŠ΅μž…λ‹ˆλ‹€.

 

 

μ—¬κΈ°κΉŒμ§€ κ°„λ‹¨ν•˜κ²Œ ν”„λ‘œλ©”ν…Œμš°μŠ€μ™€ κ·ΈλΌνŒŒλ‚˜λ₯Ό ν†΅ν•œ μ‹œκ°ν™” λͺ¨λ‹ˆν„°λ§μ„ λ§Œλ“€μ–΄λ΄€μŠ΅λ‹ˆλ‹€.

 

 

마치며

λ§ˆμΉ˜λŠ” κΈ€ 전에, ν”„λ‘œλ©”ν…Œμš°μŠ€μ— λŒ€ν•΄ 쑰금 더 μ•Œμ•„λ³΄κ² μŠ΅λ‹ˆλ‹€. 저도 λͺ¨λ‹ˆν„°λ§ μ‹œκ°ν™”λ₯Ό ꡬ좕할 λ•Œ ν”„λ‘œλ©”ν…Œμš°μŠ€λ₯Ό 톡해 데이터λ₯Ό μˆ˜μ§‘ν•˜λŠ” 데 μ• λ₯Ό λ¨Ήμ—ˆκ±°λ“ μš”. 

λ¨Όμ € ν”„λ‘œλ©”ν…Œμš°μŠ€μ˜ 데이터 νƒ€μž… μ’…λ₯˜κ°€ λͺ‡κ°€μ§€ μžˆμŠ΅λ‹ˆλ‹€. 상황에 λ§žλŠ” 데이터 νƒ€μž…μ„ μ‚¬μš©ν•΄μ•Ό μ œλŒ€λ‘œ 된 μ‹œκ°ν™” νˆ΄μ„ ꡬ좕할 수 μžˆμŠ΅λ‹ˆλ‹€. λ‹€μŒμ€ ν”„λ‘œλ©”ν…Œμš°μŠ€μ˜ 데이터 νƒ€μž…μ— λŒ€ν•œ μ„€λͺ…μž…λ‹ˆλ‹€.


1. Counter (μΉ΄μš΄ν„°)

μ„€λͺ…

  • 단쑰 증가 λ©”νŠΈλ¦­μœΌλ‘œ, 값이 0 이상이며 였직 μ¦κ°€λ§Œ κ°€λŠ₯ν•©λ‹ˆλ‹€.
  • 주둜 이벀트 횟수λ₯Ό μΈ‘μ •ν•˜λŠ” 데 μ‚¬μš©λ©λ‹ˆλ‹€.
  • μž¬μ‹œμž‘ μ‹œ μ΄ˆκΈ°ν™”λ  수 μžˆμŠ΅λ‹ˆλ‹€.

μ‚¬μš© μ˜ˆμ‹œ

# HELP http_requests_total Total number of HTTP requests
# TYPE http_requests_total counter
http_requests_total{method="GET", status="200"} 1234
http_requests_total{method="POST", status="500"} 42
  • 의미: 총 HTTP μš”μ²­ 수λ₯Ό μƒνƒœ μ½”λ“œλ³„λ‘œ ꡬ뢄.
  • PromQL 예제:
    rate(http_requests_total[5m])  # μ§€λ‚œ 5λΆ„ λ™μ•ˆ μ΄ˆλ‹Ή μš”μ²­ 수의 λΉ„μœ¨ 계산
    

2. Gauge (κ²Œμ΄μ§€)

μ„€λͺ…

  • 값이 μ¦κ°€ν•˜κ±°λ‚˜ κ°μ†Œν•  수 μžˆλŠ” λ©”νŠΈλ¦­.
  • 주둜 ν˜„μž¬ μƒνƒœ(CPU μ‚¬μš©λ₯ , λ©”λͺ¨λ¦¬ μ‚¬μš©λŸ‰ λ“±)λ₯Ό μΈ‘μ •ν•˜λŠ” 데 μ‚¬μš©λ©λ‹ˆλ‹€.

μ‚¬μš© μ˜ˆμ‹œ

# HELP memory_usage_bytes Current memory usage in bytes
# TYPE memory_usage_bytes gauge
memory_usage_bytes 204857600
  • 의미: ν˜„μž¬ λ©”λͺ¨λ¦¬ μ‚¬μš©λŸ‰(λ°”μ΄νŠΈ λ‹¨μœ„).
  • PromQL 예제:
    memory_usage_bytes  # ν˜„μž¬ λ©”λͺ¨λ¦¬ μ‚¬μš©λŸ‰ 쑰회
    

3. Histogram (νžˆμŠ€ν† κ·Έλž¨)

μ„€λͺ…

  • 데이터λ₯Ό 버킷 λ‹¨μœ„λ‘œ λΆ„ν¬μ‹œμΌœ μ €μž₯ν•©λ‹ˆλ‹€.
  • 값이 νŠΉμ • λ²”μœ„μ— μ–Όλ§ˆλ‚˜ 자주 λ‚˜νƒ€λ‚˜λŠ”μ§€λ₯Ό μΈ‘μ •ν•©λ‹ˆλ‹€.
  • μš”μ•½ 정보(_sum, _count, 버킷별 데이터)λ₯Ό μ œκ³΅ν•©λ‹ˆλ‹€.

μ‚¬μš© μ˜ˆμ‹œ

# HELP http_request_duration_seconds HTTP request duration in seconds
# TYPE http_request_duration_seconds histogram
http_request_duration_seconds_bucket{le="0.1"} 2400
http_request_duration_seconds_bucket{le="0.5"} 3000
http_request_duration_seconds_bucket{le="1.0"} 3500
http_request_duration_seconds_bucket{le="+Inf"} 4000
http_request_duration_seconds_sum 700
http_request_duration_seconds_count 4000
  • 의미:
    • le="0.1": 0.1초 μ΄ν•˜λ‘œ 처리된 μš”μ²­ μˆ˜λŠ” 2400.
    • http_request_duration_seconds_sum: λͺ¨λ“  μš”μ²­μ˜ 총 μ‹œκ°„ 합계(초 λ‹¨μœ„).
    • http_request_duration_seconds_count: μš”μ²­ 총 개수.
  • PromQL 예제:
    • 의미: μ§€λ‚œ 5λΆ„ λ™μ•ˆ μš”μ²­μ˜ 평균 처리 μ‹œκ°„.
  • rate(http_request_duration_seconds_sum[5m]) / rate(http_request_duration_seconds_count[5m])

4. Summary (μš”μ•½)

μ„€λͺ…

  • νžˆμŠ€ν† κ·Έλž¨κ³Ό μœ μ‚¬ν•˜μ§€λ§Œ 쿼타일(Quantile) 데이터λ₯Ό κ³„μ‚°ν•©λ‹ˆλ‹€.
  • 버킷 λŒ€μ‹  직접적인 톡계 κ°’(예: 0.5-λ°±λΆ„μœ„μˆ˜, 0.9-λ°±λΆ„μœ„μˆ˜)을 μ œκ³΅ν•©λ‹ˆλ‹€.
  • μ •ν™•ν•œ 계산이 κ°€λŠ₯ν•˜μ§€λ§Œ, λ©”λͺ¨λ¦¬μ™€ CPU μ‚¬μš©λŸ‰μ΄ 높을 수 μžˆμŠ΅λ‹ˆλ‹€.

μ‚¬μš© μ˜ˆμ‹œ

# HELP http_request_duration_seconds HTTP request duration in seconds
# TYPE http_request_duration_seconds summary
http_request_duration_seconds{quantile="0.5"} 0.05
http_request_duration_seconds{quantile="0.9"} 0.1
http_request_duration_seconds{quantile="0.99"} 0.2
http_request_duration_seconds_sum 500
http_request_duration_seconds_count 10000
  • 의미:
    • quantile="0.5": μš”μ²­ 처리 μ‹œκ°„μ˜ 50%κ°€ 0.05초 μ΄ν•˜.
    • quantile="0.99": μš”μ²­ 처리 μ‹œκ°„μ˜ 99%κ°€ 0.2초 μ΄ν•˜.
  • PromQL 예제:
    • 의미: 99-λ°±λΆ„μœ„μˆ˜ μš”μ²­ 처리 μ‹œκ°„.
  • http_request_duration_seconds{quantile="0.99"}

데이터 νƒ€μž… 비ꡐ 및 선택 κ°€μ΄λ“œ

νƒ€μž… μ£Όμš” νŠΉμ§• μ‚¬μš© 사둀
Counter 단쑰 증가, κ°’ μ΄ˆκΈ°ν™” κ°€λŠ₯ μš”μ²­ 수, 였λ₯˜ 수, 처리된 μž‘μ—… 수 μΈ‘μ •
Gauge κ°’ 증가/κ°μ†Œ κ°€λŠ₯, ν˜„μž¬ μƒνƒœ μΈ‘μ • CPU/λ©”λͺ¨λ¦¬ μ‚¬μš©λŸ‰, ν˜„μž¬ μ˜¨λ„, ν™œμ„± μ—°κ²° 수
Histogram 버킷 뢄포 데이터, _sum와 _count 제곡 μš”μ²­ 처리 μ‹œκ°„ 뢄포, 파일 크기 뢄포
Summary 쿼타일 기반 μš”μ•½, μ •ν™•ν•œ 계산 응닡 μ‹œκ°„μ˜ 50%, 90%, 99% λ°±λΆ„μœ„μˆ˜ 계산

 

 

ν”„λ‘œλ©”ν…Œμš°μŠ€μ™€ κ·ΈλΌνŒŒλ‚˜λ₯Ό μ΄μš©ν•˜λ©΄ κ°•λ ₯ν•˜κ³  νŽΈν•œ μ‹œκ°ν™” νˆ΄μ„ μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€. 초기 ꡬ좕이 쑰금 κΉŒλ‹€λ‘­κΈ΄ ν•˜μ§€λ§Œ, κ°„λ‹¨ν•œ μ˜ˆμ œλ‘œλΆ€ν„° μ‹œμž‘ν•΄λ³΄μ„Έμš”! 이후 μ—¬λŸ¬λΆ„λ“€μ΄ ν•˜λŠ” ν”„λ‘œμ νŠΈμ—μ„œ 보고 싢은 데이터듀을 λͺ¨λ‘ μΆ”κ°€ν•΄μ„œ μ‹€μ‹œκ°„μœΌλ‘œ μŒ“μ΄λŠ” 데이터 λ³€ν™”λ₯Ό κ°μƒν•˜μ‹œλ©΄ λ©λ‹ˆλ‹€.