160 lines
4.5 KiB
JavaScript
160 lines
4.5 KiB
JavaScript
/**
|
||
* Copyright (c) 2024-2026 Тарабанов Александр Викторович
|
||
* All rights reserved.
|
||
*
|
||
* This software is proprietary and confidential.
|
||
* Unauthorized copying, modification, or distribution is prohibited.
|
||
*
|
||
* For licensing inquiries: info@hb3-accelerator.com
|
||
* Website: https://hb3-accelerator.com
|
||
* GitHub: https://github.com/VC-HB3-Accelerator
|
||
*/
|
||
|
||
const express = require('express');
|
||
const router = express.Router();
|
||
const axios = require('axios');
|
||
const db = require('../db');
|
||
const aiAssistant = require('../services/ai-assistant');
|
||
const aiCache = require('../services/ai-cache');
|
||
const logger = require('../utils/logger');
|
||
const ollamaConfig = require('../services/ollamaConfig');
|
||
|
||
const TIMEOUTS = ollamaConfig.getTimeouts();
|
||
|
||
router.get('/', async (req, res) => {
|
||
const results = {};
|
||
|
||
// Backend
|
||
results.backend = { status: 'ok' };
|
||
|
||
// Vector Search
|
||
try {
|
||
const baseUrl = process.env.VECTOR_SEARCH_URL || 'http://vector-search:8001';
|
||
const healthUrl = baseUrl.replace(/\/$/, '') + '/health';
|
||
const vs = await axios.get(healthUrl, { timeout: TIMEOUTS.vectorHealth });
|
||
results.vectorSearch = { status: 'ok', ...vs.data };
|
||
} catch (e) {
|
||
console.log('Vector Search error:', e.message, 'Status:', e.response?.status);
|
||
results.vectorSearch = { status: 'error', error: e.message };
|
||
}
|
||
|
||
// Ollama
|
||
try {
|
||
const ollama = await axios.get(ollamaConfig.getApiUrl('tags'), { timeout: TIMEOUTS.ollamaHealth });
|
||
results.ollama = { status: 'ok', models: ollama.data.models?.length || 0 };
|
||
} catch (e) {
|
||
results.ollama = { status: 'error', error: e.message };
|
||
}
|
||
|
||
// PostgreSQL
|
||
try {
|
||
await db.query('SELECT 1');
|
||
results.postgres = { status: 'ok' };
|
||
} catch (e) {
|
||
results.postgres = { status: 'error', error: e.message };
|
||
}
|
||
|
||
// ✨ НОВОЕ: AI Cache статистика
|
||
try {
|
||
const ragService = require('../services/ragService');
|
||
const cacheStats = ragService.getCacheStats();
|
||
results.aiCache = {
|
||
status: 'ok',
|
||
size: cacheStats.size,
|
||
maxSize: cacheStats.maxSize,
|
||
hitRate: `${(cacheStats.hitRate * 100).toFixed(2)}%`,
|
||
byType: cacheStats.byType
|
||
};
|
||
} catch (e) {
|
||
results.aiCache = { status: 'error', error: e.message };
|
||
}
|
||
|
||
// ✨ НОВОЕ: AI Queue статистика
|
||
try {
|
||
const ragService = require('../services/ragService');
|
||
const queueStats = ragService.getQueueStats();
|
||
results.aiQueue = {
|
||
status: 'ok',
|
||
currentSize: queueStats.currentQueueSize,
|
||
totalProcessed: queueStats.totalProcessed,
|
||
totalFailed: queueStats.totalFailed,
|
||
avgResponseTime: `${Math.round(queueStats.averageProcessingTime)}ms`,
|
||
uptime: `${Math.round(queueStats.uptime / 1000)}s`
|
||
};
|
||
} catch (e) {
|
||
results.aiQueue = { status: 'error', error: e.message };
|
||
}
|
||
|
||
res.json({ status: 'ok', services: results, timestamp: new Date().toISOString() });
|
||
});
|
||
|
||
// GET /api/monitoring/ai-stats - статистика AI
|
||
router.get('/ai-stats', async (req, res) => {
|
||
try {
|
||
res.json({
|
||
status: 'ok',
|
||
timestamp: new Date().toISOString(),
|
||
ai: {
|
||
health: 'ok',
|
||
model: ollamaConfig.getDefaultModel(),
|
||
baseUrl: ollamaConfig.getBaseUrl()
|
||
},
|
||
cache: {
|
||
size: 0,
|
||
maxSize: 100,
|
||
hitRate: 0
|
||
},
|
||
queue: {
|
||
totalAdded: 0,
|
||
totalProcessed: 0,
|
||
totalFailed: 0,
|
||
averageProcessingTime: 0,
|
||
currentQueueSize: 0,
|
||
lastProcessedAt: null,
|
||
uptime: 0
|
||
}
|
||
});
|
||
} catch (error) {
|
||
logger.error('Error getting AI stats:', error);
|
||
res.status(500).json({
|
||
status: 'error',
|
||
error: error.message
|
||
});
|
||
}
|
||
});
|
||
|
||
// POST /api/monitoring/ai-cache/clear - очистка кэша
|
||
router.post('/ai-cache/clear', async (req, res) => {
|
||
try {
|
||
aiCache.clear();
|
||
res.json({
|
||
status: 'ok',
|
||
message: 'AI cache cleared successfully'
|
||
});
|
||
} catch (error) {
|
||
logger.error('Error clearing AI cache:', error);
|
||
res.status(500).json({
|
||
status: 'error',
|
||
error: error.message
|
||
});
|
||
}
|
||
});
|
||
|
||
// POST /api/monitoring/ai-queue/clear - очистка очереди
|
||
router.post('/ai-queue/clear', async (req, res) => {
|
||
try {
|
||
aiAssistant.aiQueue.clearQueue();
|
||
res.json({
|
||
status: 'ok',
|
||
message: 'AI queue cleared successfully'
|
||
});
|
||
} catch (error) {
|
||
logger.error('Error clearing AI queue:', error);
|
||
res.status(500).json({
|
||
status: 'error',
|
||
error: error.message
|
||
});
|
||
}
|
||
});
|
||
|
||
module.exports = router;
|