mirror of
https://github.com/kilyabin/psysonic.git
synced 2026-07-22 06:25:41 +00:00
feat(perf): live runtime logs tab in Performance Probe (#946)
* feat(perf): live runtime logs tab in Performance Probe Add a Logs tab that streams the backend runtime log ring buffer in-app, so the stdout/stderr console (unreachable on Windows without exporting) can be read live. The buffer now tracks a monotonic seq; a new tail_runtime_logs command returns lines incrementally and get_logging_mode reports the current depth. The tab has a depth switch (off/normal/debug) mirroring app settings, a line cap (500-5000), pause/clear, auto-follow, and an ordered comma-separated word filter where a plain word includes and a -word excludes, applied left to right as layers (sequence matters). * docs(changelog): note Performance Probe logs tab (PR #946) Add CHANGELOG entry and credits line for the live runtime logs tab. * fix(perf): pin log view position when scrolled up Auto-scroll keeps the logs tab at the tail, but once the user scrolls up the view now stays put — the previously-topmost line is re-pinned each tick while the log keeps appending below for further scrolling. History under the viewport is no longer trimmed while scrolled up (kept up to the ring-buffer ceiling); the cap is re-applied when following resumes. Buffer overflow is shown in the status line instead of an injected marker row. * fix(perf): scope logs tab to its own internal scroll The whole probe body scrolled (controls + filter + log) because the log container sized via height:100%, which WebKitGTK does not resolve against the flex body. Make the body a flex column with hidden overflow on the Logs tab and let the log view flex-fill, so depth/keep/pause/clear and the filter stay fixed while only the log lines scroll.
This commit is contained in:
@@ -138,6 +138,133 @@
|
||||
padding-right: 2px;
|
||||
}
|
||||
|
||||
/* Logs tab manages its own internal scroll: the body becomes a flex column with
|
||||
hidden overflow so only the log view scrolls, not the controls/filter. */
|
||||
.sidebar-perf-modal__body--logs {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
padding-right: 0;
|
||||
}
|
||||
|
||||
.perf-logs {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex: 1 1 auto;
|
||||
min-height: 0;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.perf-logs__controls {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: flex-end;
|
||||
gap: 8px;
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
|
||||
.perf-logs__control {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 3px;
|
||||
}
|
||||
|
||||
.perf-logs__control-label {
|
||||
font-size: 11px;
|
||||
color: var(--text-muted);
|
||||
}
|
||||
|
||||
.perf-logs__btn {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 5px;
|
||||
padding: 5px 10px;
|
||||
font-size: 12px;
|
||||
border-radius: 7px;
|
||||
border: 1px solid color-mix(in srgb, var(--text-muted) 30%, transparent);
|
||||
background: transparent;
|
||||
color: var(--text-primary);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.perf-logs__btn:hover {
|
||||
background: color-mix(in srgb, var(--text-muted) 16%, transparent);
|
||||
}
|
||||
|
||||
.perf-logs__btn[aria-pressed='true'] {
|
||||
border-color: color-mix(in srgb, var(--accent) 55%, transparent);
|
||||
color: var(--accent);
|
||||
}
|
||||
|
||||
.perf-logs__filter {
|
||||
width: 100%;
|
||||
flex: 0 0 auto;
|
||||
padding: 6px 9px;
|
||||
font-size: 12px;
|
||||
border-radius: 7px;
|
||||
border: 1px solid color-mix(in srgb, var(--text-muted) 28%, transparent);
|
||||
background: var(--bg-secondary, rgba(0, 0, 0, 0.2));
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
.perf-logs__view {
|
||||
position: relative;
|
||||
flex: 1 1 auto;
|
||||
min-height: 0;
|
||||
overflow-y: auto;
|
||||
padding: 8px 10px;
|
||||
border-radius: 8px;
|
||||
background: color-mix(in srgb, var(--text-muted) 8%, transparent);
|
||||
border: 1px solid color-mix(in srgb, var(--text-muted) 18%, transparent);
|
||||
font-family: var(--font-mono, ui-monospace, SFMono-Regular, Menlo, monospace);
|
||||
font-size: 11.5px;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.perf-logs__line {
|
||||
white-space: pre-wrap;
|
||||
word-break: break-word;
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
.perf-logs__line--marker {
|
||||
color: var(--accent);
|
||||
opacity: 0.8;
|
||||
text-align: center;
|
||||
padding: 2px 0;
|
||||
}
|
||||
|
||||
.perf-logs__empty {
|
||||
color: var(--text-muted);
|
||||
font-size: 12px;
|
||||
padding: 1.5rem 0.5rem;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.perf-logs__status {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 10px;
|
||||
flex: 0 0 auto;
|
||||
font-size: 11px;
|
||||
color: var(--text-muted);
|
||||
}
|
||||
|
||||
.perf-logs__jump {
|
||||
padding: 3px 9px;
|
||||
font-size: 11px;
|
||||
border-radius: 6px;
|
||||
border: 1px solid color-mix(in srgb, var(--accent) 45%, transparent);
|
||||
background: transparent;
|
||||
color: var(--accent);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.perf-logs__jump:hover {
|
||||
background: color-mix(in srgb, var(--accent) 14%, transparent);
|
||||
}
|
||||
|
||||
.perf-monitor-empty {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
Reference in New Issue
Block a user