feat: v0.7 log search and filtering#3
Open
jkhoffman wants to merge 15 commits into
Open
Conversation
Move src/tui/disk_log_reader.rs to src/disk_log_reader.rs and expose it as a top-level crate module. Also move StreamMode and LineSource enums into disk_log_reader to break the circular dependency with tui::app; re-export them from tui::app so all existing call sites remain unchanged. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…tation to spawn_process Move log file and LIDX index creation out of capture_output() into spawn_process() so that restart annotations can be written at sequence 0 before either capture task starts. The initial_annotation parameter writes the marker line synchronously to the stdout file and index, then advances the shared sequence counter to 1. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Pass initial_annotation through restart_process() and respawn_in_place() to spawn_process(), so annotations are written as the first log line before any child output. Removes post-spawn supervisor_tx sends that previously wrote annotations after a race window. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add `grep: Option<String>` and `regex: bool` fields to `Request::Logs` with `#[serde(default)]` for backward compatibility. Update all construction sites and the proptest strategy to include the new fields. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add five new flags to the Logs subcommand with parse-time validation (--context and --regex require --grep), follow-mode warnings for inapplicable flags, and stub pass-through to execute() ready for Tasks 8-9 to wire up the filter pipeline. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…skLogReader Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add src/cli/log_search.rs with the core search pipeline for non-follow log queries. The module provides: - SearchParams/SearchResult/SearchLine data types - search_process() pipeline: since resolution -> grep scan -> tail windowing -> context expansion -> line reading - parse_duration() for "30s"/"5m"/"2h" specs - expand_context() with overlapping range merging - resolve_since() supporting "start", "restart", and duration specs - print_results() with text (--separators) and JSONL output modes 10 unit tests covering parse_duration and expand_context edge cases. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Rewrite src/cli/logs.rs to use the log_search module for non-follow log reading (--grep, --regex, --since, --context, --json) and pass grep/regex to the daemon for follow mode. Add JSONL output for follow-mode --json. Also fix DiskLogReader to fall back to sequential line scan when index records are empty (unflushed), preventing blank output on newly-created log files. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The test_proxy_drops_route_after_process_exit test was flaky in CI because the exit-refresh tick (200ms) + proxy state update could take longer than the fixed 2s sleep. Replace with a retry loop (up to 5s) that polls for the expected "no running process" response. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…arators H1: find_stderr_position_by_stdout_seq() now uses binary search (O(log n)) instead of linear scan (O(n) index file opens per call). Sequence numbers are monotonically increasing so binary search is correct. H2: -- separators in text output now only appear when context expansion was used (any line has is_context=true). Previously, --grep without --context printed -- between every non-adjacent match. Removed the workaround filters in integration tests. Also removed unused _context parameter from print_results(). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
--grep: Substring or regex filtering (--regex) on log output. Server-side for--follow, client-side for non-follow.--since: Time-based log slicing —restart(since last restart marker),start(all retained history), or duration (30s/5m/2h).--context N: Show N lines before/after each match, with--group separators.--json: JSONL output withprocess,line_number,stream,text,contextfields.Ctrl-Rtoggles regex mode during filter input, with/r!error indicator for invalid patterns.[agent-procs] Restartedannotations at sequence 0, before any child output. Enables reliable--since restartacross size-based log rotations.Infrastructure changes
DiskLogReadermoved fromsrc/tui/to crate-levelsrc/disk_log_reader.rs(shared by CLI and TUI)MatchModeenum (Substring/Regex) for unified pattern matchingcapture_output()refactored to accept pre-opened file handlesspawn_process()acceptsinitial_annotationparametersrc/cli/log_search.rsmodule with the 4-stage filter pipelineTest plan
--grep "pattern"returns only matching lines--grep "pattern" --regexworks with regex alternation--grep "pattern" --tail 5returns last 5 matches, not last 5 lines filtered--grepwith no matches returns empty (exit 0)--grep "invalid[regex" --regexreturns error (exit 1)--contextwithout--grepreturns error (exit 1)--grep "pattern" --jsonreturns valid JSONL--since startreturns all output--since restartafter manual restart excludes pre-restart output--since restartwith no prior restart returns all output--grep "ERROR" --context 1shows context with--separators[agent-procs] Restarted (manual)annotation🤖 Generated with Claude Code