// Logs Page Module
class LogsPage {
constructor() {
this.logs = [];
this.init();
}
async init() {
await this.loadLogs();
this.setupEventListeners();
}
async loadLogs() {
const tableBody = document.querySelector('#logs-table tbody');
if (tableBody) tableBody.innerHTML = '
| Loading logs... |
';
try {
const data = await window.api.get('/system/logs');
this.logs = data;
this.renderLogs();
} catch (error) {
console.error('Error loading logs:', error);
window.authManager.showToast('Failed to load system logs', 'error');
}
}
renderLogs() {
const tableBody = document.querySelector('#logs-table tbody');
if (!tableBody) return;
if (this.logs.length === 0) {
tableBody.innerHTML = '| No logs found |
';
return;
}
tableBody.innerHTML = this.logs.map(log => {
const statusClass = log.status === 'success' ? 'success' : 'danger';
const timestamp = luxon.DateTime.fromISO(log.timestamp).toFormat('yyyy-MM-dd HH:mm:ss');
return `
| ${timestamp} |
${log.status.toUpperCase()}
|
${log.client_id}
${log.provider}
|
${log.model}
${log.tokens} tokens
${log.duration}ms
${log.error ? ` ${log.error} ` : ''}
|
`;
}).join('');
}
setupEventListeners() {
const refreshBtn = document.getElementById('refresh-btn');
if (refreshBtn) {
// Already handled by dashboard.js but we can add more specific logic if needed
}
const logFilter = document.getElementById('log-filter');
if (logFilter) {
logFilter.onchange = () => this.filterLogs();
}
const logSearch = document.getElementById('log-search');
if (logSearch) {
logSearch.oninput = (e) => this.searchLogs(e.target.value);
}
}
filterLogs() {
const filter = document.getElementById('log-filter').value;
if (filter === 'all') {
this.renderLogs();
return;
}
const filtered = this.logs.filter(log => log.status === (filter === 'error' ? 'error' : 'success'));
this.renderFilteredLogs(filtered);
}
searchLogs(query) {
if (!query) {
this.renderLogs();
return;
}
const q = query.toLowerCase();
const filtered = this.logs.filter(log =>
log.client_id.toLowerCase().includes(q) ||
log.model.toLowerCase().includes(q) ||
log.provider.toLowerCase().includes(q) ||
(log.error && log.error.toLowerCase().includes(q))
);
this.renderFilteredLogs(filtered);
}
renderFilteredLogs(filteredLogs) {
// reuse same rendering logic or similar
const originalLogs = this.logs;
this.logs = filteredLogs;
this.renderLogs();
this.logs = originalLogs;
}
}
window.initLogs = async () => {
window.logsPage = new LogsPage();
};