/** * @swagger * tags: * name: Performance * description: 성능 모니터링 및 최적화 API */ const express = require('express'); const router = express.Router(); const { asyncHandler } = require('../utils/errorHandler'); const cache = require('../utils/cache'); const { getPerformanceStats, suggestIndexes, analyzeQuery } = require('../utils/queryOptimizer'); /** * @swagger * /api/performance/cache/stats: * get: * tags: [Performance] * summary: 캐시 통계 조회 * description: 현재 캐시 시스템의 상태와 통계를 조회합니다. * security: * - bearerAuth: [] * responses: * 200: * description: 캐시 통계 조회 성공 * content: * application/json: * schema: * type: object * properties: * success: * type: boolean * example: true * message: * type: string * example: "캐시 통계 조회 성공" * data: * type: object * properties: * type: * type: string * example: "memory" * connected: * type: boolean * example: true * keys: * type: integer * example: 42 * hits: * type: integer * example: 150 * misses: * type: integer * example: 25 * hitRate: * type: number * example: 0.857 * 401: * description: 인증 필요 * 500: * description: 서버 오류 */ router.get('/cache/stats', asyncHandler(async (req, res) => { const stats = cache.getStats(); res.success(stats, '캐시 통계 조회 성공'); })); /** * @swagger * /api/performance/cache/flush: * post: * tags: [Performance] * summary: 캐시 초기화 * description: 모든 캐시 데이터를 삭제합니다. (관리자 전용) * security: * - bearerAuth: [] * responses: * 200: * description: 캐시 초기화 성공 * content: * application/json: * schema: * type: object * properties: * success: * type: boolean * example: true * message: * type: string * example: "캐시가 성공적으로 초기화되었습니다." * 401: * description: 인증 필요 * 403: * description: 권한 부족 * 500: * description: 서버 오류 */ router.post('/cache/flush', asyncHandler(async (req, res) => { // 관리자 권한 확인 if (req.user?.access_level !== 'admin' && req.user?.access_level !== 'system') { return res.status(403).json({ success: false, error: '캐시 초기화 권한이 없습니다.' }); } await cache.flush(); res.success(null, '캐시가 성공적으로 초기화되었습니다.'); })); /** * @swagger * /api/performance/database/stats: * get: * tags: [Performance] * summary: 데이터베이스 성능 통계 * description: 데이터베이스 연결 상태와 성능 지표를 조회합니다. * security: * - bearerAuth: [] * responses: * 200: * description: DB 성능 통계 조회 성공 * content: * application/json: * schema: * type: object * properties: * success: * type: boolean * example: true * message: * type: string * example: "DB 성능 통계 조회 성공" * data: * type: object * properties: * connections: * type: object * properties: * current: * type: integer * example: 5 * max: * type: integer * example: 151 * slowQueries: * type: integer * example: 0 * timestamp: * type: string * format: date-time * 401: * description: 인증 필요 * 500: * description: 서버 오류 */ router.get('/database/stats', asyncHandler(async (req, res) => { const stats = await getPerformanceStats(); res.success(stats, 'DB 성능 통계 조회 성공'); })); /** * @swagger * /api/performance/database/indexes/{tableName}: * get: * tags: [Performance] * summary: 인덱스 최적화 제안 * description: 특정 테이블의 인덱스 상태를 분석하고 최적화 제안을 제공합니다. * security: * - bearerAuth: [] * parameters: * - in: path * name: tableName * required: true * schema: * type: string * description: 분석할 테이블명 * example: "workers" * responses: * 200: * description: 인덱스 분석 성공 * content: * application/json: * schema: * type: object * properties: * success: * type: boolean * example: true * message: * type: string * example: "인덱스 분석 완료" * data: * type: object * properties: * tableName: * type: string * example: "workers" * currentIndexes: * type: array * items: * type: object * properties: * name: * type: string * column: * type: string * unique: * type: boolean * suggestions: * type: array * items: * type: object * properties: * type: * type: string * column: * type: string * reason: * type: string * sql: * type: string * 401: * description: 인증 필요 * 500: * description: 서버 오류 */ router.get('/database/indexes/:tableName', asyncHandler(async (req, res) => { const { tableName } = req.params; const analysis = await suggestIndexes(tableName); res.success(analysis, '인덱스 분석 완료'); })); /** * @swagger * /api/performance/query/analyze: * post: * tags: [Performance] * summary: 쿼리 성능 분석 * description: SQL 쿼리의 실행 계획과 성능을 분석합니다. (관리자 전용) * security: * - bearerAuth: [] * requestBody: * required: true * content: * application/json: * schema: * type: object * required: * - query * properties: * query: * type: string * example: "SELECT * FROM workers WHERE department = ?" * params: * type: array * items: * type: string * example: ["생산부"] * responses: * 200: * description: 쿼리 분석 성공 * content: * application/json: * schema: * type: object * properties: * success: * type: boolean * example: true * message: * type: string * example: "쿼리 분석 완료" * data: * type: object * properties: * executionTime: * type: integer * example: 15 * explainResult: * type: array * items: * type: object * recommendations: * type: array * items: * type: object * properties: * type: * type: string * message: * type: string * suggestion: * type: string * 401: * description: 인증 필요 * 403: * description: 권한 부족 * 500: * description: 서버 오류 */ router.post('/query/analyze', asyncHandler(async (req, res) => { // 관리자 권한 확인 if (req.user?.access_level !== 'admin' && req.user?.access_level !== 'system') { return res.status(403).json({ success: false, error: '쿼리 분석 권한이 없습니다.' }); } const { query, params = [] } = req.body; if (!query) { return res.status(400).json({ success: false, error: '분석할 쿼리가 필요합니다.' }); } const analysis = await analyzeQuery(query, params); res.success(analysis, '쿼리 분석 완료'); })); /** * @swagger * /api/performance/system/info: * get: * tags: [Performance] * summary: 시스템 정보 조회 * description: 서버의 메모리, CPU, 업타임 등 시스템 정보를 조회합니다. * security: * - bearerAuth: [] * responses: * 200: * description: 시스템 정보 조회 성공 * content: * application/json: * schema: * type: object * properties: * success: * type: boolean * example: true * message: * type: string * example: "시스템 정보 조회 성공" * data: * type: object * properties: * uptime: * type: number * example: 3600.5 * memory: * type: object * properties: * rss: * type: integer * heapTotal: * type: integer * heapUsed: * type: integer * external: * type: integer * nodeVersion: * type: string * example: "v18.17.0" * platform: * type: string * example: "linux" * 401: * description: 인증 필요 * 500: * description: 서버 오류 */ router.get('/system/info', asyncHandler(async (req, res) => { const systemInfo = { uptime: process.uptime(), memory: process.memoryUsage(), nodeVersion: process.version, platform: process.platform, cpuUsage: process.cpuUsage(), timestamp: new Date().toISOString() }; res.success(systemInfo, '시스템 정보 조회 성공'); })); module.exports = router;