feat(phase-5-3): 모니터링 강화

logger.ts, metrics.ts, /api/metrics 추가
Version: e3bcb4ae
This commit is contained in:
kappa
2026-01-19 16:43:36 +09:00
parent a2194a5d45
commit c0e47482c4
12 changed files with 2491 additions and 5 deletions

View File

@@ -6,6 +6,7 @@ import {
generateAIResponse,
} from '../summary-service';
import { handleCommand } from '../commands';
import { openaiCircuitBreaker } from '../openai-service';
// 사용자 조회/생성
async function getOrCreateUser(
@@ -59,6 +60,9 @@ async function getOrCreateUser(
* -H "Origin: https://hosting.anvil.it.com" \
* -H "Content-Type: application/json" \
* -d '{"email":"test@example.com","message":"test message"}'
* 6. Test metrics (Circuit Breaker status):
* curl http://localhost:8787/api/metrics \
* -H "Authorization: Bearer your-webhook-secret"
*/
export async function handleApiRequest(request: Request, env: Env, url: URL): Promise<Response> {
// Deposit API - 잔액 조회 (namecheap-api 전용)
@@ -314,5 +318,60 @@ export async function handleApiRequest(request: Request, env: Env, url: URL): Pr
});
}
// Metrics API - Circuit Breaker 상태 조회 (관리자 전용)
if (url.pathname === '/api/metrics' && request.method === 'GET') {
try {
// WEBHOOK_SECRET 인증
const authHeader = request.headers.get('Authorization');
if (!env.WEBHOOK_SECRET || authHeader !== `Bearer ${env.WEBHOOK_SECRET}`) {
return Response.json({ error: 'Unauthorized' }, { status: 401 });
}
// Circuit Breaker 상태 수집
const openaiStats = openaiCircuitBreaker.getStats();
// 메트릭 응답 생성
const metrics = {
timestamp: new Date().toISOString(),
circuitBreakers: {
openai: {
state: openaiStats.state,
failures: openaiStats.failures,
lastFailureTime: openaiStats.lastFailureTime?.toISOString(),
stats: openaiStats.stats,
config: openaiStats.config,
},
},
// 추후 확장 가능: API 호출 통계, 캐시 hit rate 등
metrics: {
api_calls: {
// 추후 구현: 실제 API 호출 통계
openai: { count: openaiStats.stats.totalRequests, avg_duration: 0 },
},
errors: {
// 추후 구현: 에러 통계
retry_exhausted: 0,
circuit_breaker_open: openaiStats.state === 'OPEN' ? 1 : 0,
},
cache: {
// 추후 구현: 캐시 hit rate
hit_rate: 0,
},
},
};
console.log('[Metrics API] Circuit breaker stats retrieved:', {
state: openaiStats.state,
failures: openaiStats.failures,
requests: openaiStats.stats.totalRequests,
});
return Response.json(metrics);
} catch (error) {
console.error('[Metrics API] Error:', error);
return Response.json({ error: String(error) }, { status: 500 });
}
}
return new Response('Not Found', { status: 404 });
}