mirror of
https://github.com/fabro-sh/fabro.git
synced 2026-09-14 23:22:51 +00:00
feat(web): colorize run logs by level and target
Parse each tracing line in the run logs panel and tint the timestamp, level, target, and message separately. Errors and warnings now stand out at a glance (coral/amber) while debug/trace and the surrounding chrome recede. Original whitespace is preserved so the formatter's column alignment is intact.
This commit is contained in:
parent
94447f9da2
commit
4beee7358b
1 changed files with 50 additions and 1 deletions
|
|
@ -57,6 +57,7 @@ function renderBody(logsQuery: ReturnType<typeof useRunLogs>) {
|
|||
|
||||
function LogPanel({ text }: { text: string }) {
|
||||
const byteCount = new Blob([text]).size;
|
||||
const lines = useMemo(() => text.split("\n"), [text]);
|
||||
return (
|
||||
<div className="rounded-md border border-line bg-panel-alt">
|
||||
<div className="flex items-center justify-between gap-3 border-b border-line px-3 py-2">
|
||||
|
|
@ -67,12 +68,60 @@ function LogPanel({ text }: { text: string }) {
|
|||
</div>
|
||||
</div>
|
||||
<pre className="max-h-[70vh] overflow-auto whitespace-pre p-4 font-mono text-xs leading-5 text-fg-2">
|
||||
{text}
|
||||
{lines.map((line, i) => (
|
||||
<LogLine key={i} line={line} trailingNewline={i < lines.length - 1} />
|
||||
))}
|
||||
</pre>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
const LOG_LINE_RE =
|
||||
/^(\S+)(\s+)(TRACE|DEBUG|INFO|WARN|ERROR)(\s+)(.*)$/;
|
||||
|
||||
const LEVEL_COLOR: Record<string, string> = {
|
||||
ERROR: "text-coral",
|
||||
WARN: "text-amber",
|
||||
INFO: "text-teal-500",
|
||||
DEBUG: "text-fg-3",
|
||||
TRACE: "text-fg-muted",
|
||||
};
|
||||
|
||||
function LogLine({ line, trailingNewline }: { line: string; trailingNewline: boolean }) {
|
||||
const newline = trailingNewline ? "\n" : "";
|
||||
const match = LOG_LINE_RE.exec(line);
|
||||
if (!match) {
|
||||
return <span>{line}{newline}</span>;
|
||||
}
|
||||
const [, timestamp, gap1, level, gap2, rest] = match;
|
||||
return (
|
||||
<span>
|
||||
<span className="text-fg-muted">{timestamp}</span>
|
||||
{gap1}
|
||||
<span className={`font-semibold ${LEVEL_COLOR[level] ?? "text-fg-2"}`}>{level}</span>
|
||||
{gap2}
|
||||
<LogRest text={rest} />
|
||||
{newline}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
const LOG_REST_RE = /^([a-zA-Z_][\w:]*):(\s+)(.*)$/;
|
||||
|
||||
function LogRest({ text }: { text: string }) {
|
||||
const match = LOG_REST_RE.exec(text);
|
||||
if (!match) return <>{text}</>;
|
||||
const [, target, gap, message] = match;
|
||||
return (
|
||||
<>
|
||||
<span className="text-fg-3">{target}</span>
|
||||
<span className="text-fg-muted">:</span>
|
||||
{gap}
|
||||
<span>{message}</span>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
function errorMessage(error: unknown): string | undefined {
|
||||
return error instanceof Error ? error.message : undefined;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue