Resolve tickets 071-074, 076: log-stream contamination, sort, ottyl_fmt column, ingest lag
- 076: gate auto-declared log-stream column/message params (`ParamDeclaration::log_stream_gated`) behind `is_log_stream_line` at extraction time, since their fixed-offset regex has no content anchor and previously extracted garbage from continuation lines and the header row itself (the regex crate doesn't support lookaround, so this couldn't be baked into the regex text). - 074: end-to-end regression test confirms sorting a real `log stream` capture by a log-stream column (e.g. PID) now actually reorders results, since 076's fix removes the garbage values that were corrupting the sort helper index; also add a "Building sort index…" indicator in the timeline UI for a slow first-time sort. - 072: attach the reserved `ottyl_fmt` pseudo-param to each `LogEntryDto`'s params so it can be picked as a Log Preview column (previously listed as pickable but always blank). - 073: track a rolling 5s high-watermark of ingestion-to-engine-processing lag and surface it in the nav stats popover next to approx_bytes_total. - 071: group the regex(...) help button back with the filter bar's other controls, and restructure the Filtering docs section into scannable per-feature subsections (also fixes stale log_type/process/pid mention). Tickets 070 (CLI scoping) and 075 (API unresponsiveness investigation) are left in place per their own scope — both are explicitly conversation/investigation tasks, not implementation tickets. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01A1ZJ3SrayzLzVndhVq9BmS
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
f34dbba6c7
commit
9fc7540a5b
+45
-16
@@ -69,6 +69,23 @@ function saveLogViewerHeight(px: number) {
|
||||
}
|
||||
}
|
||||
|
||||
// Ticket 074: a sort helper index's one-time full-scan build (`build_sort_helper_index`) runs
|
||||
// inline in the engine actor, so a `sort_by` poll can occasionally take much longer than the usual
|
||||
// sub-poll-interval round trip — without this, that stall looks exactly like "sorting is broken"
|
||||
// rather than "still indexing". Only flips `setBuilding(true)` if the fetch is still in flight after
|
||||
// `thresholdMs`, so an ordinary fast poll (helper index already built/incrementally maintained)
|
||||
// never flashes the indicator.
|
||||
const SORT_BUILDING_INDICATOR_THRESHOLD_MS = 400
|
||||
|
||||
function trackSlowSortedFetch<T>(sortBy: string | null, setBuilding: (building: boolean) => void, promise: Promise<T>): Promise<T> {
|
||||
if (!sortBy) return promise
|
||||
const timer = setTimeout(() => setBuilding(true), SORT_BUILDING_INDICATOR_THRESHOLD_MS)
|
||||
return promise.finally(() => {
|
||||
clearTimeout(timer)
|
||||
setBuilding(false)
|
||||
})
|
||||
}
|
||||
|
||||
/// Thin drag handle between the log viewer and the sections below it. Reports each pointer-move
|
||||
/// delta via `onResize` (letting the caller clamp/apply it) and fires `onResizeEnd` on release so
|
||||
/// the final size can be persisted once, not on every pixel of movement.
|
||||
@@ -286,6 +303,7 @@ function StandaloneLog() {
|
||||
const [filter, setFilter] = useState('')
|
||||
const [filterError, setFilterError] = useState<string | null>(null)
|
||||
const [sortSettings, setSortSettings] = useState<LogSortSettings>(loadLogSortSettings)
|
||||
const [sortIndexBuilding, setSortIndexBuilding] = useState(false)
|
||||
|
||||
function handleSortSettingsChange(next: LogSortSettings) {
|
||||
setSortSettings(next)
|
||||
@@ -341,14 +359,18 @@ function StandaloneLog() {
|
||||
bucketMs: effectiveRange ? computeBucketMs(effectiveRange.endMs - effectiveRange.startMs) : undefined,
|
||||
filter: filter || undefined,
|
||||
}),
|
||||
fetchLogs({
|
||||
startMs: effectiveRange?.startMs,
|
||||
endMs: effectiveRange?.endMs,
|
||||
limit: 1000,
|
||||
filter: filter || undefined,
|
||||
sortBy: sortSettings.sortBy ?? undefined,
|
||||
sortMissingFallback: sortSettings.sortBy ? sortSettings.sortMissingFallback : undefined,
|
||||
}),
|
||||
trackSlowSortedFetch(
|
||||
sortSettings.sortBy,
|
||||
setSortIndexBuilding,
|
||||
fetchLogs({
|
||||
startMs: effectiveRange?.startMs,
|
||||
endMs: effectiveRange?.endMs,
|
||||
limit: 1000,
|
||||
filter: filter || undefined,
|
||||
sortBy: sortSettings.sortBy ?? undefined,
|
||||
sortMissingFallback: sortSettings.sortBy ? sortSettings.sortMissingFallback : undefined,
|
||||
}),
|
||||
),
|
||||
// Ticket 058: params can get auto-declared from freshly ingested lines mid-run, not just from a user's own edit.
|
||||
fetchParamDeclarations(),
|
||||
])
|
||||
@@ -393,6 +415,7 @@ function StandaloneLog() {
|
||||
paramNames={params.map((p) => p.name)}
|
||||
sortSettings={sortSettings}
|
||||
onSortSettingsChange={handleSortSettingsChange}
|
||||
sortIndexBuilding={sortIndexBuilding}
|
||||
/>
|
||||
<LogPreview logs={logs} params={params} />
|
||||
</div>
|
||||
@@ -423,6 +446,7 @@ function FullApp() {
|
||||
const [logViewerCollapsed, setLogViewerCollapsed] = useSectionCollapsed('log-viewer')
|
||||
const [logViewerHeight, setLogViewerHeight] = useState(() => loadLogViewerHeight())
|
||||
const [sortSettings, setSortSettings] = useState<LogSortSettings>(loadLogSortSettings)
|
||||
const [sortIndexBuilding, setSortIndexBuilding] = useState(false)
|
||||
|
||||
function handleSortSettingsChange(next: LogSortSettings) {
|
||||
setSortSettings(next)
|
||||
@@ -497,14 +521,18 @@ function FullApp() {
|
||||
bucketMs: effectiveRange ? computeBucketMs(effectiveRange.endMs - effectiveRange.startMs) : undefined,
|
||||
filter: filter || undefined,
|
||||
}),
|
||||
fetchLogs({
|
||||
startMs: effectiveRange?.startMs,
|
||||
endMs: effectiveRange?.endMs,
|
||||
limit: 1000,
|
||||
filter: filter || undefined,
|
||||
sortBy: sortSettings.sortBy ?? undefined,
|
||||
sortMissingFallback: sortSettings.sortBy ? sortSettings.sortMissingFallback : undefined,
|
||||
}),
|
||||
trackSlowSortedFetch(
|
||||
sortSettings.sortBy,
|
||||
setSortIndexBuilding,
|
||||
fetchLogs({
|
||||
startMs: effectiveRange?.startMs,
|
||||
endMs: effectiveRange?.endMs,
|
||||
limit: 1000,
|
||||
filter: filter || undefined,
|
||||
sortBy: sortSettings.sortBy ?? undefined,
|
||||
sortMissingFallback: sortSettings.sortBy ? sortSettings.sortMissingFallback : undefined,
|
||||
}),
|
||||
),
|
||||
// Ticket 058: params can get auto-declared from freshly ingested lines mid-run, not just from a user's own edit.
|
||||
fetchParamDeclarations(),
|
||||
])
|
||||
@@ -566,6 +594,7 @@ function FullApp() {
|
||||
paramNames={params.map((p) => p.name)}
|
||||
sortSettings={sortSettings}
|
||||
onSortSettingsChange={handleSortSettingsChange}
|
||||
sortIndexBuilding={sortIndexBuilding}
|
||||
/>
|
||||
<LogPreview logs={logs} params={params} />
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user