read format

This commit is contained in:
2026-04-29 09:43:59 +07:00
parent 15d9bf18c3
commit c5e8dca8ac

View File

@@ -31,7 +31,7 @@
--text3: #555966;
--accent: #4f8ef7;
--accent-dim: #4f8ef720;
--trace: #818594;
--trace: #808080;
--debug: #555966;
--info: #4f8ef7;
--warn: #f5a623;
@@ -841,8 +841,8 @@
}
// ---- Log parsing ----
function parseLogs(text) {
const lines = text.split('\n').filter(l => l.trim());
function parseLogs(text, filedate = null) {
const lines = text.split(/\r?\n/).filter(l => l.trim());
const logs = [];
// Try JSON Lines
@@ -859,9 +859,12 @@ function parseLogs(text) {
/^(\w{3}\s+\d{1,2}\s+\d{2}:\d{2}:\d{2})\s+(DEBUG|INFO|WARN(?:ING)?|ERROR|FATAL)\s+(.+)$/i,
// INFO 2024-01-15 10:23:45 message
/^(DEBUG|INFO|WARN(?:ING)?|ERROR|FATAL)\s+(\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}:\d{2}(?:\.\d+)?)\s+(.+)$/i,
// 10:23:43.333 [INF] message
/^(\d{2}:\d{2}:\d{2}\.\d{3})\s\[(INF|WRN|ERR|CRT|DBG|TRC)\]\s(.*)$/
];
let i = 0;
debugger
while (i < lines.length) {
const line = lines[i].trim();
let matched = false;
@@ -875,7 +878,17 @@ function parseLogs(text) {
} else {
timeStr = g1; levelStr = g2.toUpperCase().replace('WARNING', 'WARN'); msg = g3;
}
const time = new Date(timeStr);
levelStr = translateLogLevel(levelStr)
let time
if (filedate === null) {
time = new Date(timeStr)
}
else {
const [hours, mins, secs, ms] = timeStr.split(/[:.]/).map(Number);
let temp_date = filedate.setHours(hours, mins, secs, ms)
time = new Date(filedate)
}
if (!isNaN(time)) {
// Collect continuation lines (stack traces etc.)
let exception = '';
@@ -937,7 +950,7 @@ function parseLogs(text) {
const buckets = Array.from({ length: BUCKETS }, (_, i) => ({
t: new Date(minT + i * bucketSize),
DEBUG: 0, INFO: 0, WARN: 0, ERROR: 0, FATAL: 0, total: 0
TRACE: 0, DEBUG: 0, INFO: 0, WARN: 0, ERROR: 0, FATAL: 0, total: 0
}));
for (const log of logs) {
@@ -950,14 +963,14 @@ function parseLogs(text) {
if (chart) chart.destroy();
const colorMap = {
DEBUG: '#55596640', INFO: '#4f8ef760', WARN: '#f5a62370', ERROR: '#e8504a80', FATAL: '#c72b2b90'
TRACE: '#80808080', DEBUG: '#55596640', INFO: '#4f8ef760', WARN: '#f5a62370', ERROR: '#e8504a80', FATAL: '#c72b2b90'
};
chart = new Chart(canvas, {
type: 'bar',
data: {
labels: buckets.map(b => b.t),
datasets: ['FATAL', 'ERROR', 'WARN', 'INFO', 'DEBUG'].map(level => ({
datasets: ['FATAL', 'ERROR', 'WARN', 'INFO', 'DEBUG', 'TRACE'].map(level => ({
label: level,
data: buckets.map(b => b[level]),
backgroundColor: colorMap[level],
@@ -1161,12 +1174,54 @@ function parseLogs(text) {
const reader = new FileReader();
reader.onload = e => {
const text = e.target.result;
allLogs = parseLogs(text);
var date = parseDateFromFilename(file.name);
allLogs = parseLogs(text, date);
if (!allLogs.length) { allLogs = generateDemoLogs(); }
initView(file.name);
};
reader.readAsText(file);
}
function parseDateFromFilename(filename) {
const formats = [
{ regex: /(\d{4})[-_](\d{2})[-_](\d{2})/, map: (m) => `${m[1]}-${m[2]}-${m[3]}` }, // YYYY-MM-DD
{ regex: /(\d{2})[-_](\d{2})[-_](\d{4})/, map: (m) => `${m[3]}-${m[2]}-${m[1]}` }, // DD-MM-YYYY
{ regex: /(\d{4})(\d{2})(\d{2})/, map: (m) => `${m[1]}-${m[2]}-${m[3]}` } // YYYYMMDD
];
for (const { regex, map } of formats) {
const match = filename.match(regex);
if (match) {
const isoString = map(match);
const date = new Date(isoString);
if (!isNaN(date.getTime())) return date;
}
}
return null;
}
function translateLogLevel(level) {
//DEBUG: 0, INFO: 0, WARN: 0, ERROR: 0, FATAL: 0, total: 0
// Normalize input to handle lowercase or uppercase variations
switch (level.toLowerCase()) {
case 'trc':
return "TRACE";
case 'dbg':
return "DEBUG";
case 'inf':
return "INFO";
case 'wrn':
case 'warning': // Multiple cases can map to the same result
return "WARN";
case 'error':
return "ERROR";
case 'fatal':
case 'crt':
return "FATAL";
default:
return level; // Unknown level
}
}
function loadDemo() {
allLogs = generateDemoLogs();