로그 정책 (Logging Policy)¶
문서 역할¶
- 역할:
규범 - 문서 종류:
policy - 충돌 시 우선 문서: 로그 레벨·형식·운영 INFO 허용 범위는 이 문서, 개인정보 분류·마스킹은 데이터 거버넌스 정책
- 기준 성격:
as-is
목적¶
개발 로그와 운영 로그를 명확히 분리하여 디버깅 효율성을 높이고, 운영 환경에서 불필요한 로그로 인한 성능 저하 및 보안 이슈를 방지한다.
기본 원칙¶
0. API 실패 로그¶
- API 실패 응답 계약과 상관관계 필드는 API 에러 계약 정책을 단일 SoT(단일 기준)로 따른다.
- API 실패 로그는
error_source,error_code를 함께 남긴다. request_id는ErrorData.request_id와 같은 값을 남기고,error_source,error_code와 같은 로그 이벤트에서 확인할 수 있어야 한다.- 로그 정책은 출력 레벨, 민감정보 제외, 저장/전송 방식만 다룬다.
1. 환경 분리¶
Backend (coupler-api)¶
// 개발 로그
if (process.env.NODE_ENV === "development") {
console.log("[ModuleName] debug summary:", debugSummary);
}
// 운영 로그 (에러, 경고만)
console.error("[ModuleName] error:", safeError);
console.warn("[ModuleName] warning:", safeWarning);
Frontend (coupler-mobile-app, coupler-admin-web)¶
// 개발 로그
if (__DEV__) {
console.log("[ComponentName] debug summary:", debugSummary);
}
// 운영 로그 (에러만, 모니터링 시스템으로 전송)
console.error("[ComponentName] error:", safeError);
2. 로그 레벨 구분¶
| 레벨 | 용도 | 개발 환경 | 운영 환경 |
|---|---|---|---|
| DEBUG | 상세 디버깅 정보 | ✅ | ❌ |
| INFO | 일반 정보성 로그 | ✅ | ⚠️ 최소화 |
| WARN | 경고 (복구 가능한 이슈) | ✅ | ✅ |
| ERROR | 에러 (복구 불가능한 이슈) | ✅ | ✅ |
로그 형식 규칙¶
로그 메시지 포맷¶
가독성 원칙¶
- 태그는 대괄호
[ModuleName]로 시작 - 키-값 쌍은 콜론(
:) 구분 - 여러 값은 쉼표로 구분하지 말고 별도 로그로 분리
- 객체/배열은 자동 포맷팅 활용 (JSON.stringify 지양)
좋은 예¶
// ✅ 명확하고 읽기 쉬운 형식
console.log("[uploadImages] type:", uploadType);
console.log("[uploadImages] files count:", req.files.length);
console.log("[SignupScreen] selected images count:", images.length);
console.error("[auth.js] signup failed:", safeErrorMessage);
// ✅ 여러 값은 별도 로그로 분리
if (__DEV__) {
console.log("[Step3] next count:", nextList.length);
console.log("[Step3] filtered count:", filtered.length);
console.log("[Step3] can proceed:", canProceed);
}
나쁜 예¶
// ❌ 태그 없음
console.log("type", uploadType);
// ❌ 불명확한 메시지
console.log("디버그:", debugSummary);
// ❌ 여러 값을 한 줄에 섞음 (가독성 저하)
console.log(
"[Step3] nextList:",
nextList.length,
"filtered count:",
filtered.length,
"can proceed:",
canProceed,
);
// ❌ JSON.stringify 남용 (자동 포맷팅이 더 읽기 쉬움)
console.log("[Step3] summary:", JSON.stringify(debugSummary));
Convention¶
모듈명 표기¶
- Backend 함수:
[functionName](예:[uploadImages],[signup]) - Frontend 컴포넌트:
[ComponentName](예:[SignupScreen],[Step3]) - 유틸리티/라이브러리:
[ModuleName](예:[review-image],[APIUtils])
일관성 유지¶
- 같은 모듈 내에서는 동일한 태그 사용
- 키 이름은 변수명과 일치시키기
- 순서: 입력 파라미터 → 중간 결과 → 최종 결과
개발 로그 예시¶
Backend 예시¶
exports.uploadImages = async (req, res) => {
if (process.env.NODE_ENV === "development") {
console.log("[uploadImages] files count:", req.files.length);
}
// 비즈니스 로직...
};
Frontend (Mobile/Web)¶
const handleSubmit = () => {
if (__DEV__) {
console.log("[SignupScreen] submit started");
}
// API 호출...
};
운영 로그 예시¶
에러만 기록 (항상 표시)¶
try {
await someOperation();
} catch (error) {
console.error("[ModuleName] operation failed:", {
request_id: requestId,
error_source: "MODULE_NAME",
error_code: "MODULE_OPERATION_FAILED",
message: safeErrorMessage,
stack: sanitizedStack,
context: safeContext,
});
}
금지 사항¶
❌ 개인정보/민감정보 로깅 금지¶
개발·운영 환경 모두 개인정보 분류와 마스킹은 데이터 거버넌스 정책을 따른다. 개발 환경은 원문 식별자와 개인정보 로깅의 예외가 아니다.
// ❌ 절대 금지
console.log("User password:", user.pwd);
console.log("Card number:", payment.card_number);
console.log("User email:", user.email);
console.log("User ID:", user.id);
// ✅ 허용
console.log("User ID:", maskedUserId);
console.log("User email:", maskedEmail);
console.log("Payment status:", payment.status);
❌ 과도한 반복 로그 금지¶
// ❌ 금지 (루프 내부)
for (let i = 0; i < 1000; i++) {
console.log("Processing item:", i);
}
// ✅ 허용
if (__DEV__) {
console.log("Processing items, count:", items.length);
}
// 처리 후 요약 로그
console.log("Processed items:", successCount, "success,", failCount, "failed");
❌ 무분별한 객체 로깅 금지¶
// ❌ 금지 (너무 큰 객체)
console.log("Entire state:", GlobalState);
// ✅ 허용 (필요한 부분만)
if (__DEV__) {
console.log("User profile images count:", GlobalState.me.profile.profile_image_paths.length);
}
로그 색인 (Log Indexing)¶
주요 모듈별 로그 태그¶
Backend 로그 태그¶
[auth.js] - 인증 관련
[member.js] - 회원 관리
[upload.js] - 파일 업로드
[review-image] - 이미지 심사
[APIUtils] - API 유틸리티
Frontend 로그 태그¶
[SignupScreen] - 회원가입
[ProfilePreviewScreen] - 프로필 미리보기
[MatchingTab] - 매칭 탭
[APIUtils] - API 호출
[GlobalState] - 전역 상태
검색 팁¶
특정 모듈 로그만 필터링:
# Backend
NODE_ENV=development node app.js | grep '\[uploadImages\]'
# Frontend (Metro bundler)
# Cmd/Ctrl + F: [SignupScreen]
운영 환경 로그 관리¶
Backend¶
- 에러 로그:
console.error로 기록, 필요 시 모니터링 시스템 연동 - 접근 로그: Express 미들웨어 사용
- 비즈니스 로그: 최소화, 필요 시 DB에 별도 저장
Frontend¶
- 에러 로그:
console.error로 기록, 필요 시 모니터링 시스템 연동 - console.log: 번들에서 자동 제거 (Babel plugin 또는 Terser 설정)
체크리스트¶
로그 추가 시 다음을 확인:
- [ ] 개발 환경 조건 (
__DEV__또는NODE_ENV === 'development') 사용했는가? - [ ] 로그 메시지에 모듈/컴포넌트명 포함했는가?
- [ ] 개인정보/민감정보가 포함되지 않았는가?
- [ ] 운영 환경에 필요한 로그인가? (에러/경고만 허용)
- [ ] API 실패 로그라면
request_id,error_source,error_code가 함께 남는가? - [ ] 반복 로그가 아닌가? (루프 외부로 이동 또는 요약)
예외 상황¶
다음 경우에만 운영 환경에서 INFO 로그 허용:
- 중요 비즈니스 이벤트: 회원가입 완료, 결제 완료 등
- 서버 시작/종료: 서버 부팅, graceful shutdown
- 스케줄러 실행: Cron 작업 시작/종료 (성공/실패 결과만)