> ## Documentation Index
> Fetch the complete documentation index at: https://docs.sifi.life/llms.txt
> Use this file to discover all available pages before exploring further.

# 알림, 대시보드, 베스트 프랙티스

> 이 문서는 **[머신러닝](/training/09-machine-learning/overview)** 섹션의 일부입니다.

## Serving UI 메트릭

Model Serving 엔드포인트 페이지에서 다음 메트릭을 실시간으로 확인할 수 있습니다.

| 메트릭                          | 설명                   |
| ---------------------------- | -------------------- |
| **QPS (Queries Per Second)** | 초당 처리 요청 수           |
| **Latency (P50, P99)**       | 응답 시간 분포             |
| **Error Rate**               | 실패한 요청 비율            |
| **GPU Utilization**          | GPU 엔드포인트의 리소스 활용도   |
| **Provisioned Concurrency**  | 동시 처리 가능한 요청 수       |
| **Scale-to-Zero Events**     | 0으로 축소/복원된 횟수        |
| **Token Throughput**         | LLM 엔드포인트의 초당 토큰 처리량 |

> 🆕 **Endpoint Telemetry (Beta)**: OpenTelemetry 기반의 관찰 가능성 기능이 추가되었습니다. OTLP(OpenTelemetry Protocol)로 외부 모니터링 시스템(Datadog, Grafana 등)과 연동할 수 있습니다.

***

## 알림 설정 (Alerting)

모니터링 메트릭에 기반한 알림을 설정하여, 문제가 발생하면 즉시 대응할 수 있습니다.

### Databricks SQL Alert 활용

```sql theme={null}
-- 에러율이 5%를 초과하면 알림 트리거
-- (이 쿼리를 Databricks SQL Alert로 등록합니다)
SELECT
    endpoint_name,
    COUNT(*) AS total_requests,
    SUM(CASE WHEN status_code >= 400 THEN 1 ELSE 0 END) AS errors,
    ROUND(
        SUM(CASE WHEN status_code >= 400 THEN 1 ELSE 0 END) * 100.0 / COUNT(*), 2
    ) AS error_rate_pct
FROM system.serving.served_model_requests
WHERE request_time >= CURRENT_TIMESTAMP() - INTERVAL 1 HOUR
GROUP BY endpoint_name
HAVING error_rate_pct > 5.0;
```

### 알림 채널 설정

| 채널                  | 설정 방법             | 적합한 용도                |
| ------------------- | ----------------- | --------------------- |
| **Email**           | SQL Alert에서 직접 지정 | 일일 리포트, 비긴급 알림        |
| **Slack**           | Webhook URL 연동    | 팀 채널 실시간 알림           |
| **PagerDuty**       | Webhook URL 연동    | 긴급 장애 대응 (On-call 연동) |
| **Microsoft Teams** | Webhook URL 연동    | 팀 채널 실시간 알림           |

```python theme={null}
# Slack Webhook을 통한 알림 예시 (Lakeflow Jobs의 Task로 실행)
import requests
import json

slack_webhook_url = "https://hooks.slack.com/services/T.../B.../..."

def send_alert(endpoint_name, error_rate, p99_latency):
    payload = {
        "text": f":rotating_light: *서빙 엔드포인트 알림*\n"
                f"- 엔드포인트: `{endpoint_name}`\n"
                f"- 에러율: {error_rate}%\n"
                f"- P99 지연시간: {p99_latency}ms"
    }
    requests.post(slack_webhook_url, json=payload)
```

***

## 대시보드 구축 (System 테이블 기반)

### 종합 모니터링 대시보드 쿼리

아래 쿼리들을 Databricks SQL 대시보드에 위젯으로 추가하면, 종합 모니터링 대시보드를 구축할 수 있습니다.

```sql theme={null}
-- 1. 일별 요청량 및 Percentile 지연 시간 (시계열 차트)
SELECT
    DATE(timestamp_ms / 1000) AS day,
    COUNT(*) AS total_requests,
    ROUND(PERCENTILE_CONT(0.50) WITHIN GROUP (ORDER BY execution_time_ms), 1) AS p50_ms,
    ROUND(PERCENTILE_CONT(0.95) WITHIN GROUP (ORDER BY execution_time_ms), 1) AS p95_ms,
    ROUND(PERCENTILE_CONT(0.99) WITHIN GROUP (ORDER BY execution_time_ms), 1) AS p99_ms,
    SUM(CASE WHEN status_code != 200 THEN 1 ELSE 0 END) AS error_count,
    ROUND(SUM(CASE WHEN status_code != 200 THEN 1 ELSE 0 END) * 100.0 / COUNT(*), 2) AS error_rate_pct
FROM ml_prod.monitoring.fraud_model_payload
WHERE date >= CURRENT_DATE() - INTERVAL 30 DAYS
GROUP BY DATE(timestamp_ms / 1000)
ORDER BY day DESC;

-- 2. LLM 엔드포인트: 토큰 사용량 추적 (시계열 차트)
SELECT
    DATE(timestamp_ms / 1000) AS day,
    SUM(request:usage.prompt_tokens) AS total_input_tokens,
    SUM(request:usage.completion_tokens) AS total_output_tokens,
    SUM(request:usage.total_tokens) AS total_tokens,
    ROUND(AVG(execution_time_ms), 0) AS avg_latency
FROM ml_prod.monitoring.agent_payload
WHERE date >= CURRENT_DATE() - INTERVAL 30 DAYS
GROUP BY DATE(timestamp_ms / 1000)
ORDER BY day DESC;

-- 3. 에러 분석 (테이블 위젯)
SELECT
    status_code,
    COUNT(*) AS count,
    FIRST(response) AS sample_error
FROM ml_prod.monitoring.fraud_model_payload
WHERE status_code != 200
    AND date = CURRENT_DATE()
GROUP BY status_code;

-- 4. 시간대별 트래픽 패턴 (히트맵)
SELECT
    DAYOFWEEK(timestamp_ms / 1000) AS day_of_week,
    HOUR(timestamp_ms / 1000) AS hour_of_day,
    COUNT(*) AS request_count
FROM ml_prod.monitoring.fraud_model_payload
WHERE date >= CURRENT_DATE() - INTERVAL 7 DAYS
GROUP BY day_of_week, hour_of_day;
```

### 멀티 엔드포인트 비교 대시보드

여러 엔드포인트를 동시에 비교하는 운영 대시보드용 쿼리입니다.

```sql theme={null}
-- 5. 엔드포인트별 SLA 준수율 비교 (가로 막대 차트)
-- SLA 기준: P99 < 1000ms, 에러율 < 1%
SELECT
    endpoint_name,
    DATE(request_time) AS day,
    COUNT(*) AS total_requests,
    ROUND(PERCENTILE_CONT(0.99) WITHIN GROUP (ORDER BY execution_time_ms), 0) AS p99_ms,
    ROUND(SUM(CASE WHEN status_code >= 400 THEN 1 ELSE 0 END) * 100.0 / COUNT(*), 2) AS error_rate_pct,
    -- SLA 준수 여부
    CASE
        WHEN PERCENTILE_CONT(0.99) WITHIN GROUP (ORDER BY execution_time_ms) <= 1000
             AND SUM(CASE WHEN status_code >= 400 THEN 1 ELSE 0 END) * 100.0 / COUNT(*) <= 1.0
        THEN 'SLA 준수'
        ELSE 'SLA 위반'
    END AS sla_status
FROM system.serving.served_model_requests
WHERE DATE(request_time) >= CURRENT_DATE() - INTERVAL 7 DAYS
GROUP BY endpoint_name, DATE(request_time)
ORDER BY day DESC, endpoint_name;

-- 6. 비용 추이 (일별, 엔드포인트별)
SELECT
    usage_date,
    usage_metadata.endpoint_name,
    SUM(usage_quantity) AS total_dbus,
    ROUND(SUM(usage_quantity * list_price), 2) AS daily_cost_usd
FROM system.billing.usage
WHERE sku_name LIKE '%SERVING%'
    AND usage_date >= CURRENT_DATE() - INTERVAL 30 DAYS
GROUP BY usage_date, usage_metadata.endpoint_name
ORDER BY usage_date DESC;
```

***

## 모니터링 장단점과 트레이드오프

모니터링 체계를 설계할 때 비용과 가치 사이의 트레이드오프를 이해해야 합니다.

### 모니터링 수준별 비교

| 수준     | 구성                       | 월 추가 비용 (예시) | 탐지 가능 문제           |
| ------ | ------------------------ | -----------: | ------------------ |
| **기본** | Serving UI만 활용           |          \$0 | 인프라 장애, 지연시간 급증    |
| **중간** | + Inference Table (100%) |    \$50\~200 | 스키마 오류, 입력 이상      |
| **고급** | + Lakehouse Monitoring   |   \$200\~500 | 데이터 드리프트, 모델 성능 저하 |
| **완전** | + Ground Truth 연동        | \$500\~2,000 | 실제 예측 정확도, 비즈니스 영향 |

> 💡 비용은 트래픽 규모, 데이터 크기, 클러스터 구성에 따라 크게 달라집니다. 실제 비용은 Databricks Cost Management에서 확인하십시오.

### Inference Table: 전수 기록 vs 샘플링

| 항목              | 전수 기록 (100%)  | 샘플링 (10%)     |
| --------------- | ------------- | ------------- |
| **비용**          | 높음            | 낮음 (약 1/10)   |
| **드리프트 감지 정확도** | 높음            | 중간 (통계적으로 충분) |
| **희귀 이벤트 캡처**   | 모두 캡처         | 누락 가능         |
| **규정 준수 감사**    | 완전한 감사 추적     | 불완전           |
| **적합한 환경**      | 금융, 의료, 법규 준수 | 추천 시스템, 일반 ML |

### Lakehouse Monitoring 설정 트레이드오프

| 항목             | 빠른 갱신 주기 (1시간) | 느린 갱신 주기 (1일) |
| -------------- | -------------- | ------------- |
| **드리프트 탐지 속도** | 빠름 (1시간 이내)    | 느림 (최대 24시간)  |
| **컴퓨팅 비용**     | 높음             | 낮음            |
| **통계적 신뢰도**    | 낮음 (샘플 수 부족 시) | 높음            |
| **적합한 환경**     | 실시간 의사결정 시스템   | 배치 예측 시스템     |

***

## 베스트 프랙티스와 흔한 실수

### 베스트 프랙티스 (Best Practices)

**1. 모니터링을 배포 전에 설계하세요**

모델 배포 후 모니터링을 추가하면 초기 데이터가 유실됩니다. Inference Table은 엔드포인트 생성 시 함께 활성화하십시오.

```python theme={null}
# 올바른 순서: 엔드포인트 생성과 Inference Table 활성화를 동시에
w.serving_endpoints.create(
    name="my-model",
    config=EndpointCoreConfigInput(
        served_entities=[...],
        auto_capture_config=AutoCaptureConfigInput(enabled=True, ...)  # 처음부터 활성화
    )
)
```

**2. 기준 분포(Baseline)를 반드시 저장하세요**

드리프트 감지는 기준 분포와의 비교로 이루어집니다. 모델 배포 시점의 입력 데이터 분포를 별도 테이블에 저장해두십시오.

```sql theme={null}
-- 배포 시점 기준 분포 저장
CREATE TABLE ml_prod.monitoring.fraud_model_baseline AS
SELECT * FROM ml_prod.monitoring.fraud_model_payload
WHERE date BETWEEN '2024-01-01' AND '2024-01-31';  -- 첫 달 데이터
```

**3. 모델 버전을 요청 메타데이터에 포함하세요**

A/B 테스트나 Canary 배포 시, 모델 버전별 성능을 분리하여 분석할 수 있습니다.

```python theme={null}
# 클라이언트에서 버전 정보를 메타데이터로 전달
import requests

response = requests.post(
    endpoint_url,
    headers={
        "Authorization": f"Bearer {token}",
        "X-Model-Version": "v3",        # 커스텀 메타데이터
        "X-Client-Id": "recommendation-service"
    },
    json={"inputs": features}
)
```

**4. P99 기준으로 SLA를 설정하세요**

평균 지연시간이 아닌 P99를 SLA 기준으로 사용해야 실제 사용자 경험을 보호할 수 있습니다.

**5. 비용 알림을 일별 예산과 연동하세요**

예상치 못한 트래픽 급증이나 프롬프트 길이 증가로 비용이 급등할 수 있습니다.

```sql theme={null}
-- 일별 비용이 임계값 초과 시 알림 (Databricks SQL Alert로 등록)
SELECT
    usage_date,
    SUM(usage_quantity * list_price) AS daily_cost_usd
FROM system.billing.usage
WHERE sku_name LIKE '%SERVING%'
    AND usage_date = CURRENT_DATE() - INTERVAL 1 DAYS
GROUP BY usage_date
HAVING daily_cost_usd > 100.0;  -- $100 초과 시 알림
```

### 흔한 실수 (Common Mistakes)

**실수 1: Inference Table을 `date` 파티션 없이 쿼리**

```sql theme={null}
-- 잘못된 예시: 전체 테이블 스캔으로 매우 느림
SELECT * FROM ml_prod.monitoring.fraud_model_payload
WHERE timestamp_ms > UNIX_TIMESTAMP(CURRENT_TIMESTAMP() - INTERVAL 1 DAYS) * 1000;

-- 올바른 예시: date 파티션 필터 추가
SELECT * FROM ml_prod.monitoring.fraud_model_payload
WHERE date >= CURRENT_DATE() - INTERVAL 1 DAYS  -- 파티션 프루닝
    AND timestamp_ms > UNIX_TIMESTAMP(CURRENT_TIMESTAMP() - INTERVAL 1 DAYS) * 1000;
```

**실수 2: Ground Truth 없이 드리프트만 모니터링**

데이터 드리프트(입력 분포 변화)만으로는 모델 성능 저하를 확인할 수 없습니다. 가능하면 Ground Truth 레이블을 수집하여 실제 정확도를 추적하십시오.

**실수 3: Scale-to-Zero 엔드포인트에 너무 짧은 타임아웃 설정**

Scale-to-Zero 엔드포인트는 콜드 스타트 시 10\~30초가 소요될 수 있습니다. 클라이언트 타임아웃을 콜드 스타트 시간을 고려하여 설정하십시오.

```python theme={null}
# 올바른 예시: 콜드 스타트를 고려한 충분한 타임아웃
response = requests.post(
    endpoint_url,
    json=payload,
    timeout=60  # 60초 타임아웃 (콜드 스타트 포함)
)
```

**실수 4: 모니터링 대시보드만 만들고 알림 미설정**

대시보드는 사람이 직접 확인해야 합니다. 반드시 임계값 기반 자동 알림을 함께 설정하십시오.

**실수 5: 너무 많은 알림으로 알림 피로(Alert Fatigue) 유발**

알림이 너무 자주 발생하면 담당자가 알림을 무시하게 됩니다. 알림 임계값을 비즈니스 영향 기준으로 설정하고, 긴급/비긴급 알림을 분리하십시오.

| 알림 유형     | 채널                  | 임계값 기준             |
| --------- | ------------------- | ------------------ |
| **P1 긴급** | PagerDuty (On-call) | 에러율 > 10%, 서비스 중단  |
| **P2 경고** | Slack #ml-alerts    | 에러율 > 5%, P99 > 2초 |
| **P3 정보** | Email 일일 리포트        | 드리프트 감지, 비용 임계값    |

***

## 트러블슈팅 가이드

| 증상                         | 가능한 원인             | 확인 방법                     | 해결 방안                     |
| -------------------------- | ------------------ | ------------------------- | ------------------------- |
| **지연 시간 급증**               | 모델 크기 증가, 입력 길이 증가 | P99 지연 시간 트렌드 확인          | 모델 최적화, 인스턴스 크기 증가        |
| **에러율 상승**                 | 입력 스키마 불일치, 메모리 부족 | 에러 로그 샘플 확인               | 입력 유효성 검증 추가, 리소스 확대      |
| **Scale-to-Zero 후 콜드 스타트** | 트래픽 불규칙            | 스케일링 이벤트 로그 확인            | 최소 프로비저닝 동시성 설정           |
| **토큰 비용 급증**               | 프롬프트 길이 증가, 트래픽 급증 | 일별 토큰 사용량 확인              | 프롬프트 최적화, Rate Limiting   |
| **드리프트 알림**                | 입력 데이터 분포 변화       | Lakehouse Monitor 대시보드 확인 | 모델 재학습, 피처 파이프라인 점검       |
| **Inference Table 미기록**    | Auto Capture 미활성화  | 엔드포인트 설정 확인               | `auto_capture_config` 활성화 |

***

## 정리

| 핵심 기능                    | 설명                                      |
| ------------------------ | --------------------------------------- |
| **Inference Table**      | 모든 요청/응답을 Delta 테이블에 자동 기록합니다           |
| **Lakehouse Monitoring** | 데이터 드리프트와 모델 품질을 자동으로 감지합니다             |
| **MLflow Tracing**       | LLM/에이전트의 실행 경로를 단계별로 추적합니다             |
| **시스템 테이블**              | 모든 엔드포인트의 운영 메트릭을 중앙에서 조회합니다            |
| **비용 모니터링**              | 토큰 사용량과 DBU 기반 비용을 추적합니다                |
| **알림**                   | SQL Alert + Webhook으로 실시간 알림을 받을 수 있습니다 |

**모니터링 설계 원칙 요약:**

1. **배포 전 설계** — Inference Table은 엔드포인트 생성 시 활성화합니다
2. **Percentile 기반 SLA** — P99를 기준으로 서비스 수준을 정의합니다
3. **계층적 알림** — 긴급/경고/정보로 구분하여 알림 피로를 방지합니다
4. **비용과 가치 균형** — 트래픽 규모에 맞는 샘플링 전략을 선택합니다
5. **Ground Truth 연동** — 가능하면 실제 레이블을 수집하여 성능을 검증합니다

***

## 참고 링크

* [Databricks: Inference tables](https://docs.databricks.com/aws/en/machine-learning/model-serving/inference-tables.html)
* [Databricks: Monitor serving endpoints](https://docs.databricks.com/aws/en/machine-learning/model-serving/monitor-diagnose-endpoints.html)
* [Databricks: Lakehouse Monitoring](https://docs.databricks.com/aws/en/lakehouse-monitoring/index.html)
* [Databricks: MLflow Tracing](https://docs.databricks.com/aws/en/mlflow/mlflow-tracing.html)
* [Databricks: System tables - Serving](https://docs.databricks.com/aws/en/admin/system-tables/serving.html)
* [Databricks: Billing usage system table](https://docs.databricks.com/aws/en/admin/system-tables/billing.html)
* [Databricks Blog: Monitoring ML models in production](https://www.databricks.com/blog/lakehouse-monitoring)
