BREAKCHANGE(database): detail logging add

This commit is contained in:
Kyush 2026-03-25 18:56:41 +09:00
commit 67532df356
37 changed files with 673 additions and 191 deletions

View file

@ -28,7 +28,7 @@
| GET | `/admin/users` | 전체 사용자 목록 |
| POST | `/admin/users` | 사용자 생성 (API 키 자동 발급) |
| GET | `/admin/users/:id` | 사용자 조회 |
| PUT | `/admin/users/:id` | 사용자 수정 (name, email, is_active) |
| PUT | `/admin/users/:id` | 사용자 수정 (name, email, is_active, detail_logging) |
| DELETE | `/admin/users/:id` | 사용자 삭제 |
| POST | `/admin/users/:id/regenerate-api-key` | API 키 재발급 |
@ -37,7 +37,7 @@
| Method | Path | Description |
|--------|------|-------------|
| GET | `/admin/backends` | 전체 백엔드 목록 |
| POST | `/admin/backends` | 백엔드 생성 (name, base_url, api_key) |
| POST | `/admin/backends` | 백엔드 생성 (name, base_url, api_key, detail_logging) |
| GET | `/admin/backends/:id` | 백엔드 조회 |
| PUT | `/admin/backends/:id` | 백엔드 수정 |
| DELETE | `/admin/backends/:id` | 백엔드 삭제 |
@ -72,5 +72,7 @@
| Method | Path | Query Params | Description |
|--------|------|-------------|-------------|
| GET | `/admin/analytics/usage` | userId, backendId, days | 사용량 통계 |
| GET | `/admin/analytics/requests` | limit, offset | 요청 로그 (페이지네이션) |
| GET | `/admin/analytics/requests` | month, date, limit, offset, q, userId, backendId, endpoint, detailLogged | 월별 상세 요청 로그 조회 |
| GET | `/admin/analytics/metrics` | backendId, days | 백엔드 성능 메트릭 |
상세 로그는 `users.detail_logging=1` 또는 `backends.detail_logging=1`일 때만 request/response header/body가 저장된다.

View file

@ -14,10 +14,10 @@ client/src/
index.ts # TypeScript 타입 정의
routes/
Dashboard.tsx # 홈 — 요약 카드 (사용자 수, 활성 백엔드, 최근 요청) + 최근 요청 테이블
Users.tsx # 사용자 관리 — CRUD, API 키 발급/재발급, 활성화 토글
Backends.tsx # 백엔드 관리 — CRUD (name, base_url, api_key)
Users.tsx # 사용자 관리 — CRUD, API 키 발급/재발급, 활성화/상세 로깅 토글
Backends.tsx # 백엔드 관리 — CRUD (name, base_url, api_key, detail_logging)
Permissions.tsx # 권한 관리 — user-backend 매핑
Analytics.tsx # 분석 — 요청 로그, 사용량 통계, 백엔드 메트릭
Analytics.tsx # 분석 — 월별 요청 로그, 사용량 통계, 백엔드 메트릭
Scripts.tsx # 스크립트 관리 — CRUD, 테스트, 활성화/비활성화
components/
Layout.tsx # 사이드바 네비게이션 + 메인 콘텐츠 레이아웃
@ -54,3 +54,8 @@ CSS 프레임워크 없음. 인라인 `style` props 사용.
## Dev Server
포트: 3002 (vite.config.ts), API 프록시: `/api``http://localhost:3000`
## Analytics Notes
- 요청 로그 조회는 월별 request_logs 파일을 대상으로 한다.
- analytics API 클라이언트는 `month`, `date`, `q`, `limit`, `offset` 등 필터를 지원한다.

View file

@ -1,8 +1,8 @@
# Database Schema
두 개의 SQLite 데이터베이스를 사용한다. 설정 데이터는 `core.db`, 운영 데이터는 `analytics.db` 저장된다.
DB는 `DB_DIR` 하위에 분리 저장된다.
스키마 원본: [database/schema.sql](../database/schema.sql), [database/analytics-schema.sql](../database/analytics-schema.sql)
스키마 원본: [database/schema.sql](../database/schema.sql), [database/analytics-schema.sql](../database/analytics-schema.sql), [database/request-logs-schema.sql](../database/request-logs-schema.sql)
---
@ -17,6 +17,7 @@
| name | TEXT | NOT NULL |
| email | TEXT | |
| is_active | BOOLEAN | DEFAULT 1 |
| detail_logging | INTEGER | DEFAULT 0 |
| created_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP |
| updated_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP |
@ -31,6 +32,7 @@ Indexes: `idx_users_api_key(api_key)`
| base_url | TEXT | NOT NULL |
| api_key | TEXT | |
| is_active | BOOLEAN | DEFAULT 1 |
| detail_logging | INTEGER | DEFAULT 0 |
| created_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP |
| updated_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP |
@ -68,29 +70,11 @@ Indexes: `idx_user_scripts_type`, `idx_user_scripts_active`, `idx_user_scripts_t
## Analytics Database (analytics.db)
### request_logs
### usage_stats
| Column | Type | Constraints |
|--------|------|-------------|
| id | INTEGER | PRIMARY KEY AUTOINCREMENT |
| user_id | INTEGER | NOT NULL |
| backend_id | INTEGER | NOT NULL |
| endpoint | TEXT | NOT NULL |
| request_model | TEXT | |
| response_model | TEXT | |
| prompt_tokens | INTEGER | |
| completion_tokens | INTEGER | |
| total_tokens | INTEGER | |
| status_code | INTEGER | |
| response_time_ms | INTEGER | |
| error_message | TEXT | |
| created_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP |
Indexes: `idx_request_logs_user`, `idx_request_logs_backend`, `idx_request_logs_date(created_at)`, `idx_request_logs_user_backend`
### usage_stats
일별 집계 테이블.
일별 집계 테이블. 날짜 경계는 `TZ`, 저장 timestamp는 UTC 기준.
| Column | Type | Constraints |
|--------|------|-------------|
@ -121,3 +105,33 @@ Indexes: `idx_usage_stats_user`, `idx_usage_stats_date`
Unique: `(backend_id, date)`
Indexes: `idx_backend_metrics_backend`, `idx_backend_metrics_date`
## Monthly Request Logs (`request_logs/request_logs_YYYY-MM.db`)
월별 상세 요청 로그는 별도 SQLite 파일에 저장된다.
### request_logs
| Column | Type | Constraints |
|--------|------|-------------|
| id | INTEGER | PRIMARY KEY AUTOINCREMENT |
| user_id | INTEGER | NOT NULL |
| backend_id | INTEGER | NOT NULL |
| endpoint | TEXT | NOT NULL |
| request_model | TEXT | |
| response_model | TEXT | |
| prompt_tokens | INTEGER | |
| completion_tokens | INTEGER | |
| total_tokens | INTEGER | |
| status_code | INTEGER | |
| response_time_ms | INTEGER | |
| error_message | TEXT | |
| detail_logged | INTEGER | DEFAULT 0 |
| local_date | TEXT | `TZ` 기준 `YYYY-MM-DD` |
| request_headers | TEXT | JSON 문자열 |
| request_body | TEXT | JSON 또는 raw 문자열 |
| response_headers | TEXT | JSON 문자열 |
| response_body | TEXT | JSON 또는 raw 문자열 |
| created_at | TEXT | UTC ISO timestamp |
Indexes: `created_at`, `local_date`, `user_id`, `backend_id`, `endpoint`, `detail_logged`

View file

@ -33,6 +33,10 @@ interface ScriptContextData {
}
```
참고:
- `request.body`, `response.body`는 직렬화 가능한 값이며 보통 JSON 객체로 전달된다.
- 스크립트가 body를 수정하면 라우터가 업스트림 전송 전에 최종 body를 기준으로 직렬화하고 `content-length`를 다시 계산한다.
## Example
```javascript

View file

@ -8,8 +8,10 @@
server/src/
index.ts # Express 앱 팩토리 (CORS, 라우트 설정, health 엔드포인트)
config/
db-paths.ts # DB_DIR 기준 파일 경로 계산
database.ts # Core SQLite 연결 및 스키마 초기화
analytics-db.ts # Analytics SQLite 연결 및 스키마 초기화
request-logs-db.ts # 월별 request_logs SQLite 연결 및 스키마 초기화
models/
User.ts # 사용자 CRUD (create, findById, findByApiKey, update, delete, regenerateApiKey)
Backend.ts # 백엔드 CRUD (create, findById, findAll, activate/deactivate)
@ -23,13 +25,15 @@ server/src/
scripts.ts # Script 관리 엔드포인트
analytics.ts # Analytics 조회 엔드포인트
services/
RouterService.ts # 백엔드 선택 (랜덤 로드밸런싱) 및 HTTP 요청 포워딩
AnalyticsService.ts # 요청 로깅, 일별 사용량/메트릭 집계
RouterService.ts # 백엔드 선택 (랜덤 로드밸런싱), HTTP 요청 포워딩, body/content-length 정규화
AnalyticsService.ts # 일별 사용량/메트릭 집계
RequestLogService.ts # 월별 request_logs 기록/조회
ScriptEngine.ts # 스크립트 체인 오케스트레이션 (onRequest/onResponse 훅 적용)
ScriptExecutor.ts # isolated-vm 기반 스크립트 컴파일/실행 (5s timeout, 50MB memory)
utils/
apiKey.ts # API 키 생성 (sk-{timestamp}-{random}, crypto.randomBytes)
logger.ts # 컬러 콘솔 로거
time.ts # TZ 기준 날짜/월 계산, UTC timestamp 생성
```
## Request Flow
@ -40,10 +44,16 @@ Client → auth.ts (API 키 검증, 권한 로드)
→ ScriptEngine.applyOnRequestScripts (요청 변조)
→ RouterService.forwardRequest (백엔드 프록시)
→ ScriptEngine.applyOnResponseScripts (응답 변조)
→ AnalyticsService.logRequest (로깅)
→ AnalyticsService.logRequest (집계 + 월별 request_logs 기록)
→ Response
```
## Time & Storage
- DB 루트는 `DB_DIR`로 설정한다. 파일은 `core.db`, `analytics.db`, `request_logs/request_logs_YYYY-MM.db` 구조로 생성된다.
- 일/월 경계 계산은 `TZ` 기준으로 수행한다.
- 저장되는 timestamp 문자열은 UTC ISO 형식으로 통일한다.
## Dependencies
| Package | Purpose |