Skip to content

에러 관측 (Sentry)

운영 에러는 Sentry 로 수집한다 (org j6nops). 서비스마다 별도 Sentry project. 자작 텔레그램 알림은 폐기하고 Sentry 로 일원화했다 (2026-05-24).

이 문서는 dartbrief 의 Sentry 연동을 다룬다. project: dartbrief-backend(Go), dartbrief-frontend(Next.js).

백엔드 (dartbrief-backend, Go)

sentry-go 로 연동. DSN 비면 no-op (로컬 dev 안전). Issue 와 Logs 두 갈래 (Sentry 표준 — log→issue 자동변환은 deprecated. 예외는 capture, 로그는 Logs 로).

Issues (알림·triage 대상)

포착방식
HTTP 5xx 응답capture5xx 미들웨어 (cmd/server/sentry_http.go) — status≥500 전부 CaptureMessage
HTTP paniccapture5xx 복구 → 500 응답 보장 → CaptureException (재던지지 않음). sentryhttp 가 바깥에서 요청별 hub 제공
AI 스케줄러 워커 panicscheduler.runJob recover → sentry.CurrentHub().Recover
  • capture5xx항상 적용 — Sentry 비활성이어도 panic→500 보장(HTTP 의미론).

Logs (검색용 로그 스트림 — "다 넣기")

  • 공식 sentry-go/slog 핸들러 + sentry.Init(EnableLogs:true). SENTRY_LOG_LEVEL(기본 Info) 이상 모든 slog 로그가 Sentry Logs 로 전송.
  • fanoutHandler 로 stdout JSON(Railway 로그)과 동시에 보냄(이중 sink).
  • 로그는 Logs, 에러는 Issues이슈 중복 없음.

환경변수 (Railway)

env비고
SENTRY_DSNdartbrief-backend project DSN. 비면 Sentry 비활성(no-op)
SENTRY_ENVIRONMENT기본 APP_ENV → 없으면 production
SENTRY_LOG_LEVELLogs 전송 최소 레벨 (debug/info/warn/error). 기본 info
RAILWAY_GIT_COMMIT_SHASentry Release. Railway 자동 주입
  • DSN 은 시크릿 아님(config). auth token(소스맵/릴리즈)은 ~/.config/cloud-tokens/sentry.env (시크릿, git 금지).
  • 로컬: .env.localSENTRY_DSN 미설정 → 캡처 안 함. 정상.

프론트 (dartbrief-frontend, Next.js)

@sentry/nextjs 로 연동 (CF Workers + @opennextjs/cloudflare). opennextjs 는 Node 런타임 (nodejs_compat)이라 표준 @sentry/nextjs 셋업 그대로 됨 (@sentry/cloudflare 불필요). 요건: wrangler.tomlnodejs_compat + compatibility_date ≥ 2025-08-16 (현재 2026-05-09 충족).

포착파일
클라이언트(브라우저) 에러src/instrumentation-client.ts (Sentry.init, 에러 시 리플레이)
서버(RSC/route/server action)src/instrumentation.ts register + onRequestError = Sentry.captureRequestError, src/sentry.server.config.ts
엣지src/sentry.edge.config.ts
클라 렌더 에러 경계src/app/global-error.tsxSentry.captureException
빌드 인스트루먼테이션 + 소스맵next.config.ts withSentryConfig (org j6nops, project dartbrief-frontend)
  • DSN 은 config 파일에 공개값으로 박음(클라 번들에 포함되는 게 정상). 런타임 env 불필요.
  • 소스맵: 빌드 시 SENTRY_AUTH_TOKEN(시크릿, ~/.config/cloud-tokens/sentry.env) 있으면 업로드 → 원본 라인. 없으면 스킵(에러 캡처는 됨, minified 스택). CF git-integration 배포면 CF build env 에 SENTRY_AUTH_TOKEN 설정.
  • 쿼터 절약: 상시 세션 리플레이 off(replaysSessionSampleRate:0), 에러 시에만 리플레이. traces 0.1.

앱 (dartbrief-mobile, Flutter)

sentry_flutter 로 연동. project dartbrief-mobile (org j6nops).

  • 포착: Dart/Flutter 미처리 에러(FlutterError/PlatformDispatcher 자동 후킹) + 네이티브 크래시(iOS/Android) + Release Health(crash-free 세션/유저).
  • 위치: mobile/lib/app/bootstrap.dartSentryFlutter.init(...)appRunner 로 전체 init+runApp 을 가드 존에서 실행.
  • DSN: 공개값. --dart-define=SENTRY_DSN= override + 하드코딩 fallback → prod 항상 동작. 빈 값이면 비활성.
  • environment: flavor 기준(prod/development). traces 0.1.
  • 심볼 업로드(네이티브 스택 가독): sentry_dart_plugin. pubspec sentry: 블록(org/project, upload_debug_symbols) + make build-ios-prod 가 ipa 빌드 후 flutter pub run sentry_dart_plugin 실행 → iOS dSYM/Android 네이티브 심볼 업로드. SENTRY_AUTH_TOKEN 은 Makefile 이 ~/.config/cloud-tokens/sentry.env 에서 주입.
    • 빌드 바이너리는 안 바꿈(난독화/--split-debug-info 미적용). Dart 스택은 릴리즈에서 이미 가독, 네이티브 크래시만 심볼로 해독. Dart 난독화/source-context 까지 원하면 추후 --split-debug-info+--save-obfuscation-map 추가.

oncall 자동수정 연계 (후속)

기존 oncall(에러→버튼→Claude Remote Control 수정) 파이프라인은 Sentry 와 연결 가능: Sentry alert rule → webhook → 텔레그램(oncall 봇) → 버튼 → Claude 세션. 관측은 Sentry, 자동수정 트리거는 oncall 로 역할 분리. (현재 미구현 — 후속 작업)