Logs
tier 2 — classes
A line-of-business app's own log, read in place: a deploy being watched, the entries behind a
failed order, an audit trail. It is the .output pane
from Live states, with columns, highlighting, rows that expand and rows that act. The app
filters, searches and pages the lines; the pane shows the ones it renders.
Live tail
A data-follow pane sticks to the newest line and lets go when the reader scrolls
up. Scroll this one up: Sedna.UI.js marks the pane data-follow-paused and the
.output-jump button appears over its foot; data-output-follow on
the button follows again. .output-panel holds the head, the pane and the
button. Pausing is the app's: render the pane without
data-follow and it stops following, render it with the attribute again and it
jumps to the newest line. The pane also fires a bubbling sedna-follow event
with detail.following, for an app that counts the lines not yet seen.
- 14:02:11 checking out release 2026.09.3
- 14:02:12 restoring packages for 6 projects
- 14:02:19 restored in 7.1s
- 14:02:19 building Orders.Api (Release)
- 14:02:31 building Orders.Worker (Release)
- 14:02:34 warning: 'Retry.Legacy' is obsolete, use 'Retry.WithBackoff'
- 14:02:40 building Orders.Console (Release)
- 14:02:52 build succeeded, 1 warning
- 14:02:52 running 1,284 tests
- 14:03:37 tests passed: 1,284, skipped: 3
- 14:03:38 publishing image orders-api:2026.09.3
- 14:03:55 pushed 4 layers, 212 MB
- 14:03:56 draining orders-console-01
- 14:04:09 orders-console-01 drained, 0 open sessions
- 14:04:10 starting orders-console-01 on 2026.09.3
- 14:04:25 health check failed: 192.0.2.41:8080 returned 503
- 14:04:25 retrying health check in 5s (attempt 2 of 5)
- 14:04:31 orders-console-01 healthy
- 14:04:31 draining orders-console-02
- 14:04:44 orders-console-02 drained, 0 open sessions
- 14:04:45 starting orders-console-02 on 2026.09.3
- 14:04:58 orders-console-02 healthy
- 14:04:58 switching traffic to 2026.09.3
- 14:05:02 waiting for the next batch…
<div class="output-panel" style="max-width:720px">
<div class="output-head">
<span class="health-badge health-badge--streaming"><span class="health-dot"></span> Streaming</span>
<span>build-runner-04</span>
<button class="btn btn-sm btn-ghost sedna-push" type="button" aria-pressed="false"><i class="ri-pause-line"></i> Pause</button>
</div>
<ul class="output" id="tail-pane" data-follow tabindex="0" aria-label="Deploy output">
<li class="output-line"><span class="output-time">14:02:11</span> checking out release 2026.09.3</li>
<li class="output-line"><span class="output-time">14:02:12</span> restoring packages for 6 projects</li>
<li class="output-line"><span class="output-time">14:02:19</span> restored in 7.1s</li>
<li class="output-line"><span class="output-time">14:02:19</span> building Orders.Api (Release)</li>
<li class="output-line"><span class="output-time">14:02:31</span> building Orders.Worker (Release)</li>
<li class="output-line output-line--warn"><span class="output-time">14:02:34</span> warning: 'Retry.Legacy' is obsolete, use 'Retry.WithBackoff'</li>
<li class="output-line"><span class="output-time">14:02:40</span> building Orders.Console (Release)</li>
<li class="output-line output-line--go"><span class="output-time">14:02:52</span> build succeeded, 1 warning</li>
<li class="output-line"><span class="output-time">14:02:52</span> running 1,284 tests</li>
<li class="output-line output-line--go"><span class="output-time">14:03:37</span> tests passed: 1,284, skipped: 3</li>
<li class="output-line"><span class="output-time">14:03:38</span> publishing image orders-api:2026.09.3</li>
<li class="output-line"><span class="output-time">14:03:55</span> pushed 4 layers, 212 MB</li>
<li class="output-line"><span class="output-time">14:03:56</span> draining orders-console-01</li>
<li class="output-line"><span class="output-time">14:04:09</span> orders-console-01 drained, 0 open sessions</li>
<li class="output-line"><span class="output-time">14:04:10</span> starting orders-console-01 on 2026.09.3</li>
<li class="output-line output-line--error"><span class="output-time">14:04:25</span> health check failed: 192.0.2.41:8080 returned 503</li>
<li class="output-line output-line--note"><span class="output-time">14:04:25</span> retrying health check in 5s (attempt 2 of 5)</li>
<li class="output-line output-line--go"><span class="output-time">14:04:31</span> orders-console-01 healthy</li>
<li class="output-line"><span class="output-time">14:04:31</span> draining orders-console-02</li>
<li class="output-line"><span class="output-time">14:04:44</span> orders-console-02 drained, 0 open sessions</li>
<li class="output-line"><span class="output-time">14:04:45</span> starting orders-console-02 on 2026.09.3</li>
<li class="output-line output-line--go"><span class="output-time">14:04:58</span> orders-console-02 healthy</li>
<li class="output-line"><span class="output-time">14:04:58</span> switching traffic to 2026.09.3</li>
<li class="output-line"><span class="output-time">14:05:02</span> waiting for the next batch…</li>
</ul>
<button class="btn btn-sm output-jump" type="button" data-output-follow aria-controls="tail-pane">
<i class="ri-arrow-down-line"></i> Jump to latest
</button>
</div>
Application log
.output--columns lays each line out as .output-time,
.output-level, .output-source and .output-msg, aligned
down the pane. The level and source columns are --output-level-width and
--output-source-width on the pane. .output-line--debug and
--info join --warn and --error: info colours only
its level, because a pane of tinted info lines hides the warnings. The level icon is Remix
Icon, and the word stays beside it. .output-id,
.output-num, .output-str and .output-key highlight
what the app marked up; the library never parses a message. On a warn or error line they
take the line's colour.
- 09:14:01.902 DEBUG orders.sync polling "warehouse-feed", since=1789371241
- 09:14:02.004 INFO orders.sync received 42 changes for order ORD-4182
- 09:14:02.117 INFO billing.invoices invoice INV-20931 created for "Northwind Retail", total=1249.90 EUR
- 09:14:02.118 WARN orders.reservations stock service slow to answer for ORD-4182, took 2311 ms
- 09:14:03.560 INFO auth.sessions signed in "alex.fischer@example.com" from 203.0.113.17
- 09:14:04.771 ERROR orders.reservations reservation failed for ORD-4190: "stock service returned 504"
- 09:14:05.012 INFO notifications.mail queued 3 messages to "orders@example.com"
<ul class="output output--columns" tabindex="0" aria-label="Application log" style="max-width:860px">
<li class="output-line output-line--debug">
<span class="output-time">09:14:01.902</span>
<span class="output-level"><i class="ri-bug-line" aria-hidden="true"></i> DEBUG</span>
<span class="output-source">orders.sync</span>
<span class="output-msg">polling <span class="output-str">"warehouse-feed"</span>, <span class="output-key">since=</span><span class="output-num">1789371241</span></span>
</li>
<li class="output-line output-line--info">
<span class="output-time">09:14:02.004</span>
<span class="output-level"><i class="ri-information-line" aria-hidden="true"></i> INFO</span>
<span class="output-source">orders.sync</span>
<span class="output-msg">received <span class="output-num">42</span> changes for order <span class="output-id">ORD-4182</span></span>
</li>
<li class="output-line output-line--info">
<span class="output-time">09:14:02.117</span>
<span class="output-level"><i class="ri-information-line" aria-hidden="true"></i> INFO</span>
<span class="output-source">billing.invoices</span>
<span class="output-msg">invoice <span class="output-id">INV-20931</span> created for <span class="output-str">"Northwind Retail"</span>, <span class="output-key">total=</span><span class="output-num">1249.90</span> EUR</span>
</li>
<li class="output-line output-line--warn">
<span class="output-time">09:14:02.118</span>
<span class="output-level"><i class="ri-alert-line" aria-hidden="true"></i> WARN</span>
<span class="output-source">orders.reservations</span>
<span class="output-msg">stock service slow to answer for <span class="output-id">ORD-4182</span>, took <span class="output-num">2311</span> ms</span>
</li>
<li class="output-line output-line--info">
<span class="output-time">09:14:03.560</span>
<span class="output-level"><i class="ri-information-line" aria-hidden="true"></i> INFO</span>
<span class="output-source">auth.sessions</span>
<span class="output-msg">signed in <span class="output-str">"alex.fischer@example.com"</span> from <span class="output-id">203.0.113.17</span></span>
</li>
<li class="output-line output-line--error">
<span class="output-time">09:14:04.771</span>
<span class="output-level"><i class="ri-close-circle-line" aria-hidden="true"></i> ERROR</span>
<span class="output-source">orders.reservations</span>
<span class="output-msg">reservation failed for <span class="output-id">ORD-4190</span>: <span class="output-str">"stock service returned 504"</span></span>
</li>
<li class="output-line output-line--info">
<span class="output-time">09:14:05.012</span>
<span class="output-level"><i class="ri-information-line" aria-hidden="true"></i> INFO</span>
<span class="output-source">notifications.mail</span>
<span class="output-msg">queued <span class="output-num">3</span> messages to <span class="output-str">"orders@example.com"</span></span>
</li>
</ul>
Without highlighting
The same columns with no level modifier and no token classes, for a log where colour would claim more than the data does — an audit trail, where every entry matters equally. Everything on this page is opt-in per line and per token.
- 2026-09-14 16:20:04 INFO admin.users role "Approver" granted to alex.fischer@example.com
- 2026-09-14 16:21:37 INFO admin.settings payment terms changed from 14 to 30 days
- 2026-09-14 16:24:10 WARN admin.exports export of 18,204 customer records started outside business hours
- 2026-09-14 16:30:52 INFO admin.users api key "reporting-02" revoked
<ul class="output output--columns" tabindex="0" aria-label="Audit log" style="max-width:860px">
<li class="output-line">
<span class="output-time">2026-09-14 16:20:04</span>
<span class="output-level">INFO</span>
<span class="output-source">admin.users</span>
<span class="output-msg">role "Approver" granted to alex.fischer@example.com</span>
</li>
<li class="output-line">
<span class="output-time">2026-09-14 16:21:37</span>
<span class="output-level">INFO</span>
<span class="output-source">admin.settings</span>
<span class="output-msg">payment terms changed from 14 to 30 days</span>
</li>
<li class="output-line">
<span class="output-time">2026-09-14 16:24:10</span>
<span class="output-level">WARN</span>
<span class="output-source">admin.exports</span>
<span class="output-msg">export of 18,204 customer records started outside business hours</span>
</li>
<li class="output-line">
<span class="output-time">2026-09-14 16:30:52</span>
<span class="output-level">INFO</span>
<span class="output-source">admin.users</span>
<span class="output-msg">api key "reporting-02" revoked</span>
</li>
</ul>
Expanding rows
A row with a stack trace, a request or the entry's fields is a <details>
with .output-details inside the line: the columns go in its
<summary> and the rest in .output-trace. The caret sits in the
row gutter, so expanding and plain rows line up. Opening a row in a following pane lets go of
the tail when the row grows past the bottom, so the trace is not scrolled away.
- 11:32:08.410 INFO orders.worker picked up batch B-7713 with 25 orders
11:32:09.022 ERROR orders.worker unhandled exception while pricing ORD-4190
System.InvalidOperationException: No price list is active for currency 'CHF'. at Orders.Pricing.PriceListResolver.Resolve(String currency) in PriceListResolver.cs:line 58 at Orders.Pricing.OrderPricer.PriceAsync(Order order, CancellationToken ct) in OrderPricer.cs:line 112 at Orders.Worker.BatchProcessor.ProcessAsync(Batch batch, CancellationToken ct) in BatchProcessor.cs:line 74
11:32:09.540 WARN http.client POST /v2/reservations answered 429, backing off
request POST https://stock.example.com/v2/reservations host src-db-14 via 198.51.100.23 attempt 2 of 5 retry in 4.0 s trace id 4bf92f3577b34da6a3ce929d0e0e4736
- 11:32:13.601 INFO orders.worker batch B-7713 done: 24 priced, 1 failed
<ul class="output output--columns" tabindex="0" aria-label="Worker log" style="max-width:860px; max-height:none">
<li class="output-line output-line--info">
<span class="output-time">11:32:08.410</span>
<span class="output-level"><i class="ri-information-line" aria-hidden="true"></i> INFO</span>
<span class="output-source">orders.worker</span>
<span class="output-msg">picked up batch <span class="output-id">B-7713</span> with <span class="output-num">25</span> orders</span>
</li>
<li class="output-line output-line--error">
<details class="output-details">
<summary>
<span class="output-time">11:32:09.022</span>
<span class="output-level"><i class="ri-close-circle-line" aria-hidden="true"></i> ERROR</span>
<span class="output-source">orders.worker</span>
<span class="output-msg">unhandled exception while pricing <span class="output-id">ORD-4190</span></span>
</summary>
<pre class="output-trace">System.InvalidOperationException: No price list is active for currency 'CHF'.
at Orders.Pricing.PriceListResolver.Resolve(String currency) in PriceListResolver.cs:line 58
at Orders.Pricing.OrderPricer.PriceAsync(Order order, CancellationToken ct) in OrderPricer.cs:line 112
at Orders.Worker.BatchProcessor.ProcessAsync(Batch batch, CancellationToken ct) in BatchProcessor.cs:line 74</pre>
</details>
</li>
<li class="output-line output-line--warn">
<details class="output-details" open>
<summary>
<span class="output-time">11:32:09.540</span>
<span class="output-level"><i class="ri-alert-line" aria-hidden="true"></i> WARN</span>
<span class="output-source">http.client</span>
<span class="output-msg">POST /v2/reservations answered 429, backing off</span>
</summary>
<pre class="output-trace">request POST https://stock.example.com/v2/reservations
host src-db-14 via 198.51.100.23
attempt 2 of 5
retry in 4.0 s
trace id 4bf92f3577b34da6a3ce929d0e0e4736</pre>
</details>
</li>
<li class="output-line output-line--info">
<span class="output-time">11:32:13.601</span>
<span class="output-level"><i class="ri-information-line" aria-hidden="true"></i> INFO</span>
<span class="output-source">orders.worker</span>
<span class="output-msg">batch <span class="output-id">B-7713</span> done: <span class="output-num">24</span> priced, <span class="output-num">1</span> failed</span>
</li>
</ul>
Row actions
.output-actions is a strip at the end of the line that shows on hover and on
focus, and stays while its .menu is open. The buttons are
.btn-ghost .btn-icon .btn-sm, the copy button is data-copy, and
the menu is the usual .menu-anchor with data-menu-toggle. Put the
strip after the <details>, never inside its
<summary>. On a touch screen the strip is always shown and the line keeps
room for two buttons, so keep it to a copy button and a menu. An open menu holds a following pane still.
- 15:47:30.118
INFO
shop.import
imported 318 products from "catalogue-2026-09.csv"
15:47:31.402 ERROR shop.import row 212 rejected: SKU NW-10442 has no price
file catalogue-2026-09.csv row 212 column price value (empty)
- 15:47:31.980
INFO
shop.search
reindex queued for 317 products
<ul class="output output--columns" tabindex="0" aria-label="Integration log" style="max-width:860px; max-height:none">
<li class="output-line output-line--info">
<span class="output-time">15:47:30.118</span>
<span class="output-level"><i class="ri-information-line" aria-hidden="true"></i> INFO</span>
<span class="output-source">shop.import</span>
<span class="output-msg">imported <span class="output-num">318</span> products from <span class="output-str">"catalogue-2026-09.csv"</span></span>
<div class="output-actions">
<button class="btn btn-sm btn-ghost btn-icon" type="button" aria-label="Copy line" data-copy="15:47:30.118 INFO shop.import imported 318 products from catalogue-2026-09.csv">
<i class="ri-file-copy-line" data-copied-hide></i>
<i class="ri-check-line" data-copied-show="ok"></i>
</button>
<div class="menu-anchor">
<button class="btn btn-sm btn-ghost btn-icon" type="button" data-menu-toggle aria-expanded="false" aria-label="More actions for this line">
<i class="ri-more-2-fill"></i>
</button>
<div class="menu" hidden>
<button class="menu-item" type="button"><i class="ri-filter-3-line"></i> Only shop.import</button>
<button class="menu-item" type="button"><i class="ri-time-line"></i> Lines around this one</button>
<button class="menu-item" type="button"><i class="ri-link"></i> Copy link to line</button>
</div>
</div>
</div>
</li>
<li class="output-line output-line--error">
<details class="output-details">
<summary>
<span class="output-time">15:47:31.402</span>
<span class="output-level"><i class="ri-close-circle-line" aria-hidden="true"></i> ERROR</span>
<span class="output-source">shop.import</span>
<span class="output-msg">row <span class="output-num">212</span> rejected: SKU <span class="output-id">NW-10442</span> has no price</span>
</summary>
<pre class="output-trace">file catalogue-2026-09.csv
row 212
column price
value (empty)</pre>
</details>
<div class="output-actions">
<button class="btn btn-sm btn-ghost btn-icon" type="button" aria-label="Copy line" data-copy="15:47:31.402 ERROR shop.import row 212 rejected: SKU NW-10442 has no price">
<i class="ri-file-copy-line" data-copied-hide></i>
<i class="ri-check-line" data-copied-show="ok"></i>
</button>
<div class="menu-anchor">
<button class="btn btn-sm btn-ghost btn-icon" type="button" data-menu-toggle aria-expanded="false" aria-label="More actions for this line">
<i class="ri-more-2-fill"></i>
</button>
<div class="menu" hidden>
<button class="menu-item" type="button"><i class="ri-filter-3-line"></i> Only shop.import</button>
<button class="menu-item" type="button"><i class="ri-edit-line"></i> Open product NW-10442</button>
<hr class="menu-sep" />
<button class="menu-item" type="button"><i class="ri-eye-off-line"></i> Mute this message</button>
</div>
</div>
</div>
</li>
<li class="output-line output-line--info">
<span class="output-time">15:47:31.980</span>
<span class="output-level"><i class="ri-information-line" aria-hidden="true"></i> INFO</span>
<span class="output-source">shop.search</span>
<span class="output-msg">reindex queued for <span class="output-num">317</span> products</span>
<div class="output-actions">
<button class="btn btn-sm btn-ghost btn-icon" type="button" aria-label="Copy line" data-copy="15:47:31.980 INFO shop.search reindex queued for 317 products">
<i class="ri-file-copy-line" data-copied-hide></i>
<i class="ri-check-line" data-copied-show="ok"></i>
</button>
<div class="menu-anchor">
<button class="btn btn-sm btn-ghost btn-icon" type="button" data-menu-toggle aria-expanded="false" aria-label="More actions for this line">
<i class="ri-more-2-fill"></i>
</button>
<div class="menu" hidden>
<button class="menu-item" type="button"><i class="ri-filter-3-line"></i> Only shop.search</button>
<button class="menu-item" type="button"><i class="ri-time-line"></i> Lines around this one</button>
<button class="menu-item" type="button"><i class="ri-link"></i> Copy link to line</button>
</div>
</div>
</div>
</li>
</ul>
Level filters and wrapping
The level filter is a set of .chip buttons in a
.toolbar: aria-pressed for the state and
.chip--active for the look, set together by the app, which then renders only
the matching lines. Wrapping is a .segmented setting
that switches .output--nowrap on the pane.
- 08:02:44.310 WARN orders.reservations stock service slow to answer for ORD-4182, took 2311 ms
- 08:02:47.901 ERROR orders.reservations reservation failed for ORD-4190: "stock service returned 504"
- 08:05:12.066 WARN billing.invoices invoice INV-20931 is due in 2 days and has not been sent
- 08:09:30.555 ERROR notifications.mail delivery to "accounts@example.org" failed permanently: mailbox does not exist
<div style="max-width:860px">
<div class="toolbar">
<div class="toolbar-filters">
<input class="form-input form-input-sm toolbar-input toolbar-input--wide" type="search" placeholder="Search messages…" aria-label="Search messages" />
<div class="chip-set" role="group" aria-label="Levels">
<button class="chip" type="button" aria-pressed="false"><i class="ri-bug-line"></i><span class="chip-label">Debug</span><span class="text-nums">204</span></button>
<button class="chip" type="button" aria-pressed="false"><i class="ri-information-line"></i><span class="chip-label">Info</span><span class="text-nums">1,318</span></button>
<button class="chip chip--active" type="button" aria-pressed="true"><i class="ri-alert-line"></i><span class="chip-label">Warn</span><span class="text-nums">12</span></button>
<button class="chip chip--active" type="button" aria-pressed="true"><i class="ri-close-circle-line"></i><span class="chip-label">Error</span><span class="text-nums">3</span></button>
</div>
</div>
<div class="toolbar-actions">
<div class="segmented segmented--sm" role="group" aria-label="Long lines">
<label class="segmented-option"><input type="radio" name="log-wrap" checked /><span><i class="ri-text-wrap"></i> Wrap</span></label>
<label class="segmented-option"><input type="radio" name="log-wrap" /><span><i class="ri-arrow-right-line"></i> One line</span></label>
</div>
</div>
</div>
<ul class="output output--columns" tabindex="0" aria-label="Warnings and errors">
<li class="output-line output-line--warn">
<span class="output-time">08:02:44.310</span>
<span class="output-level"><i class="ri-alert-line" aria-hidden="true"></i> WARN</span>
<span class="output-source">orders.reservations</span>
<span class="output-msg">stock service slow to answer for <span class="output-id">ORD-4182</span>, took <span class="output-num">2311</span> ms</span>
</li>
<li class="output-line output-line--error">
<span class="output-time">08:02:47.901</span>
<span class="output-level"><i class="ri-close-circle-line" aria-hidden="true"></i> ERROR</span>
<span class="output-source">orders.reservations</span>
<span class="output-msg">reservation failed for <span class="output-id">ORD-4190</span>: <span class="output-str">"stock service returned 504"</span></span>
</li>
<li class="output-line output-line--warn">
<span class="output-time">08:05:12.066</span>
<span class="output-level"><i class="ri-alert-line" aria-hidden="true"></i> WARN</span>
<span class="output-source">billing.invoices</span>
<span class="output-msg">invoice <span class="output-id">INV-20931</span> is due in <span class="output-num">2</span> days and has not been sent</span>
</li>
<li class="output-line output-line--error">
<span class="output-time">08:09:30.555</span>
<span class="output-level"><i class="ri-close-circle-line" aria-hidden="true"></i> ERROR</span>
<span class="output-source">notifications.mail</span>
<span class="output-msg">delivery to <span class="output-str">"accounts@example.org"</span> failed permanently: mailbox does not exist</span>
</li>
</ul>
</div>
One line per entry, dense
.output--nowrap keeps every entry on one line and cuts the message with an
ellipsis; the pane never scrolls sideways, so the row actions stay in view. Wrapping stays the
default because a cut line hides the part of a message that differs — offer an expanding
row for the whole entry. .output--dense tightens the rows for scanning a long
stretch.
- 10:41:02.114 INFO http.server GET /api/orders?status=open&warehouse=north&page=3&pageSize=50 answered 200 in 38 ms
- 10:41:02.380 INFO http.server GET /api/orders/ORD-4182/lines answered 200 in 12 ms
- 10:41:03.007 WARN http.server PUT /api/orders/ORD-4182/reservation answered 409 in 204 ms: the reservation was changed by another session after it was loaded
- 10:41:03.551 INFO http.server GET /api/customers/search?q=northwind answered 200 in 61 ms
- 10:41:03.552 DEBUG cache.customers miss for key customers:search:northwind, stored for 300 s
- 10:41:04.912 ERROR http.server POST /api/invoices/INV-20931/send answered 502 in 30012 ms: upstream mail relay at 198.51.100.8 did not respond
- 10:41:05.230 INFO http.server GET /health answered 200 in 2 ms
<ul class="output output--columns output--nowrap output--dense" tabindex="0" aria-label="Request log" style="max-width:720px">
<li class="output-line output-line--info">
<span class="output-time">10:41:02.114</span>
<span class="output-level">INFO</span>
<span class="output-source">http.server</span>
<span class="output-msg">GET /api/orders?status=open&warehouse=north&page=3&pageSize=50 answered 200 in 38 ms</span>
</li>
<li class="output-line output-line--info">
<span class="output-time">10:41:02.380</span>
<span class="output-level">INFO</span>
<span class="output-source">http.server</span>
<span class="output-msg">GET /api/orders/ORD-4182/lines answered 200 in 12 ms</span>
</li>
<li class="output-line output-line--warn">
<span class="output-time">10:41:03.007</span>
<span class="output-level">WARN</span>
<span class="output-source">http.server</span>
<span class="output-msg">PUT /api/orders/ORD-4182/reservation answered 409 in 204 ms: the reservation was changed by another session after it was loaded</span>
</li>
<li class="output-line output-line--info">
<span class="output-time">10:41:03.551</span>
<span class="output-level">INFO</span>
<span class="output-source">http.server</span>
<span class="output-msg">GET /api/customers/search?q=northwind answered 200 in 61 ms</span>
</li>
<li class="output-line output-line--debug">
<span class="output-time">10:41:03.552</span>
<span class="output-level">DEBUG</span>
<span class="output-source">cache.customers</span>
<span class="output-msg">miss for key customers:search:northwind, stored for 300 s</span>
</li>
<li class="output-line output-line--error">
<span class="output-time">10:41:04.912</span>
<span class="output-level">ERROR</span>
<span class="output-source">http.server</span>
<span class="output-msg">POST /api/invoices/INV-20931/send answered 502 in 30012 ms: upstream mail relay at 198.51.100.8 did not respond</span>
</li>
<li class="output-line output-line--info">
<span class="output-time">10:41:05.230</span>
<span class="output-level">INFO</span>
<span class="output-source">http.server</span>
<span class="output-msg">GET /health answered 200 in 2 ms</span>
</li>
</ul>
Nothing to show
.output-empty is an <li> in the pane holding an
.empty-state, so the pane keeps its frame. Say
whether the log is empty or the filter emptied it, and offer the way back.
- No errors in the last hour
Lines at every other level are hidden by the level filter.
<div style="max-width:720px">
<div class="output-head">
<span class="health-badge health-badge--idle"><span class="health-dot"></span> Idle</span>
<span class="sedna-push">Errors in the last hour</span>
</div>
<ul class="output output--columns" aria-label="Errors in the last hour">
<li class="output-empty">
<div class="empty-state">
<i class="ri-checkbox-circle-line state-icon" aria-hidden="true"></i>
<span class="empty-state-title">No errors in the last hour</span>
<p>Lines at every other level are hidden by the level filter.</p>
<button class="btn btn-sm" type="button">Show all levels</button>
</div>
</li>
</ul>
</div>
Loading
The first load is .skeleton-text lines. Fetching more
around lines already shown is .output-busy, an <li> with a
.spinner and a few words, at the end it is loading into. Mark the pane
aria-busy="true" for both.
- Loading earlier lines…
- 07:00:00.004 INFO scheduler nightly stock reconciliation started
- 07:00:41.387 INFO scheduler nightly stock reconciliation finished, 3 differences
<div class="sedna-col sedna-gap-3" style="max-width:720px">
<ul class="output output--columns" aria-label="Application log" aria-busy="true">
<li class="output-line"><span class="skeleton skeleton-text" style="width:92%"></span></li>
<li class="output-line"><span class="skeleton skeleton-text" style="width:74%"></span></li>
<li class="output-line"><span class="skeleton skeleton-text" style="width:86%"></span></li>
<li class="output-line"><span class="skeleton skeleton-text" style="width:61%"></span></li>
</ul>
<ul class="output output--columns" aria-label="Application log" aria-busy="true">
<li class="output-busy"><span class="spinner" aria-hidden="true"></span> Loading earlier lines…</li>
<li class="output-line output-line--info">
<span class="output-time">07:00:00.004</span>
<span class="output-level">INFO</span>
<span class="output-source">scheduler</span>
<span class="output-msg">nightly stock reconciliation started</span>
</li>
<li class="output-line output-line--info">
<span class="output-time">07:00:41.387</span>
<span class="output-level">INFO</span>
<span class="output-source">scheduler</span>
<span class="output-msg">nightly stock reconciliation finished, 3 differences</span>
</li>
</ul>
</div>