Updated Logging System to Include Application Logs
This commit is contained in:
58
server/services/appLogs.js
Normal file
58
server/services/appLogs.js
Normal file
@@ -0,0 +1,58 @@
|
||||
const fs = require('fs');
|
||||
const { LOG_FILE } = require('../logger');
|
||||
|
||||
// Read the application/event log (JSON lines written by the Winston file transport) for the admin
|
||||
// Application Logs viewer. Reads the current log file, parses the most recent lines, and returns them
|
||||
// newest-first with optional category/level/search filtering plus the available filter facets.
|
||||
|
||||
const SCAN_LINES = 8000; // how many trailing lines to parse (the file is size-rotated, ~5MB)
|
||||
|
||||
function readLogs(filters = {}, limit = 500) {
|
||||
let lines = [];
|
||||
try {
|
||||
lines = fs.readFileSync(LOG_FILE, 'utf8').split('\n').filter(Boolean);
|
||||
} catch {
|
||||
return { logs: [], total: 0, categories: [], levels: [] };
|
||||
}
|
||||
|
||||
// Parse the trailing window, newest first.
|
||||
const parsed = [];
|
||||
for (let i = lines.length - 1, scanned = 0; i >= 0 && scanned < SCAN_LINES; i -= 1, scanned += 1) {
|
||||
try {
|
||||
const obj = JSON.parse(lines[i]);
|
||||
parsed.push({
|
||||
timestamp: obj.timestamp || null,
|
||||
level: obj.level || 'info',
|
||||
category: obj.category || 'system',
|
||||
message: obj.message || '',
|
||||
meta: stripMeta(obj)
|
||||
});
|
||||
} catch {
|
||||
// skip malformed lines
|
||||
}
|
||||
}
|
||||
|
||||
const categories = [...new Set(parsed.map((p) => p.category))].sort();
|
||||
const levels = [...new Set(parsed.map((p) => p.level))].sort();
|
||||
|
||||
let filtered = parsed;
|
||||
if (filters.category) filtered = filtered.filter((p) => p.category === filters.category);
|
||||
if (filters.level) filtered = filtered.filter((p) => p.level === filters.level);
|
||||
if (filters.q) {
|
||||
const needle = String(filters.q).toLowerCase();
|
||||
filtered = filtered.filter((p) => `${p.message} ${JSON.stringify(p.meta)}`.toLowerCase().includes(needle));
|
||||
}
|
||||
|
||||
return { logs: filtered.slice(0, Math.min(2000, Number(limit) || 500)), total: filtered.length, categories, levels };
|
||||
}
|
||||
|
||||
// Everything on a log line except the standard fields is "meta" (the structured detail).
|
||||
function stripMeta(obj) {
|
||||
const meta = {};
|
||||
for (const [key, value] of Object.entries(obj)) {
|
||||
if (!['timestamp', 'level', 'category', 'message'].includes(key)) meta[key] = value;
|
||||
}
|
||||
return meta;
|
||||
}
|
||||
|
||||
module.exports = { readLogs };
|
||||
Reference in New Issue
Block a user