Files
chocoadmin/docs/phase/phase9.md
T

145 lines
4.7 KiB
Markdown

# Phase 9. 실행 로그 및 DB 쿼리 로그
## 로그 정책
### 환경 구분
| `APP_ENV` | 설명 |
|---|---|
| `local` | 맥미니 개발 환경 |
| `stage` | NAS에서 stage DB로 구동하는 검증 환경 |
| `production` | NAS에서 운영 DB로 구동하는 실제 서비스 환경 |
`NODE_ENV`는 Next.js 빌드 방식(dev/prod)을 제어하고, `APP_ENV`는 로그 레벨·상세도를 제어한다.
### 로그 레벨
| `LOG_LEVEL` | 출력 대상 |
|---|---|
| `debug` | debug + info + warn + error |
| `info` | info + warn + error |
| `warn` | warn + error |
| `error` | error만 |
`LOG_LEVEL`을 명시하지 않으면 `APP_ENV=production`일 때 `info`, 그 외는 `debug`가 기본값.
### 출력 형식
```
[2026-06-22T10:00:00.000Z] [INFO ] [maestros] list fetched {"totalCount":120,"duration":45}
[2026-06-22T10:00:00.000Z] [WARN ] [extension-requests/[id]] 이미 처리된 연장 신청입니다. {"id":5,"status":409,"duration":12}
[2026-06-22T10:00:00.000Z] [ERROR] [upgrade-requests/[id]] unexpected error {"id":3,"error":"...","duration":5}
```
- `warn` / `error`는 stderr, 그 외는 stdout으로 출력한다.
- JSON 데이터는 한 줄로 직렬화한다 (Docker 로그 파싱 편의).
### 민감정보 마스킹 대상
아래 값은 로그에 포함하지 않는다:
- 관리자 패스워드 (form 입력값, DB 조회 파라미터)
- `AUTH_SECRET` / `NEXTAUTH_SECRET`
- `DATABASE_URL` (패스워드 포함)
- 세션 토큰 / JWT 페이로드 원문
- SMTP 패스워드
현재 `auth.ts`의 raw SQL 파라미터에 패스워드가 포함될 수 있으므로 DB query 이벤트 핸들러 구현 시 `PASSWORD(` 포함 쿼리의 params를 마스킹한다 (Phase 9 DB query 로그 구현 시 처리).
---
## 환경변수
| 변수 | 설명 | 기본값 |
|---|---|---|
| `APP_ENV` | 환경 구분 (`local`\|`stage`\|`production`) | `local` |
| `LOG_LEVEL` | 최소 로그 레벨 (`debug`\|`info`\|`warn`\|`error`) | `APP_ENV`에 따라 자동 |
| `DB_SLOW_QUERY_MS` | DB 쿼리 slow query 임계값(ms) — DB query 로그 구현 시 사용 | `1000` |
### 권장 `.env` 설정
**.env.local (개발)**
```env
APP_ENV=local
LOG_LEVEL=debug
```
**.env.stage (검증)**
```env
APP_ENV=stage
LOG_LEVEL=debug
```
**.env.production (운영)**
```env
APP_ENV=production
LOG_LEVEL=info
DB_SLOW_QUERY_MS=500
```
---
## 적용 현황
### 완료
- `lib/logger.ts` — 공통 logger 모듈 (레벨 필터링, 포맷, stderr/stdout 분기)
- 로그인 성공/실패 로그 (`auth.ts`)
- 마에스트로 목록/상세 조회 로그
- 연장 신청 조회/승인/취소 로그 (409는 warn, 그 외 예외는 error)
- 업그레이드 신청 조회/승인/거절 로그 (409는 warn, 그 외 예외는 error)
### 미완료 (별도 확인 후 진행)
- **Correlation ID**: Edge Middleware(`proxy.ts`)에서 `x-correlation-id` 헤더 생성 → API route에서 AsyncLocalStorage로 전달하는 구조. 구현 전 설계 확정 필요.
- **DB query 로그**: `@prisma/adapter-mariadb` + Prisma query 이벤트 호환성 확인 필요. `$on('query', handler)` 발화 여부를 local에서 테스트한 뒤 진행.
- **결과 row/count 로그**: Prisma query 이벤트에 결과 데이터가 없음. `$extends` query 컴포넌트 방식으로 재설계하거나 계획 범위 축소 필요.
---
## Docker / NAS 로그 운영 절차
### 애플리케이션 로그 확인
```bash
# 실시간 스트리밍
docker compose logs -f chocoadmin
# 최근 100줄
docker compose logs --tail=100 chocoadmin
# 특정 시간 이후
docker compose logs --since="2026-06-22T10:00:00" chocoadmin
```
### warn/error만 필터링
```bash
docker compose logs -f chocoadmin 2>&1 | grep -E '\[(WARN |ERROR)\]'
```
### Nginx Proxy Manager 로그와 함께 확인
Synology NAS에서 Nginx Proxy Manager(NPM)와 chocoadmin 로그를 같이 보려면:
```bash
# NPM access log (컨테이너 이름은 환경에 맞게 조정)
docker logs nginx-proxy-manager 2>&1 | tail -50
# 두 로그를 동시에
docker compose logs -f chocoadmin &
docker logs -f nginx-proxy-manager
```
NPM의 access log에는 클라이언트 IP, HTTP method, path, status code, 응답 시간이 기록되고, chocoadmin 로그에는 인증 결과와 비즈니스 처리 결과가 기록된다. `status=409`를 NPM 로그에서 발견했을 때 chocoadmin의 `[WARN]` 로그와 함께 원인을 추적한다.
### stage/production 로그 레벨 차이
| 항목 | stage | production |
|---|---|---|
| `LOG_LEVEL` | `debug` | `info` |
| 요청 시작 로그 | 출력 (debug) | 미출력 |
| 성공 응답 로그 | 출력 (info) | 출력 (info) |
| 인증 실패/409 로그 | 출력 (warn, stderr) | 출력 (warn, stderr) |
| 예외/500 로그 | 출력 (error, stderr) | 출력 (error, stderr) |