Minbook
EN
모니터링 없이 론칭하면 생기는 일

모니터링 없이 론칭하면 생기는 일

MJ · · 5 분 소요

Sentry와 Betterstack을 활용해 $0로 구축하는 최소 모니터링 가이드와 론칭 전 80분 투자가 에러 대응 시간을 13시간에서 1시간으로 단축한 사례 분석

사용자가 알려주는 에러

WICHI를 론칭하고 첫 주, 에러 모니터링이 없었습니다. 기능은 잘 작동하는 것 같았고, 로컬에서 테스트도 통과했습니다.

문제를 알게 된 건 사용자 피드백이었습니다.

#사용자 피드백실제 원인발견까지 걸린 시간
1”결과 페이지가 안 떠요”특정 쿼리에서 API 타임아웃~18시간
2”분석이 중간에 멈춰요”LLM 응답 파싱 실패~12시간
3”결제했는데 크레딧 안 올라가요”Webhook 처리 중 예외~6시간
4”어제까지 됐는데 오늘 안 돼요”의존 서비스 API 변경~24시간
graph TD
    A["에러 발생"] --> B{"모니터링\n있나?"}
    B -->|"있음"| C["즉시 알림\n(분 단위)"]
    B -->|"없음"| D["사용자가 발견"]
    D --> E["사용자가 연락"]
    E --> F["개발자 확인"]
    F --> G["원인 파악"]

    C --> G

    H["모니터링 없음:\n평균 15시간"] --> I["모니터링 있음:\n평균 5분"]

    style D fill:#ffebee,stroke:#f44336
    style C fill:#e8f5e9,stroke:#4caf50
    style H fill:#ffebee,stroke:#f44336
    style I fill:#e8f5e9,stroke:#4caf50

사용자가 에러를 제보하는 순간, 이미 3가지가 잘못된 겁니다: (1) 에러가 발생했고, (2) 모니터링이 없어서 몰랐고, (3) 사용자 경험이 나빠졌습니다.


모니터링의 3가지 층

모니터링은 한 가지가 아닙니다. 최소 3개 층이 필요합니다.

graph TD
    subgraph L1["Layer 1: Uptime 모니터링"]
        U1["서비스가 살아있는가?"]
        U2["응답 시간이 정상인가?"]
        U3["SSL 인증서가 유효한가?"]
    end

    subgraph L2["Layer 2: 에러 추적"]
        E1["런타임 에러 캡처"]
        E2["에러 빈도와 영향 범위"]
        E3["스택 트레이스"]
    end

    subgraph L3["Layer 3: 로그 관리"]
        L3a["구조화된 로그"]
        L3b["로그 검색/필터"]
        L3c["로그 보존 기간"]
    end

    L1 --> L2 --> L3

    style L1 fill:#e8f5e9,stroke:#4caf50
    style L2 fill:#e3f2fd,stroke:#2196f3
    style L3 fill:#fff3e0,stroke:#ff9800
답하는 질문도구 예시우선순위
Uptime”서비스가 죽었나?”Betterstack, UptimeRobot1순위
에러 추적”어떤 에러가 발생했나?”Sentry, Bugsnag1순위
로그 관리”왜 발생했나?”Betterstack Logs, Datadog2순위
APM”어디가 느린가?”Sentry Performance, New Relic3순위
사용자 분석”무엇을 하고 있나?”PostHog, Mixpanel3순위

1인 SaaS에서 1순위는 Uptime + 에러 추적입니다. “서비스가 죽었나?”와 “에러가 났나?”에 답할 수 있으면 80%는 커버됩니다.


Sentry: 에러 추적

왜 Sentry인가

도구무료 티어에러 추적소스맵성능알림
Sentry5K 이벤트/월
Bugsnag7.5K 이벤트/월
Rollbar5K 이벤트/월
LogRocket1K 세션/월
자체 구축무료수동수동수동수동

Sentry를 선택한 이유:

  1. 무료 티어가 충분: 5,000 이벤트/월. 초기 SaaS에는 넉넉함
  2. SDK가 모든 프레임워크 지원: Next.js, Express, Python, React 등
  3. 소스맵 자동 업로드: minified 코드에서도 원본 위치 확인
  4. 릴리즈 추적: 어떤 배포에서 에러가 시작됐는지 확인

최소 설정

// sentry.config.js (Next.js 예시)
import * as Sentry from '@sentry/nextjs';

Sentry.init({
  dsn: process.env.SENTRY_DSN,
  environment: process.env.NODE_ENV,

  // 프로덕션에서만 활성화
  enabled: process.env.NODE_ENV === 'production',

  // 에러 샘플링 100% (초기에는 모든 에러 캡처)
  sampleRate: 1.0,

  // 성능 샘플링 10% (무료 티어 절약)
  tracesSampleRate: 0.1,
});

에러에 맥락 추가

// 사용자 컨텍스트
Sentry.setUser({
  id: user.id,
  email: user.email,  // 주의: GDPR 고려
});

// 추가 태그
Sentry.setTag('plan', user.plan);     // free, pro, enterprise
Sentry.setTag('feature', 'analysis'); // 기능 구분

// 수동 에러 캡처
try {
  await processAnalysis(query);
} catch (error) {
  Sentry.captureException(error, {
    extra: {
      queryId: query.id,
      engineCount: query.engines.length,
    },
  });
  throw error;
}

Sentry 무료 티어 최적화

5,000 이벤트/월을 효율적으로 쓰려면:

전략방법효과
중복 제거Sentry가 자동으로 같은 에러 그룹화이벤트 수 절약
에러 필터링404, 봇 트래픽 무시노이즈 제거
샘플링tracesSampleRate: 0.1성능 이벤트 90% 절약
환경 분리프로덕션만 전송개발 이벤트 제외
// 불필요한 에러 필터링
Sentry.init({
  beforeSend(event) {
    // 404는 무시
    if (event.exception?.values?.[0]?.type === 'NotFoundError') {
      return null;
    }
    // 봇 트래픽 무시
    if (event.request?.headers?.['user-agent']?.includes('bot')) {
      return null;
    }
    return event;
  },
});

Betterstack: Uptime + 로그

왜 Betterstack인가

도구무료 티어Uptime로그상태 페이지알림 채널
Betterstack5 모니터, 로그 1GBSlack, Email, SMS
UptimeRobot50 모니터Email
Pingdom유료다양
Datadog유료다양

Betterstack을 선택한 이유:

  1. Uptime + 로그가 한 곳에: 별도 도구 2개 대신 1개로 해결
  2. 무료 상태 페이지: 사용자에게 서비스 상태를 보여줄 수 있음
  3. 깔끔한 UI: 1인 개발자가 빠르게 파악 가능
  4. Heartbeat 모니터: cron job, 백그라운드 작업 감시

Uptime 모니터 설정

Betterstack에서 설정할 모니터:

#모니터 대상체크 방법주기알림
1메인 사이트HTTP 200 확인3분Slack + Email
2API 헬스체크/api/health 엔드포인트1분Slack + Email
3결제 WebhookHeartbeat (주기적 ping)5분Email + SMS
4SSL 인증서만료일 확인1일Email (30일 전)

헬스체크 엔드포인트

// /api/health — 서비스 상태 확인용
app.get('/api/health', async (req, res) => {
  const checks = {
    server: 'ok',
    database: 'unknown',
    cache: 'unknown',
  };

  try {
    await db.query('SELECT 1');
    checks.database = 'ok';
  } catch {
    checks.database = 'error';
  }

  try {
    await redis.ping();
    checks.cache = 'ok';
  } catch {
    checks.cache = 'error';
  }

  const healthy = Object.values(checks).every(v => v === 'ok');
  res.status(healthy ? 200 : 503).json({
    status: healthy ? 'healthy' : 'degraded',
    checks,
    timestamp: new Date().toISOString(),
  });
});

헬스체크 엔드포인트는 단순히 200을 반환하는 게 아니라, DB와 주요 의존성의 상태도 확인해야 합니다. 서버는 살아있는데 DB 연결이 끊어진 경우를 잡아내려면 이 구분이 필요합니다.

상태 페이지

Betterstack 무료 티어에서 상태 페이지를 제공합니다.

status.myapp.com
├── API          ●  Operational
├── Website      ●  Operational
├── Database     ●  Operational
└── Payments     ●  Operational

Uptime: 99.95% (last 90 days)

상태 페이지가 중요한 이유:

상태 페이지 없을 때상태 페이지 있을 때
사용자: “왜 안 돼?” → 이메일/DM 폭주사용자: 상태 페이지 확인 → “아 점검 중이구나”
개발자: 문의 대응에 시간 소모개발자: 수정에 집중
신뢰 하락: “이 서비스 불안한데?”신뢰 유지: “투명하게 운영하네”

Sentry + Betterstack 조합: WICHI 적용 사례

모니터링 아키텍처

graph TD
    subgraph APP["WICHI Application"]
        FE["Frontend\n(Next.js)"]
        BE["Backend\n(Express)"]
        CRON["Cron Jobs"]
    end

    subgraph SENTRY["Sentry (에러 추적)"]
        SE["에러 캡처"]
        SP["성능 모니터링"]
        SR["릴리즈 추적"]
    end

    subgraph BETTER["Betterstack (Uptime + 로그)"]
        BU["Uptime 모니터"]
        BL["로그 수집"]
        BS["상태 페이지"]
    end

    subgraph ALERT["알림"]
        SLACK["Slack"]
        EMAIL["Email"]
    end

    FE --> SE
    BE --> SE
    BE --> BL
    CRON --> BL

    BU -->|"3분마다 체크"| BE
    SE --> SLACK
    BU --> SLACK
    BU --> EMAIL

    style SENTRY fill:#e3f2fd,stroke:#2196f3
    style BETTER fill:#e8f5e9,stroke:#4caf50

역할 분담

상황감지 주체알림 내용
런타임 에러 (500)Sentry에러 메시지 + 스택 트레이스 + 사용자 컨텍스트
서비스 다운Betterstack Uptime”API 응답 없음” + 다운타임 기록
백그라운드 작업 실패Betterstack Heartbeat”마지막 heartbeat 5분 전”
응답 시간 저하Sentry Performance”p95 응답 시간 3초 초과”
SSL 만료 임박Betterstack”SSL 인증서 30일 후 만료”

실제 에러 대응 사례

모니터링 도입 후, 같은 종류의 에러가 발생했을 때의 차이:

graph LR
    subgraph BEFORE["Before: 모니터링 없음"]
        B1["에러 발생\n(오전 2시)"] --> B2["사용자 발견\n(오전 10시)"]
        B2 --> B3["피드백 전달\n(오전 11시)"]
        B3 --> B4["원인 파악\n(오후 1시)"]
        B4 --> B5["수정 배포\n(오후 3시)"]
    end

    subgraph AFTER["After: Sentry + Betterstack"]
        A1["에러 발생\n(오전 2시)"] --> A2["Slack 알림\n(오전 2시 1분)"]
        A2 --> A3["아침에 확인\n(오전 9시)"]
        A3 --> A4["원인 파악\n(오전 9시 15분)\n스택 트레이스 즉시 확인"]
        A4 --> A5["수정 배포\n(오전 10시)"]
    end

    style BEFORE fill:#ffebee,stroke:#f44336
    style AFTER fill:#e8f5e9,stroke:#4caf50
지표BeforeAfter
에러 인지 시간~8시간~1분 (알림)
원인 파악 시간~2시간~15분 (스택 트레이스)
총 대응 시간~13시간~1시간
사용자 영향 시간~13시간~8시간 (야간 발생 시)

무료 티어 비용 계산

1인 SaaS 초기에는 모니터링에 돈을 쓸 필요가 없습니다.

도구무료 범위초과 시 비용초기 SaaS 충분?
Sentry5,000 이벤트/월$26/월 (50K)✅ 충분
Betterstack Uptime5 모니터$24/월 (20개)✅ 충분
Betterstack Logs1GB/월$24/월 (5GB)✅ 충분
합계$0/월

무료 티어를 오래 쓰는 팁

전략SentryBetterstack
환경 분리프로덕션만 전송프로덕션 엔드포인트만 모니터
필터링404, 봇 에러 제외불필요한 로그 레벨 제외
샘플링성능 이벤트 10%만
보존 기간기본 90일기본 3일 (무료), 핵심 로그만

론칭 전 모니터링 체크리스트

#항목도구소요 시간
1Sentry 프로젝트 생성 + SDK 설치Sentry15분
2에러 알림 → Slack 연동Sentry5분
3에러 필터링 설정 (404, 봇 제외)Sentry10분
4Uptime 모니터 설정 (사이트 + API)Betterstack10분
5헬스체크 엔드포인트 구현직접20분
6상태 페이지 설정Betterstack10분
7Heartbeat 모니터 (cron job용)Betterstack10분
합계~80분
graph LR
    A["80분 투자"] --> B["에러 인지 시간\n8시간 → 1분"]
    A --> C["원인 파악 시간\n2시간 → 15분"]
    A --> D["사용자 불만\n감소"]
    A --> E["비용\n$0/월"]

    style A fill:#e3f2fd,stroke:#2196f3
    style E fill:#e8f5e9,stroke:#4caf50

80분이면 설정이 끝납니다. 모니터링 없이 론칭하면, 첫 번째 에러에서 그 80분의 100배를 쓰게 됩니다.


모니터링 → 체크리스트 항목

MMU의 534개 체크리스트 중 모니터링 관련은 38개입니다. 그 중 론칭 전 필수 항목 10개:

#항목MMU 카테고리
1에러 추적 도구가 프로덕션에 설치되어 있는가Monitoring
2Uptime 모니터가 설정되어 있는가Monitoring
3에러 알림이 Slack/Email로 전달되는가Monitoring
4헬스체크 엔드포인트가 있는가Monitoring
5상태 페이지가 있는가Monitoring
6소스맵이 에러 추적 도구에 업로드되는가Monitoring
7에러에 사용자 컨텍스트가 포함되는가Monitoring
8백그라운드 작업에 heartbeat 모니터가 있는가Monitoring
9SSL 인증서 만료 알림이 설정되어 있는가Security
10로그에 민감 정보(비밀번호, 토큰)가 포함되지 않는가Security

이 10개는 모두 무료 도구로, 총 80분 안에 설정할 수 있습니다. “론칭 후에 하자”는 “에러가 터진 후에 하자”와 같습니다.


정리

핵심내용
모니터링 없이 론칭한 결과에러를 사용자 제보로 알게 됨 (평균 15시간 후)
최소 조합Sentry (에러 추적) + Betterstack (Uptime + 로그)
비용$0/월 (무료 티어로 충분)
설정 시간~80분
효과에러 인지 8시간 → 1분, 원인 파악 2시간 → 15분
원칙론칭 전에 모니터링이 먼저. 기능보다 먼저
공유

관련 글