[Metric] νλ‘λ©ν μ°μ€ + κ·ΈλΌνλ
λ€μ΄κ°λ©°
컨ν μ΄λλ₯Ό κ΄λ¦¬νλ μΏ λ²λ€ν°μ€μμ νμ λ±μ₯νλ κ²μ΄ νλ‘λ©ν μ°μ€(Prometheus)μ κ·ΈλΌνλ(Grafana)μ λλ€.λ κΈ°μ μ μ² μ²ν μλ‘ λ€λ₯Έ μν μ νμ§λ§, λͺ¨λν°λ§ ν΄λ‘ μ¬μ©νκΈ°μλ κΆν©μ΄ μ’μ΅λλ€. μ€λμ λ κ°μ§ κΈ°μ μ λν΄ μ΄ν΄λ³΄κ³ , κ°λ¨ν ꡬμΆνλ λ°©λ²κΉμ§ μ΄ν΄λ³΄κ² μ΅λλ€.
νλ‘λ©ν μ°μ€ λ§€νΈλ¦(Prometheus Metrics)μ΄λ?
νλ‘λ©ν μ°μ€(Prometheus)λ λͺ¨λν°λ§ λ° μλ¦Όμ μν μ€νμμ€ μμ€ν μΌλ‘, μκ³μ΄ λ°μ΄ν°(time-series data)λ₯Ό μμ§νκ³ μ μ₯ν©λλ€. μ¬κΈ°μ "λ§€νΈλ¦(metric)"μ νλ‘λ©ν μ°μ€κ° λͺ¨λν°λ§νλ λ°μ΄ν° ν¬μΈνΈλ₯Ό μλ―Ένλ©°, μ΄λ μκ°μ λ°λΌ λ³κ²½λλ νΉμ μΈ‘μ κ°μ λνλ λλ€.
νλ‘λ©ν μ°μ€ λ§€νΈλ¦μ μ£Όμ νΉμ§
- μκ³μ΄ λ°μ΄ν°: λ§€νΈλ¦μ νΉμ μκ°(timestamp)μ λν κ°(value)κ³Ό ν΄λΉ κ°μ΄ λ°μν λ μ΄λΈ(label)μ μ§ν©μΌλ‘ μ μλ©λλ€.
- μ: cpu_usage{host="server1", core="0"} 0.85 @ 1672601983
- λ μ΄λΈ(Label): λ§€νΈλ¦μ μΆκ° μ 보λ₯Ό μ 곡νλ key-value μμ
λλ€. λ μ΄λΈμ ν΅ν΄ λμΌν λ§€νΈλ¦ μ΄λ¦μ κ°μ§ λ°μ΄ν°λΌλ ꡬ체μ μΈ κ΅¬λΆμ΄ κ°λ₯ν©λλ€.
- μ: http_requests_total{method="POST", status="500"} 10
- λ€μν μ ν: νλ‘λ©ν μ°μ€ λ§€νΈλ¦μ λ€ κ°μ§ κΈ°λ³Έ μ νμΌλ‘ λΆλ₯λ©λλ€.
νλ‘λ©ν μ°μ€ λ§€νΈλ¦μ μ₯μ
- κ³ λλ‘ μ»€μ€ν°λ§μ΄μ§ κ°λ₯ν λ μ΄λΈ: 볡μ‘ν λ°μ΄ν° 쿼리μ λΆμ κ°λ₯.
- ν¨μ¨μ μΈ μ€ν 리μ§: μκ³μ΄ λ°μ΄ν°λ₯Ό ν¨μ¨μ μΌλ‘ μ μ₯νκ³ μ²λ¦¬.
- μλ¦Ό μμ€ν ν΅ν©: AlertManagerμ ν¨κ» μ¬μ©ν΄ λ¬Έμ λ°μ μ μλ¦Όμ λ³΄λΌ μ μμ.
μ¦, νλ‘λ©ν μ°μ€λ λ°μ΄ν° μμ§λ§μ λ΄λΉνλ μλΉμ€μ λλ€.
κ·ΈλΌνλ(Grafana)λ?
κ·ΈλΌνλ(Grafana)λ λ°μ΄ν° μκ°νμ λͺ¨λν°λ§μ μν μ€νμμ€ νλ«νΌμ λλ€. λ€μν λ°μ΄ν° μμ€μμ λ°μ΄ν°λ₯Ό κ°μ Έμ λμ보λλ₯Ό μμ±νκ³ , μκ³μ΄ λ°μ΄ν°λ₯Ό μκ°ννμ¬ μ€μκ°μΌλ‘ λΆμν μ μλλ‘ λμμ€λλ€. μ£Όλ‘ νλ‘λ©ν μ°μ€(Prometheus)μ ν¨κ» μ¬μ©λμ§λ§, λ€λ₯Έ λ°μ΄ν° μμ€μλ μ ν΅ν©λ©λλ€.
κ·ΈλΌνλμ μ£Όμ κΈ°λ₯
- λ°μ΄ν° μκ°ν
- μκ³μ΄ λ°μ΄ν°λ₯Ό μ°¨νΈ, κ·Έλν, ν μ΄λΈ ννλ‘ μκ°ν.
- λ°μ΄ν°λ₯Ό μ΄ν΄νκΈ° μ½κ³ μ§κ΄μ μΌλ‘ νμ κ°λ₯.
- λ€μν λ°μ΄ν° μμ€ μ§μ
- Prometheus, InfluxDB, Elasticsearch, OpenSearch, MySQL, PostgreSQL λ±κ³Ό μ°λ κ°λ₯.
- μ¬λ¬ λ°μ΄ν° μμ€λ₯Ό ν λμ보λμ ν΅ν©νμ¬ λΆμ κ°λ₯.
- λμ보λ μμ± λ° μ»€μ€ν°λ§μ΄μ§
- λλκ·Έ μ€ λλ‘ λ°©μμΌλ‘ λμ보λ μμ±.
- λ€μν μμ ―(κ·Έλν, κ²μ΄μ§, ννΈλ§΅ λ±) μ 곡.
- μλ¦Ό(Alerting)
- νΉμ 쑰건μ μ€μ ν΄ μλ¦Όμ μμ±νκ³ μ΄λ©μΌ, Slack, PagerDuty λ±μΌλ‘ μλ¦Ό μ μ‘.
- μ: μλ²μ CPU μ¬μ©λ₯ μ΄ 90%λ₯Ό μ΄κ³Όν κ²½μ° μλ¦Ό λ°μ‘.
- μ¬μ©μ κ΄λ¦¬ λ° κ³΅μ
- λμ보λλ₯Ό νκ³Ό 곡μ νκ±°λ μ¬μ©μλ³ μ κ·Ό κΆν μ€μ .
- νΉμ μ¬μ©μλ νμ λ§μΆ λμ보λ μ 곡.
- νλ¬κ·ΈμΈ νμ₯μ±
- μλ°± κ°μ νλ¬κ·ΈμΈμ μ€μΉνμ¬ μλ‘μ΄ λ°μ΄ν° μμ€, μ°¨νΈ μ ν, ν¨λ κΈ°λ₯ μΆκ° κ°λ₯.
κ·ΈλΌνλμ μ£Όμ νμ© μ¬λ‘
- μλ² λ° μμ€ν
λͺ¨λν°λ§
- CPU, λ©λͺ¨λ¦¬, λ€νΈμν¬ μ¬μ©λ μΆμ .
- νλ‘λ©ν μ°μ€μ μ°λνμ¬ μλ² μνλ₯Ό μ€μκ°μΌλ‘ λͺ¨λν°λ§.
- μ ν리μΌμ΄μ
μ±λ₯ κ΄λ¦¬(APM)
- μ ν리μΌμ΄μ μ μλ΅ μκ°, μλ¬μ¨, νΈλν½ λΆμ.
- λ°μ΄ν° μμ€λ‘ New Relic, Jaeger λ± μ¬μ©.
- λΉμ¦λμ€ λ°μ΄ν° μκ°ν
- λ§€μΆ, μ¬μ©μ νλ, νΈλμμ λ°μ΄ν° λΆμ.
- MySQL, PostgreSQL λ±μμ λ°μ΄ν° κ°μ Έμ λμ보λ μμ±.
- ν΄λΌμ°λ μΈνλΌ λͺ¨λν°λ§
- 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% λ°±λΆμμ κ³μ° |
νλ‘λ©ν μ°μ€μ κ·ΈλΌνλλ₯Ό μ΄μ©νλ©΄ κ°λ ₯νκ³ νΈν μκ°ν ν΄μ μ¬μ©ν μ μμ΅λλ€. μ΄κΈ° ꡬμΆμ΄ μ‘°κΈ κΉλ€λ‘κΈ΄ νμ§λ§, κ°λ¨ν μμ λ‘λΆν° μμν΄λ³΄μΈμ! μ΄ν μ¬λ¬λΆλ€μ΄ νλ νλ‘μ νΈμμ λ³΄κ³ μΆμ λ°μ΄ν°λ€μ λͺ¨λ μΆκ°ν΄μ μ€μκ°μΌλ‘ μμ΄λ λ°μ΄ν° λ³νλ₯Ό κ°μνμλ©΄ λ©λλ€.
