diff --git a/src/lib/logger.test.ts b/src/lib/logger.test.ts new file mode 100644 index 0000000..6183666 --- /dev/null +++ b/src/lib/logger.test.ts @@ -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"); + }); +}); diff --git a/src/lib/logger.ts b/src/lib/logger.ts index a673676..998abb3 100644 --- a/src/lib/logger.ts +++ b/src/lib/logger.ts @@ -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 { } }, }; diff --git a/src/web/routes/dashboard.ts b/src/web/routes/dashboard.ts index 0b89714..e7141e8 100644 --- a/src/web/routes/dashboard.ts +++ b/src/web/routes/dashboard.ts @@ -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 = `