/**
* 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();