로깅 및 모니터링
규칙
- 구조화된 로깅:
timestamp, level, message, requestId, userId 필드를 포함한 JSON 형식 사용
- 로그 레벨:
error (중대한 오류), warn (성능 저하), info (비즈니스 이벤트), debug (개발 전용)
- Node.js 로깅에는 Pino 사용 — 빠르고, 구조화되어 있으며, 기본적으로 JSON 형식
- 오류 추적에는 Sentry 사용: 초기에 초기화하고, 처리되지 않은 예외를 캡처하며, 사용자 컨텍스트 및 breadcrumbs 추가
- 요청 ID로 로그 상관 관계 설정 — 요청마다 UUID를 생성하고 모든 서비스 호출에 전달
- 비밀번호, 토큰, 전체 신용카드 번호 등 민감한 정보를 절대 로깅하지 않음 — 민감한 필드는 자동 마스킹
- 개별 오류가 아닌 오류율 급증에 대해 알림 — 임계값 사용 (예: 5분 이내 오류율 5% 초과)
- Axiom/Datadog: OTLP 또는 네이티브 SDK를 통해 로그를 전송하고, 비즈니스 KPI에 대한 사용자 정의 메트릭 추가
- 건강 상태 확인 엔드포인트:
GET /health — { status: "ok" } 반환 및 DB 연결 상태 확인 포함
- 응답 시간 p50, p95, p99 모니터링 — p95 성능 저하 시 알림
패턴
import pino from "pino";
const logger = pino({ level: process.env.LOG_LEVEL || "info" });
logger.info({ userId, action: "checkout", orderId }, "주문 완료");
logger.error({ err, requestId }, "결제 처리 실패");
import * as Sentry from "@sentry/nextjs";
Sentry.init({ dsn: process.env.SENTRY_DSN, tracesSampleRate: 0.1 });
피해야 할 사항
- 프로덕션 환경에서
console.log 사용 — 구조화된 로거를 사용하세요
- 모든 요청 본문을 로깅하는 것 — 요약 정보를 로깅하고 전체 페이로드는 피하세요
- 처리되지 않은 Promise rejection 무시 — 항상 캡처하세요
- 시끄러운 알림으로 인한 알림 피로 — 임계값을 조정하고 유사한 오류를 그룹화하세요