Simplify the log grouping logic

This commit is contained in:
Pierre committed 2026-10-04 14:29:14 +02:00
1 parent f57e23d76a
commit 3aa0120e3d
10 files changed
+82 -84

No files matched your search

+1 -28
View File
@@ -223,14 +223,7 @@ export class LogExplorer implements vscode.Disposable {
}
private publish() {
const publication = ++this.publication;
const entries = [...this.entries.values()].sort((a, b) => {
const time = a.time - b.time;
if (time) { return time; }
// Include raw app.log() lines written in the same second as initialization markers.
const priority = (entry: LogEntry) => /Initialization (?:started|completed|failed)/.test(entry.message)
? (entry.message.includes('started') ? -1 : 1) : 0;
return priority(a) - priority(b);
});
const entries = [...this.entries.values()].sort((a, b) => a.time - b.time);
// Legacy errors duplicated across main/error logs are merged only on exact match.
const seen = new Set<string>();
const unique = entries.filter(e => {
@@ -238,26 +231,6 @@ export class LogExplorer implements vscode.Disposable {
if (seen.has(key)) { return false; } seen.add(key); return true;
});
this.onErrorCountChanged?.(unique.filter(e => (e.kind === 'log' || e.kind.startsWith('initialization_')) && (e.level === 'ERROR' || e.level === 'CRITICAL')).length);
// Direct app.log() calls have no LoggerInterface tag. Infer their initialization
// group while an explicit per-app initialize() scope is open.
const activeInitialization = new Map<string, string>();
for (const entry of unique) {
const marker = entry.message.match(/Initialization (started|completed|failed) \[group=initialization:([a-f0-9]{12})\]/i);
if (marker?.[1] === 'started') { activeInitialization.set(entry.app, marker[2]); }
const activeId = activeInitialization.get(entry.app);
if (activeId && !entry.group_id) {
entry.group_id = activeId;
entry.group_kind = 'initialization';
entry.initialization_id = activeId;
entry.phase = 'initialization';
entry.group_inferred = true;
}
if (entry.group_kind === 'initialization') {
entry.initialization_id = entry.initialization_id || entry.group_id;
entry.phase = 'initialization';
}
if (marker && (marker[1] === 'completed' || marker[1] === 'failed')) { activeInitialization.delete(entry.app); }
}
const zone = vscode.workspace.getConfiguration('appdaemon').get<string>('logTimezone', 'Europe/Berlin');
this.activeWebview?.postMessage({ type: 'entries', entries: unique, warnings: [...this.warnings], limit: 10000, timezone: zone });
void this.resolveSources(unique, publication);
+5 -7
View File
@@ -3,8 +3,8 @@ export interface LogEntry {
kind: string; cause_ids: string[]; probable_cause_ids?: string[];
entity?: string; values?: Record<string, unknown>;
source?: { path: string; line: number };
initialization_id?: string; phase?: string; status?: string;
group_id?: string; group_kind?: string; group_inferred?: boolean;
status?: string;
group_id?: string; group_kind?: string;
file?: string; raw?: string; time: number; trace_id?: string;
[key: string]: unknown;
}
@@ -38,12 +38,10 @@ export function parseLine(line: string, file: string, offset: number, zone = 'Eu
}
const m = line.match(/^(\d{2}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}(?:\.\d+)?)\s+(DEBUG|INFO|WARNING|ERROR|CRITICAL)\s+([^:]+):\s?(.*)$/);
if (!m) { return undefined; }
const init = m[4].match(/\[init=([\w-]+)\]/);
const group = m[4].match(/\[group=(initialization|smartcondition|value_selector):([a-f0-9]{12})\]/i);
const group = m[4].match(/\[group=([^\]\r\n]+):([a-f0-9]{12})\]/i);
const id = m[4].match(/\[event=([\w-]+) trace=([\w-]+)\]/);
const groupKind = group?.[1]?.toLowerCase();
const initializationId = groupKind === 'initialization' ? group?.[2] : init?.[1];
return { event_id: id?.[1] || `${file}:${offset}`, trace_id: id?.[2], initialization_id: initializationId, phase: initializationId ? 'initialization' : undefined, group_id: group?.[2], group_kind: groupKind, timestamp: m[1], time: rawTime(m[1], zone), app: m[3].trim(), level: m[2], message: m[4], kind: 'log', cause_ids: [], file, raw: line };
const groupKind = group?.[1]?.trim();
return { event_id: id?.[1] || `${file}:${offset}`, trace_id: id?.[2], group_id: group?.[2], group_kind: groupKind, timestamp: m[1], time: rawTime(m[1], zone), app: m[3].trim(), level: m[2], message: m[4], kind: 'log', cause_ids: [], file, raw: line };
}
/** Preserve valid UTF-8 spans, including files containing mixed legacy bytes. */