/** * Diagnostics Page */ import { apiClient } from '../../shared/js/core/api-client.js'; class DiagnosticsPage { constructor() { this.isRunning = false; this.requestLog = []; } async init() { console.log('[Diagnostics] Initializing...'); this.bindEvents(); await this.loadHealthData(); await this.loadLogs(); this.startRequestTracking(); } bindEvents() { document.getElementById('health-refresh')?.addEventListener('click', () => { this.loadHealthData(); }); document.getElementById('logs-refresh')?.addEventListener('click', () => { this.loadLogs(); }); document.getElementById('logs-clear')?.addEventListener('click', () => { this.clearLogs(); }); document.getElementById('refresh-btn')?.addEventListener('click', () => { this.refreshAll(); }); document.getElementById('log-type')?.addEventListener('change', () => { this.loadLogs(); }); } /** Load system health data */ async loadHealthData() { const container = document.getElementById('health-grid'); if (!container) return; container.innerHTML = '
'; try { const response = await apiClient.fetch('/api/health'); const data = await response.json(); const services = [ { name: 'Backend Server', status: data.status === 'healthy' ? 'online' : 'offline', key: 'backend' }, { name: 'CoinMarketCap', status: data.sources?.coinmarketcap || 'unknown', key: 'coinmarketcap' }, { name: 'NewsAPI', status: data.sources?.newsapi || 'unknown', key: 'newsapi' }, { name: 'Etherscan', status: data.sources?.etherscan || 'unknown', key: 'etherscan' }, { name: 'BSCScan', status: data.sources?.bscscan || 'unknown', key: 'bscscan' }, { name: 'TronScan', status: data.sources?.tronscan || 'unknown', key: 'tronscan' } ]; container.innerHTML = services.map(service => `
${this.getStatusIcon(service.status)}

${service.name}

${service.status}
`).join(''); this.updateLastUpdate(); } catch (error) { console.error('Failed to load health data:', error); container.innerHTML = `

Failed to load health data: ${error.message}

`; } } /** Load system logs */ async loadLogs() { const container = document.getElementById('logs-container'); if (!container) return; const logType = document.getElementById('log-type')?.value || 'recent'; const endpoint = logType === 'errors' ? '/api/logs/errors' : '/api/logs/recent'; container.innerHTML = '
'; try { const response = await apiClient.fetch(endpoint); const data = await response.json(); const logs = data.logs || data.errors || []; if (logs.length === 0) { container.innerHTML = '

No logs found

'; return; } container.innerHTML = `
${logs.map(log => `
${log.timestamp ? new Date(log.timestamp).toLocaleTimeString() : 'N/A'} ${log.level || 'INFO'} ${log.message || log.msg || log.text || ''}
`).join('')}
`; } catch (error) { console.error('Failed to load logs:', error); container.innerHTML = `

Failed to load logs: ${error.message}

`; } } /** Clear logs */ async clearLogs() { const container = document.getElementById('logs-container'); if (!container) return; container.innerHTML = '

Logs cleared

'; } /** Track API requests */ startRequestTracking() { // Intercept apiClient requests const originalFetch = apiClient.fetch.bind(apiClient); apiClient.fetch = async (...args) => { const startTime = Date.now(); const url = args[0]; try { const response = await originalFetch(...args); const duration = Date.now() - startTime; this.logRequest({ time: new Date(), method: 'GET', endpoint: url, status: response.status, duration }); return response; } catch (error) { const duration = Date.now() - startTime; this.logRequest({ time: new Date(), method: 'GET', endpoint: url, status: 'ERROR', duration }); throw error; } }; } /** Log a request */ logRequest(request) { this.requestLog.unshift(request); if (this.requestLog.length > 50) { this.requestLog = this.requestLog.slice(0, 50); } this.updateRequestsTable(); } /** Update requests table */ updateRequestsTable() { const tbody = document.getElementById('requests-tbody'); if (!tbody) return; if (this.requestLog.length === 0) { tbody.innerHTML = 'No requests logged yet'; return; } tbody.innerHTML = this.requestLog.map(req => ` ${req.time.toLocaleTimeString()} ${req.method} ${req.endpoint} ${req.status} ${req.duration}ms `).join(''); } /** Refresh all sections */ async refreshAll() { await Promise.all([ this.loadHealthData(), this.loadLogs() ]); } /** Update last update timestamp */ updateLastUpdate() { const elem = document.getElementById('last-update'); if (elem) { elem.textContent = new Date().toLocaleTimeString(); } } /** Get status icon SVG */ getStatusIcon(status) { const normalized = status?.toLowerCase(); if (normalized === 'online' || normalized === 'healthy' || normalized === 'operational') { return ''; } else if (normalized === 'degraded' || normalized === 'warning') { return ''; } else { return ''; } } } const diagnosticsPage = new DiagnosticsPage(); diagnosticsPage.init();