feat: replace mock dashboard data with live telemetry

This commit is contained in:
syntaxbullet
2026-01-07 13:47:02 +01:00
parent a2cb684b71
commit 259b8d6875
4 changed files with 145 additions and 24 deletions

38
src/lib/logger.test.ts Normal file
View File

@@ -0,0 +1,38 @@
import { describe, it, expect, beforeEach } from "bun:test";
import { logger, getRecentLogs } from "./logger";
describe("Logger Buffer", () => {
// Note: Since the buffer is a module-level variable, it persists across tests.
// In a real scenario we might want a reset function, but for now we'll just check relative additions.
it("should add logs to the buffer", () => {
const initialLength = getRecentLogs().length;
logger.info("Test Info Log");
const newLogs = getRecentLogs();
expect(newLogs.length).toBe(initialLength + 1);
expect(newLogs[0]?.message).toBe("Test Info Log");
expect(newLogs[0]?.type).toBe("info");
});
it("should cap the buffer size at 50", () => {
// Fill the buffer
for (let i = 0; i < 60; i++) {
logger.debug(`Log overflow test ${i}`);
}
const logs = getRecentLogs();
expect(logs.length).toBeLessThanOrEqual(50);
expect(logs[0]?.message).toBe("Log overflow test 59");
});
it("should handle different log levels", () => {
logger.error("Critical Error");
logger.success("Operation Successful");
const logs = getRecentLogs();
expect(logs[0]?.type).toBe("success");
expect(logs[1]?.type).toBe("error");
});
});

View File

@@ -3,12 +3,29 @@ import { WebServer } from "@/web/server";
/**
* Centralized logging utility with consistent formatting
*/
const LOG_BUFFER_SIZE = 50;
const logBuffer: Array<{ time: string; type: string; message: string }> = [];
function addToBuffer(type: string, message: string) {
const time = new Date().toLocaleTimeString();
logBuffer.unshift({ time, type, message });
if (logBuffer.length > LOG_BUFFER_SIZE) {
logBuffer.pop();
}
}
export function getRecentLogs() {
return logBuffer;
}
export const logger = {
/**
* General information message
*/
info: (message: string, ...args: any[]) => {
console.log(` ${message}`, ...args);
addToBuffer("info", message);
try { WebServer.broadcastLog("info", message); } catch { }
},
@@ -17,6 +34,7 @@ export const logger = {
*/
success: (message: string, ...args: any[]) => {
console.log(`${message}`, ...args);
addToBuffer("success", message);
try { WebServer.broadcastLog("success", message); } catch { }
},
@@ -25,6 +43,7 @@ export const logger = {
*/
warn: (message: string, ...args: any[]) => {
console.warn(`⚠️ ${message}`, ...args);
addToBuffer("warning", message);
try { WebServer.broadcastLog("warning", message); } catch { }
},
@@ -33,6 +52,7 @@ export const logger = {
*/
error: (message: string, ...args: any[]) => {
console.error(`${message}`, ...args);
addToBuffer("error", message);
try { WebServer.broadcastLog("error", message); } catch { }
},
@@ -41,6 +61,7 @@ export const logger = {
*/
debug: (message: string, ...args: any[]) => {
console.log(`🔍 ${message}`, ...args);
addToBuffer("debug", message);
try { WebServer.broadcastLog("debug", message); } catch { }
},
};

View File

@@ -1,20 +1,23 @@
import { BaseLayout } from "../views/layout";
import { AuroraClient } from "@/lib/BotClient";
import { getRecentLogs } from "@/lib/logger";
export function dashboardRoute(): Response {
// Gather real data where possible, mock where not
// Gather real data
const guildCount = AuroraClient.guilds.cache.size;
const userCount = AuroraClient.guilds.cache.reduce((acc, guild) => acc + guild.memberCount, 0); // Approximation
const userCount = AuroraClient.guilds.cache.reduce((acc, guild) => acc + guild.memberCount, 0);
const commandCount = AuroraClient.commands.size;
const ping = AuroraClient.ws.ping;
// In a real app, these would be dynamic charts or lists
const mockedActivity = [
{ time: "10:42:01", type: "info", message: "User 'Syntax' ran /profile" },
{ time: "10:41:55", type: "success", message: "Task 'HourlyCleanup' completed" },
{ time: "10:40:12", type: "warning", message: "API Latency spike detected (150ms)" },
{ time: "10:39:00", type: "info", message: "Bot connected to Gateway" },
];
// Real system metrics
const memoryUsage = (process.memoryUsage().heapUsed / 1024 / 1024).toFixed(2);
const uptimeSeconds = process.uptime();
const uptime = new Date(uptimeSeconds * 1000).toISOString().substr(11, 8); // HH:MM:SS
// Real activity logs
const activityLogs = getRecentLogs();
const content = `
<div class="dashboard-grid">
@@ -44,31 +47,38 @@ export function dashboardRoute(): Response {
<span class="badge live">LIVE</span>
</div>
<ul class="activity-feed">
${mockedActivity.map(log => `
${activityLogs.length > 0 ? activityLogs.map(log => `
<li class="activity-item ${log.type}">
<span class="time">${log.time}</span>
<span class="message">${log.message}</span>
</li>
`).join('')}
<li class="activity-item info"><span class="time">--:--:--</span> <span class="message">Waiting for events...</span></li>
`).join('') : `
<li class="activity-item info"><span class="time">--:--:--</span> <span class="message">No recent activity.</span></li>
`}
</ul>
</div>
<div class="panel metrics-panel">
<div class="panel-header">
<h2>System Metrics</h2>
<h2>System Health</h2>
</div>
<div class="mock-chart-container">
<div class="mock-chart-bar" style="height: 40%"></div>
<div class="mock-chart-bar" style="height: 60%"></div>
<div class="mock-chart-bar" style="height: 30%"></div>
<div class="mock-chart-bar" style="height: 80%"></div>
<div class="mock-chart-bar" style="height: 50%"></div>
<div class="mock-chart-bar" style="height: 90%"></div>
<div class="mock-chart-bar" style="height: 45%"></div>
</div>
<div class="metrics-legend">
<span>CPU Load (Mock)</span>
<div class="metrics-grid">
<div class="metric-item">
<span class="metric-label">Uptime</span>
<span class="metric-value">${uptime}</span>
</div>
<div class="metric-item">
<span class="metric-label">Memory (Heap)</span>
<span class="metric-value">${memoryUsage} MB</span>
</div>
<div class="metric-item">
<span class="metric-label">Node Version</span>
<span class="metric-value">${process.version}</span>
</div>
<div class="metric-item">
<span class="metric-label">Platform</span>
<span class="metric-value">${process.platform}</span>
</div>
</div>
</div>
</div>