Skip to content

feat: multi-pod/container log monitoring with word wrap - #21

Merged
Esysc merged 9 commits into
mainfrom
feature/multi-pods
Sep 9, 2026
Merged

Esysc merged 9 commits into
mainfrom
feature/multi-pods

Conversation

@Esysc

@Esysc Esysc commented Sep 9, 2026

Copy link
Copy Markdown
Owner

Summary

Enhances the log stream to support monitoring multiple containers/pods at once and improves the log display with word wrapping.

Changes

Multi-container selection

  • PodContainerSelect.jsx: Converted the pod/container picker from single-select to multi-select. Users can pick multiple containers across different pods; chosen values render as removable chips.
  • Whole-pod selection: Each pod row has a checkbox that selects/deselects all of that pod's containers at once, with an indeterminate state when only some are selected.
  • StreamConfig.jsx: Wires the picker to the config using comma-separated pod/container tokens.
  • StreamPanel.jsx: Container changes now trigger a debounced reconnect (previously the stream silently stayed on the old container). Filter chips are built per selected token.
  • logUtils.js: compileLogFilters now builds an anchored alternation regex from the selected container tokens.
  • main.go: Backend parses comma-separated container tokens, derives unique pod names, and builds the container/pod regex filters for the stern stream.

Word wrap

  • LogViewer.jsx: Log rows now use whitespace-pre-wrap break-words so long lines wrap vertically instead of overflowing horizontally. Horizontal overflow is hidden, rows size naturally, and virtualization uses inline spacers so variable-height rows don't overlap.

Tests

  • Added LogViewer.test.jsx (9 tests) and expanded PodContainerSelect.test.jsx (pod select-all / deselect).
  • Full frontend suite: 88/88 passing; lint and build clean.

Docs

  • Updated .github/instructions/unittestMcp.instructions.md to document the review_test protective gate.

Commits

  • 091c9c0 feat: support multiple container selection without reconnect
  • b9d425c feat: allow selecting an entire pod (all containers) in the picker
  • 8b722ff feat: wrap long log lines in LogViewer
  • 7ea3154 docs: add review_test protective gate to unit test instructions

Esysc added 4 commits September 9, 2026 08:38
Allow selecting multiple containers (across same or different pods)
in the Pod/Container picker without disconnecting and reconnecting.

- PodContainerSelect: multi-select checkboxes replacing single-select dropdown
- StreamConfig: stores multiple selections as comma-separated 'pod/container' tokens
- StreamPanel: auto-reconnects on container change (was missing), per-token removable chips
- logUtils: compileLogFilters handles comma-separated container tokens for client-side filtering
- main.go: parseRegexFilters builds alternation regex from comma-separated container tokens
Add a checkbox on each pod row that selects/deselects all of that pod's
containers at once, complementing the per-container checkboxes. Shows an
'indeterminate'/partial-count indicator when only some containers are picked.
- Switch log rows from whitespace-nowrap to whitespace-pre-wrap break-words
  so long lines wrap vertically instead of overflowing horizontally
- Hide horizontal overflow on the scroll container
- Let rows size naturally (min-height instead of fixed height) so wrapped
  lines are fully visible
- Replace absolute-position virtualization with inline spacers so variable
  height rows don't overlap
- Add LogViewer component tests

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

StreamConfig clears state with two sequential updateConfig calls that both spread stale config, so the container filter is not actually reset when clearing or picking a single whole-pod selection.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

This PR extends the log-streaming UI so a user can monitor multiple containers/pods at once and enables word wrapping for long log lines. It reworks the pod/container picker from single- to multi-select, threads a comma-separated pod/container token list through the frontend config and the Go backend's regex filtering, and switches the log viewer to naturally-sized wrapped rows with spacer-based virtualization. It fits into the existing StreamPanel → StreamConfig → PodContainerSelect config flow and the parseRegexFilters backend pipeline.

Changes:

  • Multi-select pod/container picker with per-pod select-all (indeterminate) checkboxes, chips, and comma-separated token config wiring across PodContainerSelect, StreamConfig, and StreamPanel.
  • Backend (main.go) and client (logUtils.js) now parse multiple tokens into anchored alternation regexes for pods and containers.
  • LogViewer wraps long lines (whitespace-pre-wrap break-words) and uses inline spacers for virtualization; new/expanded tests and docs.
File summaries
File Description
main.go Parses comma-separated container tokens, derives unique pod names, builds combined pod/container regex filters.
frontend/src/utils/logUtils.js compileLogFilters builds an anchored alternation regex from multiple container tokens.
frontend/src/components/stream/StreamPanel.jsx Reconnects on container change; builds per-token filter chips.
frontend/src/components/stream/StreamConfig.jsx Maps multi-select selection to container/query; has a stale multi-field update bug.
frontend/src/components/logs/LogViewer.jsx Word-wrapped, naturally-sized rows with spacer-based virtualization (fixed ROW_HEIGHT assumption).
frontend/src/components/common/PodContainerSelect.jsx Converted single-select picker to multi-select with per-pod checkboxes/chips.
frontend/src/components/logs/__tests__/LogViewer.test.jsx New tests for rendering, wrapping classes, and scroll buttons.
frontend/src/components/common/__tests__/PodContainerSelect.test.jsx Added multi-select and pod select-all/deselect tests.
.github/instructions/unittestMcp.instructions.md Documents the review_test protective gate.
Review details
  • Files reviewed: 9/9 changed files
  • Comments generated: 3
  • Review effort level: Balanced

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread frontend/src/components/logs/LogViewer.jsx
Comment thread frontend/src/components/stream/StreamConfig.jsx
Comment thread frontend/src/utils/logUtils.js
Esysc added 5 commits September 9, 2026 10:09
Addresses review feedback: the fixed ROW_HEIGHT virtualization drifted when
lines wrapped. Now each rendered row is measured via a callback ref and its
real height feeds prefix sums that drive the visible slice and spacers, so
wrapped rows contribute their actual size to the scroll geometry.

- Key measurements by log id (stable across filter changes)
- Binary-search the visible slice over measured prefix sums
- Reset measurements when the underlying log set changes
- Re-pin to the tail after measurements change total height while following
- Add test verifying measured heights are reflected in scroll geometry
Addresses review feedback: the empty-selection and single whole-pod branches
called updateConfig twice in a row. Since each call derives from the same
render-time config and forwards to setConfig, React applied only the last
call, so container was never actually cleared. Merge each pair into one
onChange call, matching the multi-select branch.

- Add StreamConfig tests covering clear, multi-select, and single-select
Addresses review feedback: the new comma-separated multi-token behavior in
compileLogFilters was untested. Add cases asserting that multiple
pod/container tokens (and mixed plain tokens) build an alternation that
matches any of the containers.
@Esysc
Esysc merged commit e4b51dd into main Sep 9, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants