Log viewer

Shows a run's or an eval's output line by line as it streams, with levels, search and follow.

Examples

A finished run with one failure

Log for run_01J9ZKQX8M2V4E7Q9 lines1 failed
1 failed line

Streaming

Log for run_01J9ZKQX8M2V4E7Q3 linesStreaming

Bare, for a small panel

Chrome

  • Full5 lines

    fulldefault

  • bare

States

  • Empty0 lines

    No output.

    empty

  • Waiting0 linesStreaming

    Waiting for the first line.

    waiting

  • Streaming3 linesStreaming

    streaming

  • Failed4 lines1 failed
    1 failed line

    failed

Usage

When to use it
Use
A run, deploy or eval writes lines the person reads while it works or after it fails.
Use
A log can reach thousands of lines and needs filtering by level and text.
Not for
The output is one block of code or a command. Use Code block.
Not for
The output is structured data. Use JSON view.
Not for
The steps are a handful with durations. Use Timeline.

Rules

8 rules
Must
Give every line a stable id that never changes or repeats; do not use the array index when lines are removed or reordered. Because rows are windowed and measured by id, so a reused id shows the wrong height and the wrong text after a filter.
Must
Set level to debug, info, warn or fail; leave it out for info. Because only warn and fail take color, through the row wash and the level word, and the level cells count by these four.
Must
Pass streaming while lines still arrive and drop it when the run ends. Because it shows "Streaming" with a running arc and says "Waiting for the first line" instead of "No output" while empty.
Must
Pass label as a noun phrase that names the log: "Deploy log for api@v314". Because it is the header title and the accessible name of the log region, and the default "Logs" cannot tell two logs apart.
Should
Set a fixed height that fits its place; the log scrolls inside it. Because rows are windowed, so the box needs a fixed height to know how many to render.
Should
Pass kind for the thing the log belongs to: run for an eval, agent for an agent. Because the hue names what the log is about without coloring the lines.
Never
Send lines with a live key, token or customer card number. Because every line is searchable, copyable and kept in the page, and Copy lines puts the whole log on the clipboard.
Never
Underline resource IDs inside lines; the viewer turns that off on purpose. Because in a log the most repeated ID would get the loudest mark, which is noise.

State order

2 states, highest first
1
streaming
2
failed

Accessibility

6 checks
The body is role="log" with aria-live="off" and one tab stop, named by label, so a streaming log does not read every line.
A polite status region announces the number of failed lines when it changes.
Level is a word on every row, so color is never the only signal; fail and warn add a wash and a colored word.
The level cells are toggle buttons with aria-pressed; the wrap toggle is named "Wrap lines".
Next failure is named with its count; the jump button names how many lines are new and how many failed.
The log stays left to right inside a right-to-left page.

Keyboard

3 keys
Tab
Moves through filter, levels, wrap, then the log body as one stop.
Escape in the filter
Clears the filter text.
Arrow keys, Page Up, Page Down
Scroll the focused log body.

Edge cases

10 edge cases
No lines, streaming
Says "Waiting for the first line."
No lines, finished
Says "No output."
Filter matches nothing
Says "No lines match" with the text in a code tag, or "No lines at these levels."
Scrolled up while lines arrive
Following stops; a button counts the new lines and the failed ones, "38 new, 2 fail".
100,000 lines
Only the rows on screen render; each is measured as it appears.
Failure 40,000 lines up
Next failure walks the fail lines in order and centers each.
Hand selection
Copies one line per row, with the time, level and source joined by spaces.
Narrow box
The filter takes its own row under 448px, level counts show from 576px and the time column hides below 640px.
Offscreen while streaming
The running arc pauses when the frame leaves the viewport.
Zoom 200%
Rows re-measure and grow with the text.

API

10 props
lines
LogLine[] default required
streaming
boolean default false
follow
boolean default true
label
string default 'Logs'
height
number default 360
header
boolean default true
toolbar
boolean default false
timestamps
boolean default true
wrap
boolean default true
kind
'agent' | 'key' | 'run' | 'deploy' | 'model'

Tokens

16 tokens
--log-level
5ch
--code-text
var(--ink)
--code-comment
oklch(var(--ink-c) / var(--code-comment-alpha))
--accent-wash
var(--surface-selected)
--fail-text
oklch(51% 0.180 26)
--warn-text
oklch(49% 0.100 68)
--surface-page
var(--paper)
--surface-hover
oklch(var(--ink-c) / 0.05)
--surface-pressed
oklch(var(--ink-c) / 0.08)
--surface-inverse
var(--ink)
--text-inverse
var(--paper)
--line-frame
oklch(var(--ink-c) / var(--line-frame-alpha))
--line-row
oklch(var(--ink-c) / 0.08)
--elev-overlay
0 0 0 1px var(--line-frame), 0 12px 24px -12px oklch(var(--text-on-field-c) / var(--shadow-alpha))
--type-code
400 13px/20px var(--font-mono)
--type-label-sm
400 12px/16px var(--font-sans)

Install

For your coding agent

GitHub

Please star me pookie

141

A new design system every week

Leave your email before you copy the prompt.