tambahannya

This commit is contained in:
bipproduction
2025-10-22 15:50:05 +08:00
parent f0544b2364
commit 9d0f3bc5a3

View File

@@ -1,4 +1,4 @@
import Elysia from "elysia"; import Elysia, { t } from "elysia";
import fs from "fs/promises"; import fs from "fs/promises";
import path from "path"; import path from "path";
@@ -6,71 +6,92 @@ const LOGS_PATH = process.env.APP_LOGS_PATH || "./.logs";
// Pastikan folder log ada saat startup // Pastikan folder log ada saat startup
(async () => { (async () => {
try { try {
await fs.access(LOGS_PATH); await fs.access(LOGS_PATH);
} catch { } catch {
await fs.mkdir(LOGS_PATH, { recursive: true }); await fs.mkdir(LOGS_PATH, { recursive: true });
} }
})(); })();
// Helper baca log file + optional filter // Helper baca log file + optional filter
async function readLogs(limit?: number, level?: string) { async function readLogs(limit?: number, level?: string) {
const filePath = path.join(LOGS_PATH, "app.log"); const filePath = path.join(LOGS_PATH, "app.log");
try { try {
const data = await fs.readFile(filePath, "utf-8"); const data = await fs.readFile(filePath, "utf-8");
let lines = data.trim().split("\n").filter(Boolean); // tiap baris = JSON log let lines = data.trim().split("\n").filter(Boolean); // tiap baris = JSON log
if (limit) { if (limit) {
lines = lines.slice(-limit); lines = lines.slice(-limit);
}
let parsed = lines.map((line) => {
try {
return JSON.parse(line);
} catch {
return { raw: line };
}
});
// Filter berdasarkan level (error, info, debug, warn)
if (level) {
parsed = parsed.filter((log) =>
log.level ? String(log.level) === level || log.level === level : false
);
}
return parsed;
} catch {
return null;
} }
let parsed = lines.map((line) => {
try {
return JSON.parse(line);
} catch {
return { raw: line };
}
});
// Filter berdasarkan level (error, info, debug, warn)
if (level) {
parsed = parsed.filter((log) =>
log.level ? String(log.level) === level || log.level === level : false
);
}
return parsed;
} catch {
return null;
}
} }
const LogsRoute = new Elysia({ const LogsRoute = new Elysia({
prefix: "/logs", prefix: "/logs",
tags: ["logs"], tags: ["logs"],
}) })
/** /**
* GET /logs/app?lines=100&level=error * GET /logs/app?lines=100&level=error
*/ */
.get("/app", async ({ query }) => { .get("/show", async ({ query }) => {
const lines = query.lines ? Number(query.lines) : undefined; const lines = query.lines ? Number(query.lines) : undefined;
const level = query.level || undefined; const level = query.level || undefined;
const logs = await readLogs(lines, level); const logs = await readLogs(lines, level);
if (!logs) { if (!logs) {
return { return {
success: false, success: false,
message: "Log file not found or unreadable", message: "Log file not found or unreadable",
}; };
} }
return { return {
success: true, success: true,
total: logs.length, total: logs.length,
data: logs, data: logs,
}; };
}); }, {
query: t.Object({
lines: t.Optional(t.Number()),
level: t.Optional(t.String()),
}),
detail: {
summary: "Get logs",
description: "Get logs from app.log",
}
})
.post("/clear", async () => {
await fs.rm(path.join(LOGS_PATH, "app.log"));
return {
success: true,
message: "Log file cleared",
};
}, {
detail: {
summary: "Clear logs",
description: "Clear logs from app.log",
}
});
export default LogsRoute; export default LogsRoute;