본문 바로가기
C.W.K.
Stream
Lesson 01 of 06 · published

밤에 도는 파이프라인 모니터링

~12 min · monitoring, production, alerting

Level 0구경꾼
0 XP0/47 lessons0/11 achievements
0/120 XP to next level120 XP to go0% complete

첫 규칙: 속사정 말고 결과에 알림을 걸어

나쁜 모니터링은 CPU 가 튀었다고 on-call 을 불러. 좋은 모니터링은 데이터가 틀렸거나 늦었을 때 불러. 이 둘은 완전히 달라. CPU 는 안에서 벌어지는 증상이고, consumer 가 진짜로 신경 쓰는 SLA 는 freshness 와 correctness 야.

모든 파이프라인이 내보내야 할 4가지 신호

  • Freshness. 이 테이블 마지막 업데이트가 언제야? SLA ("매일 오전 9시") 와 비교해서, 기준보다 오래 묵으면 알림.
  • Volume. 이번 run 에 row 가 몇 개 들어왔어? 최근 7일 범위 (예: ±3σ) 를 벗어나면 알림.
  • Schema. Column 모양이 바뀌었어? 검증 실패는 page 감이고, 부드러운 drift 는 경고 감이야.
  • 분포. 값이 움직였어? Mean / median / null-rate / cardinality 를 지난주와 대 봐.

Escalation ladder

모든 신호가 page 는 아니야. 알림은 층을 나눠서 걸어:

  • Page — 깨진 contract 에: schema 변경, SLA 를 넘긴 missing 데이터, 검증 hard-fail.
  • Slack — 경고 신호에: row count 가 범위 밖, 분포 drift.
  • 대시보드 — 전부 다에: 모든 run 의 metric 을 시간 위에 그려서.

Code

단순한 freshness/volume 모니터 — 모든 파이프라인 후 실행·python
import pandas as pd
from datetime import datetime, timedelta, timezone

def check_table_health(table_path: str, sla_hours: int = 24, volume_band: tuple = (0.7, 1.3)) -> list[str]:
    '''사람 읽을 수 있는 문제 list 반환. 빈 list = 건강.'''
    df = pd.read_parquet(table_path)
    issues = []
    now = datetime.now(timezone.utc)      # aware; utcnow() 는 naive 고 deprecated

    # Freshness — max(ingested_at) column 가정.
    # Parquet 타임스탬프는 보통 tz-aware 라 빼기 전에 맞춰야 해.
    # aware 랑 naive 를 섞으면 TypeError 나.
    last_update = pd.Timestamp(df['ingested_at'].max())
    if last_update.tzinfo is None:
        last_update = last_update.tz_localize('UTC')
    age = now - last_update.to_pydatetime()
    if age > timedelta(hours=sla_hours):
        issues.append(f'stale: 마지막 업데이트 {last_update} ({age.total_seconds() / 3600:.1f}h 전)')

    # Volume — 오늘과 어제 비교
    today = df.loc[df['ingested_at'].dt.date == now.date()]
    yesterday = df.loc[df['ingested_at'].dt.date == (now - timedelta(days=1)).date()]
    if len(yesterday) > 0:
        ratio = len(today) / len(yesterday)
        if ratio < volume_band[0] or ratio > volume_band[1]:
            issues.append(f'volume band 밖: 오늘/어제 = {ratio:.2f}')

    return issues

External links

Exercise

본인 테이블 하나를 놓고 4가지 신호 (freshness, volume, schema, 분포) 마다 적어 봐: (a) SLA 가 뭔지, (b) metric 을 어디로 내보낼지, (c) 알림 기준이 뭔지, (d) page 감인지 Slack 감인지. 이 연습을 해 본 팀이 드물어 — production 급 모니터링은 정확히 여기서 시작돼.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.