UNPKG

@boundless-oss/atlas

Version:

Atlas - MCP Server for comprehensive startup project management

426 lines 16.5 kB
export function setupMetricsAPI(app, performanceMonitor, exportEnabled = true) { // Metrics API endpoints setup // System overview metrics app.get('/api/metrics/overview', async (req, res) => { try { const metrics = await performanceMonitor.getSystemMetrics(); res.json({ success: true, data: metrics, timestamp: new Date().toISOString() }); } catch (error) { console.error('📊 Error fetching system metrics:', error); res.status(500).json({ success: false, error: 'Failed to fetch system metrics', message: error.message }); } }); // Tool-specific metrics app.get('/api/metrics/tools', async (req, res) => { try { const { toolName, timeRange = '24h' } = req.query; if (toolName && typeof toolName === 'string') { // Get metrics for specific tool const metrics = await performanceMonitor.getToolMetrics(toolName); res.json({ success: true, data: { toolName, metrics, timeRange }, timestamp: new Date().toISOString() }); } else { // Get metrics for all tools const systemMetrics = performanceMonitor.getSystemMetrics(); // Build tool metrics from the available data const toolMetrics = {}; // Extract data from top performing tools systemMetrics.topPerformingTools.forEach(tool => { toolMetrics[tool.tool] = { calls: tool.calls, successRate: tool.successRate }; }); // Add data from slowest tools systemMetrics.slowestTools.forEach(tool => { if (!toolMetrics[tool.tool]) { toolMetrics[tool.tool] = {}; } toolMetrics[tool.tool].avgTime = tool.avgTime; toolMetrics[tool.tool].calls = tool.calls; }); // Add data from error-prone tools systemMetrics.mostErrorProneTools.forEach(tool => { if (!toolMetrics[tool.tool]) { toolMetrics[tool.tool] = {}; } toolMetrics[tool.tool].errorRate = tool.errorRate; toolMetrics[tool.tool].calls = tool.calls; }); res.json({ success: true, data: { tools: toolMetrics, systemMetrics, timeRange }, timestamp: new Date().toISOString() }); } } catch (error) { console.error('📊 Error fetching tool metrics:', error); res.status(500).json({ success: false, error: 'Failed to fetch tool metrics', message: error.message }); } }); // Performance trends over time app.get('/api/metrics/trends', async (req, res) => { try { const { timeRange = '7d', metric = 'performance' } = req.query; // This would need to be implemented in PerformanceMonitor // For now, return sample trend data const trends = { timeRange, metric, dataPoints: [ { timestamp: new Date(Date.now() - 6 * 24 * 60 * 60 * 1000).toISOString(), value: 95.2 }, { timestamp: new Date(Date.now() - 5 * 24 * 60 * 60 * 1000).toISOString(), value: 97.1 }, { timestamp: new Date(Date.now() - 4 * 24 * 60 * 60 * 1000).toISOString(), value: 94.8 }, { timestamp: new Date(Date.now() - 3 * 24 * 60 * 60 * 1000).toISOString(), value: 96.5 }, { timestamp: new Date(Date.now() - 2 * 24 * 60 * 60 * 1000).toISOString(), value: 98.2 }, { timestamp: new Date(Date.now() - 1 * 24 * 60 * 60 * 1000).toISOString(), value: 97.9 }, { timestamp: new Date().toISOString(), value: 96.8 } ] }; res.json({ success: true, data: trends, timestamp: new Date().toISOString() }); } catch (error) { console.error('📊 Error fetching performance trends:', error); res.status(500).json({ success: false, error: 'Failed to fetch performance trends', message: error.message }); } }); // Quality metrics app.get('/api/metrics/quality', async (req, res) => { try { const { toolName, timeRange = '7d' } = req.query; const qualityMetrics = await performanceMonitor.getQualityMetrics(typeof toolName === 'string' ? toolName : undefined); res.json({ success: true, data: { toolName: toolName || 'all', timeRange, qualityMetrics }, timestamp: new Date().toISOString() }); } catch (error) { console.error('📊 Error fetching quality metrics:', error); res.status(500).json({ success: false, error: 'Failed to fetch quality metrics', message: error.message }); } }); // Performance alerts app.get('/api/metrics/alerts', async (req, res) => { try { const alerts = await performanceMonitor.generateAlerts(); res.json({ success: true, data: { alerts, count: alerts.length }, timestamp: new Date().toISOString() }); } catch (error) { console.error('📊 Error fetching performance alerts:', error); res.status(500).json({ success: false, error: 'Failed to fetch performance alerts', message: error.message }); } }); // Record quality evaluation app.post('/api/metrics/quality/evaluate', async (req, res) => { try { const { toolName, quality, feedback, executionId } = req.body; if (!toolName || quality === undefined) { return res.status(400).json({ success: false, error: 'Missing required fields: toolName and quality are required' }); } if (quality < 1 || quality > 10) { return res.status(400).json({ success: false, error: 'Quality rating must be between 1 and 10' }); } performanceMonitor.recordQualityEvaluation({ toolName, outputQuality: quality, appropriatenessScore: quality, completenessScore: quality, accuracyScore: quality, comments: feedback, evaluationCriteria: ['user_feedback'] }); res.json({ success: true, message: 'Quality evaluation recorded successfully', data: { toolName, quality, feedback }, timestamp: new Date().toISOString() }); } catch (error) { console.error('📊 Error recording quality evaluation:', error); res.status(500).json({ success: false, error: 'Failed to record quality evaluation', message: error.message }); } }); // Export metrics data if (exportEnabled) { app.get('/api/metrics/export', async (req, res) => { try { const { format = 'csv', timeRange = '24h', includeQuality = 'true' } = req.query; const exportData = await performanceMonitor.exportMetrics(format); const exportPath = `.atlas/exports/metrics-${new Date().toISOString().split('T')[0]}.${format}`; // Save to file const fs = await import('fs/promises'); const path = await import('path'); await fs.mkdir(path.dirname(exportPath), { recursive: true }); await fs.writeFile(exportPath, typeof exportData === 'string' ? exportData : JSON.stringify(exportData)); res.json({ success: true, data: { exportPath, format, timeRange, includeQuality: includeQuality === 'true' }, message: 'Metrics exported successfully', timestamp: new Date().toISOString() }); } catch (error) { console.error('📊 Error exporting metrics:', error); res.status(500).json({ success: false, error: 'Failed to export metrics', message: error.message }); } }); app.get('/api/metrics/download/:filename', async (req, res) => { try { const { filename } = req.params; // Basic security check if (!filename.match(/^[a-zA-Z0-9_-]+\.(csv|json)$/)) { return res.status(400).json({ success: false, error: 'Invalid filename format' }); } // This would need to serve files from the export directory // For now, return a placeholder response res.json({ success: false, error: 'File download not implemented yet', message: 'Use the export endpoint to generate files' }); } catch (error) { console.error('📊 Error downloading metrics file:', error); res.status(500).json({ success: false, error: 'Failed to download metrics file', message: error.message }); } }); } // Record tool execution app.post('/api/metrics/record', async (req, res) => { try { const { tool, success, duration, metadata } = req.body; if (!tool || success === undefined) { return res.status(400).json({ success: false, error: 'Tool name and success status are required' }); } performanceMonitor.recordToolExecution(tool, duration || 0, success); res.json({ success: true, message: 'Tool execution recorded', data: { tool, success, duration }, timestamp: new Date().toISOString() }); } catch (error) { console.error('📊 Error recording tool execution:', error); res.status(500).json({ success: false, error: 'Failed to record tool execution', message: error.message }); } }); // Get module-specific metrics app.get('/api/metrics/modules', async (req, res) => { try { const { moduleName } = req.query; const moduleMetrics = await performanceMonitor.getModuleMetrics(typeof moduleName === 'string' ? moduleName : undefined); res.json({ success: true, data: moduleMetrics, timestamp: new Date().toISOString() }); } catch (error) { console.error('📊 Error fetching module metrics:', error); res.status(500).json({ success: false, error: 'Failed to fetch module metrics', message: error.message }); } }); // Analyze performance bottlenecks app.get('/api/metrics/bottlenecks', async (req, res) => { try { const options = { threshold: Number(req.query.threshold) || 500 }; const bottlenecks = await performanceMonitor.analyzeBottlenecks(options); res.json({ success: true, data: bottlenecks, timestamp: new Date().toISOString() }); } catch (error) { console.error('📊 Error analyzing bottlenecks:', error); res.status(500).json({ success: false, error: 'Failed to analyze bottlenecks', message: error.message }); } }); // Generate performance report app.get('/api/metrics/report', async (req, res) => { try { const options = { format: req.query.format || 'json', includeRecommendations: req.query.includeRecommendations === 'true' }; const report = await performanceMonitor.generatePerformanceReport(options); res.json({ success: true, data: report, timestamp: new Date().toISOString() }); } catch (error) { console.error('📊 Error generating performance report:', error); res.status(500).json({ success: false, error: 'Failed to generate performance report', message: error.message }); } }); // Clear metrics app.delete('/api/metrics/clear', async (req, res) => { try { const { confirm, before } = req.query; if (confirm !== 'yes') { return res.status(400).json({ success: false, error: 'Confirmation required to clear metrics' }); } const options = before ? { before: before } : undefined; await performanceMonitor.clearMetrics(options); res.json({ success: true, message: 'Metrics cleared successfully', timestamp: new Date().toISOString() }); } catch (error) { console.error('📊 Error clearing metrics:', error); res.status(500).json({ success: false, error: 'Failed to clear metrics', message: error.message }); } }); // Health check for metrics service app.get('/api/metrics/health', async (req, res) => { try { // Test if performance monitor is working const testMetrics = await performanceMonitor.getSystemMetrics(); res.json({ success: true, status: 'healthy', data: { metricsCollected: testMetrics ? true : false, exportEnabled, features: { systemMetrics: true, toolMetrics: true, qualityMetrics: true, alerts: true, export: exportEnabled } }, timestamp: new Date().toISOString() }); } catch (error) { console.error('📊 Metrics health check failed:', error); res.status(503).json({ success: false, status: 'unhealthy', error: 'Metrics service is not functioning properly', message: error.message, timestamp: new Date().toISOString() }); } }); } //# sourceMappingURL=metrics.js.map